diff --git a/contracts-domain/deployments/base/TransferDomainProcessor.json b/contracts-domain/deployments/base/TransferDomainProcessor.json index 42ea8220..382d1ec1 100644 --- a/contracts-domain/deployments/base/TransferDomainProcessor.json +++ b/contracts-domain/deployments/base/TransferDomainProcessor.json @@ -1,5 +1,5 @@ { - "address": "0x57C3C3880ca40a17d800FF9c42b5C0e2c026F45B", + "address": "0x5d915599DEaf3A15b47c2625F1910599B9D5a1fd", "abi": [ { "inputs": [ @@ -261,34 +261,34 @@ "type": "function" } ], - "transactionHash": "0xdd0da9fa55715536c1380ecd14ae93a4a6b988d4b6336b38cebd81d96907589c", + "transactionHash": "0xc9cc5d8c6239868dbe0abe78545e7396bb9996ea53653b4bc657ba76f26d84ae", "receipt": { "to": null, "from": "0x84e113087C97Cd80eA9D78983D4B8Ff61ECa1929", - "contractAddress": "0x57C3C3880ca40a17d800FF9c42b5C0e2c026F45B", - "transactionIndex": 88, - "gasUsed": "1844254", - "logsBloom": "0x00000000000000000000000000000000000000000000004000800000000000000000008000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000201000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d4f44d826d2bac2b3beeb4ee271204509c34651a25c6ca8102d4761aa98637e", - "transactionHash": "0xdd0da9fa55715536c1380ecd14ae93a4a6b988d4b6336b38cebd81d96907589c", + "contractAddress": "0x5d915599DEaf3A15b47c2625F1910599B9D5a1fd", + "transactionIndex": 71, + "gasUsed": "1844002", + "logsBloom": "0x00000000000000000000000000000000000000000000004000800000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000800000000000000001000000010000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000020000000000000000000000000000000000000000000001000000000000000000000", + "blockHash": "0xc6c3e945dfa29a014ae30f51fcbe885ef9aead7f431766487539bb8b8641c20a", + "transactionHash": "0xc9cc5d8c6239868dbe0abe78545e7396bb9996ea53653b4bc657ba76f26d84ae", "logs": [ { - "transactionIndex": 88, - "blockNumber": 20166829, - "transactionHash": "0xdd0da9fa55715536c1380ecd14ae93a4a6b988d4b6336b38cebd81d96907589c", - "address": "0x57C3C3880ca40a17d800FF9c42b5C0e2c026F45B", + "transactionIndex": 71, + "blockNumber": 20381165, + "transactionHash": "0xc9cc5d8c6239868dbe0abe78545e7396bb9996ea53653b4bc657ba76f26d84ae", + "address": "0x5d915599DEaf3A15b47c2625F1910599B9D5a1fd", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000084e113087c97cd80ea9d78983d4b8ff61eca1929" ], "data": "0x", - "logIndex": 302, - "blockHash": "0x4d4f44d826d2bac2b3beeb4ee271204509c34651a25c6ca8102d4761aa98637e" + "logIndex": 286, + "blockHash": "0xc6c3e945dfa29a014ae30f51fcbe885ef9aead7f431766487539bb8b8641c20a" } ], - "blockNumber": 20166829, - "cumulativeGasUsed": "18138147", + "blockNumber": 20381165, + "cumulativeGasUsed": "12709651", "status": 1, "byzantium": true }, @@ -299,10 +299,10 @@ "0" ], "numDeployments": 1, - "solcInputHash": "a43d75c8fa53cbd70612f5013c5d17a2", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_exchange\",\"type\":\"address\"},{\"internalType\":\"contract INullifierRegistry\",\"name\":\"_nullifierRegistry\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_emailFromAddress\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"emailFromAddress\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"exchange\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getEmailFromAddress\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"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\":[{\"internalType\":\"uint256[2]\",\"name\":\"a\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"b\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"c\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[10]\",\"name\":\"signals\",\"type\":\"uint256[10]\"}],\"internalType\":\"struct ITransferDomainProcessor.TransferProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"processProof\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"dkimKeyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"hashedReceiverId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"domainName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"bidId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_emailFromAddress\",\"type\":\"string\"}],\"name\":\"setEmailFromAddress\",\"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\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"_pA\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"_pB\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"_pC\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[10]\",\"name\":\"_pubSignals\",\"type\":\"uint256[10]\"}],\"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.\"},\"setEmailFromAddress(string)\":{\"params\":{\"_emailFromAddress\":\"The from email address for validated emails, MUST BE PROPERLY PADDED\"}},\"setTimestampBuffer(uint256)\":{\"params\":{\"_timestampBuffer\":\"The timestamp buffer for validated emails\"}},\"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\":{\"setEmailFromAddress(string)\":{\"notice\":\"ONLY OWNER: Sets the from email address for validated emails. Check that email address is properly padded (if necessary). Padding will be dependent on if unpacking functions cut trailing 0s or not.\"},\"setTimestampBuffer(uint256)\":{\"notice\":\"ONLY OWNER: Sets the timestamp buffer for validated emails. 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/TransferDomainProcessor.sol\":\"TransferDomainProcessor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"details\":{\"constantOptimizer\":true,\"cse\":true,\"deduplicate\":true,\"inliner\":true,\"jumpdestRemover\":true,\"orderLiterals\":true,\"peephole\":true,\"yul\":true,\"yulDetails\":{\"optimizerSteps\":\"u:fDnTOc\",\"stackAllocation\":true}},\"runs\":200},\"remappings\":[],\"viaIR\":true},\"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 (last updated v4.9.4) (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 function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\"},\"@zk-email/contracts/utils/StringUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.7.6;\\n\\n// https://github.com/nalinbhardwaj/ethdosnumber/blob/main/ethdos-contracts/src/HexStrings.sol\\nlibrary StringUtils {\\n bytes16 internal constant ALPHABET = \\\"0123456789abcdef\\\";\\n uint256 internal constant DEFAULT_PACK_SIZE = 31;\\n\\n /// @notice Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n /// @dev Credit to Open Zeppelin under MIT license https://github.com/OpenZeppelin/openzeppelin-contracts/blob/243adff49ce1700e0ecb99fe522fb16cff1d1ddc/contracts/utils/Strings.sol#L55\\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] = ALPHABET[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length);\\n for (uint256 i = buffer.length; i > 0; i--) {\\n buffer[i - 1] = ALPHABET[value & 0xf];\\n value >>= 4;\\n }\\n return string(buffer);\\n }\\n\\n function toString(uint256 value) internal pure returns (string memory) {\\n return toString(abi.encodePacked(value));\\n }\\n\\n function toString(bytes32 value) internal pure returns (string memory) {\\n return toString(abi.encodePacked(value));\\n }\\n\\n function toString(address account) internal pure returns (string memory) {\\n return toString(abi.encodePacked(account));\\n }\\n\\n function stringEq(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));\\n }\\n\\n function toString(bytes memory data) internal pure returns (string memory) {\\n bytes memory alphabet = \\\"0123456789abcdef\\\";\\n\\n bytes memory str = new bytes(2 + data.length * 2);\\n str[0] = \\\"0\\\";\\n str[1] = \\\"x\\\";\\n for (uint256 i = 0; i < data.length; i++) {\\n str[2 + i * 2] = alphabet[uint256(uint8(data[i] >> 4))];\\n str[3 + i * 2] = alphabet[uint256(uint8(data[i] & 0x0f))];\\n }\\n return string(str);\\n }\\n\\n // 1 packed byte = packSize (usually 31) normal bytes, all in one 255/256-bit value\\n // Note that this is not 32 due to the field modulus of circom\\n function convertPackedByteToString(uint256 packedByte, uint256 packSize)\\n internal\\n pure\\n returns (string memory extractedString)\\n {\\n uint256[] memory packedBytes = new uint256[](1);\\n packedBytes[0] = packedByte;\\n return convertPackedBytesToString(packedBytes, packSize, packSize);\\n }\\n\\n // Note: This convenience function removes the max string length check, which may cause misalignment with the circom\\n // If using this, then the circom needs to rangecheck packed length in the circuit itself\\n // This defaults to 31 bytes per packed byte\\n function convertPackedBytesToString(uint256[] memory packedBytes) \\n internal\\n pure\\n returns (string memory extractedString)\\n {\\n return convertPackedBytesToString(packedBytes, packedBytes.length * DEFAULT_PACK_SIZE, DEFAULT_PACK_SIZE);\\n }\\n\\n // Unpacks uint256s into bytes and then extracts the non-zero characters\\n // Only extracts contiguous non-zero characters and ensures theres only 1 such state\\n // Note that unpackedLen may be more than packedBytes.length * 8 since there may be 0s\\n // signals is the total number of signals (i.e. bytes) packed into the packedBytes. it defaults to packedBytes.length * packSize\\n function convertPackedBytesToString(uint256[] memory packedBytes, uint256 signals, uint256 packSize)\\n internal\\n pure\\n returns (string memory extractedString)\\n {\\n uint8 state = 0;\\n // bytes: 0 0 0 0 y u s h _ g 0 0 0\\n // state: 0 0 0 0 1 1 1 1 1 1 2 2 2\\n bytes memory nonzeroBytesArray = new bytes(packedBytes.length * packSize);\\n uint256 nonzeroBytesArrayIndex = 0;\\n for (uint16 i = 0; i < packedBytes.length; i++) {\\n uint256 packedByte = packedBytes[i];\\n uint8[] memory unpackedBytes = new uint8[](packSize);\\n for (uint256 j = 0; j < packSize; j++) {\\n unpackedBytes[j] = uint8(packedByte >> (j * 8));\\n }\\n for (uint256 j = 0; j < packSize; j++) {\\n uint256 unpackedByte = unpackedBytes[j]; //unpackedBytes[j];\\n if (unpackedByte != 0) {\\n nonzeroBytesArray[nonzeroBytesArrayIndex] = bytes1(uint8(unpackedByte));\\n nonzeroBytesArrayIndex++;\\n if (state % 2 == 0) {\\n state += 1;\\n }\\n } else {\\n if (state % 2 == 1) {\\n state += 1;\\n }\\n }\\n packedByte = packedByte >> 8;\\n }\\n }\\n // TODO: You might want to assert that the state is exactly 1 or 2\\n // If not, that means empty bytse have been removed from the middle and things have been concatenated.\\n // We removed due to some tests failing, but this is not ideal and the require should be uncommented as soon as tests pass with it.\\n\\n // require(state == 1 || state == 2, \\\"Invalid final state of packed bytes in email; more than two non-zero regions found!\\\");\\n require(state >= 1, \\\"No packed bytes found! Invalid final state of packed bytes in email; value is likely 0!\\\");\\n require(nonzeroBytesArrayIndex <= signals, \\\"Packed bytes more than allowed max number of signals!\\\");\\n string memory returnValue = removeTrailingZeros(string(nonzeroBytesArray));\\n return returnValue;\\n // Have to end at the end of the email -- state cannot be 1 since there should be an email footer\\n }\\n\\n function bytes32ToString(bytes32 input) internal pure returns (string memory) {\\n uint256 i;\\n for (i = 0; i < 32 && input[i] != 0; i++) {}\\n bytes memory resultBytes = new bytes(i);\\n for (i = 0; i < 32 && input[i] != 0; i++) {\\n resultBytes[i] = input[i];\\n }\\n return string(resultBytes);\\n }\\n\\n // sliceArray is used to slice an array of uint256s from start-end into a new array of uint256s\\n function sliceArray(uint256[] memory input, uint256 start, uint256 end) internal pure returns (uint256[] memory) {\\n require(start <= end && end <= input.length, \\\"Invalid slice indices\\\");\\n uint256[] memory result = new uint256[](end - start);\\n for (uint256 i = start; i < end; i++) {\\n result[i - start] = input[i];\\n }\\n return result;\\n }\\n\\n // stringToUint is used to convert a string like \\\"45\\\" to a uint256 4\\n function stringToUint(string memory s) internal pure returns (uint256) {\\n bytes memory b = bytes(s);\\n uint256 result = 0;\\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 // TODO: Currently truncates decimals\\n if (b[i] == 0x2E) {\\n return result;\\n }\\n }\\n return result;\\n }\\n\\n // getDomainFromEmail is used to extract the domain from an email i.e. the part after the @\\n function getDomainFromEmail(string memory fromEmail) internal pure returns (string memory) {\\n bytes memory emailBytes = bytes(fromEmail);\\n uint256 atIndex;\\n for (uint256 i = 0; i < emailBytes.length; i++) {\\n if (emailBytes[i] == \\\"@\\\") {\\n atIndex = i;\\n break;\\n }\\n }\\n\\n bytes memory domainBytes = new bytes(emailBytes.length - atIndex - 1);\\n for (uint256 j = 0; j < domainBytes.length; j++) {\\n domainBytes[j] = emailBytes[atIndex + 1 + j];\\n }\\n return bytes32ToString(bytes32(bytes(domainBytes)));\\n }\\n\\n function removeTrailingZeros(string memory input) public pure returns (string memory) {\\n bytes memory inputBytes = bytes(input);\\n uint256 endIndex = inputBytes.length;\\n\\n for (uint256 i = 0; i < inputBytes.length; i++) {\\n if (inputBytes[i] == 0) {\\n endIndex = i;\\n break;\\n }\\n }\\n\\n bytes memory resultBytes = new bytes(endIndex);\\n for (uint256 i = 0; i < endIndex; i++) {\\n resultBytes[i] = inputBytes[i];\\n }\\n\\n return string(resultBytes);\\n }\\n\\n // Upper/lower string utils from https://github.com/willitscale/solidity-util/blob/master/lib/Strings.sol\\n /**\\n * Upper\\n *\\n * Converts all the values of a string to their corresponding upper case\\n * value.\\n *\\n * @param _base When being used for a data type this is the extended object\\n * otherwise this is the string base to convert to upper case\\n * @return string\\n */\\n function upper(string memory _base) public pure returns (string memory) {\\n bytes memory _baseBytes = bytes(_base);\\n for (uint256 i = 0; i < _baseBytes.length; i++) {\\n _baseBytes[i] = _upper(_baseBytes[i]);\\n }\\n return string(_baseBytes);\\n }\\n\\n /**\\n * Lower\\n *\\n * Converts all the values of a string to their corresponding lower case\\n * value.\\n *\\n * @param _base When being used for a data type this is the extended object\\n * otherwise this is the string base to convert to lower case\\n * @return string\\n */\\n function lower(string memory _base) public pure returns (string memory) {\\n bytes memory _baseBytes = bytes(_base);\\n for (uint256 i = 0; i < _baseBytes.length; i++) {\\n _baseBytes[i] = _lower(_baseBytes[i]);\\n }\\n return string(_baseBytes);\\n }\\n\\n /**\\n * Upper\\n *\\n * Convert an alphabetic character to upper case and return the original\\n * value when not alphabetic\\n *\\n * @param _b1 The byte to be converted to upper case\\n * @return bytes1 The converted value if the passed value was alphabetic\\n * and in a lower case otherwise returns the original value\\n */\\n function _upper(bytes1 _b1) private pure returns (bytes1) {\\n if (_b1 >= 0x61 && _b1 <= 0x7A) {\\n return bytes1(uint8(_b1) - 32);\\n }\\n\\n return _b1;\\n }\\n\\n /**\\n * Lower\\n *\\n * Convert an alphabetic character to lower case and return the original\\n * value when not alphabetic\\n *\\n * @param _b1 The byte to be converted to lower case\\n * @return bytes1 The converted value if the passed value was alphabetic\\n * and in a upper case otherwise returns the original value\\n */\\n function _lower(bytes1 _b1) private pure returns (bytes1) {\\n if (_b1 >= 0x41 && _b1 <= 0x5A) {\\n return bytes1(uint8(_b1) + 32);\\n }\\n\\n return _b1;\\n }\\n}\\n\",\"keccak256\":\"0x8c5b56494116a0c056c63e28fe892eea9bee5b056b09efa6aba1c9a82dc26c18\",\"license\":\"MIT\"},\"contracts/TransferDomainProcessor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\nimport { StringUtils } from \\\"@zk-email/contracts/utils/StringUtils.sol\\\";\\n\\nimport { EmailBaseProcessor } from \\\"./external/processors/EmailBaseProcessor.sol\\\";\\nimport { INullifierRegistry } from \\\"./external/interfaces/INullifierRegistry.sol\\\";\\nimport { StringConversionUtils } from \\\"./external/lib/StringConversionUtils.sol\\\";\\n\\nimport { Groth16Verifier } from \\\"./verifiers/namecheap_transfer_verifier.sol\\\";\\nimport { ITransferDomainProcessor } from \\\"./interfaces/ITransferDomainProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract TransferDomainProcessor is Groth16Verifier, ITransferDomainProcessor, EmailBaseProcessor {\\n \\n using StringUtils for uint256[];\\n using StringConversionUtils for string;\\n\\n /* ============ Constants ============ */\\n uint256 constant PACK_SIZE = 31;\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _exchange,\\n INullifierRegistry _nullifierRegistry,\\n string memory _emailFromAddress,\\n uint256 _timestampBuffer\\n )\\n Groth16Verifier()\\n EmailBaseProcessor(\\n _exchange,\\n _nullifierRegistry,\\n _emailFromAddress,\\n _timestampBuffer\\n )\\n {}\\n \\n /* ============ External Functions ============ */\\n\\n function processProof(\\n TransferProof calldata _proof\\n )\\n external\\n override\\n onlyExchange\\n returns (\\n bytes32 dkimKeyHash,\\n bytes32 hashedReceiverId,\\n string memory domainName, \\n uint256 bidId\\n )\\n {\\n require(this.verifyProof(_proof.a, _proof.b, _proof.c, _proof.signals), \\\"Invalid Proof\\\");\\n\\n // Signal [0] is the DKIM key hash\\n dkimKeyHash = bytes32(_proof.signals[0]);\\n\\n // Signals [1:2] are the packed from email address\\n string memory fromEmail = _parseSignalArray(_proof.signals, 1, 2);\\n require(\\n keccak256(abi.encodePacked(fromEmail)) == keccak256(emailFromAddress), \\n \\\"Invalid email from address\\\"\\n );\\n \\n // Signals [2:7] are packed domain name\\n domainName = _parseSignalArray(_proof.signals, 2, 7);\\n\\n // Signal [7] is packed hashed namecheap id to which domain was transferred\\n hashedReceiverId = bytes32(_proof.signals[7]);\\n\\n // Check if email has been used previously, if not nullify it so it can't be used again\\n _validateAndAddNullifier(bytes32(_proof.signals[8]));\\n\\n // Signal [9] is bidId\\n bidId = _proof.signals[9];\\n }\\n \\n /* ============ Internal Functions ============ */\\n\\n function _parseSignalArray(uint256[10] calldata _signals, uint8 _from, uint8 _to) \\n internal \\n pure \\n returns (string memory) \\n {\\n uint256[] memory signalArray = new uint256[](_to - _from);\\n for (uint256 i = _from; i < _to; i++) {\\n signalArray[i - _from] = _signals[i];\\n }\\n\\n return signalArray.convertPackedBytesToString(signalArray.length * PACK_SIZE, PACK_SIZE);\\n }\\n}\\n\",\"keccak256\":\"0x27e7d34dbe222f5a865d0b34f276eac82f3888f00e9816c398ee5fe9cf18bb2c\",\"license\":\"MIT\"},\"contracts/external/interfaces/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/external/interfaces/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/external/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/external/processors/EmailBaseProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport { IKeyHashAdapterV2 } from \\\"../interfaces/IKeyHashAdapterV2.sol\\\";\\nimport { INullifierRegistry } from \\\"../interfaces/INullifierRegistry.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract EmailBaseProcessor is Ownable {\\n\\n /* ============ Modifiers ============ */\\n modifier onlyExchange() {\\n require(msg.sender == exchange, \\\"Only exchange can call this function\\\");\\n _;\\n }\\n\\n /* ============ State Variables ============ */\\n address public immutable exchange;\\n INullifierRegistry public nullifierRegistry;\\n bytes public emailFromAddress;\\n uint256 public timestampBuffer;\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _exchange,\\n INullifierRegistry _nullifierRegistry,\\n string memory _emailFromAddress,\\n uint256 _timestampBuffer\\n )\\n Ownable()\\n {\\n exchange = _exchange;\\n nullifierRegistry = _nullifierRegistry;\\n emailFromAddress = bytes(_emailFromAddress);\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice ONLY OWNER: Sets the from email address for validated emails. Check that email address is properly\\n * padded (if necessary). Padding will be dependent on if unpacking functions cut trailing 0s or not.\\n *\\n * @param _emailFromAddress The from email address for validated emails, MUST BE PROPERLY PADDED\\n */\\n function setEmailFromAddress(string memory _emailFromAddress) external onlyOwner {\\n emailFromAddress = bytes(_emailFromAddress);\\n }\\n\\n /**\\n * @notice ONLY OWNER: Sets the timestamp buffer for validated emails. 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 emails\\n */\\n function setTimestampBuffer(uint256 _timestampBuffer) external onlyOwner {\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ External Getters ============ */\\n\\n function getEmailFromAddress() external view returns (bytes memory) {\\n return emailFromAddress;\\n }\\n\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateAndAddNullifier(bytes32 _nullifier) internal {\\n require(!nullifierRegistry.isNullified(_nullifier), \\\"Nullifier has already been used\\\");\\n nullifierRegistry.addNullifier(_nullifier);\\n }\\n}\\n\",\"keccak256\":\"0xe210c8e937a457c2d2aff798f3696f04ce1d011470294f02fb1169006a385f07\",\"license\":\"MIT\"},\"contracts/interfaces/ITransferDomainProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n\\ninterface ITransferDomainProcessor {\\n\\n struct TransferProof {\\n uint256[2] a;\\n uint256[2][2] b;\\n uint256[2] c;\\n uint256[10] signals;\\n }\\n\\n function processProof(\\n TransferProof calldata _proof\\n ) \\n external \\n returns (\\n bytes32 dkimKeyHash, \\n bytes32 hashedReceiverId, \\n string memory domainName, \\n uint256 bidId\\n );\\n}\",\"keccak256\":\"0x9cf5f1b070d7bad73d8ae57f7b20d449853f96fcbb5df1a443723df41c91339d\",\"license\":\"MIT\"},\"contracts/verifiers/namecheap_transfer_verifier.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n/*\\n Copyright 2021 0KIMS association.\\n\\n This file is generated with [snarkJS](https://github.com/iden3/snarkjs).\\n\\n snarkJS is a free software: you can redistribute it and/or modify it\\n under the terms of the GNU General Public License as published by\\n the Free Software Foundation, either version 3 of the License, or\\n (at your option) any later version.\\n\\n snarkJS is distributed in the hope that it will be useful, but WITHOUT\\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\\n or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\\n License for more details.\\n\\n You should have received a copy of the GNU General Public License\\n along with snarkJS. If not, see .\\n*/\\n\\npragma solidity >=0.7.0 <0.9.0;\\n\\ncontract Groth16Verifier {\\n // Scalar field size\\n uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n // Base field size\\n uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\\n\\n // Verification Key data\\n uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042;\\n uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958;\\n uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132;\\n uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731;\\n uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679;\\n uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856;\\n uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;\\n uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;\\n uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;\\n uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;\\n uint256 constant deltax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;\\n uint256 constant deltax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;\\n uint256 constant deltay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;\\n uint256 constant deltay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;\\n\\n \\n uint256 constant IC0x = 12718791721466586474772975178991944367361898681403889293050590835735829974174;\\n uint256 constant IC0y = 6579614210328804738196110281777440845203538387714672921854127346802897741731;\\n \\n uint256 constant IC1x = 15050971342023334328313633330499885418161248915553086390701402242486225179368;\\n uint256 constant IC1y = 5024764877577619588829734526990256704181621131776349449360023481477820279987;\\n \\n uint256 constant IC2x = 7494265978725599958916265753653166549633529129800692658333846839504191651648;\\n uint256 constant IC2y = 6331829577874431053631060489192183034310045972687441697179743819760334117448;\\n \\n uint256 constant IC3x = 19001722242244131321371144536562173279385056519981716838131699446018662048085;\\n uint256 constant IC3y = 8148711952593941450664988855383229951630582602775661040234820121548658879338;\\n \\n uint256 constant IC4x = 3624352076627862068761560802183636400416483488844158805038644908873200708814;\\n uint256 constant IC4y = 20894074159790604892251457333772898092352374489464929653588484093719978460605;\\n \\n uint256 constant IC5x = 2098287694939727519558784139808406325855172668407809961967029546183317335265;\\n uint256 constant IC5y = 5659241113472526955215440521431168972841548603376846026887752206139550832697;\\n \\n uint256 constant IC6x = 17054571586962694690567468783102453574497782768524521043534058966826398455175;\\n uint256 constant IC6y = 4087439525418017845490176926142509334113265173570304433911881676407144081865;\\n \\n uint256 constant IC7x = 7441928267847731392209447389119131741297268634643246304512516729270550734194;\\n uint256 constant IC7y = 15714253901405577134617988311525363228461039013850912155558149694323922788327;\\n \\n uint256 constant IC8x = 11989172231499636764423272601594485978016807201316866170676011918612131765820;\\n uint256 constant IC8y = 15918479982497737545158513843427772249925445687882255296587424450200131669618;\\n \\n uint256 constant IC9x = 19827744545534206076315711984525184804508732918768894016552346430789516516368;\\n uint256 constant IC9y = 16361460611570894490152793347002588479282989223552655286979659973731335376509;\\n \\n uint256 constant IC10x = 10898965818757221383985300751768263931593441442012024286290119328446015154272;\\n uint256 constant IC10y = 6989418820395701171656324073128354251482680955655018162117108617053607002569;\\n \\n \\n // Memory data\\n uint16 constant pVk = 0;\\n uint16 constant pPairing = 128;\\n\\n uint16 constant pLastMem = 896;\\n\\n function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[10] calldata _pubSignals) public view returns (bool) {\\n assembly {\\n function checkField(v) {\\n if iszero(lt(v, r)) {\\n mstore(0, 0)\\n return(0, 0x20)\\n }\\n }\\n \\n // G1 function to multiply a G1 value(x,y) to value in an address\\n function g1_mulAccC(pR, x, y, s) {\\n let success\\n let mIn := mload(0x40)\\n mstore(mIn, x)\\n mstore(add(mIn, 32), y)\\n mstore(add(mIn, 64), s)\\n\\n success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)\\n\\n if iszero(success) {\\n mstore(0, 0)\\n return(0, 0x20)\\n }\\n\\n mstore(add(mIn, 64), mload(pR))\\n mstore(add(mIn, 96), mload(add(pR, 32)))\\n\\n success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)\\n\\n if iszero(success) {\\n mstore(0, 0)\\n return(0, 0x20)\\n }\\n }\\n\\n function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {\\n let _pPairing := add(pMem, pPairing)\\n let _pVk := add(pMem, pVk)\\n\\n mstore(_pVk, IC0x)\\n mstore(add(_pVk, 32), IC0y)\\n\\n // Compute the linear combination vk_x\\n \\n g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))\\n \\n g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))\\n \\n g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))\\n \\n g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))\\n \\n g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))\\n \\n g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160)))\\n \\n g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192)))\\n \\n g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224)))\\n \\n g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256)))\\n \\n g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288)))\\n \\n\\n // -A\\n mstore(_pPairing, calldataload(pA))\\n mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))\\n\\n // B\\n mstore(add(_pPairing, 64), calldataload(pB))\\n mstore(add(_pPairing, 96), calldataload(add(pB, 32)))\\n mstore(add(_pPairing, 128), calldataload(add(pB, 64)))\\n mstore(add(_pPairing, 160), calldataload(add(pB, 96)))\\n\\n // alpha1\\n mstore(add(_pPairing, 192), alphax)\\n mstore(add(_pPairing, 224), alphay)\\n\\n // beta2\\n mstore(add(_pPairing, 256), betax1)\\n mstore(add(_pPairing, 288), betax2)\\n mstore(add(_pPairing, 320), betay1)\\n mstore(add(_pPairing, 352), betay2)\\n\\n // vk_x\\n mstore(add(_pPairing, 384), mload(add(pMem, pVk)))\\n mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))\\n\\n\\n // gamma2\\n mstore(add(_pPairing, 448), gammax1)\\n mstore(add(_pPairing, 480), gammax2)\\n mstore(add(_pPairing, 512), gammay1)\\n mstore(add(_pPairing, 544), gammay2)\\n\\n // C\\n mstore(add(_pPairing, 576), calldataload(pC))\\n mstore(add(_pPairing, 608), calldataload(add(pC, 32)))\\n\\n // delta2\\n mstore(add(_pPairing, 640), deltax1)\\n mstore(add(_pPairing, 672), deltax2)\\n mstore(add(_pPairing, 704), deltay1)\\n mstore(add(_pPairing, 736), deltay2)\\n\\n\\n let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)\\n\\n isOk := and(success, mload(_pPairing))\\n }\\n\\n let pMem := mload(0x40)\\n mstore(0x40, add(pMem, pLastMem))\\n\\n // Validate that all evaluations \\u2208 F\\n \\n checkField(calldataload(add(_pubSignals, 0)))\\n \\n checkField(calldataload(add(_pubSignals, 32)))\\n \\n checkField(calldataload(add(_pubSignals, 64)))\\n \\n checkField(calldataload(add(_pubSignals, 96)))\\n \\n checkField(calldataload(add(_pubSignals, 128)))\\n \\n checkField(calldataload(add(_pubSignals, 160)))\\n \\n checkField(calldataload(add(_pubSignals, 192)))\\n \\n checkField(calldataload(add(_pubSignals, 224)))\\n \\n checkField(calldataload(add(_pubSignals, 256)))\\n \\n checkField(calldataload(add(_pubSignals, 288)))\\n \\n checkField(calldataload(add(_pubSignals, 320)))\\n \\n\\n // Validate all evaluations\\n let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)\\n\\n mstore(0, isValid)\\n return(0, 0x20)\\n }\\n }\\n }\\n\",\"keccak256\":\"0x8217154b5c54e3ae008197fcd5f09c15c539d7026ac0fcb2d80e19810edeee7e\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x60a06040523462000044576200002262000018620001f4565b929190916200021d565b604051611eb66200054c82396080518181816104da01526109460152611eb690f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b90601f01601f191681019081106001600160401b038211176200008157604052565b62000049565b906200009e6200009660405190565b92836200005f565b565b6001600160a01b031690565b90565b6001600160a01b0381165b036200004457565b905051906200009e82620000af565b6001600160a01b038116620000ba565b905051906200009e82620000d1565b6001600160401b0381116200008157602090601f01601f19160190565b60005b838110620001215750506000910152565b818101518382015260200162000110565b909291926200014b6200014582620000f0565b62000087565b9381855260208501908284011162000044576200009e926200010d565b9080601f8301121562000044578151620000ac9260200162000132565b80620000ba565b905051906200009e8262000185565b6080818303126200004457620001b28282620000c2565b92620001c28360208401620000e1565b604083015190936001600160401b0382116200004457620001ea81620000ac93860162000168565b936060016200018c565b6200021762002402803803806200020b8162000087565b9283398101906200019b565b90919293565b906200009e939291620004ab565b906001600160a01b03905b9181191691161790565b620000ac90620000a0906001600160a01b031682565b620000ac9062000240565b620000ac9062000256565b9062000280620000ac620002889262000261565b82546200022b565b9055565b634e487b7160e01b600052602260045260246000fd5b9060016002830492168015620002c5575b6020831014620002bf57565b6200028c565b91607f1691620002b3565b9160001960089290920291821b911b62000236565b620000ac620000ac620000ac9290565b91906200030a620000ac6200028893620002e5565b908354620002d0565b6200009e91600091620002f5565b8181106200032d575050565b806200033d600060019362000313565b0162000321565b9190601f81116200035457505050565b620003686200009e93600052602060002090565b906020601f8401819004830193106200038c575b6020601f90910104019062000321565b90915081906200037c565b90620003a1815190565b906001600160401b0382116200008157620003c982620003c28554620002a2565b8562000344565b602090601f8311600114620004085762000288929160009183620003fc575b5050600019600883021c1916906002021790565b015190503880620003e8565b601f198316916200041e85600052602060002090565b9260005b8181106200045f5750916002939185600196941062000445575b50505002019055565b01516000196008601f8516021c191690553880806200043c565b9193602060018192878701518155019501920162000422565b906200009e9162000397565b906000199062000236565b90620004a3620000ac6200028892620002e5565b825462000484565b6200009e9392620000ac620004dc93620004d493620004c9620004e4565b60805260016200026c565b600262000478565b60036200048f565b6200009e336000546001600160a01b031690620005038160006200026c565b6200053a620005337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09362000261565b9162000261565b916200054560405190565b600090a356fe6080604052600436101561001257600080fd5b60003560e01c806365cd296c146100d2578063715018a6146100cd5780638da5cb5b146100c8578063b2a3fda4146100c3578063b870676c146100be578063c0d05fed146100b9578063ced1e978146100b4578063d2f7265a146100af578063dbac5821146100aa578063f2fde38b146100a5578063f3bb70f6146100a05763f6c7226b036100e6576106bf565b6105f9565b61057b565b610520565b6104c5565b6104aa565b610483565b6102e7565b610265565b610206565b6101dd565b61019d565b90816102409103126100e65790565b600080fd5b90610240828203126100e657610100916100d7565b90565b9052565b60005b83811061011a5750506000910152565b818101518382015260200161010a565b61014b61015460209361015e9361013f815190565b80835293849260200190565b95869101610107565b601f01601f191690565b0190565b94939160609161019b946101896101969361018260808b019460008c0152565b60208a0152565b878203604089015261012a565b940152565b565b346100e6576101ce6101b86101b33660046100eb565b610d21565b906101c594929460405190565b94859485610162565b0390f35b60009103126100e657565b346100e6576101ed3660046101d2565b6101f561072c565b604051005b6001600160a01b031690565b346100e6576102163660046101d2565b6101ce6102216106ea565b604051918291826001600160a01b03909116815260200190565b805b036100e657565b9050359061019b8261023b565b906020828203126100e65761010091610244565b346100e6576101f5610278366004610251565b6115da565b610100916008021c6001600160a01b031690565b90610100915461027d565b61010060006001610291565b610100906101fa906001600160a01b031682565b610100906102a8565b610100906102bc565b610103906102c5565b60208101929161019b91906102ce565b346100e6576102f73660046101d2565b6101ce61030261029c565b604051918291826102d7565b634e487b7160e01b600052600060045260246000fd5b634e487b7160e01b600052602260045260246000fd5b906001600283049216801561035a575b602083101461035557565b610324565b91607f169161034a565b805460009392916103816103778361033a565b8085529360200190565b91600181169081156103d3575060011461039a57505050565b6103ad9192939450600052602060002090565b916000925b8184106103bf5750500190565b8054848401526020909301926001016103b2565b92949550505060ff1916825215156020020190565b9061010091610364565b634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff82111761042a57604052565b6103f2565b9061019b6104499261044060405190565b938480926103e8565b0383610408565b90600010610461576101009061042f565b61030e565b61010060006002610450565b60208082526101009291019061012a565b346100e6576104933660046101d2565b6101ce61049e610466565b60405191829182610472565b346100e6576104ba3660046101d2565b6101ce61049e6115e3565b346100e6576104d53660046101d2565b6101ce7f0000000000000000000000000000000000000000000000000000000000000000610221565b610100916008021c81565b9061010091546104fe565b61010060006003610509565b346100e6576105303660046101d2565b6101ce61053b610514565b6040519182918290815260200190565b6001600160a01b03811661023d565b9050359061019b8261054b565b906020828203126100e6576101009161055a565b346100e6576101f561058e366004610567565b610843565b919060408301116100e657565b919060808301116100e657565b91906101408301116100e657565b610240818303126100e6576105d08282610593565b926101006105e184604085016105a0565b936105ef8160c08601610593565b93610100016105ad565b346100e6576106093660046105bb565b92919091611dc5565b9061019b61061f60405190565b9283610408565b67ffffffffffffffff811161042a57602090601f01601f19160190565b90826000939282370152565b9092919261066461065f82610626565b610612565b938185526020850190828401116100e65761019b92610643565b9080601f830112156100e6578160206101009335910161064f565b906020828203126100e657813567ffffffffffffffff81116100e657610100920161067e565b346100e6576101f56106d2366004610699565b611594565b610100906101fa565b61010090546106d7565b61010060006106e0565b6106fc610788565b61019b61071a565b6101fa6101006101009290565b61010090610704565b61019b6107276000610711565b61087c565b61019b6106f4565b1561073b57565b60405162461bcd60e51b815280610784600482016020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b0390fd5b61019b6107936106ea565b6107ac61079f336101fa565b916001600160a01b031690565b14610734565b61019b906107be610788565b61081e565b156107ca57565b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b61019b906107276108326101fa6000610711565b6001600160a01b03831614156107c3565b61019b906107b2565b906001600160a01b03905b9181191691161790565b90610871610100610878926102c5565b825461084c565b9055565b61088660006106e0565b90610892816000610861565b6108c56108bf7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936102c5565b916102c5565b916108cf60405190565b600090a3565b156108dc57565b60405162461bcd60e51b8152602060048201526024808201527f4f6e6c792065786368616e67652063616e2063616c6c20746869732066756e636044820152633a34b7b760e11b6064820152608490fd5b61097694939291906109713361096b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001661079f565b146108d5565b610b73565b90919293565b80151561023d565b9050519061019b8261097c565b906020828203126100e65761010091610984565b9037565b61019b916040916109a5565b9061015e816040936109a9565b6109d26109ce60029390565b9190565b806000925b8484106109e5575050505050565b610a016109fa6001926109f58690565b6109b5565b9360400190565b930192916109d7565b61019b91610140916109a5565b610a4f61019b94610a4561010094989795610a3b61024086019a60008701906109a9565b60408501906109c2565b60c08301906109a9565b0190610a0a565b6040513d6000823e3d90fd5b15610a6957565b60405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210283937b7b360991b6044820152606490fd5b634e487b7160e01b600052603260045260246000fd5b90600a811015610ac5576020020190565b610a9e565b6101006101006101009290565b356101008161023b565b610aee6101006101009290565b60ff1690565b61015e610b0c92602092610b06815190565b94859290565b93849101610107565b61010091610af4565b6101009061042f565b15610b2e57565b60405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420656d61696c2066726f6d20616464726573730000000000006044820152606490fd5b50505050610b80306102c5565b602063f3bb70f6916000840190610bb96040860194610bc461010060c0890198018098610bac60405190565b9889978896879660e01b90565b865260048601610a17565b03915afa8015610d1c57610be091600091610cee575b50610a62565b610c03610bfe610bf9610bf36000610aca565b84610ab4565b610ad7565b610aca565b91600290610c88610c146001610ae1565b92610c826109ce610c73610c32610c2a85610ae1565b80988a610e1c565b610c5a610c3e60405190565b8092610c4e602083019182610b15565b90810382520382610408565b610c6c610c65825190565b9160200190565b2093610b1e565b610c7e610c65825190565b2090565b14610b27565b610100610bf9610cbc610bfe610bf9610cb6610cb0600798610ca98a610ae1565b908b610e1c565b97610aca565b88610ab4565b94610cde610cd9610bfe610bf9610cd36008610aca565b85610ab4565b611639565b610ce86009610aca565b90610ab4565b610d0f915060203d8111610d15575b610d078183610408565b810190610991565b38610bda565b503d610cfd565b610a56565b6109769060006060818061092d565b634e487b7160e01b600052601160045260246000fd5b610d559060ff165b9160ff1690565b90039060ff8211610d6257565b610d30565b6101006101006101009260ff1690565b67ffffffffffffffff811161042a5760208091020190565b90610d9c61065f83610d77565b918252565b369037565b9061019b610dbc610db684610d8f565b93610d77565b601f190160208401610da1565b6000198114610d625760010190565b91908203918211610d6257565b90610dee825190565b811015610ac5576020809102010190565b610100601f610aca565b81810292918115918404141715610d6257565b909290610e39610e34610e2f8686610d46565b610d67565b610da6565b91610e4385610d67565b610e4c85610d67565b811015610e9457610e8d81610e88610e6a610bf9610e4c9588610ab4565b610e85610e7f610e798c610d67565b85610dd8565b89610de5565b52565b610dc9565b9050610e43565b509350506101009150610ea5815190565b90610eb8610eb1610dff565b8093610e09565b906110c9565b90610d9c61065f83610626565b9061019b610dbc610edb84610ebe565b93610626565b610eee6101006101009290565b61ffff1690565b61ffff1661ffff8114610d625760010190565b6101006101006101009261ffff1690565b61010090610f2a6109ce6101009490565b901c90565b634e487b7160e01b600052601260045260246000fd5b610f519060ff16610d4e565b908115610f5c570690565b610f2f565b610f6d9060ff16610d4e565b019060ff8211610d6257565b610f8f610f896101009260ff1690565b60f81b90565b6001600160f81b03191690565b90610fa5825190565b811015610ac5570160200190565b61010090610f2a6109ce6101009460ff1690565b15610fce57565b60405162461bcd60e51b815260206004820152605760248201527f4e6f207061636b656420627974657320666f756e642120496e76616c6964206660448201527f696e616c207374617465206f66207061636b656420627974657320696e20656d60648201527f61696c3b2076616c7565206973206c696b656c79203021000000000000000000608482015260a490fd5b1561106657565b60405162461bcd60e51b815260206004820152603560248201527f5061636b6564206279746573206d6f7265207468616e20616c6c6f776564206d6044820152746178206e756d626572206f66207369676e616c732160581b6064820152608490fd5b926000926110d684610ae1565b6110ef6110ea836110e5895190565b610e09565b610ecb565b946110f981610aca565b9561110382610ee1565b965b6111106101008a5190565b61111989610f08565b10156112e75761113861113461112e8a610f08565b8b610de5565b5190565b98899661114487610da6565b9861114e86610aca565b8881101561119b5780610e888c8f6111969461118861118361118e9361117d6111776008610aca565b85610e09565b90610f19565b610ae1565b92610de5565b9060ff169052565b61114e565b5091909a50989295989793969194976111b388610aca565b955b8a8710156112c6576111d4610e2f6111cd8989610de5565b5160ff1690565b6111dd8a610aca565b811461127957906111f86111f361120a93610ae1565b610f79565b8a1a611204828b610f9c565b53610dc9565b9261121e6112186002610ae1565b8b610f45565b61122a610d4e8b610ae1565b14611255575b61124861124e915b6112426008610ae1565b90610fb3565b96610dc9565b95926111b5565b9861124861127061124e9261126a6001610ae1565b90610f61565b9a915050611230565b50926112886112186002610ae1565b600190611297610d4e83610ae1565b146112aa575b5061124861124e91611238565b6112be61124e929b61126a61124893610ae1565b9a915061129d565b989550935097949598916112da9150610ef5565b9695979197949094611105565b926109ce919598506101009750610100945061131a92509561010061132197611313610d4e6001610ae1565b1015610fc7565b111561105f565b611333565b610f8f610f896101009290565b80519060009261134284610aca565b61134d610100845190565b8110156113ef5761136f6113618285610f9c565b516001600160f81b03191690565b61138961137b87611326565b916001600160f81b03191690565b1461139c5761139790610dc9565b611342565b9250905b6113a983610ecb565b916113b385610aca565b845b8110156113e3576113dc816113d06113616113b59487610f9c565b881a6112048288610f9c565b90506113b3565b50935050610100915090565b50906113a0565b61019b90611402610788565b611589565b9160001960089290920291821b911b610857565b919061142c61010061087893610aca565b908354611407565b61019b9160009161141b565b81811061144b575050565b806114596000600193611434565b01611440565b9190601f811161146e57505050565b61148061019b93600052602060002090565b906020601f8401819004830193106114a2575b6020601f909101040190611440565b9091508190611493565b906114b5815190565b9067ffffffffffffffff821161042a576114d9826114d3855461033a565b8561145f565b602090601f831160011461151457610878929160009183611509575b5050600019600883021c1916906002021790565b0151905038806114f5565b601f1983169161152985600052602060002090565b9260005b8181106115675750916002939185600196941061154e575b50505002019055565b01516000196008601f8516021c19169055388080611545565b9193602060018192878701518155019501920161152d565b9061019b916114ac565b61019b90600261157f565b61019b906113f6565b61019b906115a9610788565b6115cf565b9060001990610857565b906115c861010061087892610aca565b82546115ae565b61019b9060036115b8565b61019b9061159d565b6101006002610b1e565b156115f457565b60405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e2075736564006044820152606490fd5b611668602061165061164b60016106e0565b6102c5565b63169394bb9061165f60405190565b93849260e01b90565b82526004820185905260249082905afa908115610d1c57611698916116939160009161170b57501590565b6115ed565b6116a561164b60016106e0565b90635bd4df3290823b156100e6576116e2926116d4600080946116c760405190565b9687958694859360e01b90565b835260048301526024820190565b03925af18015610d1c576116f35750565b61019b9060006117038183610408565b8101906101d2565b611723915060203d8111610d1557610d078183610408565b1590565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001111561175057565b6000805260206000f35b919290926040519384526020840152604083015260408260608160076107d05a03fa156117505760806040928251848201526020830151606082015260066107d05a03fa1561175057565b93909260606020947f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47866080860198611b4061012060008901977f1c1e94bcd36515d96e435f61ee4fa0dc859f4090dcd5430374ced5e4ba688c9e89527f0e8bedfefb241a5448eac861c9f80086b6607f3082ace30b718ad164db3867a3858a015261187760008201357f0b1bea87e58d7f9b1df1b6e6530258dc6bf8354ee1e0287efbcde5faf0876cb37f21468c42c1abfe13be4583929db42dc4b6f1a3feb44d8e1336bbd6337b9992e88c61175a565b6118c6858201357f0dffb044274ff4d10fbf5545d248655f5203dca9161a6fd6ad5308d4ad2d9a487f10919aaea1bb570dabdefb8f9328f924ab0d33a21482584e6dbe5cc23d707f408c61175a565b61191660408201357f120401ecf289d3509044f33e1aab31e9cc9242ca08b56fe495beb5bf63dcab6a7f2a0297fa255705f360180d052e0f129394b63fedbf85496d1f61e4c335d5a1558c61175a565b611965888201357f2e31a07bdd388f34a6d84d0472485df1348189472b2f0119f41660d3c22045bd7f08034f82261ae61a6d5991ff892682a8d3117745585fea2279e9baf22f982cce8c61175a565b6119b560808201357f0c8304577691476e7b57b48d30630acc74c9b52baf12c6ef8bc1e28cc78798397f04a396b83d64f44cb37262119ef21df828153f3e5b22833520b2892c83752ce18c61175a565b611a0560a08201357f090968a6484d95f390fc636cfe1613f6ee8dac2b288485a2cf277886982669c97f25b48ba246ea1a991339587df4a62b88be3279d0b3b1d326cf9521a33d7b15878c61175a565b611a5560c08201357f22bdf3d83eddebc573238bb59aabc778011e095a196740f3ac64f69991275fe77f1073fb6d0a6ed98484e814d7d7cc0382850f5e66ff79e3215e470ccdbc3925728c61175a565b611aa560e08201357f23318a569b541a09f38bb1b3d2dec411fd8c6650abe56326b4abc7cdf5fd0e727f1a81a189d3c977a50f37f8fb6442804d25dced44e296159c9d9a1a313ea45e3c8c61175a565b611af66101008201357f242c422f58c0818ce1bc402140ef550d2ce6f537f7b97990b6c853d772818e7d7f2bd61b1039bd486ebd25c9866b7a34429b9d05f3ada0d35090b2b5a04c03dc108c61175a565b01357f0f73def0c88e50c35c62db1ac618eceec4f44d1d0666468a9c28cd8c8cbf81c97f1818989682bac795f6357e1a3d405e82b9a3bdbc86f5eb980be62287b25d28608961175a565b80358a5201358103068688015280356040880152858101358288015260408101356080880152013560a08601527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e260c08601527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d192660e08601527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101008601527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101208601527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101408601527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8610160860152516101808501528260000101516101a08401527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101c08401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101e08401527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102008401527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa610220840152803561024084015201356102608201527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26102808201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6102a08201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102c08201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6102e08201526020816103008160086107d05a03fa90511690565b91611e779391611dd3600090565b50604051936103808501604052611ded6000850135611727565b611dfa6020850135611727565b611e076040850135611727565b611e146060850135611727565b611e216080850135611727565b611e2e60a0850135611727565b611e3b60c0850135611727565b611e4860e0850135611727565b611e56610100850135611727565b611e64610120850135611727565b611e72610140850135611727565b6117a5565b60005260206000f3fea2646970667358221220b070e387d647569a745b0f851caaf898e12804e32149ebe4dcfc527f1e24f21e64736f6c63430008120033", - "deployedBytecode": "0x6080604052600436101561001257600080fd5b60003560e01c806365cd296c146100d2578063715018a6146100cd5780638da5cb5b146100c8578063b2a3fda4146100c3578063b870676c146100be578063c0d05fed146100b9578063ced1e978146100b4578063d2f7265a146100af578063dbac5821146100aa578063f2fde38b146100a5578063f3bb70f6146100a05763f6c7226b036100e6576106bf565b6105f9565b61057b565b610520565b6104c5565b6104aa565b610483565b6102e7565b610265565b610206565b6101dd565b61019d565b90816102409103126100e65790565b600080fd5b90610240828203126100e657610100916100d7565b90565b9052565b60005b83811061011a5750506000910152565b818101518382015260200161010a565b61014b61015460209361015e9361013f815190565b80835293849260200190565b95869101610107565b601f01601f191690565b0190565b94939160609161019b946101896101969361018260808b019460008c0152565b60208a0152565b878203604089015261012a565b940152565b565b346100e6576101ce6101b86101b33660046100eb565b610d21565b906101c594929460405190565b94859485610162565b0390f35b60009103126100e657565b346100e6576101ed3660046101d2565b6101f561072c565b604051005b6001600160a01b031690565b346100e6576102163660046101d2565b6101ce6102216106ea565b604051918291826001600160a01b03909116815260200190565b805b036100e657565b9050359061019b8261023b565b906020828203126100e65761010091610244565b346100e6576101f5610278366004610251565b6115da565b610100916008021c6001600160a01b031690565b90610100915461027d565b61010060006001610291565b610100906101fa906001600160a01b031682565b610100906102a8565b610100906102bc565b610103906102c5565b60208101929161019b91906102ce565b346100e6576102f73660046101d2565b6101ce61030261029c565b604051918291826102d7565b634e487b7160e01b600052600060045260246000fd5b634e487b7160e01b600052602260045260246000fd5b906001600283049216801561035a575b602083101461035557565b610324565b91607f169161034a565b805460009392916103816103778361033a565b8085529360200190565b91600181169081156103d3575060011461039a57505050565b6103ad9192939450600052602060002090565b916000925b8184106103bf5750500190565b8054848401526020909301926001016103b2565b92949550505060ff1916825215156020020190565b9061010091610364565b634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff82111761042a57604052565b6103f2565b9061019b6104499261044060405190565b938480926103e8565b0383610408565b90600010610461576101009061042f565b61030e565b61010060006002610450565b60208082526101009291019061012a565b346100e6576104933660046101d2565b6101ce61049e610466565b60405191829182610472565b346100e6576104ba3660046101d2565b6101ce61049e6115e3565b346100e6576104d53660046101d2565b6101ce7f0000000000000000000000000000000000000000000000000000000000000000610221565b610100916008021c81565b9061010091546104fe565b61010060006003610509565b346100e6576105303660046101d2565b6101ce61053b610514565b6040519182918290815260200190565b6001600160a01b03811661023d565b9050359061019b8261054b565b906020828203126100e6576101009161055a565b346100e6576101f561058e366004610567565b610843565b919060408301116100e657565b919060808301116100e657565b91906101408301116100e657565b610240818303126100e6576105d08282610593565b926101006105e184604085016105a0565b936105ef8160c08601610593565b93610100016105ad565b346100e6576106093660046105bb565b92919091611dc5565b9061019b61061f60405190565b9283610408565b67ffffffffffffffff811161042a57602090601f01601f19160190565b90826000939282370152565b9092919261066461065f82610626565b610612565b938185526020850190828401116100e65761019b92610643565b9080601f830112156100e6578160206101009335910161064f565b906020828203126100e657813567ffffffffffffffff81116100e657610100920161067e565b346100e6576101f56106d2366004610699565b611594565b610100906101fa565b61010090546106d7565b61010060006106e0565b6106fc610788565b61019b61071a565b6101fa6101006101009290565b61010090610704565b61019b6107276000610711565b61087c565b61019b6106f4565b1561073b57565b60405162461bcd60e51b815280610784600482016020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b0390fd5b61019b6107936106ea565b6107ac61079f336101fa565b916001600160a01b031690565b14610734565b61019b906107be610788565b61081e565b156107ca57565b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b61019b906107276108326101fa6000610711565b6001600160a01b03831614156107c3565b61019b906107b2565b906001600160a01b03905b9181191691161790565b90610871610100610878926102c5565b825461084c565b9055565b61088660006106e0565b90610892816000610861565b6108c56108bf7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936102c5565b916102c5565b916108cf60405190565b600090a3565b156108dc57565b60405162461bcd60e51b8152602060048201526024808201527f4f6e6c792065786368616e67652063616e2063616c6c20746869732066756e636044820152633a34b7b760e11b6064820152608490fd5b61097694939291906109713361096b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001661079f565b146108d5565b610b73565b90919293565b80151561023d565b9050519061019b8261097c565b906020828203126100e65761010091610984565b9037565b61019b916040916109a5565b9061015e816040936109a9565b6109d26109ce60029390565b9190565b806000925b8484106109e5575050505050565b610a016109fa6001926109f58690565b6109b5565b9360400190565b930192916109d7565b61019b91610140916109a5565b610a4f61019b94610a4561010094989795610a3b61024086019a60008701906109a9565b60408501906109c2565b60c08301906109a9565b0190610a0a565b6040513d6000823e3d90fd5b15610a6957565b60405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210283937b7b360991b6044820152606490fd5b634e487b7160e01b600052603260045260246000fd5b90600a811015610ac5576020020190565b610a9e565b6101006101006101009290565b356101008161023b565b610aee6101006101009290565b60ff1690565b61015e610b0c92602092610b06815190565b94859290565b93849101610107565b61010091610af4565b6101009061042f565b15610b2e57565b60405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420656d61696c2066726f6d20616464726573730000000000006044820152606490fd5b50505050610b80306102c5565b602063f3bb70f6916000840190610bb96040860194610bc461010060c0890198018098610bac60405190565b9889978896879660e01b90565b865260048601610a17565b03915afa8015610d1c57610be091600091610cee575b50610a62565b610c03610bfe610bf9610bf36000610aca565b84610ab4565b610ad7565b610aca565b91600290610c88610c146001610ae1565b92610c826109ce610c73610c32610c2a85610ae1565b80988a610e1c565b610c5a610c3e60405190565b8092610c4e602083019182610b15565b90810382520382610408565b610c6c610c65825190565b9160200190565b2093610b1e565b610c7e610c65825190565b2090565b14610b27565b610100610bf9610cbc610bfe610bf9610cb6610cb0600798610ca98a610ae1565b908b610e1c565b97610aca565b88610ab4565b94610cde610cd9610bfe610bf9610cd36008610aca565b85610ab4565b611639565b610ce86009610aca565b90610ab4565b610d0f915060203d8111610d15575b610d078183610408565b810190610991565b38610bda565b503d610cfd565b610a56565b6109769060006060818061092d565b634e487b7160e01b600052601160045260246000fd5b610d559060ff165b9160ff1690565b90039060ff8211610d6257565b610d30565b6101006101006101009260ff1690565b67ffffffffffffffff811161042a5760208091020190565b90610d9c61065f83610d77565b918252565b369037565b9061019b610dbc610db684610d8f565b93610d77565b601f190160208401610da1565b6000198114610d625760010190565b91908203918211610d6257565b90610dee825190565b811015610ac5576020809102010190565b610100601f610aca565b81810292918115918404141715610d6257565b909290610e39610e34610e2f8686610d46565b610d67565b610da6565b91610e4385610d67565b610e4c85610d67565b811015610e9457610e8d81610e88610e6a610bf9610e4c9588610ab4565b610e85610e7f610e798c610d67565b85610dd8565b89610de5565b52565b610dc9565b9050610e43565b509350506101009150610ea5815190565b90610eb8610eb1610dff565b8093610e09565b906110c9565b90610d9c61065f83610626565b9061019b610dbc610edb84610ebe565b93610626565b610eee6101006101009290565b61ffff1690565b61ffff1661ffff8114610d625760010190565b6101006101006101009261ffff1690565b61010090610f2a6109ce6101009490565b901c90565b634e487b7160e01b600052601260045260246000fd5b610f519060ff16610d4e565b908115610f5c570690565b610f2f565b610f6d9060ff16610d4e565b019060ff8211610d6257565b610f8f610f896101009260ff1690565b60f81b90565b6001600160f81b03191690565b90610fa5825190565b811015610ac5570160200190565b61010090610f2a6109ce6101009460ff1690565b15610fce57565b60405162461bcd60e51b815260206004820152605760248201527f4e6f207061636b656420627974657320666f756e642120496e76616c6964206660448201527f696e616c207374617465206f66207061636b656420627974657320696e20656d60648201527f61696c3b2076616c7565206973206c696b656c79203021000000000000000000608482015260a490fd5b1561106657565b60405162461bcd60e51b815260206004820152603560248201527f5061636b6564206279746573206d6f7265207468616e20616c6c6f776564206d6044820152746178206e756d626572206f66207369676e616c732160581b6064820152608490fd5b926000926110d684610ae1565b6110ef6110ea836110e5895190565b610e09565b610ecb565b946110f981610aca565b9561110382610ee1565b965b6111106101008a5190565b61111989610f08565b10156112e75761113861113461112e8a610f08565b8b610de5565b5190565b98899661114487610da6565b9861114e86610aca565b8881101561119b5780610e888c8f6111969461118861118361118e9361117d6111776008610aca565b85610e09565b90610f19565b610ae1565b92610de5565b9060ff169052565b61114e565b5091909a50989295989793969194976111b388610aca565b955b8a8710156112c6576111d4610e2f6111cd8989610de5565b5160ff1690565b6111dd8a610aca565b811461127957906111f86111f361120a93610ae1565b610f79565b8a1a611204828b610f9c565b53610dc9565b9261121e6112186002610ae1565b8b610f45565b61122a610d4e8b610ae1565b14611255575b61124861124e915b6112426008610ae1565b90610fb3565b96610dc9565b95926111b5565b9861124861127061124e9261126a6001610ae1565b90610f61565b9a915050611230565b50926112886112186002610ae1565b600190611297610d4e83610ae1565b146112aa575b5061124861124e91611238565b6112be61124e929b61126a61124893610ae1565b9a915061129d565b989550935097949598916112da9150610ef5565b9695979197949094611105565b926109ce919598506101009750610100945061131a92509561010061132197611313610d4e6001610ae1565b1015610fc7565b111561105f565b611333565b610f8f610f896101009290565b80519060009261134284610aca565b61134d610100845190565b8110156113ef5761136f6113618285610f9c565b516001600160f81b03191690565b61138961137b87611326565b916001600160f81b03191690565b1461139c5761139790610dc9565b611342565b9250905b6113a983610ecb565b916113b385610aca565b845b8110156113e3576113dc816113d06113616113b59487610f9c565b881a6112048288610f9c565b90506113b3565b50935050610100915090565b50906113a0565b61019b90611402610788565b611589565b9160001960089290920291821b911b610857565b919061142c61010061087893610aca565b908354611407565b61019b9160009161141b565b81811061144b575050565b806114596000600193611434565b01611440565b9190601f811161146e57505050565b61148061019b93600052602060002090565b906020601f8401819004830193106114a2575b6020601f909101040190611440565b9091508190611493565b906114b5815190565b9067ffffffffffffffff821161042a576114d9826114d3855461033a565b8561145f565b602090601f831160011461151457610878929160009183611509575b5050600019600883021c1916906002021790565b0151905038806114f5565b601f1983169161152985600052602060002090565b9260005b8181106115675750916002939185600196941061154e575b50505002019055565b01516000196008601f8516021c19169055388080611545565b9193602060018192878701518155019501920161152d565b9061019b916114ac565b61019b90600261157f565b61019b906113f6565b61019b906115a9610788565b6115cf565b9060001990610857565b906115c861010061087892610aca565b82546115ae565b61019b9060036115b8565b61019b9061159d565b6101006002610b1e565b156115f457565b60405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e2075736564006044820152606490fd5b611668602061165061164b60016106e0565b6102c5565b63169394bb9061165f60405190565b93849260e01b90565b82526004820185905260249082905afa908115610d1c57611698916116939160009161170b57501590565b6115ed565b6116a561164b60016106e0565b90635bd4df3290823b156100e6576116e2926116d4600080946116c760405190565b9687958694859360e01b90565b835260048301526024820190565b03925af18015610d1c576116f35750565b61019b9060006117038183610408565b8101906101d2565b611723915060203d8111610d1557610d078183610408565b1590565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001111561175057565b6000805260206000f35b919290926040519384526020840152604083015260408260608160076107d05a03fa156117505760806040928251848201526020830151606082015260066107d05a03fa1561175057565b93909260606020947f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47866080860198611b4061012060008901977f1c1e94bcd36515d96e435f61ee4fa0dc859f4090dcd5430374ced5e4ba688c9e89527f0e8bedfefb241a5448eac861c9f80086b6607f3082ace30b718ad164db3867a3858a015261187760008201357f0b1bea87e58d7f9b1df1b6e6530258dc6bf8354ee1e0287efbcde5faf0876cb37f21468c42c1abfe13be4583929db42dc4b6f1a3feb44d8e1336bbd6337b9992e88c61175a565b6118c6858201357f0dffb044274ff4d10fbf5545d248655f5203dca9161a6fd6ad5308d4ad2d9a487f10919aaea1bb570dabdefb8f9328f924ab0d33a21482584e6dbe5cc23d707f408c61175a565b61191660408201357f120401ecf289d3509044f33e1aab31e9cc9242ca08b56fe495beb5bf63dcab6a7f2a0297fa255705f360180d052e0f129394b63fedbf85496d1f61e4c335d5a1558c61175a565b611965888201357f2e31a07bdd388f34a6d84d0472485df1348189472b2f0119f41660d3c22045bd7f08034f82261ae61a6d5991ff892682a8d3117745585fea2279e9baf22f982cce8c61175a565b6119b560808201357f0c8304577691476e7b57b48d30630acc74c9b52baf12c6ef8bc1e28cc78798397f04a396b83d64f44cb37262119ef21df828153f3e5b22833520b2892c83752ce18c61175a565b611a0560a08201357f090968a6484d95f390fc636cfe1613f6ee8dac2b288485a2cf277886982669c97f25b48ba246ea1a991339587df4a62b88be3279d0b3b1d326cf9521a33d7b15878c61175a565b611a5560c08201357f22bdf3d83eddebc573238bb59aabc778011e095a196740f3ac64f69991275fe77f1073fb6d0a6ed98484e814d7d7cc0382850f5e66ff79e3215e470ccdbc3925728c61175a565b611aa560e08201357f23318a569b541a09f38bb1b3d2dec411fd8c6650abe56326b4abc7cdf5fd0e727f1a81a189d3c977a50f37f8fb6442804d25dced44e296159c9d9a1a313ea45e3c8c61175a565b611af66101008201357f242c422f58c0818ce1bc402140ef550d2ce6f537f7b97990b6c853d772818e7d7f2bd61b1039bd486ebd25c9866b7a34429b9d05f3ada0d35090b2b5a04c03dc108c61175a565b01357f0f73def0c88e50c35c62db1ac618eceec4f44d1d0666468a9c28cd8c8cbf81c97f1818989682bac795f6357e1a3d405e82b9a3bdbc86f5eb980be62287b25d28608961175a565b80358a5201358103068688015280356040880152858101358288015260408101356080880152013560a08601527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e260c08601527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d192660e08601527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101008601527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101208601527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101408601527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8610160860152516101808501528260000101516101a08401527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101c08401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101e08401527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102008401527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa610220840152803561024084015201356102608201527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26102808201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6102a08201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102c08201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6102e08201526020816103008160086107d05a03fa90511690565b91611e779391611dd3600090565b50604051936103808501604052611ded6000850135611727565b611dfa6020850135611727565b611e076040850135611727565b611e146060850135611727565b611e216080850135611727565b611e2e60a0850135611727565b611e3b60c0850135611727565b611e4860e0850135611727565b611e56610100850135611727565b611e64610120850135611727565b611e72610140850135611727565b6117a5565b60005260206000f3fea2646970667358221220b070e387d647569a745b0f851caaf898e12804e32149ebe4dcfc527f1e24f21e64736f6c63430008120033", + "solcInputHash": "a22247643263102eca9fc6c72e24c17d", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_exchange\",\"type\":\"address\"},{\"internalType\":\"contract INullifierRegistry\",\"name\":\"_nullifierRegistry\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_emailFromAddress\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_timestampBuffer\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"emailFromAddress\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"exchange\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getEmailFromAddress\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"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\":[{\"internalType\":\"uint256[2]\",\"name\":\"a\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"b\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"c\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[10]\",\"name\":\"signals\",\"type\":\"uint256[10]\"}],\"internalType\":\"struct ITransferDomainProcessor.TransferProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"processProof\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"dkimKeyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"hashedReceiverId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"domainName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"bidId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_emailFromAddress\",\"type\":\"string\"}],\"name\":\"setEmailFromAddress\",\"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\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"_pA\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"_pB\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"_pC\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[10]\",\"name\":\"_pubSignals\",\"type\":\"uint256[10]\"}],\"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.\"},\"setEmailFromAddress(string)\":{\"params\":{\"_emailFromAddress\":\"The from email address for validated emails, MUST BE PROPERLY PADDED\"}},\"setTimestampBuffer(uint256)\":{\"params\":{\"_timestampBuffer\":\"The timestamp buffer for validated emails\"}},\"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\":{\"setEmailFromAddress(string)\":{\"notice\":\"ONLY OWNER: Sets the from email address for validated emails. Check that email address is properly padded (if necessary). Padding will be dependent on if unpacking functions cut trailing 0s or not.\"},\"setTimestampBuffer(uint256)\":{\"notice\":\"ONLY OWNER: Sets the timestamp buffer for validated emails. 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/TransferDomainProcessor.sol\":\"TransferDomainProcessor\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"details\":{\"constantOptimizer\":true,\"cse\":true,\"deduplicate\":true,\"inliner\":true,\"jumpdestRemover\":true,\"orderLiterals\":true,\"peephole\":true,\"yul\":true,\"yulDetails\":{\"optimizerSteps\":\"u:fDnTOc\",\"stackAllocation\":true}},\"runs\":200},\"remappings\":[],\"viaIR\":true},\"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 (last updated v4.9.4) (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 function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\"},\"@zk-email/contracts/utils/StringUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.7.6;\\n\\n// https://github.com/nalinbhardwaj/ethdosnumber/blob/main/ethdos-contracts/src/HexStrings.sol\\nlibrary StringUtils {\\n bytes16 internal constant ALPHABET = \\\"0123456789abcdef\\\";\\n uint256 internal constant DEFAULT_PACK_SIZE = 31;\\n\\n /// @notice Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n /// @dev Credit to Open Zeppelin under MIT license https://github.com/OpenZeppelin/openzeppelin-contracts/blob/243adff49ce1700e0ecb99fe522fb16cff1d1ddc/contracts/utils/Strings.sol#L55\\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] = ALPHABET[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length);\\n for (uint256 i = buffer.length; i > 0; i--) {\\n buffer[i - 1] = ALPHABET[value & 0xf];\\n value >>= 4;\\n }\\n return string(buffer);\\n }\\n\\n function toString(uint256 value) internal pure returns (string memory) {\\n return toString(abi.encodePacked(value));\\n }\\n\\n function toString(bytes32 value) internal pure returns (string memory) {\\n return toString(abi.encodePacked(value));\\n }\\n\\n function toString(address account) internal pure returns (string memory) {\\n return toString(abi.encodePacked(account));\\n }\\n\\n function stringEq(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));\\n }\\n\\n function toString(bytes memory data) internal pure returns (string memory) {\\n bytes memory alphabet = \\\"0123456789abcdef\\\";\\n\\n bytes memory str = new bytes(2 + data.length * 2);\\n str[0] = \\\"0\\\";\\n str[1] = \\\"x\\\";\\n for (uint256 i = 0; i < data.length; i++) {\\n str[2 + i * 2] = alphabet[uint256(uint8(data[i] >> 4))];\\n str[3 + i * 2] = alphabet[uint256(uint8(data[i] & 0x0f))];\\n }\\n return string(str);\\n }\\n\\n // 1 packed byte = packSize (usually 31) normal bytes, all in one 255/256-bit value\\n // Note that this is not 32 due to the field modulus of circom\\n function convertPackedByteToString(uint256 packedByte, uint256 packSize)\\n internal\\n pure\\n returns (string memory extractedString)\\n {\\n uint256[] memory packedBytes = new uint256[](1);\\n packedBytes[0] = packedByte;\\n return convertPackedBytesToString(packedBytes, packSize, packSize);\\n }\\n\\n // Note: This convenience function removes the max string length check, which may cause misalignment with the circom\\n // If using this, then the circom needs to rangecheck packed length in the circuit itself\\n // This defaults to 31 bytes per packed byte\\n function convertPackedBytesToString(uint256[] memory packedBytes) \\n internal\\n pure\\n returns (string memory extractedString)\\n {\\n return convertPackedBytesToString(packedBytes, packedBytes.length * DEFAULT_PACK_SIZE, DEFAULT_PACK_SIZE);\\n }\\n\\n // Unpacks uint256s into bytes and then extracts the non-zero characters\\n // Only extracts contiguous non-zero characters and ensures theres only 1 such state\\n // Note that unpackedLen may be more than packedBytes.length * 8 since there may be 0s\\n // signals is the total number of signals (i.e. bytes) packed into the packedBytes. it defaults to packedBytes.length * packSize\\n function convertPackedBytesToString(uint256[] memory packedBytes, uint256 signals, uint256 packSize)\\n internal\\n pure\\n returns (string memory extractedString)\\n {\\n uint8 state = 0;\\n // bytes: 0 0 0 0 y u s h _ g 0 0 0\\n // state: 0 0 0 0 1 1 1 1 1 1 2 2 2\\n bytes memory nonzeroBytesArray = new bytes(packedBytes.length * packSize);\\n uint256 nonzeroBytesArrayIndex = 0;\\n for (uint16 i = 0; i < packedBytes.length; i++) {\\n uint256 packedByte = packedBytes[i];\\n uint8[] memory unpackedBytes = new uint8[](packSize);\\n for (uint256 j = 0; j < packSize; j++) {\\n unpackedBytes[j] = uint8(packedByte >> (j * 8));\\n }\\n for (uint256 j = 0; j < packSize; j++) {\\n uint256 unpackedByte = unpackedBytes[j]; //unpackedBytes[j];\\n if (unpackedByte != 0) {\\n nonzeroBytesArray[nonzeroBytesArrayIndex] = bytes1(uint8(unpackedByte));\\n nonzeroBytesArrayIndex++;\\n if (state % 2 == 0) {\\n state += 1;\\n }\\n } else {\\n if (state % 2 == 1) {\\n state += 1;\\n }\\n }\\n packedByte = packedByte >> 8;\\n }\\n }\\n // TODO: You might want to assert that the state is exactly 1 or 2\\n // If not, that means empty bytse have been removed from the middle and things have been concatenated.\\n // We removed due to some tests failing, but this is not ideal and the require should be uncommented as soon as tests pass with it.\\n\\n // require(state == 1 || state == 2, \\\"Invalid final state of packed bytes in email; more than two non-zero regions found!\\\");\\n require(state >= 1, \\\"No packed bytes found! Invalid final state of packed bytes in email; value is likely 0!\\\");\\n require(nonzeroBytesArrayIndex <= signals, \\\"Packed bytes more than allowed max number of signals!\\\");\\n string memory returnValue = removeTrailingZeros(string(nonzeroBytesArray));\\n return returnValue;\\n // Have to end at the end of the email -- state cannot be 1 since there should be an email footer\\n }\\n\\n function bytes32ToString(bytes32 input) internal pure returns (string memory) {\\n uint256 i;\\n for (i = 0; i < 32 && input[i] != 0; i++) {}\\n bytes memory resultBytes = new bytes(i);\\n for (i = 0; i < 32 && input[i] != 0; i++) {\\n resultBytes[i] = input[i];\\n }\\n return string(resultBytes);\\n }\\n\\n // sliceArray is used to slice an array of uint256s from start-end into a new array of uint256s\\n function sliceArray(uint256[] memory input, uint256 start, uint256 end) internal pure returns (uint256[] memory) {\\n require(start <= end && end <= input.length, \\\"Invalid slice indices\\\");\\n uint256[] memory result = new uint256[](end - start);\\n for (uint256 i = start; i < end; i++) {\\n result[i - start] = input[i];\\n }\\n return result;\\n }\\n\\n // stringToUint is used to convert a string like \\\"45\\\" to a uint256 4\\n function stringToUint(string memory s) internal pure returns (uint256) {\\n bytes memory b = bytes(s);\\n uint256 result = 0;\\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 // TODO: Currently truncates decimals\\n if (b[i] == 0x2E) {\\n return result;\\n }\\n }\\n return result;\\n }\\n\\n // getDomainFromEmail is used to extract the domain from an email i.e. the part after the @\\n function getDomainFromEmail(string memory fromEmail) internal pure returns (string memory) {\\n bytes memory emailBytes = bytes(fromEmail);\\n uint256 atIndex;\\n for (uint256 i = 0; i < emailBytes.length; i++) {\\n if (emailBytes[i] == \\\"@\\\") {\\n atIndex = i;\\n break;\\n }\\n }\\n\\n bytes memory domainBytes = new bytes(emailBytes.length - atIndex - 1);\\n for (uint256 j = 0; j < domainBytes.length; j++) {\\n domainBytes[j] = emailBytes[atIndex + 1 + j];\\n }\\n return bytes32ToString(bytes32(bytes(domainBytes)));\\n }\\n\\n function removeTrailingZeros(string memory input) public pure returns (string memory) {\\n bytes memory inputBytes = bytes(input);\\n uint256 endIndex = inputBytes.length;\\n\\n for (uint256 i = 0; i < inputBytes.length; i++) {\\n if (inputBytes[i] == 0) {\\n endIndex = i;\\n break;\\n }\\n }\\n\\n bytes memory resultBytes = new bytes(endIndex);\\n for (uint256 i = 0; i < endIndex; i++) {\\n resultBytes[i] = inputBytes[i];\\n }\\n\\n return string(resultBytes);\\n }\\n\\n // Upper/lower string utils from https://github.com/willitscale/solidity-util/blob/master/lib/Strings.sol\\n /**\\n * Upper\\n *\\n * Converts all the values of a string to their corresponding upper case\\n * value.\\n *\\n * @param _base When being used for a data type this is the extended object\\n * otherwise this is the string base to convert to upper case\\n * @return string\\n */\\n function upper(string memory _base) public pure returns (string memory) {\\n bytes memory _baseBytes = bytes(_base);\\n for (uint256 i = 0; i < _baseBytes.length; i++) {\\n _baseBytes[i] = _upper(_baseBytes[i]);\\n }\\n return string(_baseBytes);\\n }\\n\\n /**\\n * Lower\\n *\\n * Converts all the values of a string to their corresponding lower case\\n * value.\\n *\\n * @param _base When being used for a data type this is the extended object\\n * otherwise this is the string base to convert to lower case\\n * @return string\\n */\\n function lower(string memory _base) public pure returns (string memory) {\\n bytes memory _baseBytes = bytes(_base);\\n for (uint256 i = 0; i < _baseBytes.length; i++) {\\n _baseBytes[i] = _lower(_baseBytes[i]);\\n }\\n return string(_baseBytes);\\n }\\n\\n /**\\n * Upper\\n *\\n * Convert an alphabetic character to upper case and return the original\\n * value when not alphabetic\\n *\\n * @param _b1 The byte to be converted to upper case\\n * @return bytes1 The converted value if the passed value was alphabetic\\n * and in a lower case otherwise returns the original value\\n */\\n function _upper(bytes1 _b1) private pure returns (bytes1) {\\n if (_b1 >= 0x61 && _b1 <= 0x7A) {\\n return bytes1(uint8(_b1) - 32);\\n }\\n\\n return _b1;\\n }\\n\\n /**\\n * Lower\\n *\\n * Convert an alphabetic character to lower case and return the original\\n * value when not alphabetic\\n *\\n * @param _b1 The byte to be converted to lower case\\n * @return bytes1 The converted value if the passed value was alphabetic\\n * and in a upper case otherwise returns the original value\\n */\\n function _lower(bytes1 _b1) private pure returns (bytes1) {\\n if (_b1 >= 0x41 && _b1 <= 0x5A) {\\n return bytes1(uint8(_b1) + 32);\\n }\\n\\n return _b1;\\n }\\n}\\n\",\"keccak256\":\"0x8c5b56494116a0c056c63e28fe892eea9bee5b056b09efa6aba1c9a82dc26c18\",\"license\":\"MIT\"},\"contracts/TransferDomainProcessor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\nimport { StringUtils } from \\\"@zk-email/contracts/utils/StringUtils.sol\\\";\\n\\nimport { EmailBaseProcessor } from \\\"./external/processors/EmailBaseProcessor.sol\\\";\\nimport { INullifierRegistry } from \\\"./external/interfaces/INullifierRegistry.sol\\\";\\nimport { StringConversionUtils } from \\\"./external/lib/StringConversionUtils.sol\\\";\\n\\nimport { Groth16Verifier } from \\\"./verifiers/namecheap_transfer_verifier.sol\\\";\\nimport { ITransferDomainProcessor } from \\\"./interfaces/ITransferDomainProcessor.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract TransferDomainProcessor is Groth16Verifier, ITransferDomainProcessor, EmailBaseProcessor {\\n \\n using StringUtils for uint256[];\\n using StringConversionUtils for string;\\n\\n /* ============ Constants ============ */\\n uint256 constant PACK_SIZE = 31;\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _exchange,\\n INullifierRegistry _nullifierRegistry,\\n string memory _emailFromAddress,\\n uint256 _timestampBuffer\\n )\\n Groth16Verifier()\\n EmailBaseProcessor(\\n _exchange,\\n _nullifierRegistry,\\n _emailFromAddress,\\n _timestampBuffer\\n )\\n {}\\n \\n /* ============ External Functions ============ */\\n\\n function processProof(\\n TransferProof calldata _proof\\n )\\n external\\n override\\n onlyExchange\\n returns (\\n bytes32 dkimKeyHash,\\n bytes32 hashedReceiverId,\\n string memory domainName, \\n uint256 bidId\\n )\\n {\\n require(this.verifyProof(_proof.a, _proof.b, _proof.c, _proof.signals), \\\"Invalid Proof\\\");\\n\\n // Signal [0] is the DKIM key hash\\n dkimKeyHash = bytes32(_proof.signals[0]);\\n\\n // Signals [1:2] are the packed from email address\\n string memory fromEmail = _parseSignalArray(_proof.signals, 1, 2);\\n require(\\n keccak256(abi.encodePacked(fromEmail)) == keccak256(emailFromAddress), \\n \\\"Invalid email from address\\\"\\n );\\n \\n // Signals [2:7] are packed domain name\\n domainName = _parseSignalArray(_proof.signals, 2, 7);\\n\\n // Signal [7] is packed hashed namecheap id to which domain was transferred\\n hashedReceiverId = bytes32(_proof.signals[7]);\\n\\n // Check if email has been used previously, if not nullify it so it can't be used again\\n _validateAndAddNullifier(bytes32(_proof.signals[8]));\\n\\n // Signal [9] is bidId\\n bidId = _proof.signals[9];\\n }\\n \\n /* ============ Internal Functions ============ */\\n\\n function _parseSignalArray(uint256[10] calldata _signals, uint8 _from, uint8 _to) \\n internal \\n pure \\n returns (string memory) \\n {\\n uint256[] memory signalArray = new uint256[](_to - _from);\\n for (uint256 i = _from; i < _to; i++) {\\n signalArray[i - _from] = _signals[i];\\n }\\n\\n return signalArray.convertPackedBytesToString(signalArray.length * PACK_SIZE, PACK_SIZE);\\n }\\n}\\n\",\"keccak256\":\"0x27e7d34dbe222f5a865d0b34f276eac82f3888f00e9816c398ee5fe9cf18bb2c\",\"license\":\"MIT\"},\"contracts/external/interfaces/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/external/interfaces/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/external/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/external/processors/EmailBaseProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport { IKeyHashAdapterV2 } from \\\"../interfaces/IKeyHashAdapterV2.sol\\\";\\nimport { INullifierRegistry } from \\\"../interfaces/INullifierRegistry.sol\\\";\\n\\npragma solidity ^0.8.18;\\n\\ncontract EmailBaseProcessor is Ownable {\\n\\n /* ============ Modifiers ============ */\\n modifier onlyExchange() {\\n require(msg.sender == exchange, \\\"Only exchange can call this function\\\");\\n _;\\n }\\n\\n /* ============ State Variables ============ */\\n address public immutable exchange;\\n INullifierRegistry public nullifierRegistry;\\n bytes public emailFromAddress;\\n uint256 public timestampBuffer;\\n\\n /* ============ Constructor ============ */\\n constructor(\\n address _exchange,\\n INullifierRegistry _nullifierRegistry,\\n string memory _emailFromAddress,\\n uint256 _timestampBuffer\\n )\\n Ownable()\\n {\\n exchange = _exchange;\\n nullifierRegistry = _nullifierRegistry;\\n emailFromAddress = bytes(_emailFromAddress);\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ External Functions ============ */\\n\\n /**\\n * @notice ONLY OWNER: Sets the from email address for validated emails. Check that email address is properly\\n * padded (if necessary). Padding will be dependent on if unpacking functions cut trailing 0s or not.\\n *\\n * @param _emailFromAddress The from email address for validated emails, MUST BE PROPERLY PADDED\\n */\\n function setEmailFromAddress(string memory _emailFromAddress) external onlyOwner {\\n emailFromAddress = bytes(_emailFromAddress);\\n }\\n\\n /**\\n * @notice ONLY OWNER: Sets the timestamp buffer for validated emails. 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 emails\\n */\\n function setTimestampBuffer(uint256 _timestampBuffer) external onlyOwner {\\n timestampBuffer = _timestampBuffer;\\n }\\n\\n /* ============ External Getters ============ */\\n\\n function getEmailFromAddress() external view returns (bytes memory) {\\n return emailFromAddress;\\n }\\n\\n\\n /* ============ Internal Functions ============ */\\n\\n function _validateAndAddNullifier(bytes32 _nullifier) internal {\\n require(!nullifierRegistry.isNullified(_nullifier), \\\"Nullifier has already been used\\\");\\n nullifierRegistry.addNullifier(_nullifier);\\n }\\n}\\n\",\"keccak256\":\"0xe210c8e937a457c2d2aff798f3696f04ce1d011470294f02fb1169006a385f07\",\"license\":\"MIT\"},\"contracts/interfaces/ITransferDomainProcessor.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n\\ninterface ITransferDomainProcessor {\\n\\n struct TransferProof {\\n uint256[2] a;\\n uint256[2][2] b;\\n uint256[2] c;\\n uint256[10] signals;\\n }\\n\\n function processProof(\\n TransferProof calldata _proof\\n ) \\n external \\n returns (\\n bytes32 dkimKeyHash, \\n bytes32 hashedReceiverId, \\n string memory domainName, \\n uint256 bidId\\n );\\n}\",\"keccak256\":\"0x9cf5f1b070d7bad73d8ae57f7b20d449853f96fcbb5df1a443723df41c91339d\",\"license\":\"MIT\"},\"contracts/verifiers/namecheap_transfer_verifier.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n/*\\n Copyright 2021 0KIMS association.\\n\\n This file is generated with [snarkJS](https://github.com/iden3/snarkjs).\\n\\n snarkJS is a free software: you can redistribute it and/or modify it\\n under the terms of the GNU General Public License as published by\\n the Free Software Foundation, either version 3 of the License, or\\n (at your option) any later version.\\n\\n snarkJS is distributed in the hope that it will be useful, but WITHOUT\\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\\n or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\\n License for more details.\\n\\n You should have received a copy of the GNU General Public License\\n along with snarkJS. If not, see .\\n*/\\n\\npragma solidity >=0.7.0 <0.9.0;\\n\\ncontract Groth16Verifier {\\n // Scalar field size\\n uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n // Base field size\\n uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\\n\\n // Verification Key data\\n uint256 constant alphax = 16428432848801857252194528405604668803277877773566238944394625302971855135431;\\n uint256 constant alphay = 16846502678714586896801519656441059708016666274385668027902869494772365009666;\\n uint256 constant betax1 = 3182164110458002340215786955198810119980427837186618912744689678939861918171;\\n uint256 constant betax2 = 16348171800823588416173124589066524623406261996681292662100840445103873053252;\\n uint256 constant betay1 = 4920802715848186258981584729175884379674325733638798907835771393452862684714;\\n uint256 constant betay2 = 19687132236965066906216944365591810874384658708175106803089633851114028275753;\\n uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;\\n uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;\\n uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;\\n uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;\\n uint256 constant deltax1 = 1482036359054785987758983791437636255761203148422438653991915394359246721370;\\n uint256 constant deltax2 = 10001792791670748994653802587965307894251588681124493339739643276539399327199;\\n uint256 constant deltay1 = 12929924181374602539079631103652565558658437684289021022192643357266276129313;\\n uint256 constant deltay2 = 18621234594885561836856860416599021020030685616956494244557460320066348275486;\\n\\n\\n uint256 constant IC0x = 13679841311419499947196488030563927052737833631831087839800108582001619982756;\\n uint256 constant IC0y = 14398831345642232008615460969424497321419317733481671851297924133275173512121;\\n\\n uint256 constant IC1x = 2408377228439232698160803002782752816762776284505564408880728084177561554601;\\n uint256 constant IC1y = 4562823341627914579340945271513298981280656371775082655869052525475797696282;\\n\\n uint256 constant IC2x = 11698161615520749679058702638780643731158760523880360973169686160750874723717;\\n uint256 constant IC2y = 5482072052337866918379448154185642235470279334903213679209093769947335616093;\\n\\n uint256 constant IC3x = 20768666777689851453960746019474086479608334345599593721826216429323116802773;\\n uint256 constant IC3y = 144384800173925255346616036805594882403322575509153153064641653383667680325;\\n\\n uint256 constant IC4x = 5484190953638831817876258480017744165730276029855186594303418421204653869358;\\n uint256 constant IC4y = 2388977283212189651166234573571473197529151009141226183250075013106275368678;\\n\\n uint256 constant IC5x = 17286960896074201491464437213186707946980083024758675396143906384940172672768;\\n uint256 constant IC5y = 5559244286107427512674714237837993184640251130340291817174978126569513551048;\\n\\n uint256 constant IC6x = 5981106732853641044464779767035945345345676221237979116689771873940770600376;\\n uint256 constant IC6y = 16757892553277885270560523048286665969871413522533097385031102756444326127164;\\n\\n uint256 constant IC7x = 21137398581361954385460769732122488724166715754152295898647889069721843981111;\\n uint256 constant IC7y = 17117057588842742212408259815326568334655191160255595656714878965037331239848;\\n\\n uint256 constant IC8x = 16214254713514974179767304814474510985714849436687773447034352068497147314860;\\n uint256 constant IC8y = 13028412764820438875408464005100529475148539560770504369038194564947786526663;\\n\\n uint256 constant IC9x = 18408046483761423912872515862380512887546745528686003625682162751275305246737;\\n uint256 constant IC9y = 14576373605584916924675717896952852805094073315049779994296007237958279154545;\\n\\n uint256 constant IC10x = 19754959014163302021033520556658948350285362357974437446624957863682467085464;\\n uint256 constant IC10y = 6837772045404055003823337103437422613565931626793512604498169200205461541951;\\n\\n\\n // Memory data\\n uint16 constant pVk = 0;\\n uint16 constant pPairing = 128;\\n\\n uint16 constant pLastMem = 896;\\n\\n function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[10] calldata _pubSignals) public view returns (bool) {\\n assembly {\\n function checkField(v) {\\n if iszero(lt(v, r)) {\\n mstore(0, 0)\\n return(0, 0x20)\\n }\\n }\\n\\n // G1 function to multiply a G1 value(x,y) to value in an address\\n function g1_mulAccC(pR, x, y, s) {\\n let success\\n let mIn := mload(0x40)\\n mstore(mIn, x)\\n mstore(add(mIn, 32), y)\\n mstore(add(mIn, 64), s)\\n\\n success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)\\n\\n if iszero(success) {\\n mstore(0, 0)\\n return(0, 0x20)\\n }\\n\\n mstore(add(mIn, 64), mload(pR))\\n mstore(add(mIn, 96), mload(add(pR, 32)))\\n\\n success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)\\n\\n if iszero(success) {\\n mstore(0, 0)\\n return(0, 0x20)\\n }\\n }\\n\\n function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {\\n let _pPairing := add(pMem, pPairing)\\n let _pVk := add(pMem, pVk)\\n\\n mstore(_pVk, IC0x)\\n mstore(add(_pVk, 32), IC0y)\\n\\n // Compute the linear combination vk_x\\n\\n g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))\\n\\n g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))\\n\\n g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))\\n\\n g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))\\n\\n g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))\\n\\n g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160)))\\n\\n g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192)))\\n\\n g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224)))\\n\\n g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256)))\\n\\n g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288)))\\n\\n\\n // -A\\n mstore(_pPairing, calldataload(pA))\\n mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))\\n\\n // B\\n mstore(add(_pPairing, 64), calldataload(pB))\\n mstore(add(_pPairing, 96), calldataload(add(pB, 32)))\\n mstore(add(_pPairing, 128), calldataload(add(pB, 64)))\\n mstore(add(_pPairing, 160), calldataload(add(pB, 96)))\\n\\n // alpha1\\n mstore(add(_pPairing, 192), alphax)\\n mstore(add(_pPairing, 224), alphay)\\n\\n // beta2\\n mstore(add(_pPairing, 256), betax1)\\n mstore(add(_pPairing, 288), betax2)\\n mstore(add(_pPairing, 320), betay1)\\n mstore(add(_pPairing, 352), betay2)\\n\\n // vk_x\\n mstore(add(_pPairing, 384), mload(add(pMem, pVk)))\\n mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))\\n\\n\\n // gamma2\\n mstore(add(_pPairing, 448), gammax1)\\n mstore(add(_pPairing, 480), gammax2)\\n mstore(add(_pPairing, 512), gammay1)\\n mstore(add(_pPairing, 544), gammay2)\\n\\n // C\\n mstore(add(_pPairing, 576), calldataload(pC))\\n mstore(add(_pPairing, 608), calldataload(add(pC, 32)))\\n\\n // delta2\\n mstore(add(_pPairing, 640), deltax1)\\n mstore(add(_pPairing, 672), deltax2)\\n mstore(add(_pPairing, 704), deltay1)\\n mstore(add(_pPairing, 736), deltay2)\\n\\n\\n let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)\\n\\n isOk := and(success, mload(_pPairing))\\n }\\n\\n let pMem := mload(0x40)\\n mstore(0x40, add(pMem, pLastMem))\\n\\n // Validate that all evaluations \\u2208 F\\n\\n checkField(calldataload(add(_pubSignals, 0)))\\n\\n checkField(calldataload(add(_pubSignals, 32)))\\n\\n checkField(calldataload(add(_pubSignals, 64)))\\n\\n checkField(calldataload(add(_pubSignals, 96)))\\n\\n checkField(calldataload(add(_pubSignals, 128)))\\n\\n checkField(calldataload(add(_pubSignals, 160)))\\n\\n checkField(calldataload(add(_pubSignals, 192)))\\n\\n checkField(calldataload(add(_pubSignals, 224)))\\n\\n checkField(calldataload(add(_pubSignals, 256)))\\n\\n checkField(calldataload(add(_pubSignals, 288)))\\n\\n checkField(calldataload(add(_pubSignals, 320)))\\n\\n\\n // Validate all evaluations\\n let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)\\n\\n mstore(0, isValid)\\n return(0, 0x20)\\n }\\n }\\n }\",\"keccak256\":\"0xe7d4d4df7314df193c8206345215947c6902e58dd2e51e426eae6cc394028ca8\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523462000044576200002262000018620001f4565b929190916200021d565b604051611eb56200054c82396080518181816104da01526109460152611eb590f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b90601f01601f191681019081106001600160401b038211176200008157604052565b62000049565b906200009e6200009660405190565b92836200005f565b565b6001600160a01b031690565b90565b6001600160a01b0381165b036200004457565b905051906200009e82620000af565b6001600160a01b038116620000ba565b905051906200009e82620000d1565b6001600160401b0381116200008157602090601f01601f19160190565b60005b838110620001215750506000910152565b818101518382015260200162000110565b909291926200014b6200014582620000f0565b62000087565b9381855260208501908284011162000044576200009e926200010d565b9080601f8301121562000044578151620000ac9260200162000132565b80620000ba565b905051906200009e8262000185565b6080818303126200004457620001b28282620000c2565b92620001c28360208401620000e1565b604083015190936001600160401b0382116200004457620001ea81620000ac93860162000168565b936060016200018c565b6200021762002401803803806200020b8162000087565b9283398101906200019b565b90919293565b906200009e939291620004ab565b906001600160a01b03905b9181191691161790565b620000ac90620000a0906001600160a01b031682565b620000ac9062000240565b620000ac9062000256565b9062000280620000ac620002889262000261565b82546200022b565b9055565b634e487b7160e01b600052602260045260246000fd5b9060016002830492168015620002c5575b6020831014620002bf57565b6200028c565b91607f1691620002b3565b9160001960089290920291821b911b62000236565b620000ac620000ac620000ac9290565b91906200030a620000ac6200028893620002e5565b908354620002d0565b6200009e91600091620002f5565b8181106200032d575050565b806200033d600060019362000313565b0162000321565b9190601f81116200035457505050565b620003686200009e93600052602060002090565b906020601f8401819004830193106200038c575b6020601f90910104019062000321565b90915081906200037c565b90620003a1815190565b906001600160401b0382116200008157620003c982620003c28554620002a2565b8562000344565b602090601f8311600114620004085762000288929160009183620003fc575b5050600019600883021c1916906002021790565b015190503880620003e8565b601f198316916200041e85600052602060002090565b9260005b8181106200045f5750916002939185600196941062000445575b50505002019055565b01516000196008601f8516021c191690553880806200043c565b9193602060018192878701518155019501920162000422565b906200009e9162000397565b906000199062000236565b90620004a3620000ac6200028892620002e5565b825462000484565b6200009e9392620000ac620004dc93620004d493620004c9620004e4565b60805260016200026c565b600262000478565b60036200048f565b6200009e336000546001600160a01b031690620005038160006200026c565b6200053a620005337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09362000261565b9162000261565b916200054560405190565b600090a356fe6080604052600436101561001257600080fd5b60003560e01c806365cd296c146100d2578063715018a6146100cd5780638da5cb5b146100c8578063b2a3fda4146100c3578063b870676c146100be578063c0d05fed146100b9578063ced1e978146100b4578063d2f7265a146100af578063dbac5821146100aa578063f2fde38b146100a5578063f3bb70f6146100a05763f6c7226b036100e6576106bf565b6105f9565b61057b565b610520565b6104c5565b6104aa565b610483565b6102e7565b610265565b610206565b6101dd565b61019d565b90816102409103126100e65790565b600080fd5b90610240828203126100e657610100916100d7565b90565b9052565b60005b83811061011a5750506000910152565b818101518382015260200161010a565b61014b61015460209361015e9361013f815190565b80835293849260200190565b95869101610107565b601f01601f191690565b0190565b94939160609161019b946101896101969361018260808b019460008c0152565b60208a0152565b878203604089015261012a565b940152565b565b346100e6576101ce6101b86101b33660046100eb565b610d21565b906101c594929460405190565b94859485610162565b0390f35b60009103126100e657565b346100e6576101ed3660046101d2565b6101f561072c565b604051005b6001600160a01b031690565b346100e6576102163660046101d2565b6101ce6102216106ea565b604051918291826001600160a01b03909116815260200190565b805b036100e657565b9050359061019b8261023b565b906020828203126100e65761010091610244565b346100e6576101f5610278366004610251565b6115da565b610100916008021c6001600160a01b031690565b90610100915461027d565b61010060006001610291565b610100906101fa906001600160a01b031682565b610100906102a8565b610100906102bc565b610103906102c5565b60208101929161019b91906102ce565b346100e6576102f73660046101d2565b6101ce61030261029c565b604051918291826102d7565b634e487b7160e01b600052600060045260246000fd5b634e487b7160e01b600052602260045260246000fd5b906001600283049216801561035a575b602083101461035557565b610324565b91607f169161034a565b805460009392916103816103778361033a565b8085529360200190565b91600181169081156103d3575060011461039a57505050565b6103ad9192939450600052602060002090565b916000925b8184106103bf5750500190565b8054848401526020909301926001016103b2565b92949550505060ff1916825215156020020190565b9061010091610364565b634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff82111761042a57604052565b6103f2565b9061019b6104499261044060405190565b938480926103e8565b0383610408565b90600010610461576101009061042f565b61030e565b61010060006002610450565b60208082526101009291019061012a565b346100e6576104933660046101d2565b6101ce61049e610466565b60405191829182610472565b346100e6576104ba3660046101d2565b6101ce61049e6115e3565b346100e6576104d53660046101d2565b6101ce7f0000000000000000000000000000000000000000000000000000000000000000610221565b610100916008021c81565b9061010091546104fe565b61010060006003610509565b346100e6576105303660046101d2565b6101ce61053b610514565b6040519182918290815260200190565b6001600160a01b03811661023d565b9050359061019b8261054b565b906020828203126100e6576101009161055a565b346100e6576101f561058e366004610567565b610843565b919060408301116100e657565b919060808301116100e657565b91906101408301116100e657565b610240818303126100e6576105d08282610593565b926101006105e184604085016105a0565b936105ef8160c08601610593565b93610100016105ad565b346100e6576106093660046105bb565b92919091611dc4565b9061019b61061f60405190565b9283610408565b67ffffffffffffffff811161042a57602090601f01601f19160190565b90826000939282370152565b9092919261066461065f82610626565b610612565b938185526020850190828401116100e65761019b92610643565b9080601f830112156100e6578160206101009335910161064f565b906020828203126100e657813567ffffffffffffffff81116100e657610100920161067e565b346100e6576101f56106d2366004610699565b611594565b610100906101fa565b61010090546106d7565b61010060006106e0565b6106fc610788565b61019b61071a565b6101fa6101006101009290565b61010090610704565b61019b6107276000610711565b61087c565b61019b6106f4565b1561073b57565b60405162461bcd60e51b815280610784600482016020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b0390fd5b61019b6107936106ea565b6107ac61079f336101fa565b916001600160a01b031690565b14610734565b61019b906107be610788565b61081e565b156107ca57565b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b61019b906107276108326101fa6000610711565b6001600160a01b03831614156107c3565b61019b906107b2565b906001600160a01b03905b9181191691161790565b90610871610100610878926102c5565b825461084c565b9055565b61088660006106e0565b90610892816000610861565b6108c56108bf7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936102c5565b916102c5565b916108cf60405190565b600090a3565b156108dc57565b60405162461bcd60e51b8152602060048201526024808201527f4f6e6c792065786368616e67652063616e2063616c6c20746869732066756e636044820152633a34b7b760e11b6064820152608490fd5b61097694939291906109713361096b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001661079f565b146108d5565b610b73565b90919293565b80151561023d565b9050519061019b8261097c565b906020828203126100e65761010091610984565b9037565b61019b916040916109a5565b9061015e816040936109a9565b6109d26109ce60029390565b9190565b806000925b8484106109e5575050505050565b610a016109fa6001926109f58690565b6109b5565b9360400190565b930192916109d7565b61019b91610140916109a5565b610a4f61019b94610a4561010094989795610a3b61024086019a60008701906109a9565b60408501906109c2565b60c08301906109a9565b0190610a0a565b6040513d6000823e3d90fd5b15610a6957565b60405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210283937b7b360991b6044820152606490fd5b634e487b7160e01b600052603260045260246000fd5b90600a811015610ac5576020020190565b610a9e565b6101006101006101009290565b356101008161023b565b610aee6101006101009290565b60ff1690565b61015e610b0c92602092610b06815190565b94859290565b93849101610107565b61010091610af4565b6101009061042f565b15610b2e57565b60405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420656d61696c2066726f6d20616464726573730000000000006044820152606490fd5b50505050610b80306102c5565b602063f3bb70f6916000840190610bb96040860194610bc461010060c0890198018098610bac60405190565b9889978896879660e01b90565b865260048601610a17565b03915afa8015610d1c57610be091600091610cee575b50610a62565b610c03610bfe610bf9610bf36000610aca565b84610ab4565b610ad7565b610aca565b91600290610c88610c146001610ae1565b92610c826109ce610c73610c32610c2a85610ae1565b80988a610e1c565b610c5a610c3e60405190565b8092610c4e602083019182610b15565b90810382520382610408565b610c6c610c65825190565b9160200190565b2093610b1e565b610c7e610c65825190565b2090565b14610b27565b610100610bf9610cbc610bfe610bf9610cb6610cb0600798610ca98a610ae1565b908b610e1c565b97610aca565b88610ab4565b94610cde610cd9610bfe610bf9610cd36008610aca565b85610ab4565b611639565b610ce86009610aca565b90610ab4565b610d0f915060203d8111610d15575b610d078183610408565b810190610991565b38610bda565b503d610cfd565b610a56565b6109769060006060818061092d565b634e487b7160e01b600052601160045260246000fd5b610d559060ff165b9160ff1690565b90039060ff8211610d6257565b610d30565b6101006101006101009260ff1690565b67ffffffffffffffff811161042a5760208091020190565b90610d9c61065f83610d77565b918252565b369037565b9061019b610dbc610db684610d8f565b93610d77565b601f190160208401610da1565b6000198114610d625760010190565b91908203918211610d6257565b90610dee825190565b811015610ac5576020809102010190565b610100601f610aca565b81810292918115918404141715610d6257565b909290610e39610e34610e2f8686610d46565b610d67565b610da6565b91610e4385610d67565b610e4c85610d67565b811015610e9457610e8d81610e88610e6a610bf9610e4c9588610ab4565b610e85610e7f610e798c610d67565b85610dd8565b89610de5565b52565b610dc9565b9050610e43565b509350506101009150610ea5815190565b90610eb8610eb1610dff565b8093610e09565b906110c9565b90610d9c61065f83610626565b9061019b610dbc610edb84610ebe565b93610626565b610eee6101006101009290565b61ffff1690565b61ffff1661ffff8114610d625760010190565b6101006101006101009261ffff1690565b61010090610f2a6109ce6101009490565b901c90565b634e487b7160e01b600052601260045260246000fd5b610f519060ff16610d4e565b908115610f5c570690565b610f2f565b610f6d9060ff16610d4e565b019060ff8211610d6257565b610f8f610f896101009260ff1690565b60f81b90565b6001600160f81b03191690565b90610fa5825190565b811015610ac5570160200190565b61010090610f2a6109ce6101009460ff1690565b15610fce57565b60405162461bcd60e51b815260206004820152605760248201527f4e6f207061636b656420627974657320666f756e642120496e76616c6964206660448201527f696e616c207374617465206f66207061636b656420627974657320696e20656d60648201527f61696c3b2076616c7565206973206c696b656c79203021000000000000000000608482015260a490fd5b1561106657565b60405162461bcd60e51b815260206004820152603560248201527f5061636b6564206279746573206d6f7265207468616e20616c6c6f776564206d6044820152746178206e756d626572206f66207369676e616c732160581b6064820152608490fd5b926000926110d684610ae1565b6110ef6110ea836110e5895190565b610e09565b610ecb565b946110f981610aca565b9561110382610ee1565b965b6111106101008a5190565b61111989610f08565b10156112e75761113861113461112e8a610f08565b8b610de5565b5190565b98899661114487610da6565b9861114e86610aca565b8881101561119b5780610e888c8f6111969461118861118361118e9361117d6111776008610aca565b85610e09565b90610f19565b610ae1565b92610de5565b9060ff169052565b61114e565b5091909a50989295989793969194976111b388610aca565b955b8a8710156112c6576111d4610e2f6111cd8989610de5565b5160ff1690565b6111dd8a610aca565b811461127957906111f86111f361120a93610ae1565b610f79565b8a1a611204828b610f9c565b53610dc9565b9261121e6112186002610ae1565b8b610f45565b61122a610d4e8b610ae1565b14611255575b61124861124e915b6112426008610ae1565b90610fb3565b96610dc9565b95926111b5565b9861124861127061124e9261126a6001610ae1565b90610f61565b9a915050611230565b50926112886112186002610ae1565b600190611297610d4e83610ae1565b146112aa575b5061124861124e91611238565b6112be61124e929b61126a61124893610ae1565b9a915061129d565b989550935097949598916112da9150610ef5565b9695979197949094611105565b926109ce919598506101009750610100945061131a92509561010061132197611313610d4e6001610ae1565b1015610fc7565b111561105f565b611333565b610f8f610f896101009290565b80519060009261134284610aca565b61134d610100845190565b8110156113ef5761136f6113618285610f9c565b516001600160f81b03191690565b61138961137b87611326565b916001600160f81b03191690565b1461139c5761139790610dc9565b611342565b9250905b6113a983610ecb565b916113b385610aca565b845b8110156113e3576113dc816113d06113616113b59487610f9c565b881a6112048288610f9c565b90506113b3565b50935050610100915090565b50906113a0565b61019b90611402610788565b611589565b9160001960089290920291821b911b610857565b919061142c61010061087893610aca565b908354611407565b61019b9160009161141b565b81811061144b575050565b806114596000600193611434565b01611440565b9190601f811161146e57505050565b61148061019b93600052602060002090565b906020601f8401819004830193106114a2575b6020601f909101040190611440565b9091508190611493565b906114b5815190565b9067ffffffffffffffff821161042a576114d9826114d3855461033a565b8561145f565b602090601f831160011461151457610878929160009183611509575b5050600019600883021c1916906002021790565b0151905038806114f5565b601f1983169161152985600052602060002090565b9260005b8181106115675750916002939185600196941061154e575b50505002019055565b01516000196008601f8516021c19169055388080611545565b9193602060018192878701518155019501920161152d565b9061019b916114ac565b61019b90600261157f565b61019b906113f6565b61019b906115a9610788565b6115cf565b9060001990610857565b906115c861010061087892610aca565b82546115ae565b61019b9060036115b8565b61019b9061159d565b6101006002610b1e565b156115f457565b60405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e2075736564006044820152606490fd5b611668602061165061164b60016106e0565b6102c5565b63169394bb9061165f60405190565b93849260e01b90565b82526004820185905260249082905afa908115610d1c57611698916116939160009161170b57501590565b6115ed565b6116a561164b60016106e0565b90635bd4df3290823b156100e6576116e2926116d4600080946116c760405190565b9687958694859360e01b90565b835260048301526024820190565b03925af18015610d1c576116f35750565b61019b9060006117038183610408565b8101906101d2565b611723915060203d8111610d1557610d078183610408565b1590565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001111561175057565b6000805260206000f35b919290926040519384526020840152604083015260408260608160076107d05a03fa156117505760806040928251848201526020830151606082015260066107d05a03fa1561175057565b93909260606020947f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47866080860198611b3f61012060008901977f1e3e840b53d3d27676a7593010db26c5d9c1be77982792c6a77bc51d996f59a489527f1fd57321e650c7231e9c2bcaf52236a0c52183e7dce757a3f1d74795afb9e3b9858a015261187760008201357f0a16776c085ca9fef14f58edbe5d3a3bdab9e490c9a3eef08331d35ad2687f1a7f055317dc49fd6dcd6f0d41a0f2be1e9ee5791af5077463c528dfb11944e38ea98c61175a565b6118c6858201357f0c1ebe29c01c5507488889e7ce28a5c925303856991945abb9a582b5218fe65d7f19dcecc22906300af06e53e1474d9b7c1d903775ddc1d8fc80587b6295d805858c61175a565b61191560408201357e51b809e3826e7d4bd859712d063d94783155f1e3c2d2df15240e8e7a1084457f2deaa61988aa335a5d94e8fc258fc360642f04989206c5b2f7377375bda2f2d58c61175a565b611964888201357f05481cfc53d291fb148bad51bc06bde7867ed38f3a019ecab25623ef9712bee67f0c1ff12c2af5e77866e13bc8bf89c58fd71e00f8d9fa29f44d3dda23267e892e8c61175a565b6119b460808201357f0c4a6bb6fdf60dbd2bebbd94c6d1ee9df64d15d4daa5573259e8724aa6d204c87f263812b8d2f91cd28b047e4935b8f7690c058763f2a57e02dc585416581d7f008c61175a565b611a0460a08201357f250ca18d4fd055aaa9095afd2d9cc339494b15341db450dca87bc857af2ce63c7f0d392fbad06e8aa6134b36ab2f7e2dd3c4b9f1a6aa009025978b5c4392a735b88c61175a565b611a5460c08201357f25d7e948e6ed9a2c550e9ac258a07d4a63182e4d7f0485acbf4eaeed0605d3a87f2ebb57f846731282b83de6b1fb4972b43713d037e1201de95880dd93590cdb378c61175a565b611aa460e08201357f1ccdd1ff9c12fee3aa632ef781714c2bc0bf12f01700911ed53536eb8c06efc77f23d8f1651f2fc35e077cb85ebb8b439f03c6fe4278ab0506703076037eba42ac8c61175a565b611af56101008201357f2039ef6253562b611e7f25a9bc2040f51ca3b9418e814163399ac11e8400cb717f28b295c865a6ed002fca95eef35f5c03e2ce284451a870d8cf7652f93757a0118c61175a565b01357f0f1e0ab547325e430a7356fe384a8db2f12c7fa605bdd918070ba1f0c87d543f7f2bace91ad1b222b2adfe20661747868d7c6a0c051efa473232733d915c32bc988961175a565b80358a5201358103068688015280356040880152858101358288015260408101356080880152013560a08601527f245229d9b076b3c0e8a4d70bde8c1cccffa08a9fae7557b165b3b0dbd653e2c760c08601527f253ec85988dbb84e46e94b5efa3373b47a000b4ac6c86b2d4b798d274a18230260e08601527f07090a82e8fabbd39299be24705b92cf208ee8b3487f6f2b39ff27978a29a1db6101008601527f2424bcc1f60a5472685fd50705b2809626e170120acaf441e133a2bd5e61d2446101208601527f0ae1135cffdaf227c5dc266740607aa930bc3bd92ddc2b135086d9da2dfd3e2a6101408601527f2b86859fd3d55c9d150fb3f0aeba798826493dd73d357ab0f9fdaced9fc81829610160860152516101808501528260000101516101a08401527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101c08401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101e08401527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102008401527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa610220840152803561024084015201356102608201527f0346cd87c9157b61554887f5f9b224de5cbe4ff8a86144a187d3f4e29c88115a6102808201527f161cd069685c9306d50c4af8ae4066febce4c3ee37dc0ae7050c3c2867c94ddf6102a08201527f1c9613e703c7c4be8c54ac686117c49201b663c52e59a0696ab3601a31ce1a216102c08201527f292b3ecaed6bffe99dea030955f5d260b73b0d381d1edf05efa16d6fc8c0571e6102e08201526020816103008160086107d05a03fa90511690565b91611e769391611dd2600090565b50604051936103808501604052611dec6000850135611727565b611df96020850135611727565b611e066040850135611727565b611e136060850135611727565b611e206080850135611727565b611e2d60a0850135611727565b611e3a60c0850135611727565b611e4760e0850135611727565b611e55610100850135611727565b611e63610120850135611727565b611e71610140850135611727565b6117a5565b60005260206000f3fea26469706673582212205d578d1e202f46a1a10e4e4c0a699e25343984036d710450a93c5624e06ec55b64736f6c63430008120033", + "deployedBytecode": "0x6080604052600436101561001257600080fd5b60003560e01c806365cd296c146100d2578063715018a6146100cd5780638da5cb5b146100c8578063b2a3fda4146100c3578063b870676c146100be578063c0d05fed146100b9578063ced1e978146100b4578063d2f7265a146100af578063dbac5821146100aa578063f2fde38b146100a5578063f3bb70f6146100a05763f6c7226b036100e6576106bf565b6105f9565b61057b565b610520565b6104c5565b6104aa565b610483565b6102e7565b610265565b610206565b6101dd565b61019d565b90816102409103126100e65790565b600080fd5b90610240828203126100e657610100916100d7565b90565b9052565b60005b83811061011a5750506000910152565b818101518382015260200161010a565b61014b61015460209361015e9361013f815190565b80835293849260200190565b95869101610107565b601f01601f191690565b0190565b94939160609161019b946101896101969361018260808b019460008c0152565b60208a0152565b878203604089015261012a565b940152565b565b346100e6576101ce6101b86101b33660046100eb565b610d21565b906101c594929460405190565b94859485610162565b0390f35b60009103126100e657565b346100e6576101ed3660046101d2565b6101f561072c565b604051005b6001600160a01b031690565b346100e6576102163660046101d2565b6101ce6102216106ea565b604051918291826001600160a01b03909116815260200190565b805b036100e657565b9050359061019b8261023b565b906020828203126100e65761010091610244565b346100e6576101f5610278366004610251565b6115da565b610100916008021c6001600160a01b031690565b90610100915461027d565b61010060006001610291565b610100906101fa906001600160a01b031682565b610100906102a8565b610100906102bc565b610103906102c5565b60208101929161019b91906102ce565b346100e6576102f73660046101d2565b6101ce61030261029c565b604051918291826102d7565b634e487b7160e01b600052600060045260246000fd5b634e487b7160e01b600052602260045260246000fd5b906001600283049216801561035a575b602083101461035557565b610324565b91607f169161034a565b805460009392916103816103778361033a565b8085529360200190565b91600181169081156103d3575060011461039a57505050565b6103ad9192939450600052602060002090565b916000925b8184106103bf5750500190565b8054848401526020909301926001016103b2565b92949550505060ff1916825215156020020190565b9061010091610364565b634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff82111761042a57604052565b6103f2565b9061019b6104499261044060405190565b938480926103e8565b0383610408565b90600010610461576101009061042f565b61030e565b61010060006002610450565b60208082526101009291019061012a565b346100e6576104933660046101d2565b6101ce61049e610466565b60405191829182610472565b346100e6576104ba3660046101d2565b6101ce61049e6115e3565b346100e6576104d53660046101d2565b6101ce7f0000000000000000000000000000000000000000000000000000000000000000610221565b610100916008021c81565b9061010091546104fe565b61010060006003610509565b346100e6576105303660046101d2565b6101ce61053b610514565b6040519182918290815260200190565b6001600160a01b03811661023d565b9050359061019b8261054b565b906020828203126100e6576101009161055a565b346100e6576101f561058e366004610567565b610843565b919060408301116100e657565b919060808301116100e657565b91906101408301116100e657565b610240818303126100e6576105d08282610593565b926101006105e184604085016105a0565b936105ef8160c08601610593565b93610100016105ad565b346100e6576106093660046105bb565b92919091611dc4565b9061019b61061f60405190565b9283610408565b67ffffffffffffffff811161042a57602090601f01601f19160190565b90826000939282370152565b9092919261066461065f82610626565b610612565b938185526020850190828401116100e65761019b92610643565b9080601f830112156100e6578160206101009335910161064f565b906020828203126100e657813567ffffffffffffffff81116100e657610100920161067e565b346100e6576101f56106d2366004610699565b611594565b610100906101fa565b61010090546106d7565b61010060006106e0565b6106fc610788565b61019b61071a565b6101fa6101006101009290565b61010090610704565b61019b6107276000610711565b61087c565b61019b6106f4565b1561073b57565b60405162461bcd60e51b815280610784600482016020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b0390fd5b61019b6107936106ea565b6107ac61079f336101fa565b916001600160a01b031690565b14610734565b61019b906107be610788565b61081e565b156107ca57565b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b61019b906107276108326101fa6000610711565b6001600160a01b03831614156107c3565b61019b906107b2565b906001600160a01b03905b9181191691161790565b90610871610100610878926102c5565b825461084c565b9055565b61088660006106e0565b90610892816000610861565b6108c56108bf7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936102c5565b916102c5565b916108cf60405190565b600090a3565b156108dc57565b60405162461bcd60e51b8152602060048201526024808201527f4f6e6c792065786368616e67652063616e2063616c6c20746869732066756e636044820152633a34b7b760e11b6064820152608490fd5b61097694939291906109713361096b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001661079f565b146108d5565b610b73565b90919293565b80151561023d565b9050519061019b8261097c565b906020828203126100e65761010091610984565b9037565b61019b916040916109a5565b9061015e816040936109a9565b6109d26109ce60029390565b9190565b806000925b8484106109e5575050505050565b610a016109fa6001926109f58690565b6109b5565b9360400190565b930192916109d7565b61019b91610140916109a5565b610a4f61019b94610a4561010094989795610a3b61024086019a60008701906109a9565b60408501906109c2565b60c08301906109a9565b0190610a0a565b6040513d6000823e3d90fd5b15610a6957565b60405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210283937b7b360991b6044820152606490fd5b634e487b7160e01b600052603260045260246000fd5b90600a811015610ac5576020020190565b610a9e565b6101006101006101009290565b356101008161023b565b610aee6101006101009290565b60ff1690565b61015e610b0c92602092610b06815190565b94859290565b93849101610107565b61010091610af4565b6101009061042f565b15610b2e57565b60405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420656d61696c2066726f6d20616464726573730000000000006044820152606490fd5b50505050610b80306102c5565b602063f3bb70f6916000840190610bb96040860194610bc461010060c0890198018098610bac60405190565b9889978896879660e01b90565b865260048601610a17565b03915afa8015610d1c57610be091600091610cee575b50610a62565b610c03610bfe610bf9610bf36000610aca565b84610ab4565b610ad7565b610aca565b91600290610c88610c146001610ae1565b92610c826109ce610c73610c32610c2a85610ae1565b80988a610e1c565b610c5a610c3e60405190565b8092610c4e602083019182610b15565b90810382520382610408565b610c6c610c65825190565b9160200190565b2093610b1e565b610c7e610c65825190565b2090565b14610b27565b610100610bf9610cbc610bfe610bf9610cb6610cb0600798610ca98a610ae1565b908b610e1c565b97610aca565b88610ab4565b94610cde610cd9610bfe610bf9610cd36008610aca565b85610ab4565b611639565b610ce86009610aca565b90610ab4565b610d0f915060203d8111610d15575b610d078183610408565b810190610991565b38610bda565b503d610cfd565b610a56565b6109769060006060818061092d565b634e487b7160e01b600052601160045260246000fd5b610d559060ff165b9160ff1690565b90039060ff8211610d6257565b610d30565b6101006101006101009260ff1690565b67ffffffffffffffff811161042a5760208091020190565b90610d9c61065f83610d77565b918252565b369037565b9061019b610dbc610db684610d8f565b93610d77565b601f190160208401610da1565b6000198114610d625760010190565b91908203918211610d6257565b90610dee825190565b811015610ac5576020809102010190565b610100601f610aca565b81810292918115918404141715610d6257565b909290610e39610e34610e2f8686610d46565b610d67565b610da6565b91610e4385610d67565b610e4c85610d67565b811015610e9457610e8d81610e88610e6a610bf9610e4c9588610ab4565b610e85610e7f610e798c610d67565b85610dd8565b89610de5565b52565b610dc9565b9050610e43565b509350506101009150610ea5815190565b90610eb8610eb1610dff565b8093610e09565b906110c9565b90610d9c61065f83610626565b9061019b610dbc610edb84610ebe565b93610626565b610eee6101006101009290565b61ffff1690565b61ffff1661ffff8114610d625760010190565b6101006101006101009261ffff1690565b61010090610f2a6109ce6101009490565b901c90565b634e487b7160e01b600052601260045260246000fd5b610f519060ff16610d4e565b908115610f5c570690565b610f2f565b610f6d9060ff16610d4e565b019060ff8211610d6257565b610f8f610f896101009260ff1690565b60f81b90565b6001600160f81b03191690565b90610fa5825190565b811015610ac5570160200190565b61010090610f2a6109ce6101009460ff1690565b15610fce57565b60405162461bcd60e51b815260206004820152605760248201527f4e6f207061636b656420627974657320666f756e642120496e76616c6964206660448201527f696e616c207374617465206f66207061636b656420627974657320696e20656d60648201527f61696c3b2076616c7565206973206c696b656c79203021000000000000000000608482015260a490fd5b1561106657565b60405162461bcd60e51b815260206004820152603560248201527f5061636b6564206279746573206d6f7265207468616e20616c6c6f776564206d6044820152746178206e756d626572206f66207369676e616c732160581b6064820152608490fd5b926000926110d684610ae1565b6110ef6110ea836110e5895190565b610e09565b610ecb565b946110f981610aca565b9561110382610ee1565b965b6111106101008a5190565b61111989610f08565b10156112e75761113861113461112e8a610f08565b8b610de5565b5190565b98899661114487610da6565b9861114e86610aca565b8881101561119b5780610e888c8f6111969461118861118361118e9361117d6111776008610aca565b85610e09565b90610f19565b610ae1565b92610de5565b9060ff169052565b61114e565b5091909a50989295989793969194976111b388610aca565b955b8a8710156112c6576111d4610e2f6111cd8989610de5565b5160ff1690565b6111dd8a610aca565b811461127957906111f86111f361120a93610ae1565b610f79565b8a1a611204828b610f9c565b53610dc9565b9261121e6112186002610ae1565b8b610f45565b61122a610d4e8b610ae1565b14611255575b61124861124e915b6112426008610ae1565b90610fb3565b96610dc9565b95926111b5565b9861124861127061124e9261126a6001610ae1565b90610f61565b9a915050611230565b50926112886112186002610ae1565b600190611297610d4e83610ae1565b146112aa575b5061124861124e91611238565b6112be61124e929b61126a61124893610ae1565b9a915061129d565b989550935097949598916112da9150610ef5565b9695979197949094611105565b926109ce919598506101009750610100945061131a92509561010061132197611313610d4e6001610ae1565b1015610fc7565b111561105f565b611333565b610f8f610f896101009290565b80519060009261134284610aca565b61134d610100845190565b8110156113ef5761136f6113618285610f9c565b516001600160f81b03191690565b61138961137b87611326565b916001600160f81b03191690565b1461139c5761139790610dc9565b611342565b9250905b6113a983610ecb565b916113b385610aca565b845b8110156113e3576113dc816113d06113616113b59487610f9c565b881a6112048288610f9c565b90506113b3565b50935050610100915090565b50906113a0565b61019b90611402610788565b611589565b9160001960089290920291821b911b610857565b919061142c61010061087893610aca565b908354611407565b61019b9160009161141b565b81811061144b575050565b806114596000600193611434565b01611440565b9190601f811161146e57505050565b61148061019b93600052602060002090565b906020601f8401819004830193106114a2575b6020601f909101040190611440565b9091508190611493565b906114b5815190565b9067ffffffffffffffff821161042a576114d9826114d3855461033a565b8561145f565b602090601f831160011461151457610878929160009183611509575b5050600019600883021c1916906002021790565b0151905038806114f5565b601f1983169161152985600052602060002090565b9260005b8181106115675750916002939185600196941061154e575b50505002019055565b01516000196008601f8516021c19169055388080611545565b9193602060018192878701518155019501920161152d565b9061019b916114ac565b61019b90600261157f565b61019b906113f6565b61019b906115a9610788565b6115cf565b9060001990610857565b906115c861010061087892610aca565b82546115ae565b61019b9060036115b8565b61019b9061159d565b6101006002610b1e565b156115f457565b60405162461bcd60e51b815260206004820152601f60248201527f4e756c6c69666965722068617320616c7265616479206265656e2075736564006044820152606490fd5b611668602061165061164b60016106e0565b6102c5565b63169394bb9061165f60405190565b93849260e01b90565b82526004820185905260249082905afa908115610d1c57611698916116939160009161170b57501590565b6115ed565b6116a561164b60016106e0565b90635bd4df3290823b156100e6576116e2926116d4600080946116c760405190565b9687958694859360e01b90565b835260048301526024820190565b03925af18015610d1c576116f35750565b61019b9060006117038183610408565b8101906101d2565b611723915060203d8111610d1557610d078183610408565b1590565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001111561175057565b6000805260206000f35b919290926040519384526020840152604083015260408260608160076107d05a03fa156117505760806040928251848201526020830151606082015260066107d05a03fa1561175057565b93909260606020947f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47866080860198611b3f61012060008901977f1e3e840b53d3d27676a7593010db26c5d9c1be77982792c6a77bc51d996f59a489527f1fd57321e650c7231e9c2bcaf52236a0c52183e7dce757a3f1d74795afb9e3b9858a015261187760008201357f0a16776c085ca9fef14f58edbe5d3a3bdab9e490c9a3eef08331d35ad2687f1a7f055317dc49fd6dcd6f0d41a0f2be1e9ee5791af5077463c528dfb11944e38ea98c61175a565b6118c6858201357f0c1ebe29c01c5507488889e7ce28a5c925303856991945abb9a582b5218fe65d7f19dcecc22906300af06e53e1474d9b7c1d903775ddc1d8fc80587b6295d805858c61175a565b61191560408201357e51b809e3826e7d4bd859712d063d94783155f1e3c2d2df15240e8e7a1084457f2deaa61988aa335a5d94e8fc258fc360642f04989206c5b2f7377375bda2f2d58c61175a565b611964888201357f05481cfc53d291fb148bad51bc06bde7867ed38f3a019ecab25623ef9712bee67f0c1ff12c2af5e77866e13bc8bf89c58fd71e00f8d9fa29f44d3dda23267e892e8c61175a565b6119b460808201357f0c4a6bb6fdf60dbd2bebbd94c6d1ee9df64d15d4daa5573259e8724aa6d204c87f263812b8d2f91cd28b047e4935b8f7690c058763f2a57e02dc585416581d7f008c61175a565b611a0460a08201357f250ca18d4fd055aaa9095afd2d9cc339494b15341db450dca87bc857af2ce63c7f0d392fbad06e8aa6134b36ab2f7e2dd3c4b9f1a6aa009025978b5c4392a735b88c61175a565b611a5460c08201357f25d7e948e6ed9a2c550e9ac258a07d4a63182e4d7f0485acbf4eaeed0605d3a87f2ebb57f846731282b83de6b1fb4972b43713d037e1201de95880dd93590cdb378c61175a565b611aa460e08201357f1ccdd1ff9c12fee3aa632ef781714c2bc0bf12f01700911ed53536eb8c06efc77f23d8f1651f2fc35e077cb85ebb8b439f03c6fe4278ab0506703076037eba42ac8c61175a565b611af56101008201357f2039ef6253562b611e7f25a9bc2040f51ca3b9418e814163399ac11e8400cb717f28b295c865a6ed002fca95eef35f5c03e2ce284451a870d8cf7652f93757a0118c61175a565b01357f0f1e0ab547325e430a7356fe384a8db2f12c7fa605bdd918070ba1f0c87d543f7f2bace91ad1b222b2adfe20661747868d7c6a0c051efa473232733d915c32bc988961175a565b80358a5201358103068688015280356040880152858101358288015260408101356080880152013560a08601527f245229d9b076b3c0e8a4d70bde8c1cccffa08a9fae7557b165b3b0dbd653e2c760c08601527f253ec85988dbb84e46e94b5efa3373b47a000b4ac6c86b2d4b798d274a18230260e08601527f07090a82e8fabbd39299be24705b92cf208ee8b3487f6f2b39ff27978a29a1db6101008601527f2424bcc1f60a5472685fd50705b2809626e170120acaf441e133a2bd5e61d2446101208601527f0ae1135cffdaf227c5dc266740607aa930bc3bd92ddc2b135086d9da2dfd3e2a6101408601527f2b86859fd3d55c9d150fb3f0aeba798826493dd73d357ab0f9fdaced9fc81829610160860152516101808501528260000101516101a08401527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101c08401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101e08401527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102008401527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa610220840152803561024084015201356102608201527f0346cd87c9157b61554887f5f9b224de5cbe4ff8a86144a187d3f4e29c88115a6102808201527f161cd069685c9306d50c4af8ae4066febce4c3ee37dc0ae7050c3c2867c94ddf6102a08201527f1c9613e703c7c4be8c54ac686117c49201b663c52e59a0696ab3601a31ce1a216102c08201527f292b3ecaed6bffe99dea030955f5d260b73b0d381d1edf05efa16d6fc8c0571e6102e08201526020816103008160086107d05a03fa90511690565b91611e769391611dd2600090565b50604051936103808501604052611dec6000850135611727565b611df96020850135611727565b611e066040850135611727565b611e136060850135611727565b611e206080850135611727565b611e2d60a0850135611727565b611e3a60c0850135611727565b611e4760e0850135611727565b611e55610100850135611727565b611e63610120850135611727565b611e71610140850135611727565b6117a5565b60005260206000f3fea26469706673582212205d578d1e202f46a1a10e4e4c0a699e25343984036d710450a93c5624e06ec55b64736f6c63430008120033", "devdoc": { "kind": "dev", "methods": { diff --git a/contracts-domain/deployments/base/solcInputs/a22247643263102eca9fc6c72e24c17d.json b/contracts-domain/deployments/base/solcInputs/a22247643263102eca9fc6c72e24c17d.json new file mode 100644 index 00000000..66052c82 --- /dev/null +++ b/contracts-domain/deployments/base/solcInputs/a22247643263102eca9fc6c72e24c17d.json @@ -0,0 +1,68 @@ +{ + "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/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (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 function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n" + }, + "@zk-email/contracts/utils/StringUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.7.6;\n\n// https://github.com/nalinbhardwaj/ethdosnumber/blob/main/ethdos-contracts/src/HexStrings.sol\nlibrary StringUtils {\n bytes16 internal constant ALPHABET = \"0123456789abcdef\";\n uint256 internal constant DEFAULT_PACK_SIZE = 31;\n\n /// @notice Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n /// @dev Credit to Open Zeppelin under MIT license https://github.com/OpenZeppelin/openzeppelin-contracts/blob/243adff49ce1700e0ecb99fe522fb16cff1d1ddc/contracts/utils/Strings.sol#L55\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] = ALPHABET[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length);\n for (uint256 i = buffer.length; i > 0; i--) {\n buffer[i - 1] = ALPHABET[value & 0xf];\n value >>= 4;\n }\n return string(buffer);\n }\n\n function toString(uint256 value) internal pure returns (string memory) {\n return toString(abi.encodePacked(value));\n }\n\n function toString(bytes32 value) internal pure returns (string memory) {\n return toString(abi.encodePacked(value));\n }\n\n function toString(address account) internal pure returns (string memory) {\n return toString(abi.encodePacked(account));\n }\n\n function stringEq(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));\n }\n\n function toString(bytes memory data) internal pure returns (string memory) {\n bytes memory alphabet = \"0123456789abcdef\";\n\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i = 0; i < data.length; i++) {\n str[2 + i * 2] = alphabet[uint256(uint8(data[i] >> 4))];\n str[3 + i * 2] = alphabet[uint256(uint8(data[i] & 0x0f))];\n }\n return string(str);\n }\n\n // 1 packed byte = packSize (usually 31) normal bytes, all in one 255/256-bit value\n // Note that this is not 32 due to the field modulus of circom\n function convertPackedByteToString(uint256 packedByte, uint256 packSize)\n internal\n pure\n returns (string memory extractedString)\n {\n uint256[] memory packedBytes = new uint256[](1);\n packedBytes[0] = packedByte;\n return convertPackedBytesToString(packedBytes, packSize, packSize);\n }\n\n // Note: This convenience function removes the max string length check, which may cause misalignment with the circom\n // If using this, then the circom needs to rangecheck packed length in the circuit itself\n // This defaults to 31 bytes per packed byte\n function convertPackedBytesToString(uint256[] memory packedBytes) \n internal\n pure\n returns (string memory extractedString)\n {\n return convertPackedBytesToString(packedBytes, packedBytes.length * DEFAULT_PACK_SIZE, DEFAULT_PACK_SIZE);\n }\n\n // Unpacks uint256s into bytes and then extracts the non-zero characters\n // Only extracts contiguous non-zero characters and ensures theres only 1 such state\n // Note that unpackedLen may be more than packedBytes.length * 8 since there may be 0s\n // signals is the total number of signals (i.e. bytes) packed into the packedBytes. it defaults to packedBytes.length * packSize\n function convertPackedBytesToString(uint256[] memory packedBytes, uint256 signals, uint256 packSize)\n internal\n pure\n returns (string memory extractedString)\n {\n uint8 state = 0;\n // bytes: 0 0 0 0 y u s h _ g 0 0 0\n // state: 0 0 0 0 1 1 1 1 1 1 2 2 2\n bytes memory nonzeroBytesArray = new bytes(packedBytes.length * packSize);\n uint256 nonzeroBytesArrayIndex = 0;\n for (uint16 i = 0; i < packedBytes.length; i++) {\n uint256 packedByte = packedBytes[i];\n uint8[] memory unpackedBytes = new uint8[](packSize);\n for (uint256 j = 0; j < packSize; j++) {\n unpackedBytes[j] = uint8(packedByte >> (j * 8));\n }\n for (uint256 j = 0; j < packSize; j++) {\n uint256 unpackedByte = unpackedBytes[j]; //unpackedBytes[j];\n if (unpackedByte != 0) {\n nonzeroBytesArray[nonzeroBytesArrayIndex] = bytes1(uint8(unpackedByte));\n nonzeroBytesArrayIndex++;\n if (state % 2 == 0) {\n state += 1;\n }\n } else {\n if (state % 2 == 1) {\n state += 1;\n }\n }\n packedByte = packedByte >> 8;\n }\n }\n // TODO: You might want to assert that the state is exactly 1 or 2\n // If not, that means empty bytse have been removed from the middle and things have been concatenated.\n // We removed due to some tests failing, but this is not ideal and the require should be uncommented as soon as tests pass with it.\n\n // require(state == 1 || state == 2, \"Invalid final state of packed bytes in email; more than two non-zero regions found!\");\n require(state >= 1, \"No packed bytes found! Invalid final state of packed bytes in email; value is likely 0!\");\n require(nonzeroBytesArrayIndex <= signals, \"Packed bytes more than allowed max number of signals!\");\n string memory returnValue = removeTrailingZeros(string(nonzeroBytesArray));\n return returnValue;\n // Have to end at the end of the email -- state cannot be 1 since there should be an email footer\n }\n\n function bytes32ToString(bytes32 input) internal pure returns (string memory) {\n uint256 i;\n for (i = 0; i < 32 && input[i] != 0; i++) {}\n bytes memory resultBytes = new bytes(i);\n for (i = 0; i < 32 && input[i] != 0; i++) {\n resultBytes[i] = input[i];\n }\n return string(resultBytes);\n }\n\n // sliceArray is used to slice an array of uint256s from start-end into a new array of uint256s\n function sliceArray(uint256[] memory input, uint256 start, uint256 end) internal pure returns (uint256[] memory) {\n require(start <= end && end <= input.length, \"Invalid slice indices\");\n uint256[] memory result = new uint256[](end - start);\n for (uint256 i = start; i < end; i++) {\n result[i - start] = input[i];\n }\n return result;\n }\n\n // stringToUint is used to convert a string like \"45\" to a uint256 4\n function stringToUint(string memory s) internal pure returns (uint256) {\n bytes memory b = bytes(s);\n uint256 result = 0;\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 // TODO: Currently truncates decimals\n if (b[i] == 0x2E) {\n return result;\n }\n }\n return result;\n }\n\n // getDomainFromEmail is used to extract the domain from an email i.e. the part after the @\n function getDomainFromEmail(string memory fromEmail) internal pure returns (string memory) {\n bytes memory emailBytes = bytes(fromEmail);\n uint256 atIndex;\n for (uint256 i = 0; i < emailBytes.length; i++) {\n if (emailBytes[i] == \"@\") {\n atIndex = i;\n break;\n }\n }\n\n bytes memory domainBytes = new bytes(emailBytes.length - atIndex - 1);\n for (uint256 j = 0; j < domainBytes.length; j++) {\n domainBytes[j] = emailBytes[atIndex + 1 + j];\n }\n return bytes32ToString(bytes32(bytes(domainBytes)));\n }\n\n function removeTrailingZeros(string memory input) public pure returns (string memory) {\n bytes memory inputBytes = bytes(input);\n uint256 endIndex = inputBytes.length;\n\n for (uint256 i = 0; i < inputBytes.length; i++) {\n if (inputBytes[i] == 0) {\n endIndex = i;\n break;\n }\n }\n\n bytes memory resultBytes = new bytes(endIndex);\n for (uint256 i = 0; i < endIndex; i++) {\n resultBytes[i] = inputBytes[i];\n }\n\n return string(resultBytes);\n }\n\n // Upper/lower string utils from https://github.com/willitscale/solidity-util/blob/master/lib/Strings.sol\n /**\n * Upper\n *\n * Converts all the values of a string to their corresponding upper case\n * value.\n *\n * @param _base When being used for a data type this is the extended object\n * otherwise this is the string base to convert to upper case\n * @return string\n */\n function upper(string memory _base) public pure returns (string memory) {\n bytes memory _baseBytes = bytes(_base);\n for (uint256 i = 0; i < _baseBytes.length; i++) {\n _baseBytes[i] = _upper(_baseBytes[i]);\n }\n return string(_baseBytes);\n }\n\n /**\n * Lower\n *\n * Converts all the values of a string to their corresponding lower case\n * value.\n *\n * @param _base When being used for a data type this is the extended object\n * otherwise this is the string base to convert to lower case\n * @return string\n */\n function lower(string memory _base) public pure returns (string memory) {\n bytes memory _baseBytes = bytes(_base);\n for (uint256 i = 0; i < _baseBytes.length; i++) {\n _baseBytes[i] = _lower(_baseBytes[i]);\n }\n return string(_baseBytes);\n }\n\n /**\n * Upper\n *\n * Convert an alphabetic character to upper case and return the original\n * value when not alphabetic\n *\n * @param _b1 The byte to be converted to upper case\n * @return bytes1 The converted value if the passed value was alphabetic\n * and in a lower case otherwise returns the original value\n */\n function _upper(bytes1 _b1) private pure returns (bytes1) {\n if (_b1 >= 0x61 && _b1 <= 0x7A) {\n return bytes1(uint8(_b1) - 32);\n }\n\n return _b1;\n }\n\n /**\n * Lower\n *\n * Convert an alphabetic character to lower case and return the original\n * value when not alphabetic\n *\n * @param _b1 The byte to be converted to lower case\n * @return bytes1 The converted value if the passed value was alphabetic\n * and in a upper case otherwise returns the original value\n */\n function _lower(bytes1 _b1) private pure returns (bytes1) {\n if (_b1 >= 0x41 && _b1 <= 0x5A) {\n return bytes1(uint8(_b1) + 32);\n }\n\n return _b1;\n }\n}\n" + }, + "contracts/external/interfaces/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/external/interfaces/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/external/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/external/processors/EmailBaseProcessor.sol": { + "content": "//SPDX-License-Identifier: MIT\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport { IKeyHashAdapterV2 } from \"../interfaces/IKeyHashAdapterV2.sol\";\nimport { INullifierRegistry } from \"../interfaces/INullifierRegistry.sol\";\n\npragma solidity ^0.8.18;\n\ncontract EmailBaseProcessor is Ownable {\n\n /* ============ Modifiers ============ */\n modifier onlyExchange() {\n require(msg.sender == exchange, \"Only exchange can call this function\");\n _;\n }\n\n /* ============ State Variables ============ */\n address public immutable exchange;\n INullifierRegistry public nullifierRegistry;\n bytes public emailFromAddress;\n uint256 public timestampBuffer;\n\n /* ============ Constructor ============ */\n constructor(\n address _exchange,\n INullifierRegistry _nullifierRegistry,\n string memory _emailFromAddress,\n uint256 _timestampBuffer\n )\n Ownable()\n {\n exchange = _exchange;\n nullifierRegistry = _nullifierRegistry;\n emailFromAddress = bytes(_emailFromAddress);\n timestampBuffer = _timestampBuffer;\n }\n\n /* ============ External Functions ============ */\n\n /**\n * @notice ONLY OWNER: Sets the from email address for validated emails. Check that email address is properly\n * padded (if necessary). Padding will be dependent on if unpacking functions cut trailing 0s or not.\n *\n * @param _emailFromAddress The from email address for validated emails, MUST BE PROPERLY PADDED\n */\n function setEmailFromAddress(string memory _emailFromAddress) external onlyOwner {\n emailFromAddress = bytes(_emailFromAddress);\n }\n\n /**\n * @notice ONLY OWNER: Sets the timestamp buffer for validated emails. 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 emails\n */\n function setTimestampBuffer(uint256 _timestampBuffer) external onlyOwner {\n timestampBuffer = _timestampBuffer;\n }\n\n /* ============ External Getters ============ */\n\n function getEmailFromAddress() external view returns (bytes memory) {\n return emailFromAddress;\n }\n\n\n /* ============ Internal Functions ============ */\n\n function _validateAndAddNullifier(bytes32 _nullifier) internal {\n require(!nullifierRegistry.isNullified(_nullifier), \"Nullifier has already been used\");\n nullifierRegistry.addNullifier(_nullifier);\n }\n}\n" + }, + "contracts/interfaces/ITransferDomainProcessor.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n\ninterface ITransferDomainProcessor {\n\n struct TransferProof {\n uint256[2] a;\n uint256[2][2] b;\n uint256[2] c;\n uint256[10] signals;\n }\n\n function processProof(\n TransferProof calldata _proof\n ) \n external \n returns (\n bytes32 dkimKeyHash, \n bytes32 hashedReceiverId, \n string memory domainName, \n uint256 bidId\n );\n}" + }, + "contracts/TransferDomainProcessor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\nimport { StringUtils } from \"@zk-email/contracts/utils/StringUtils.sol\";\n\nimport { EmailBaseProcessor } from \"./external/processors/EmailBaseProcessor.sol\";\nimport { INullifierRegistry } from \"./external/interfaces/INullifierRegistry.sol\";\nimport { StringConversionUtils } from \"./external/lib/StringConversionUtils.sol\";\n\nimport { Groth16Verifier } from \"./verifiers/namecheap_transfer_verifier.sol\";\nimport { ITransferDomainProcessor } from \"./interfaces/ITransferDomainProcessor.sol\";\n\npragma solidity ^0.8.18;\n\ncontract TransferDomainProcessor is Groth16Verifier, ITransferDomainProcessor, EmailBaseProcessor {\n \n using StringUtils for uint256[];\n using StringConversionUtils for string;\n\n /* ============ Constants ============ */\n uint256 constant PACK_SIZE = 31;\n\n /* ============ Constructor ============ */\n constructor(\n address _exchange,\n INullifierRegistry _nullifierRegistry,\n string memory _emailFromAddress,\n uint256 _timestampBuffer\n )\n Groth16Verifier()\n EmailBaseProcessor(\n _exchange,\n _nullifierRegistry,\n _emailFromAddress,\n _timestampBuffer\n )\n {}\n \n /* ============ External Functions ============ */\n\n function processProof(\n TransferProof calldata _proof\n )\n external\n override\n onlyExchange\n returns (\n bytes32 dkimKeyHash,\n bytes32 hashedReceiverId,\n string memory domainName, \n uint256 bidId\n )\n {\n require(this.verifyProof(_proof.a, _proof.b, _proof.c, _proof.signals), \"Invalid Proof\");\n\n // Signal [0] is the DKIM key hash\n dkimKeyHash = bytes32(_proof.signals[0]);\n\n // Signals [1:2] are the packed from email address\n string memory fromEmail = _parseSignalArray(_proof.signals, 1, 2);\n require(\n keccak256(abi.encodePacked(fromEmail)) == keccak256(emailFromAddress), \n \"Invalid email from address\"\n );\n \n // Signals [2:7] are packed domain name\n domainName = _parseSignalArray(_proof.signals, 2, 7);\n\n // Signal [7] is packed hashed namecheap id to which domain was transferred\n hashedReceiverId = bytes32(_proof.signals[7]);\n\n // Check if email has been used previously, if not nullify it so it can't be used again\n _validateAndAddNullifier(bytes32(_proof.signals[8]));\n\n // Signal [9] is bidId\n bidId = _proof.signals[9];\n }\n \n /* ============ Internal Functions ============ */\n\n function _parseSignalArray(uint256[10] calldata _signals, uint8 _from, uint8 _to) \n internal \n pure \n returns (string memory) \n {\n uint256[] memory signalArray = new uint256[](_to - _from);\n for (uint256 i = _from; i < _to; i++) {\n signalArray[i - _from] = _signals[i];\n }\n\n return signalArray.convertPackedBytesToString(signalArray.length * PACK_SIZE, PACK_SIZE);\n }\n}\n" + }, + "contracts/verifiers/namecheap_transfer_verifier.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n/*\n Copyright 2021 0KIMS association.\n\n This file is generated with [snarkJS](https://github.com/iden3/snarkjs).\n\n snarkJS is a free software: you can redistribute it and/or modify it\n under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n snarkJS is distributed in the hope that it will be useful, but WITHOUT\n ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n License for more details.\n\n You should have received a copy of the GNU General Public License\n along with snarkJS. If not, see .\n*/\n\npragma solidity >=0.7.0 <0.9.0;\n\ncontract Groth16Verifier {\n // Scalar field size\n uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n // Base field size\n uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n // Verification Key data\n uint256 constant alphax = 16428432848801857252194528405604668803277877773566238944394625302971855135431;\n uint256 constant alphay = 16846502678714586896801519656441059708016666274385668027902869494772365009666;\n uint256 constant betax1 = 3182164110458002340215786955198810119980427837186618912744689678939861918171;\n uint256 constant betax2 = 16348171800823588416173124589066524623406261996681292662100840445103873053252;\n uint256 constant betay1 = 4920802715848186258981584729175884379674325733638798907835771393452862684714;\n uint256 constant betay2 = 19687132236965066906216944365591810874384658708175106803089633851114028275753;\n uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;\n uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;\n uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;\n uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;\n uint256 constant deltax1 = 1482036359054785987758983791437636255761203148422438653991915394359246721370;\n uint256 constant deltax2 = 10001792791670748994653802587965307894251588681124493339739643276539399327199;\n uint256 constant deltay1 = 12929924181374602539079631103652565558658437684289021022192643357266276129313;\n uint256 constant deltay2 = 18621234594885561836856860416599021020030685616956494244557460320066348275486;\n\n\n uint256 constant IC0x = 13679841311419499947196488030563927052737833631831087839800108582001619982756;\n uint256 constant IC0y = 14398831345642232008615460969424497321419317733481671851297924133275173512121;\n\n uint256 constant IC1x = 2408377228439232698160803002782752816762776284505564408880728084177561554601;\n uint256 constant IC1y = 4562823341627914579340945271513298981280656371775082655869052525475797696282;\n\n uint256 constant IC2x = 11698161615520749679058702638780643731158760523880360973169686160750874723717;\n uint256 constant IC2y = 5482072052337866918379448154185642235470279334903213679209093769947335616093;\n\n uint256 constant IC3x = 20768666777689851453960746019474086479608334345599593721826216429323116802773;\n uint256 constant IC3y = 144384800173925255346616036805594882403322575509153153064641653383667680325;\n\n uint256 constant IC4x = 5484190953638831817876258480017744165730276029855186594303418421204653869358;\n uint256 constant IC4y = 2388977283212189651166234573571473197529151009141226183250075013106275368678;\n\n uint256 constant IC5x = 17286960896074201491464437213186707946980083024758675396143906384940172672768;\n uint256 constant IC5y = 5559244286107427512674714237837993184640251130340291817174978126569513551048;\n\n uint256 constant IC6x = 5981106732853641044464779767035945345345676221237979116689771873940770600376;\n uint256 constant IC6y = 16757892553277885270560523048286665969871413522533097385031102756444326127164;\n\n uint256 constant IC7x = 21137398581361954385460769732122488724166715754152295898647889069721843981111;\n uint256 constant IC7y = 17117057588842742212408259815326568334655191160255595656714878965037331239848;\n\n uint256 constant IC8x = 16214254713514974179767304814474510985714849436687773447034352068497147314860;\n uint256 constant IC8y = 13028412764820438875408464005100529475148539560770504369038194564947786526663;\n\n uint256 constant IC9x = 18408046483761423912872515862380512887546745528686003625682162751275305246737;\n uint256 constant IC9y = 14576373605584916924675717896952852805094073315049779994296007237958279154545;\n\n uint256 constant IC10x = 19754959014163302021033520556658948350285362357974437446624957863682467085464;\n uint256 constant IC10y = 6837772045404055003823337103437422613565931626793512604498169200205461541951;\n\n\n // Memory data\n uint16 constant pVk = 0;\n uint16 constant pPairing = 128;\n\n uint16 constant pLastMem = 896;\n\n function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[10] calldata _pubSignals) public view returns (bool) {\n assembly {\n function checkField(v) {\n if iszero(lt(v, r)) {\n mstore(0, 0)\n return(0, 0x20)\n }\n }\n\n // G1 function to multiply a G1 value(x,y) to value in an address\n function g1_mulAccC(pR, x, y, s) {\n let success\n let mIn := mload(0x40)\n mstore(mIn, x)\n mstore(add(mIn, 32), y)\n mstore(add(mIn, 64), s)\n\n success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)\n\n if iszero(success) {\n mstore(0, 0)\n return(0, 0x20)\n }\n\n mstore(add(mIn, 64), mload(pR))\n mstore(add(mIn, 96), mload(add(pR, 32)))\n\n success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)\n\n if iszero(success) {\n mstore(0, 0)\n return(0, 0x20)\n }\n }\n\n function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {\n let _pPairing := add(pMem, pPairing)\n let _pVk := add(pMem, pVk)\n\n mstore(_pVk, IC0x)\n mstore(add(_pVk, 32), IC0y)\n\n // Compute the linear combination vk_x\n\n g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))\n\n g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))\n\n g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))\n\n g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))\n\n g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))\n\n g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160)))\n\n g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192)))\n\n g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224)))\n\n g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256)))\n\n g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288)))\n\n\n // -A\n mstore(_pPairing, calldataload(pA))\n mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))\n\n // B\n mstore(add(_pPairing, 64), calldataload(pB))\n mstore(add(_pPairing, 96), calldataload(add(pB, 32)))\n mstore(add(_pPairing, 128), calldataload(add(pB, 64)))\n mstore(add(_pPairing, 160), calldataload(add(pB, 96)))\n\n // alpha1\n mstore(add(_pPairing, 192), alphax)\n mstore(add(_pPairing, 224), alphay)\n\n // beta2\n mstore(add(_pPairing, 256), betax1)\n mstore(add(_pPairing, 288), betax2)\n mstore(add(_pPairing, 320), betay1)\n mstore(add(_pPairing, 352), betay2)\n\n // vk_x\n mstore(add(_pPairing, 384), mload(add(pMem, pVk)))\n mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))\n\n\n // gamma2\n mstore(add(_pPairing, 448), gammax1)\n mstore(add(_pPairing, 480), gammax2)\n mstore(add(_pPairing, 512), gammay1)\n mstore(add(_pPairing, 544), gammay2)\n\n // C\n mstore(add(_pPairing, 576), calldataload(pC))\n mstore(add(_pPairing, 608), calldataload(add(pC, 32)))\n\n // delta2\n mstore(add(_pPairing, 640), deltax1)\n mstore(add(_pPairing, 672), deltax2)\n mstore(add(_pPairing, 704), deltay1)\n mstore(add(_pPairing, 736), deltay2)\n\n\n let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)\n\n isOk := and(success, mload(_pPairing))\n }\n\n let pMem := mload(0x40)\n mstore(0x40, add(pMem, pLastMem))\n\n // Validate that all evaluations ∈ F\n\n checkField(calldataload(add(_pubSignals, 0)))\n\n checkField(calldataload(add(_pubSignals, 32)))\n\n checkField(calldataload(add(_pubSignals, 64)))\n\n checkField(calldataload(add(_pubSignals, 96)))\n\n checkField(calldataload(add(_pubSignals, 128)))\n\n checkField(calldataload(add(_pubSignals, 160)))\n\n checkField(calldataload(add(_pubSignals, 192)))\n\n checkField(calldataload(add(_pubSignals, 224)))\n\n checkField(calldataload(add(_pubSignals, 256)))\n\n checkField(calldataload(add(_pubSignals, 288)))\n\n checkField(calldataload(add(_pubSignals, 320)))\n\n\n // Validate all evaluations\n let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)\n\n mstore(0, isValid)\n return(0, 0x20)\n }\n }\n }" + } + }, + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "yulDetails": { + "optimizerSteps": "u" + } + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/contracts-domain/deployments/outputs/baseContracts.ts b/contracts-domain/deployments/outputs/baseContracts.ts index f596da2f..79bac65f 100644 --- a/contracts-domain/deployments/outputs/baseContracts.ts +++ b/contracts-domain/deployments/outputs/baseContracts.ts @@ -2049,7 +2049,7 @@ export default { ] }, "TransferDomainProcessor": { - "address": "0x57C3C3880ca40a17d800FF9c42b5C0e2c026F45B", + "address": "0x5d915599DEaf3A15b47c2625F1910599B9D5a1fd", "abi": [ { "inputs": [