diff --git a/crypto/enums/abi_function.py b/crypto/enums/abi_function.py index ece44321..c0cad256 100644 --- a/crypto/enums/abi_function.py +++ b/crypto/enums/abi_function.py @@ -3,5 +3,7 @@ class AbiFunction(Enum): VOTE = 'vote' UNVOTE = 'unvote' + USERNAME_REGISTRATION = 'registerUsername' + USERNAME_RESIGNATION = 'resignUsername' VALIDATOR_REGISTRATION = 'registerValidator' VALIDATOR_RESIGNATION = 'resignValidator' diff --git a/crypto/enums/contract_abi_type.py b/crypto/enums/contract_abi_type.py new file mode 100644 index 00000000..a9eefb1d --- /dev/null +++ b/crypto/enums/contract_abi_type.py @@ -0,0 +1,6 @@ +from enum import Enum + +class ContractAbiType(Enum): + CUSTOM = 'custom' + CONSENSUS = 'consensus' + USERNAMES = 'usernames' diff --git a/crypto/enums/contract_addresses.py b/crypto/enums/contract_addresses.py new file mode 100644 index 00000000..ac0b0510 --- /dev/null +++ b/crypto/enums/contract_addresses.py @@ -0,0 +1,6 @@ +from enum import Enum + +class ContractAddresses(Enum): + CONSENSUS = '0x535B3D7A252fa034Ed71F0C53ec0C6F784cB64E1' + MULTIPAYMENT = '0x83769BeEB7e5405ef0B7dc3C66C43E3a51A6d27f' + USERNAMES = '0x2c1DE3b4Dbb4aDebEbB5dcECAe825bE2a9fc6eb6' diff --git a/crypto/exceptions.py b/crypto/exceptions.py index 58b1421d..8c424c13 100644 --- a/crypto/exceptions.py +++ b/crypto/exceptions.py @@ -8,3 +8,7 @@ class ArkSerializerException(ArkCryptoException): class ArkInvalidTransaction(ArkCryptoException): """Raised when transaction is not valid""" + + +class InvalidUsernameException(Exception): + """Raised when username is invalid""" diff --git a/crypto/transactions/builder/username_registration_builder.py b/crypto/transactions/builder/username_registration_builder.py new file mode 100644 index 00000000..8719b699 --- /dev/null +++ b/crypto/transactions/builder/username_registration_builder.py @@ -0,0 +1,39 @@ +import re +from typing import Optional +from crypto.enums.contract_addresses import ContractAddresses +from crypto.exceptions import InvalidUsernameException +from crypto.transactions.builder.base import AbstractTransactionBuilder +from crypto.transactions.types.username_registration import UsernameRegistration + +class UsernameRegistrationBuilder(AbstractTransactionBuilder): + def __init__(self, data: Optional[dict] = None): + super().__init__(data) + + self.recipient_address(ContractAddresses.USERNAMES.value) + + def username(self, username: str): + self.is_valid_username(username) + + self.transaction.data['username'] = username + self.transaction.refresh_payload_data() + + return self + + def get_transaction_instance(self, data: dict): + return UsernameRegistration(data) + + @staticmethod + def is_valid_username(username: str) -> bool: + if len(username) < 1 or len(username) > 20: + raise InvalidUsernameException(f'Username must be between 1 and 20 characters long. Got {len(username)} characters.') + + if re.match('/[^a-z0-9_]/', username): + raise InvalidUsernameException('Username can only contain lowercase letters, numbers and underscores.') + + if re.match('/^_|_$/', username): + raise InvalidUsernameException('Username cannot start or end with an underscore.') + + if re.match('/__/', username): + raise InvalidUsernameException('Username cannot contain consecutive underscores.') + + return True diff --git a/crypto/transactions/builder/username_resignation_builder.py b/crypto/transactions/builder/username_resignation_builder.py new file mode 100644 index 00000000..fd925cb2 --- /dev/null +++ b/crypto/transactions/builder/username_resignation_builder.py @@ -0,0 +1,13 @@ +from typing import Optional +from crypto.enums.contract_addresses import ContractAddresses +from crypto.transactions.builder.base import AbstractTransactionBuilder +from crypto.transactions.types.username_resignation import UsernameResignation + +class UsernameResignationBuilder(AbstractTransactionBuilder): + def __init__(self, data: Optional[dict] = None): + super().__init__(data) + + self.recipient_address(ContractAddresses.USERNAMES.value) + + def get_transaction_instance(self, data: dict): + return UsernameResignation(data) diff --git a/crypto/transactions/types/username_registration.py b/crypto/transactions/types/username_registration.py new file mode 100644 index 00000000..100333a8 --- /dev/null +++ b/crypto/transactions/types/username_registration.py @@ -0,0 +1,21 @@ +from crypto.enums.contract_abi_type import ContractAbiType +from crypto.transactions.types.abstract_transaction import AbstractTransaction +from crypto.utils.abi_encoder import AbiEncoder +from crypto.enums.abi_function import AbiFunction + +class UsernameRegistration(AbstractTransaction): + def __init__(self, data: dict = None): + data = data or {} + payload = self.decode_payload(data) + if payload: + data['username'] = payload.get('args', [None])[0] if payload.get('args') else None + + super().__init__(data) + + def get_payload(self) -> str: + if 'username' not in self.data: + return '' + + encoder = AbiEncoder(ContractAbiType.USERNAMES) + + return encoder.encode_function_call(AbiFunction.USERNAME_REGISTRATION.value, [self.data['username']]) diff --git a/crypto/transactions/types/username_resignation.py b/crypto/transactions/types/username_resignation.py new file mode 100644 index 00000000..8dbf023e --- /dev/null +++ b/crypto/transactions/types/username_resignation.py @@ -0,0 +1,10 @@ +from crypto.enums.contract_abi_type import ContractAbiType +from crypto.transactions.types.abstract_transaction import AbstractTransaction +from crypto.utils.abi_encoder import AbiEncoder +from crypto.enums.abi_function import AbiFunction + +class UsernameResignation(AbstractTransaction): + def get_payload(self) -> str: + encoder = AbiEncoder(ContractAbiType.USERNAMES) + + return encoder.encode_function_call(AbiFunction.USERNAME_RESIGNATION.value) diff --git a/crypto/utils/Abi.Consensus.json b/crypto/utils/abi/json/Abi.Consensus.json similarity index 100% rename from crypto/utils/Abi.Consensus.json rename to crypto/utils/abi/json/Abi.Consensus.json diff --git a/crypto/utils/abi/json/Abi.Usernames.json b/crypto/utils/abi/json/Abi.Usernames.json new file mode 100644 index 00000000..424ccc19 --- /dev/null +++ b/crypto/utils/abi/json/Abi.Usernames.json @@ -0,0 +1,900 @@ +{ + "abi": [ + { + "type": "function", + "name": "UPGRADE_INTERFACE_VERSION", + "inputs": [], + "outputs": [ + { "name": "", "type": "string", "internalType": "string" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "addUsername", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + }, + { + "name": "username", + "type": "string", + "internalType": "string" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getUsername", + "inputs": [ + { "name": "user", "type": "address", "internalType": "address" } + ], + "outputs": [ + { "name": "", "type": "string", "internalType": "string" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getUsernames", + "inputs": [ + { + "name": "addresses", + "type": "address[]", + "internalType": "address[]" + } + ], + "outputs": [ + { + "name": "", + "type": "tuple[]", + "internalType": "struct UsernamesV1.User[]", + "components": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + }, + { + "name": "username", + "type": "string", + "internalType": "string" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isUsernameRegistered", + "inputs": [ + { + "name": "username", + "type": "string", + "internalType": "string" + } + ], + "outputs": [{ "name": "", "type": "bool", "internalType": "bool" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isUsernameValid", + "inputs": [ + { + "name": "username", + "type": "string", + "internalType": "string" + } + ], + "outputs": [{ "name": "", "type": "bool", "internalType": "bool" }], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { "name": "", "type": "address", "internalType": "address" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "proxiableUUID", + "inputs": [], + "outputs": [ + { "name": "", "type": "bytes32", "internalType": "bytes32" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "registerUsername", + "inputs": [ + { + "name": "username", + "type": "string", + "internalType": "string" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "resignUsername", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "upgradeToAndCall", + "inputs": [ + { + "name": "newImplementation", + "type": "address", + "internalType": "address" + }, + { "name": "data", "type": "bytes", "internalType": "bytes" } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { "name": "", "type": "uint256", "internalType": "uint256" } + ], + "stateMutability": "pure" + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Upgraded", + "inputs": [ + { + "name": "implementation", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "UsernameRegistered", + "inputs": [ + { + "name": "addr", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "username", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "previousUsername", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "UsernameResigned", + "inputs": [ + { + "name": "addr", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "username", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC1967InvalidImplementation", + "inputs": [ + { + "name": "implementation", + "type": "address", + "internalType": "address" + } + ] + }, + { "type": "error", "name": "ERC1967NonPayable", "inputs": [] }, + { "type": "error", "name": "FailedCall", "inputs": [] }, + { "type": "error", "name": "InvalidInitialization", "inputs": [] }, + { "type": "error", "name": "InvalidUsername", "inputs": [] }, + { "type": "error", "name": "NotInitializing", "inputs": [] }, + { + "type": "error", + "name": "OwnableInvalidOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "OwnableUnauthorizedAccount", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ] + }, + { "type": "error", "name": "TakenUsername", "inputs": [] }, + { + "type": "error", + "name": "UUPSUnauthorizedCallContext", + "inputs": [] + }, + { + "type": "error", + "name": "UUPSUnsupportedProxiableUUID", + "inputs": [ + { "name": "slot", "type": "bytes32", "internalType": "bytes32" } + ] + }, + { "type": "error", "name": "UsernameNotRegistered", "inputs": [] } + ], + "bytecode": { + "object": "0x60a0604052306080523480156012575f5ffd5b5060805161186b6100395f395f8181610d7c01528181610da50152610ee4015261186b5ff3fe6080604052600436106100e4575f3560e01c80638129fc1c11610087578063e5abdcef11610057578063e5abdcef14610285578063ebed6dab146102a4578063f2fde38b146102b8578063f5ab196e146102d7575f5ffd5b80638129fc1c146101cf5780638da5cb5b146101e3578063ad3cb1cc14610229578063ce43c03214610266575f5ffd5b806352ac2091116100c257806352ac20911461015057806352d1902d1461018657806354fd4d50146101a8578063715018a6146101bb575f5ffd5b8063117720be146100e857806336a941341461011c5780634f1ef2861461013d575b5f5ffd5b3480156100f3575f5ffd5b50610107610102366004611313565b610303565b60405190151581526020015b60405180910390f35b348015610127575f5ffd5b5061013b610136366004611313565b610313565b005b61013b61014b366004611368565b610349565b34801561015b575f5ffd5b5061010761016a366004611313565b80516020918201205f9081526001909152604090205460ff1690565b348015610191575f5ffd5b5061019a610364565b604051908152602001610113565b3480156101b3575f5ffd5b50600161019a565b3480156101c6575f5ffd5b5061013b61037f565b3480156101da575f5ffd5b5061013b610392565b3480156101ee575f5ffd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546040516001600160a01b039091168152602001610113565b348015610234575f5ffd5b50610259604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101139190611413565b348015610271575f5ffd5b50610259610280366004611425565b6104a0565b348015610290575f5ffd5b5061013b61029f36600461143e565b610549565b3480156102af575f5ffd5b5061013b610592565b3480156102c3575f5ffd5b5061013b6102d2366004611425565b6106e9565b3480156102e2575f5ffd5b506102f66102f136600461147f565b610728565b60405161011391906114f0565b5f61030d826109eb565b92915050565b8061031d816109eb565b61033a57604051630a1de65160e31b815260040160405180910390fd5b610345338383610bfc565b5050565b610351610d71565b61035a82610e15565b6103458282610e1d565b5f61036d610ed9565b505f5160206118165f395f51905f5290565b610387610f22565b6103905f610f7d565b565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f811580156103d75750825b90505f8267ffffffffffffffff1660011480156103f35750303b155b905081158015610401575080155b1561041f5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561044957845460ff60401b1916600160401b1785555b61045233610fed565b831561049957845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2906020015b60405180910390a15b5050505050565b6001600160a01b0381165f9081526020819052604090208054606091906104c690611573565b80601f01602080910402602001604051908101604052809291908181526020018280546104f290611573565b801561053d5780601f106105145761010080835404028352916020019161053d565b820191905f5260205f20905b81548152906001019060200180831161052057829003601f168201915b50505050509050919050565b610551610f22565b8051819060011180610564575060148151115b1561058257604051630a1de65160e31b815260040160405180910390fd5b61058d838383610bfc565b505050565b335f90815260208190526040812080546105ab90611573565b80601f01602080910402602001604051908101604052809291908181526020018280546105d790611573565b80156106225780601f106105f957610100808354040283529160200191610622565b820191905f5260205f20905b81548152906001019060200180831161060557829003601f168201915b505050505090505f815111156106cd57335f908152602081905260408082209051600191839161065291906115ab565b604080519182900390912082526020808301939093529081015f908120805460ff19169415159490941790935533835290829052812061069191611220565b7ff5a79d28213d53340730f0c5a952f4809e33db20cbe21a2a0b5fa7d77fa107b333826040516106c292919061161c565b60405180910390a150565b6040516341c5396760e01b815260040160405180910390fd5b50565b6106f1610f22565b6001600160a01b03811661071f57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6106e681610f7d565b60605f8267ffffffffffffffff8111156107445761074461126a565b60405190808252806020026020018201604052801561078957816020015b604080518082019091525f8152606060208201528152602001906001900390816107625790505b5090505f805b84811015610935575f5f8787848181106107ab576107ab61163f565b90506020020160208101906107c09190611425565b6001600160a01b03166001600160a01b031681526020019081526020015f2080546107ea90611573565b15905061092d57604051806040016040528087878481811061080e5761080e61163f565b90506020020160208101906108239190611425565b6001600160a01b031681526020015f5f8989868181106108455761084561163f565b905060200201602081019061085a9190611425565b6001600160a01b03166001600160a01b031681526020019081526020015f20805461088490611573565b80601f01602080910402602001604051908101604052809291908181526020018280546108b090611573565b80156108fb5780601f106108d2576101008083540402835291602001916108fb565b820191905f5260205f20905b8154815290600101906020018083116108de57829003601f168201915b505050505081525083838061090f90611667565b9450815181106109215761092161163f565b60200260200101819052505b60010161078f565b505f8167ffffffffffffffff8111156109505761095061126a565b60405190808252806020026020018201604052801561099557816020015b604080518082019091525f81526060602082015281526020019060019003908161096e5790505b5090505f5b828110156109e1578381815181106109b4576109b461163f565b60200260200101518282815181106109ce576109ce61163f565b602090810291909101015260010161099a565b5095945050505050565b5f6001825110806109fd575060148251115b15610a0957505f919050565b815f81518110610a1b57610a1b61163f565b6020910101516001600160f81b031916605f60f81b1480610a6d57508160018351610a46919061167f565b81518110610a5657610a5661163f565b6020910101516001600160f81b031916605f60f81b145b15610a7957505f919050565b5f5b8251811015610bf357603060f81b838281518110610a9b57610a9b61163f565b01602001516001600160f81b03191610801590610adc5750603960f81b838281518110610aca57610aca61163f565b01602001516001600160f81b03191611155b158015610b3e5750606160f81b838281518110610afb57610afb61163f565b01602001516001600160f81b03191610801590610b3c5750607a60f81b838281518110610b2a57610b2a61163f565b01602001516001600160f81b03191611155b155b8015610b6f5750828181518110610b5757610b5761163f565b6020910101516001600160f81b031916605f60f81b14155b15610b7c57505f92915050565b828181518110610b8e57610b8e61163f565b6020910101516001600160f81b031916605f60f81b148015610bde575082610bb7826001611692565b81518110610bc757610bc761163f565b6020910101516001600160f81b031916605f60f81b145b15610beb57505f92915050565b600101610a7b565b50600192915050565b80516020808301919091205f818152600190925260409091205460ff1615610c375760405163506517a760e11b815260040160405180910390fd5b6001600160a01b0384165f9081526020819052604081208054610c5990611573565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8590611573565b8015610cd05780601f10610ca757610100808354040283529160200191610cd0565b820191905f5260205f20905b815481529060010190602001808311610cb357829003601f168201915b505050505090505f81511115610d015780516020808301919091205f908152600190915260409020805460ff191690555b6001600160a01b0385165f908152602081905260409020610d2285826116e9565b505f82815260016020819052604091829020805460ff19169091179055517fdc393f1f31882fea068a12acfed8ed6e9f7e88a6ed213355b5afb78ad76a704590610490908790879085906117a4565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480610df757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610deb5f5160206118165f395f51905f52546001600160a01b031690565b6001600160a01b031614155b156103905760405163703e46dd60e11b815260040160405180910390fd5b6106e6610f22565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610e77575060408051601f3d908101601f19168201909252610e74918101906117e3565b60015b610e9f57604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610716565b5f5160206118165f395f51905f528114610ecf57604051632a87526960e21b815260048101829052602401610716565b61058d8383610ffe565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103905760405163703e46dd60e11b815260040160405180910390fd5b33610f547f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146103905760405163118cdaa760e01b8152336004820152602401610716565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b610ff5611053565b6106e68161109c565b611007826110a4565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a280511561104b5761058d8282611107565b610345611179565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661039057604051631afcd79f60e31b815260040160405180910390fd5b6106f1611053565b806001600160a01b03163b5f036110d957604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610716565b5f5160206118165f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b03168460405161112391906117fa565b5f60405180830381855af49150503d805f811461115b576040519150601f19603f3d011682016040523d82523d5f602084013e611160565b606091505b5091509150611170858383611198565b95945050505050565b34156103905760405163b398979f60e01b815260040160405180910390fd5b6060826111ad576111a8826111f7565b6111f0565b81511580156111c457506001600160a01b0384163b155b156111ed57604051639996b31560e01b81526001600160a01b0385166004820152602401610716565b50805b9392505050565b8051156112075780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b50805461122c90611573565b5f825580601f1061123b575050565b601f0160209004905f5260205f20908101906106e691905b80821115611266575f8155600101611253565b5090565b634e487b7160e01b5f52604160045260245ffd5b5f5f67ffffffffffffffff8411156112985761129861126a565b50604051601f19601f85018116603f0116810181811067ffffffffffffffff821117156112c7576112c761126a565b6040528381529050808284018510156112de575f5ffd5b838360208301375f60208583010152509392505050565b5f82601f830112611304575f5ffd5b6111f08383356020850161127e565b5f60208284031215611323575f5ffd5b813567ffffffffffffffff811115611339575f5ffd5b611345848285016112f5565b949350505050565b80356001600160a01b0381168114611363575f5ffd5b919050565b5f5f60408385031215611379575f5ffd5b6113828361134d565b9150602083013567ffffffffffffffff81111561139d575f5ffd5b8301601f810185136113ad575f5ffd5b6113bc8582356020840161127e565b9150509250929050565b5f5b838110156113e05781810151838201526020016113c8565b50505f910152565b5f81518084526113ff8160208601602086016113c6565b601f01601f19169290920160200192915050565b602081525f6111f060208301846113e8565b5f60208284031215611435575f5ffd5b6111f08261134d565b5f5f6040838503121561144f575f5ffd5b6114588361134d565b9150602083013567ffffffffffffffff811115611473575f5ffd5b6113bc858286016112f5565b5f5f60208385031215611490575f5ffd5b823567ffffffffffffffff8111156114a6575f5ffd5b8301601f810185136114b6575f5ffd5b803567ffffffffffffffff8111156114cc575f5ffd5b8560208260051b84010111156114e0575f5ffd5b6020919091019590945092505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561156757868503603f19018452815180516001600160a01b03168652602090810151604091870182905290611551908701826113e8565b9550506020938401939190910190600101611516565b50929695505050505050565b600181811c9082168061158757607f821691505b6020821081036115a557634e487b7160e01b5f52602260045260245ffd5b50919050565b5f5f83546115b881611573565b6001821680156115cf57600181146115e457611611565b60ff1983168652811515820286019350611611565b865f5260205f205f5b83811015611609578154888201526001909101906020016115ed565b505081860193505b509195945050505050565b6001600160a01b03831681526040602082018190525f90611345908301846113e8565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161167857611678611653565b5060010190565b8181038181111561030d5761030d611653565b8082018082111561030d5761030d611653565b601f82111561058d57805f5260205f20601f840160051c810160208510156116ca5750805b601f840160051c820191505b81811015610499575f81556001016116d6565b815167ffffffffffffffff8111156117035761170361126a565b611717816117118454611573565b846116a5565b6020601f821160018114611749575f83156117325750848201515b5f19600385901b1c1916600184901b178455610499565b5f84815260208120601f198516915b828110156117785787850151825560209485019460019092019101611758565b508482101561179557868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b6001600160a01b03841681526060602082018190525f906117c7908301856113e8565b82810360408401526117d981856113e8565b9695505050505050565b5f602082840312156117f3575f5ffd5b5051919050565b5f825161180b8184602087016113c6565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212202cd847cb3edf0b7eef198ed0ae022f99a0d18fa21cb2a945077443915317943b64736f6c634300081b0033", + "sourceMap": "285:5015:37:-:0;;;1171:4:25;1128:48;;285:5015:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;", + "linkReferences": {} + }, + "deployedBytecode": { + "object": "0x6080604052600436106100e4575f3560e01c80638129fc1c11610087578063e5abdcef11610057578063e5abdcef14610285578063ebed6dab146102a4578063f2fde38b146102b8578063f5ab196e146102d7575f5ffd5b80638129fc1c146101cf5780638da5cb5b146101e3578063ad3cb1cc14610229578063ce43c03214610266575f5ffd5b806352ac2091116100c257806352ac20911461015057806352d1902d1461018657806354fd4d50146101a8578063715018a6146101bb575f5ffd5b8063117720be146100e857806336a941341461011c5780634f1ef2861461013d575b5f5ffd5b3480156100f3575f5ffd5b50610107610102366004611313565b610303565b60405190151581526020015b60405180910390f35b348015610127575f5ffd5b5061013b610136366004611313565b610313565b005b61013b61014b366004611368565b610349565b34801561015b575f5ffd5b5061010761016a366004611313565b80516020918201205f9081526001909152604090205460ff1690565b348015610191575f5ffd5b5061019a610364565b604051908152602001610113565b3480156101b3575f5ffd5b50600161019a565b3480156101c6575f5ffd5b5061013b61037f565b3480156101da575f5ffd5b5061013b610392565b3480156101ee575f5ffd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546040516001600160a01b039091168152602001610113565b348015610234575f5ffd5b50610259604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101139190611413565b348015610271575f5ffd5b50610259610280366004611425565b6104a0565b348015610290575f5ffd5b5061013b61029f36600461143e565b610549565b3480156102af575f5ffd5b5061013b610592565b3480156102c3575f5ffd5b5061013b6102d2366004611425565b6106e9565b3480156102e2575f5ffd5b506102f66102f136600461147f565b610728565b60405161011391906114f0565b5f61030d826109eb565b92915050565b8061031d816109eb565b61033a57604051630a1de65160e31b815260040160405180910390fd5b610345338383610bfc565b5050565b610351610d71565b61035a82610e15565b6103458282610e1d565b5f61036d610ed9565b505f5160206118165f395f51905f5290565b610387610f22565b6103905f610f7d565b565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f811580156103d75750825b90505f8267ffffffffffffffff1660011480156103f35750303b155b905081158015610401575080155b1561041f5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561044957845460ff60401b1916600160401b1785555b61045233610fed565b831561049957845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2906020015b60405180910390a15b5050505050565b6001600160a01b0381165f9081526020819052604090208054606091906104c690611573565b80601f01602080910402602001604051908101604052809291908181526020018280546104f290611573565b801561053d5780601f106105145761010080835404028352916020019161053d565b820191905f5260205f20905b81548152906001019060200180831161052057829003601f168201915b50505050509050919050565b610551610f22565b8051819060011180610564575060148151115b1561058257604051630a1de65160e31b815260040160405180910390fd5b61058d838383610bfc565b505050565b335f90815260208190526040812080546105ab90611573565b80601f01602080910402602001604051908101604052809291908181526020018280546105d790611573565b80156106225780601f106105f957610100808354040283529160200191610622565b820191905f5260205f20905b81548152906001019060200180831161060557829003601f168201915b505050505090505f815111156106cd57335f908152602081905260408082209051600191839161065291906115ab565b604080519182900390912082526020808301939093529081015f908120805460ff19169415159490941790935533835290829052812061069191611220565b7ff5a79d28213d53340730f0c5a952f4809e33db20cbe21a2a0b5fa7d77fa107b333826040516106c292919061161c565b60405180910390a150565b6040516341c5396760e01b815260040160405180910390fd5b50565b6106f1610f22565b6001600160a01b03811661071f57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6106e681610f7d565b60605f8267ffffffffffffffff8111156107445761074461126a565b60405190808252806020026020018201604052801561078957816020015b604080518082019091525f8152606060208201528152602001906001900390816107625790505b5090505f805b84811015610935575f5f8787848181106107ab576107ab61163f565b90506020020160208101906107c09190611425565b6001600160a01b03166001600160a01b031681526020019081526020015f2080546107ea90611573565b15905061092d57604051806040016040528087878481811061080e5761080e61163f565b90506020020160208101906108239190611425565b6001600160a01b031681526020015f5f8989868181106108455761084561163f565b905060200201602081019061085a9190611425565b6001600160a01b03166001600160a01b031681526020019081526020015f20805461088490611573565b80601f01602080910402602001604051908101604052809291908181526020018280546108b090611573565b80156108fb5780601f106108d2576101008083540402835291602001916108fb565b820191905f5260205f20905b8154815290600101906020018083116108de57829003601f168201915b505050505081525083838061090f90611667565b9450815181106109215761092161163f565b60200260200101819052505b60010161078f565b505f8167ffffffffffffffff8111156109505761095061126a565b60405190808252806020026020018201604052801561099557816020015b604080518082019091525f81526060602082015281526020019060019003908161096e5790505b5090505f5b828110156109e1578381815181106109b4576109b461163f565b60200260200101518282815181106109ce576109ce61163f565b602090810291909101015260010161099a565b5095945050505050565b5f6001825110806109fd575060148251115b15610a0957505f919050565b815f81518110610a1b57610a1b61163f565b6020910101516001600160f81b031916605f60f81b1480610a6d57508160018351610a46919061167f565b81518110610a5657610a5661163f565b6020910101516001600160f81b031916605f60f81b145b15610a7957505f919050565b5f5b8251811015610bf357603060f81b838281518110610a9b57610a9b61163f565b01602001516001600160f81b03191610801590610adc5750603960f81b838281518110610aca57610aca61163f565b01602001516001600160f81b03191611155b158015610b3e5750606160f81b838281518110610afb57610afb61163f565b01602001516001600160f81b03191610801590610b3c5750607a60f81b838281518110610b2a57610b2a61163f565b01602001516001600160f81b03191611155b155b8015610b6f5750828181518110610b5757610b5761163f565b6020910101516001600160f81b031916605f60f81b14155b15610b7c57505f92915050565b828181518110610b8e57610b8e61163f565b6020910101516001600160f81b031916605f60f81b148015610bde575082610bb7826001611692565b81518110610bc757610bc761163f565b6020910101516001600160f81b031916605f60f81b145b15610beb57505f92915050565b600101610a7b565b50600192915050565b80516020808301919091205f818152600190925260409091205460ff1615610c375760405163506517a760e11b815260040160405180910390fd5b6001600160a01b0384165f9081526020819052604081208054610c5990611573565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8590611573565b8015610cd05780601f10610ca757610100808354040283529160200191610cd0565b820191905f5260205f20905b815481529060010190602001808311610cb357829003601f168201915b505050505090505f81511115610d015780516020808301919091205f908152600190915260409020805460ff191690555b6001600160a01b0385165f908152602081905260409020610d2285826116e9565b505f82815260016020819052604091829020805460ff19169091179055517fdc393f1f31882fea068a12acfed8ed6e9f7e88a6ed213355b5afb78ad76a704590610490908790879085906117a4565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480610df757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610deb5f5160206118165f395f51905f52546001600160a01b031690565b6001600160a01b031614155b156103905760405163703e46dd60e11b815260040160405180910390fd5b6106e6610f22565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610e77575060408051601f3d908101601f19168201909252610e74918101906117e3565b60015b610e9f57604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610716565b5f5160206118165f395f51905f528114610ecf57604051632a87526960e21b815260048101829052602401610716565b61058d8383610ffe565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103905760405163703e46dd60e11b815260040160405180910390fd5b33610f547f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146103905760405163118cdaa760e01b8152336004820152602401610716565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b610ff5611053565b6106e68161109c565b611007826110a4565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a280511561104b5761058d8282611107565b610345611179565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661039057604051631afcd79f60e31b815260040160405180910390fd5b6106f1611053565b806001600160a01b03163b5f036110d957604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610716565b5f5160206118165f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b03168460405161112391906117fa565b5f60405180830381855af49150503d805f811461115b576040519150601f19603f3d011682016040523d82523d5f602084013e611160565b606091505b5091509150611170858383611198565b95945050505050565b34156103905760405163b398979f60e01b815260040160405180910390fd5b6060826111ad576111a8826111f7565b6111f0565b81511580156111c457506001600160a01b0384163b155b156111ed57604051639996b31560e01b81526001600160a01b0385166004820152602401610716565b50805b9392505050565b8051156112075780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b50805461122c90611573565b5f825580601f1061123b575050565b601f0160209004905f5260205f20908101906106e691905b80821115611266575f8155600101611253565b5090565b634e487b7160e01b5f52604160045260245ffd5b5f5f67ffffffffffffffff8411156112985761129861126a565b50604051601f19601f85018116603f0116810181811067ffffffffffffffff821117156112c7576112c761126a565b6040528381529050808284018510156112de575f5ffd5b838360208301375f60208583010152509392505050565b5f82601f830112611304575f5ffd5b6111f08383356020850161127e565b5f60208284031215611323575f5ffd5b813567ffffffffffffffff811115611339575f5ffd5b611345848285016112f5565b949350505050565b80356001600160a01b0381168114611363575f5ffd5b919050565b5f5f60408385031215611379575f5ffd5b6113828361134d565b9150602083013567ffffffffffffffff81111561139d575f5ffd5b8301601f810185136113ad575f5ffd5b6113bc8582356020840161127e565b9150509250929050565b5f5b838110156113e05781810151838201526020016113c8565b50505f910152565b5f81518084526113ff8160208601602086016113c6565b601f01601f19169290920160200192915050565b602081525f6111f060208301846113e8565b5f60208284031215611435575f5ffd5b6111f08261134d565b5f5f6040838503121561144f575f5ffd5b6114588361134d565b9150602083013567ffffffffffffffff811115611473575f5ffd5b6113bc858286016112f5565b5f5f60208385031215611490575f5ffd5b823567ffffffffffffffff8111156114a6575f5ffd5b8301601f810185136114b6575f5ffd5b803567ffffffffffffffff8111156114cc575f5ffd5b8560208260051b84010111156114e0575f5ffd5b6020919091019590945092505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561156757868503603f19018452815180516001600160a01b03168652602090810151604091870182905290611551908701826113e8565b9550506020938401939190910190600101611516565b50929695505050505050565b600181811c9082168061158757607f821691505b6020821081036115a557634e487b7160e01b5f52602260045260245ffd5b50919050565b5f5f83546115b881611573565b6001821680156115cf57600181146115e457611611565b60ff1983168652811515820286019350611611565b865f5260205f205f5b83811015611609578154888201526001909101906020016115ed565b505081860193505b509195945050505050565b6001600160a01b03831681526040602082018190525f90611345908301846113e8565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161167857611678611653565b5060010190565b8181038181111561030d5761030d611653565b8082018082111561030d5761030d611653565b601f82111561058d57805f5260205f20601f840160051c810160208510156116ca5750805b601f840160051c820191505b81811015610499575f81556001016116d6565b815167ffffffffffffffff8111156117035761170361126a565b611717816117118454611573565b846116a5565b6020601f821160018114611749575f83156117325750848201515b5f19600385901b1c1916600184901b178455610499565b5f84815260208120601f198516915b828110156117785787850151825560209485019460019092019101611758565b508482101561179557868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b6001600160a01b03841681526060602082018190525f906117c7908301856113e8565b82810360408401526117d981856113e8565b9695505050505050565b5f602082840312156117f3575f5ffd5b5051919050565b5f825161180b8184602087016113c6565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212202cd847cb3edf0b7eef198ed0ae022f99a0d18fa21cb2a945077443915317943b64736f6c634300081b0033", + "sourceMap": "285:5015:37:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2491:134;;;;;;;;;;-1:-1:-1;2491:134:37;;;;;:::i;:::-;;:::i;:::-;;;1586:14:40;;1579:22;1561:41;;1549:2;1534:18;2491:134:37;;;;;;;;1375:273;;;;;;;;;;-1:-1:-1;1375:273:37;;;;;:::i;:::-;;:::i;:::-;;4161:214:25;;;;;;:::i;:::-;;:::i;2335:150:37:-;;;;;;;;;;-1:-1:-1;2335:150:37;;;;;:::i;:::-;2451:26;;;;;;;2412:4;2435:43;;;:15;:43;;;;;;;;;;2335:150;3708:134:25;;;;;;;;;;;;;:::i;:::-;;;2466:25:40;;;2454:2;2439:18;3708:134:25;2320:177:40;2134:76:37;;;;;;;;;;-1:-1:-1;2202:1:37;2134:76;;3155:101:23;;;;;;;;;;;;;:::i;788:84:37:-;;;;;;;;;;;;;:::i;2441:144:23:-;;;;;;;;;;-1:-1:-1;1313:22:23;2570:8;2441:144;;-1:-1:-1;;;;;2570:8:23;;;2830:51:40;;2818:2;2803:18;2441:144:23;2684:203:40;1819:58:25;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1819:58:25;;;;;;;;;;;;:::i;2216:113:37:-;;;;;;;;;;-1:-1:-1;2216:113:37;;;;;:::i;:::-;;:::i;1011:358::-;;;;;;;;;;-1:-1:-1;1011:358:37;;;;;:::i;:::-;;:::i;1654:434::-;;;;;;;;;;;;;:::i;3405:215:23:-;;;;;;;;;;-1:-1:-1;3405:215:23;;;;;:::i;:::-;;:::i;2631:621:37:-;;;;;;;;;;-1:-1:-1;2631:621:37;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2491:134::-;2563:4;2586:32;2608:8;2586:15;:32::i;:::-;2579:39;2491:134;-1:-1:-1;;2491:134:37:o;1375:273::-;1496:8;1520:18;1496:8;1520:15;:18::i;:::-;1515:74;;1561:17;;-1:-1:-1;;;1561:17:37;;;;;;;;;;;1515:74;1599:42;1617:10;1629:8;1639:1;1599:17;:42::i;:::-;1434:214;1375:273;:::o;4161:214:25:-;2655:13;:11;:13::i;:::-;4276:36:::1;4294:17;4276;:36::i;:::-;4322:46;4344:17;4363:4;4322:21;:46::i;3708:134::-:0;3777:7;2926:20;:18;:20::i;:::-;-1:-1:-1;;;;;;;;;;;;3708:134:25;:::o;3155:101:23:-;2334:13;:11;:13::i;:::-;3219:30:::1;3246:1;3219:18;:30::i;:::-;3155:101::o:0;788:84:37:-;8870:21:24;4302:15;;-1:-1:-1;;;4302:15:24;;;;4301:16;;4348:14;;4158:30;4726:16;;:34;;;;;4746:14;4726:34;4706:54;;4770:17;4790:11;:16;;4805:1;4790:16;:50;;;;-1:-1:-1;4818:4:24;4810:25;:30;4790:50;4770:70;;4856:12;4855:13;:30;;;;;4873:12;4872:13;4855:30;4851:91;;;4908:23;;-1:-1:-1;;;4908:23:24;;;;;;;;;;;4851:91;4951:18;;-1:-1:-1;;4951:18:24;4968:1;4951:18;;;4979:67;;;;5013:22;;-1:-1:-1;;;;5013:22:24;-1:-1:-1;;;5013:22:24;;;4979:67;839:26:37::1;854:10;839:14;:26::i;:::-;5070:14:24::0;5066:101;;;5100:23;;-1:-1:-1;;;;5100:23:24;;;5142:14;;-1:-1:-1;6020:50:40;;5142:14:24;;6008:2:40;5993:18;5142:14:24;;;;;;;;5066:101;4092:1081;;;;;788:84:37:o;2216:113::-;-1:-1:-1;;;;;2306:16:37;;:10;:16;;;;;;;;;;2299:23;;2274:13;;2306:16;2299:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2216:113;;;:::o;1011:358::-;2334:13:23;:11;:13::i;:::-;1236:8:37;;1122;;1247:1:::1;-1:-1:-1::0;1236:12:37;:29:::1;;;1263:2;1252:1;:8;:13;1236:29;1232:84;;;1288:17;;-1:-1:-1::0;;;1288:17:37::1;;;;;;;;;;;1232:84;1326:36;1344:4;1350:8;1360:1;1326:17;:36::i;:::-;1089:280;1011:358:::0;;:::o;1654:434::-;1735:10;1699:22;1724;;;;;;;;;;1699:47;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1827:1;1808:8;1802:22;:26;1798:284;;;1887:10;1904:5;1876:22;;;;;;;;;;;1860:40;;1844:15;;1904:5;;1860:40;;1876:22;1860:40;:::i;:::-;;;;;;;;;;;1844:57;;;;;;;;;;;;;-1:-1:-1;1844:57:37;;;:65;;-1:-1:-1;;1844:65:37;;;;;;;;;;;1941:10;1930:22;;;;;;;;1923:29;;;:::i;:::-;1972:38;1989:10;2001:8;1972:38;;;;;;;:::i;:::-;;;;;;;;1689:399;1654:434::o;1798:284::-;2048:23;;-1:-1:-1;;;2048:23:37;;;;;;;;;;;1798:284;1689:399;1654:434::o;3405:215:23:-;2334:13;:11;:13::i;:::-;-1:-1:-1;;;;;3489:22:23;::::1;3485:91;;3534:31;::::0;-1:-1:-1;;;3534:31:23;;3562:1:::1;3534:31;::::0;::::1;2830:51:40::0;2803:18;;3534:31:23::1;;;;;;;;3485:91;3585:28;3604:8;3585:18;:28::i;2631:621:37:-:0;2706:13;2731:19;2764:9;2753:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;2753:28:37;;;;;;;;;;;;;;;-1:-1:-1;2731:50:37;-1:-1:-1;2791:13:37;;2818:214;2838:20;;;2818:214;;;2889:10;:24;2900:9;;2910:1;2900:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;2889:24:37;-1:-1:-1;;;;;2889:24:37;;;;;;;;;;;;2883:38;;;;;:::i;:::-;:43;;-1:-1:-1;2879:143:37;;2963:44;;;;;;;;2968:9;;2978:1;2968:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;2963:44:37;;;;;2982:10;:24;2993:9;;3003:1;2993:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;2982:24:37;-1:-1:-1;;;;;2982:24:37;;;;;;;;;;;;2963:44;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2946:5;2952:7;;;;;:::i;:::-;;;2946:14;;;;;;;;:::i;:::-;;;;;;:61;;;;2879:143;2860:3;;2818:214;;;;3091:20;3125:5;3114:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;3114:17:37;;;;;;;;;;;;;;;-1:-1:-1;3091:40:37;-1:-1:-1;3146:9:37;3141:81;3165:5;3161:1;:9;3141:81;;;3203:5;3209:1;3203:8;;;;;;;;:::i;:::-;;;;;;;3191:6;3198:1;3191:9;;;;;;;;:::i;:::-;;;;;;;;;;:20;3172:3;;3141:81;;;-1:-1:-1;3239:6:37;2631:621;-1:-1:-1;;;;;2631:621:37:o;3541:1108::-;3612:4;3734:1;3716:8;:15;:19;:43;;;;3757:2;3739:8;:15;:20;3716:43;3712:86;;;-1:-1:-1;3782:5:37;;3541:1108;-1:-1:-1;3541:1108:37:o;3712:86::-;3859:8;3868:1;3859:11;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;3859:11:37;-1:-1:-1;;;3859:19:37;;:60;;;3882:8;3909:1;3891:8;:15;:19;;;;:::i;:::-;3882:29;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;3882:29:37;-1:-1:-1;;;3882:37:37;3859:60;3855:103;;;-1:-1:-1;3942:5:37;;3541:1108;-1:-1:-1;3541:1108:37:o;3855:103::-;3973:9;3968:653;3992:8;:15;3988:1;:19;3968:653;;;4141:4;4126:19;;:8;4135:1;4126:11;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;4126:11:37;:19;;;;:42;;;4164:4;4149:19;;:8;4158:1;4149:11;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;4149:11:37;:19;;4126:42;4124:45;:121;;;;;4217:4;4202:19;;:8;4211:1;4202:11;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;4202:11:37;:19;;;;:42;;;4240:4;4225:19;;:8;4234:1;4225:11;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;4225:11:37;:19;;4202:42;4200:45;4124:121;:174;;;;;4278:8;4287:1;4278:11;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;4278:11:37;-1:-1:-1;;;4278:19:37;4276:22;4124:174;4103:260;;;-1:-1:-1;4343:5:37;;3541:1108;-1:-1:-1;;3541:1108:37:o;4103:260::-;4518:8;4527:1;4518:11;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;4518:11:37;-1:-1:-1;;;4518:19:37;:46;;;;-1:-1:-1;4541:8:37;4550:5;:1;4554;4550:5;:::i;:::-;4541:15;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;4541:15:37;-1:-1:-1;;;4541:23:37;4518:46;4514:97;;;-1:-1:-1;4591:5:37;;3541:1108;-1:-1:-1;;3541:1108:37:o;4514:97::-;4009:3;;3968:653;;;-1:-1:-1;4638:4:37;;3541:1108;-1:-1:-1;;3541:1108:37:o;4655:643::-;4778:12;;;;;;;;;;4755:20;4804:29;;;:15;:29;;;;;;;;;;4800:82;;;4856:15;;-1:-1:-1;;;4856:15:37;;;;;;;;;;;4800:82;-1:-1:-1;;;;;4925:16:37;;4892:30;4925:16;;;;;;;;;;4892:49;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5030:1;5003:16;4997:30;:34;4993:147;;;5063:34;;;;;;;;;;5101:5;5047:51;;;:15;:51;;;;;;:59;;-1:-1:-1;;5047:59:37;;;4993:147;-1:-1:-1;;;;;5150:16:37;;:10;:16;;;;;;;;;;:27;5169:8;5150:16;:27;:::i;:::-;-1:-1:-1;5187:29:37;;;;5219:4;5187:29;;;;;;;;;:36;;-1:-1:-1;;5187:36:37;;;;;;5239:52;;;;;5258:4;;5264:8;;5274:16;;5239:52;:::i;4603:312:25:-;4683:4;-1:-1:-1;;;;;4692:6:25;4675:23;;;:120;;;4789:6;-1:-1:-1;;;;;4753:42:25;:32;-1:-1:-1;;;;;;;;;;;1519:53:30;-1:-1:-1;;;;;1519:53:30;;1441:138;4753:32:25;-1:-1:-1;;;;;4753:42:25;;;4675:120;4658:251;;;4869:29;;-1:-1:-1;;;4869:29:25;;;;;;;;;;;895:84:37;2334:13:23;:11;:13::i;6057:538:25:-;6174:17;-1:-1:-1;;;;;6156:50:25;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6156:52:25;;;;;;;;-1:-1:-1;;6156:52:25;;;;;;;;;;;;:::i;:::-;;;6152:437;;6518:60;;-1:-1:-1;;;6518:60:25;;-1:-1:-1;;;;;2848:32:40;;6518:60:25;;;2830:51:40;2803:18;;6518:60:25;2684:203:40;6152:437:25;-1:-1:-1;;;;;;;;;;;6250:40:25;;6246:120;;6317:34;;-1:-1:-1;;;6317:34:25;;;;;2466:25:40;;;2439:18;;6317:34:25;2320:177:40;6246:120:25;6379:54;6409:17;6428:4;6379:29;:54::i;5032:213::-;5106:4;-1:-1:-1;;;;;5115:6:25;5098:23;;5094:145;;5199:29;;-1:-1:-1;;;5199:29:25;;;;;;;;;;;2658:162:23;966:10:26;2717:7:23;1313:22;2570:8;-1:-1:-1;;;;;2570:8:23;;2441:144;2717:7;-1:-1:-1;;;;;2717:23:23;;2713:101;;2763:40;;-1:-1:-1;;;2763:40:23;;966:10:26;2763:40:23;;;2830:51:40;2803:18;;2763:40:23;2684:203:40;3774:248:23;1313:22;3923:8;;-1:-1:-1;;;;;;3941:19:23;;-1:-1:-1;;;;;3941:19:23;;;;;;;;3975:40;;3923:8;;;;;3975:40;;3847:24;;3975:40;3837:185;;3774:248;:::o;1847:127::-;6931:20:24;:18;:20::i;:::-;1929:38:23::1;1954:12;1929:24;:38::i;2264:344:30:-:0;2355:37;2374:17;2355:18;:37::i;:::-;2407:36;;-1:-1:-1;;;;;2407:36:30;;;;;;;;2458:11;;:15;2454:148;;2489:53;2518:17;2537:4;2489:28;:53::i;2454:148::-;2573:18;:16;:18::i;7084:141:24:-;8870:21;8560:40;-1:-1:-1;;;8560:40:24;;;;7146:73;;7191:17;;-1:-1:-1;;;7191:17:24;;;;;;;;;;;1980:235:23;6931:20:24;:18;:20::i;1671:281:30:-;1748:17;-1:-1:-1;;;;;1748:29:30;;1781:1;1748:34;1744:119;;1805:47;;-1:-1:-1;;;1805:47:30;;-1:-1:-1;;;;;2848:32:40;;1805:47:30;;;2830:51:40;2803:18;;1805:47:30;2684:203:40;1744:119:30;-1:-1:-1;;;;;;;;;;;1872:73:30;;-1:-1:-1;;;;;;1872:73:30;-1:-1:-1;;;;;1872:73:30;;;;;;;;;;1671:281::o;3900:253:34:-;3983:12;4008;4022:23;4049:6;-1:-1:-1;;;;;4049:19:34;4069:4;4049:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4007:67;;;;4091:55;4118:6;4126:7;4135:10;4091:26;:55::i;:::-;4084:62;3900:253;-1:-1:-1;;;;;3900:253:34:o;6113:122:30:-;6163:9;:13;6159:70;;6199:19;;-1:-1:-1;;;6199:19:30;;;;;;;;;;;4421:582:34;4565:12;4594:7;4589:408;;4617:19;4625:10;4617:7;:19::i;:::-;4589:408;;;4841:17;;:22;:49;;;;-1:-1:-1;;;;;;4867:18:34;;;:23;4841:49;4837:119;;;4917:24;;-1:-1:-1;;;4917:24:34;;-1:-1:-1;;;;;2848:32:40;;4917:24:34;;;2830:51:40;2803:18;;4917:24:34;2684:203:40;4837:119:34;-1:-1:-1;4976:10:34;4589:408;4421:582;;;;;:::o;5543:487::-;5674:17;;:21;5670:354;;5871:10;5865:17;5927:15;5914:10;5910:2;5906:19;5899:44;5670:354;5994:19;;-1:-1:-1;;;5994:19:34;;;;;;;;;;;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:127:40:-;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:716;211:5;243:1;267:18;259:6;256:30;253:56;;;289:18;;:::i;:::-;-1:-1:-1;444:2:40;438:9;-1:-1:-1;;357:2:40;336:15;;332:29;;502:2;490:15;486:29;474:42;;567:22;;;546:18;531:34;;528:62;525:88;;;593:18;;:::i;:::-;629:2;622:22;677;;;662:6;-1:-1:-1;662:6:40;714:16;;;711:25;-1:-1:-1;708:45:40;;;749:1;746;739:12;708:45;799:6;794:3;787:4;779:6;775:17;762:44;854:1;847:4;838:6;830;826:19;822:30;815:41;;146:716;;;;;:::o;867:222::-;910:5;963:3;956:4;948:6;944:17;940:27;930:55;;981:1;978;971:12;930:55;1003:80;1079:3;1070:6;1057:20;1050:4;1042:6;1038:17;1003:80;:::i;1094:322::-;1163:6;1216:2;1204:9;1195:7;1191:23;1187:32;1184:52;;;1232:1;1229;1222:12;1184:52;1272:9;1259:23;1305:18;1297:6;1294:30;1291:50;;;1337:1;1334;1327:12;1291:50;1360;1402:7;1393:6;1382:9;1378:22;1360:50;:::i;:::-;1350:60;1094:322;-1:-1:-1;;;;1094:322:40:o;1613:173::-;1681:20;;-1:-1:-1;;;;;1730:31:40;;1720:42;;1710:70;;1776:1;1773;1766:12;1710:70;1613:173;;;:::o;1791:524::-;1868:6;1876;1929:2;1917:9;1908:7;1904:23;1900:32;1897:52;;;1945:1;1942;1935:12;1897:52;1968:29;1987:9;1968:29;:::i;:::-;1958:39;;2048:2;2037:9;2033:18;2020:32;2075:18;2067:6;2064:30;2061:50;;;2107:1;2104;2097:12;2061:50;2130:22;;2183:4;2175:13;;2171:27;-1:-1:-1;2161:55:40;;2212:1;2209;2202:12;2161:55;2235:74;2301:7;2296:2;2283:16;2278:2;2274;2270:11;2235:74;:::i;:::-;2225:84;;;1791:524;;;;;:::o;2892:250::-;2977:1;2987:113;3001:6;2998:1;2995:13;2987:113;;;3077:11;;;3071:18;3058:11;;;3051:39;3023:2;3016:10;2987:113;;;-1:-1:-1;;3134:1:40;3116:16;;3109:27;2892:250::o;3147:271::-;3189:3;3227:5;3221:12;3254:6;3249:3;3242:19;3270:76;3339:6;3332:4;3327:3;3323:14;3316:4;3309:5;3305:16;3270:76;:::i;:::-;3400:2;3379:15;-1:-1:-1;;3375:29:40;3366:39;;;;3407:4;3362:50;;3147:271;-1:-1:-1;;3147:271:40:o;3423:220::-;3572:2;3561:9;3554:21;3535:4;3592:45;3633:2;3622:9;3618:18;3610:6;3592:45;:::i;3648:186::-;3707:6;3760:2;3748:9;3739:7;3735:23;3731:32;3728:52;;;3776:1;3773;3766:12;3728:52;3799:29;3818:9;3799:29;:::i;3839:396::-;3917:6;3925;3978:2;3966:9;3957:7;3953:23;3949:32;3946:52;;;3994:1;3991;3984:12;3946:52;4017:29;4036:9;4017:29;:::i;:::-;4007:39;;4097:2;4086:9;4082:18;4069:32;4124:18;4116:6;4113:30;4110:50;;;4156:1;4153;4146:12;4110:50;4179;4221:7;4212:6;4201:9;4197:22;4179:50;:::i;4240:610::-;4326:6;4334;4387:2;4375:9;4366:7;4362:23;4358:32;4355:52;;;4403:1;4400;4393:12;4355:52;4443:9;4430:23;4476:18;4468:6;4465:30;4462:50;;;4508:1;4505;4498:12;4462:50;4531:22;;4584:4;4576:13;;4572:27;-1:-1:-1;4562:55:40;;4613:1;4610;4603:12;4562:55;4653:2;4640:16;4679:18;4671:6;4668:30;4665:50;;;4711:1;4708;4701:12;4665:50;4764:7;4759:2;4749:6;4746:1;4742:14;4738:2;4734:23;4730:32;4727:45;4724:65;;;4785:1;4782;4775:12;4724:65;4816:2;4808:11;;;;;4838:6;;-1:-1:-1;4240:610:40;-1:-1:-1;;;4240:610:40:o;4855:1007::-;5043:4;5091:2;5080:9;5076:18;5121:2;5110:9;5103:21;5144:6;5179;5173:13;5210:6;5202;5195:22;5248:2;5237:9;5233:18;5226:25;;5310:2;5300:6;5297:1;5293:14;5282:9;5278:30;5274:39;5260:53;;5348:2;5340:6;5336:15;5369:1;5379:454;5393:6;5390:1;5387:13;5379:454;;;5458:22;;;-1:-1:-1;;5454:36:40;5442:49;;5514:13;;5559:9;;-1:-1:-1;;;;;5555:35:40;5540:51;;5638:2;5630:11;;;5624:18;5679:2;5662:15;;;5655:27;;;5624:18;5705:48;;5737:15;;5624:18;5705:48;:::i;:::-;5695:58;-1:-1:-1;;5788:2:40;5811:12;;;;5776:15;;;;;5415:1;5408:9;5379:454;;;-1:-1:-1;5850:6:40;;4855:1007;-1:-1:-1;;;;;;4855:1007:40:o;6081:380::-;6160:1;6156:12;;;;6203;;;6224:61;;6278:4;6270:6;6266:17;6256:27;;6224:61;6331:2;6323:6;6320:14;6300:18;6297:38;6294:161;;6377:10;6372:3;6368:20;6365:1;6358:31;6412:4;6409:1;6402:15;6440:4;6437:1;6430:15;6294:161;;6081:380;;;:::o;6595:799::-;6725:3;6754:1;6787:6;6781:13;6817:36;6843:9;6817:36;:::i;:::-;6884:1;6869:17;;6895:133;;;;7042:1;7037:332;;;;6862:507;;6895:133;-1:-1:-1;;6928:24:40;;6916:37;;7001:14;;6994:22;6982:35;;6973:45;;;-1:-1:-1;6895:133:40;;7037:332;7068:6;7065:1;7058:17;7116:4;7113:1;7103:18;7143:1;7157:166;7171:6;7168:1;7165:13;7157:166;;;7251:14;;7238:11;;;7231:35;7307:1;7294:15;;;;7193:4;7186:12;7157:166;;;7161:3;;7352:6;7347:3;7343:16;7336:23;;6862:507;-1:-1:-1;7385:3:40;;6595:799;-1:-1:-1;;;;;6595:799:40:o;7399:317::-;-1:-1:-1;;;;;7576:32:40;;7558:51;;7645:2;7640;7625:18;;7618:30;;;-1:-1:-1;;7665:45:40;;7691:18;;7683:6;7665:45;:::i;7721:127::-;7782:10;7777:3;7773:20;7770:1;7763:31;7813:4;7810:1;7803:15;7837:4;7834:1;7827:15;7853:127;7914:10;7909:3;7905:20;7902:1;7895:31;7945:4;7942:1;7935:15;7969:4;7966:1;7959:15;7985:135;8024:3;8045:17;;;8042:43;;8065:18;;:::i;:::-;-1:-1:-1;8112:1:40;8101:13;;7985:135::o;8125:128::-;8192:9;;;8213:11;;;8210:37;;;8227:18;;:::i;8258:125::-;8323:9;;;8344:10;;;8341:36;;;8357:18;;:::i;8388:518::-;8490:2;8485:3;8482:11;8479:421;;;8526:5;8523:1;8516:16;8570:4;8567:1;8557:18;8640:2;8628:10;8624:19;8621:1;8617:27;8611:4;8607:38;8676:4;8664:10;8661:20;8658:47;;;-1:-1:-1;8699:4:40;8658:47;8754:2;8749:3;8745:12;8742:1;8738:20;8732:4;8728:31;8718:41;;8809:81;8827:2;8820:5;8817:13;8809:81;;;8886:1;8872:16;;8853:1;8842:13;8809:81;;9082:1302;9208:3;9202:10;9235:18;9227:6;9224:30;9221:56;;;9257:18;;:::i;:::-;9286:97;9376:6;9336:38;9368:4;9362:11;9336:38;:::i;:::-;9330:4;9286:97;:::i;:::-;9432:4;9463:2;9452:14;;9480:1;9475:652;;;;10171:1;10188:6;10185:89;;;-1:-1:-1;10240:19:40;;;10234:26;10185:89;-1:-1:-1;;9039:1:40;9035:11;;;9031:24;9027:29;9017:40;9063:1;9059:11;;;9014:57;10287:81;;9445:933;;9475:652;6542:1;6535:14;;;6579:4;6566:18;;-1:-1:-1;;9511:20:40;;;9632:222;9646:7;9643:1;9640:14;9632:222;;;9728:19;;;9722:26;9707:42;;9835:4;9820:20;;;;9788:1;9776:14;;;;9662:12;9632:222;;;9636:3;9882:6;9873:7;9870:19;9867:201;;;9943:19;;;9937:26;-1:-1:-1;;10026:1:40;10022:14;;;10038:3;10018:24;10014:37;10010:42;9995:58;9980:74;;9867:201;-1:-1:-1;;;;10114:1:40;10098:14;;;10094:22;10081:36;;-1:-1:-1;9082:1302:40:o;10389:480::-;-1:-1:-1;;;;;10614:32:40;;10596:51;;10683:2;10678;10663:18;;10656:30;;;-1:-1:-1;;10709:45:40;;10735:18;;10727:6;10709:45;:::i;:::-;10802:9;10794:6;10790:22;10785:2;10774:9;10770:18;10763:50;10830:33;10856:6;10848;10830:33;:::i;:::-;10822:41;10389:480;-1:-1:-1;;;;;;10389:480:40:o;10874:184::-;10944:6;10997:2;10985:9;10976:7;10972:23;10968:32;10965:52;;;11013:1;11010;11003:12;10965:52;-1:-1:-1;11036:16:40;;10874:184;-1:-1:-1;10874:184:40:o;11063:287::-;11192:3;11230:6;11224:13;11246:66;11305:6;11300:3;11293:4;11285:6;11281:17;11246:66;:::i;:::-;11328:16;;;;;11063:287;-1:-1:-1;;11063:287:40:o", + "linkReferences": {}, + "immutableReferences": { + "40567": [ + { "start": 3452, "length": 32 }, + { "start": 3493, "length": 32 }, + { "start": 3812, "length": 32 } + ] + } + }, + "methodIdentifiers": { + "UPGRADE_INTERFACE_VERSION()": "ad3cb1cc", + "addUsername(address,string)": "e5abdcef", + "getUsername(address)": "ce43c032", + "getUsernames(address[])": "f5ab196e", + "initialize()": "8129fc1c", + "isUsernameRegistered(string)": "52ac2091", + "isUsernameValid(string)": "117720be", + "owner()": "8da5cb5b", + "proxiableUUID()": "52d1902d", + "registerUsername(string)": "36a94134", + "renounceOwnership()": "715018a6", + "resignUsername()": "ebed6dab", + "transferOwnership(address)": "f2fde38b", + "upgradeToAndCall(address,bytes)": "4f1ef286", + "version()": "54fd4d50" + }, + "rawMetadata": "{\"compiler\":{\"version\":\"0.8.27+commit.40a35a09\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"ERC1967InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ERC1967NonPayable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsername\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TakenUsername\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UsernameNotRegistered\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"username\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"previousUsername\",\"type\":\"string\"}],\"name\":\"UsernameRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"username\",\"type\":\"string\"}],\"name\":\"UsernameResigned\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"UPGRADE_INTERFACE_VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"username\",\"type\":\"string\"}],\"name\":\"addUsername\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"getUsername\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"name\":\"getUsernames\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"username\",\"type\":\"string\"}],\"internalType\":\"struct UsernamesV1.User[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"username\",\"type\":\"string\"}],\"name\":\"isUsernameRegistered\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"username\",\"type\":\"string\"}],\"name\":\"isUsernameValid\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"username\",\"type\":\"string\"}],\"name\":\"registerUsername\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resignUsername\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AddressEmptyCode(address)\":[{\"details\":\"There's no code at `target` (it is not a contract).\"}],\"ERC1967InvalidImplementation(address)\":[{\"details\":\"The `implementation` of the proxy is invalid.\"}],\"ERC1967NonPayable()\":[{\"details\":\"An upgrade function sees `msg.value > 0` that may be lost.\"}],\"FailedCall()\":[{\"details\":\"A call to an address target failed. The target may have reverted.\"}],\"InvalidInitialization()\":[{\"details\":\"The contract is already initialized.\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"OwnableInvalidOwner(address)\":[{\"details\":\"The owner is not a valid owner account. (eg. `address(0)`)\"}],\"OwnableUnauthorizedAccount(address)\":[{\"details\":\"The caller account is not authorized to perform an operation.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC-1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/usernames/UsernamesV1.sol\":\"UsernamesV1\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@contracts/=src/\",\":@forge-std/=lib/forge-std/src/\",\":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/\",\":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/\",\":openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/\",\":solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/\"]},\"sources\":{\"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol\":{\"keccak256\":\"0xc163fcf9bb10138631a9ba5564df1fa25db9adff73bd9ee868a8ae1858fe093a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9706d43a0124053d9880f6e31a59f31bc0a6a3dc1acd66ce0a16e1111658c5f6\",\"dweb:/ipfs/QmUFmfowzkRwGtDu36cXV9SPTBHJ3n7dG9xQiK5B28jTf2\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x631188737069917d2f909d29ce62c4d48611d326686ba6683e26b72a23bfac0b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7a61054ae84cd6c4d04c0c4450ba1d6de41e27e0a2c4f1bcdf58f796b401c609\",\"dweb:/ipfs/QmUvtdp7X1mRVyC3CsHrtPbgoqWaXHp3S1ZR24tpAQYJWM\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol\":{\"keccak256\":\"0xf72d3b11f41fccbbdcacd121f994daab8267ccfceb1fb4f247e4ba274c169d27\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1e46ee40ddc9e2009176ce5d76aa2c046fd68f2ed52d02d77db191365b7c5b2e\",\"dweb:/ipfs/QmZnxgPmCCHosdvbh4J65uTaFYeGtZGzQ1sXRdeh1y68Zr\"]},\"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol\":{\"keccak256\":\"0xdbef5f0c787055227243a7318ef74c8a5a1108ca3a07f2b3a00ef67769e1e397\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://08e39f23d5b4692f9a40803e53a8156b72b4c1f9902a88cd65ba964db103dab9\",\"dweb:/ipfs/QmPKn6EYDgpga7KtpkA8wV2yJCYGMtc9K4LkJfhKX2RVSV\"]},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol\":{\"keccak256\":\"0xb25a4f11fa80c702bf5cd85adec90e6f6f507f32f4a8e6f5dbc31e8c10029486\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6917f8a323e7811f041aecd4d9fd6e92455a6fba38a797ac6f6e208c7912b79d\",\"dweb:/ipfs/QmShuYv55wYHGi4EFkDB8QfF7ZCHoKk2efyz3AWY1ExSq7\"]},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol\":{\"keccak256\":\"0xc42facb5094f2f35f066a7155bda23545e39a3156faef3ddc00185544443ba7d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d3b36282ab029b46bd082619a308a2ea11c309967b9425b7b7a6eb0b0c1c3196\",\"dweb:/ipfs/QmP2YVfDB2FoREax3vJu7QhDnyYRMw52WPrCD4vdT2kuDA\"]},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol\":{\"keccak256\":\"0x911c3346ee26afe188f3b9dc267ef62a7ccf940aba1afa963e3922f0ca3d8a06\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://04539f4419e44a831807d7203375d2bc6a733da256efd02e51290f5d5015218c\",\"dweb:/ipfs/QmPZ97gsAAgaMRPiE2WJfkzRsudQnW5tPAvMgGj1jcTJtR\"]},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol\":{\"keccak256\":\"0xc59a78b07b44b2cf2e8ab4175fca91e8eca1eee2df7357b8d2a8833e5ea1f64c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5aa4f07e65444784c29cd7bfcc2341b34381e4e5b5da9f0c5bd00d7f430e66fa\",\"dweb:/ipfs/QmWRMh4Q9DpaU9GvsiXmDdoNYMyyece9if7hnfLz7uqzWM\"]},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x9d8da059267bac779a2dbbb9a26c2acf00ca83085e105d62d5d4ef96054a47f5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c78e2aa4313323cecd1ef12a8d6265b96beee1a199923abf55d9a2a9e291ad23\",\"dweb:/ipfs/QmUTs2KStXucZezzFo3EYeqYu47utu56qrF7jj1Gue65vb\"]},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Errors.sol\":{\"keccak256\":\"0x6afa713bfd42cf0f7656efa91201007ac465e42049d7de1d50753a373648c123\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ba1d02f4847670a1b83dec9f7d37f0b0418d6043447b69f3a29a5f9efc547fcf\",\"dweb:/ipfs/QmQ7iH2keLNUKgq2xSWcRmuBE5eZ3F5whYAkAGzCNNoEWB\"]},\"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol\":{\"keccak256\":\"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b\",\"dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM\"]},\"src/usernames/UsernamesV1.sol\":{\"keccak256\":\"0x3d0012765a2c9a0a96b156052d6e530feb6b140af87c9e99f73526843751d8f7\",\"license\":\"GNU GENERAL PUBLIC LICENSE\",\"urls\":[\"bzz-raw://8156867b0c788dc6ff3eebdd37e949dc9d3a5b5330359ecad6ebc38fc87946f4\",\"dweb:/ipfs/QmemCY8hmvu5dGiW4k9ssJiwNekgWaHC7mzCWutNuJV7Rq\"]}},\"version\":1}", + "metadata": { + "compiler": { "version": "0.8.27+commit.40a35a09" }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "type": "error", + "name": "AddressEmptyCode" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "type": "error", + "name": "ERC1967InvalidImplementation" + }, + { "inputs": [], "type": "error", "name": "ERC1967NonPayable" }, + { "inputs": [], "type": "error", "name": "FailedCall" }, + { + "inputs": [], + "type": "error", + "name": "InvalidInitialization" + }, + { "inputs": [], "type": "error", "name": "InvalidUsername" }, + { "inputs": [], "type": "error", "name": "NotInitializing" }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "type": "error", + "name": "OwnableInvalidOwner" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "type": "error", + "name": "OwnableUnauthorizedAccount" + }, + { "inputs": [], "type": "error", "name": "TakenUsername" }, + { + "inputs": [], + "type": "error", + "name": "UUPSUnauthorizedCallContext" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "type": "error", + "name": "UUPSUnsupportedProxiableUUID" + }, + { + "inputs": [], + "type": "error", + "name": "UsernameNotRegistered" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "version", + "type": "uint64", + "indexed": false + } + ], + "type": "event", + "name": "Initialized", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "previousOwner", + "type": "address", + "indexed": true + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "OwnershipTransferred", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "Upgraded", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address", + "indexed": false + }, + { + "internalType": "string", + "name": "username", + "type": "string", + "indexed": false + }, + { + "internalType": "string", + "name": "previousUsername", + "type": "string", + "indexed": false + } + ], + "type": "event", + "name": "UsernameRegistered", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address", + "indexed": false + }, + { + "internalType": "string", + "name": "username", + "type": "string", + "indexed": false + } + ], + "type": "event", + "name": "UsernameResigned", + "anonymous": false + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "string", + "name": "username", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "addUsername" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "getUsername", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ] + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "addresses", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function", + "name": "getUsernames", + "outputs": [ + { + "internalType": "struct UsernamesV1.User[]", + "name": "", + "type": "tuple[]", + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "string", + "name": "username", + "type": "string" + } + ] + } + ] + }, + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "function", + "name": "initialize" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "username", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function", + "name": "isUsernameRegistered", + "outputs": [ + { "internalType": "bool", "name": "", "type": "bool" } + ] + }, + { + "inputs": [ + { + "internalType": "string", + "name": "username", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function", + "name": "isUsernameValid", + "outputs": [ + { "internalType": "bool", "name": "", "type": "bool" } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ] + }, + { + "inputs": [ + { + "internalType": "string", + "name": "username", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "registerUsername" + }, + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "function", + "name": "renounceOwnership" + }, + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "function", + "name": "resignUsername" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "transferOwnership" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function", + "name": "upgradeToAndCall" + }, + { + "inputs": [], + "stateMutability": "pure", + "type": "function", + "name": "version", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ] + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "proxiableUUID()": { + "details": "Implementation of the ERC-1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "upgradeToAndCall(address,bytes)": { + "custom:oz-upgrades-unsafe-allow-reachable": "delegatecall", + "details": "Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event." + } + }, + "version": 1 + }, + "userdoc": { "kind": "user", "methods": {}, "version": 1 } + }, + "settings": { + "remappings": [ + "@contracts/=src/", + "@forge-std/=lib/forge-std/src/", + "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", + "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/", + "ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/", + "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", + "forge-std/=lib/forge-std/src/", + "halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/", + "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", + "openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/", + "openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/", + "solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/" + ], + "optimizer": { "enabled": true, "runs": 200 }, + "metadata": { "bytecodeHash": "ipfs" }, + "compilationTarget": { + "src/usernames/UsernamesV1.sol": "UsernamesV1" + }, + "evmVersion": "shanghai", + "libraries": {} + }, + "sources": { + "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol": { + "keccak256": "0xc163fcf9bb10138631a9ba5564df1fa25db9adff73bd9ee868a8ae1858fe093a", + "urls": [ + "bzz-raw://9706d43a0124053d9880f6e31a59f31bc0a6a3dc1acd66ce0a16e1111658c5f6", + "dweb:/ipfs/QmUFmfowzkRwGtDu36cXV9SPTBHJ3n7dG9xQiK5B28jTf2" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol": { + "keccak256": "0x631188737069917d2f909d29ce62c4d48611d326686ba6683e26b72a23bfac0b", + "urls": [ + "bzz-raw://7a61054ae84cd6c4d04c0c4450ba1d6de41e27e0a2c4f1bcdf58f796b401c609", + "dweb:/ipfs/QmUvtdp7X1mRVyC3CsHrtPbgoqWaXHp3S1ZR24tpAQYJWM" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol": { + "keccak256": "0xf72d3b11f41fccbbdcacd121f994daab8267ccfceb1fb4f247e4ba274c169d27", + "urls": [ + "bzz-raw://1e46ee40ddc9e2009176ce5d76aa2c046fd68f2ed52d02d77db191365b7c5b2e", + "dweb:/ipfs/QmZnxgPmCCHosdvbh4J65uTaFYeGtZGzQ1sXRdeh1y68Zr" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol": { + "keccak256": "0xdbef5f0c787055227243a7318ef74c8a5a1108ca3a07f2b3a00ef67769e1e397", + "urls": [ + "bzz-raw://08e39f23d5b4692f9a40803e53a8156b72b4c1f9902a88cd65ba964db103dab9", + "dweb:/ipfs/QmPKn6EYDgpga7KtpkA8wV2yJCYGMtc9K4LkJfhKX2RVSV" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol": { + "keccak256": "0xb25a4f11fa80c702bf5cd85adec90e6f6f507f32f4a8e6f5dbc31e8c10029486", + "urls": [ + "bzz-raw://6917f8a323e7811f041aecd4d9fd6e92455a6fba38a797ac6f6e208c7912b79d", + "dweb:/ipfs/QmShuYv55wYHGi4EFkDB8QfF7ZCHoKk2efyz3AWY1ExSq7" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol": { + "keccak256": "0xc42facb5094f2f35f066a7155bda23545e39a3156faef3ddc00185544443ba7d", + "urls": [ + "bzz-raw://d3b36282ab029b46bd082619a308a2ea11c309967b9425b7b7a6eb0b0c1c3196", + "dweb:/ipfs/QmP2YVfDB2FoREax3vJu7QhDnyYRMw52WPrCD4vdT2kuDA" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol": { + "keccak256": "0x911c3346ee26afe188f3b9dc267ef62a7ccf940aba1afa963e3922f0ca3d8a06", + "urls": [ + "bzz-raw://04539f4419e44a831807d7203375d2bc6a733da256efd02e51290f5d5015218c", + "dweb:/ipfs/QmPZ97gsAAgaMRPiE2WJfkzRsudQnW5tPAvMgGj1jcTJtR" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol": { + "keccak256": "0xc59a78b07b44b2cf2e8ab4175fca91e8eca1eee2df7357b8d2a8833e5ea1f64c", + "urls": [ + "bzz-raw://5aa4f07e65444784c29cd7bfcc2341b34381e4e5b5da9f0c5bd00d7f430e66fa", + "dweb:/ipfs/QmWRMh4Q9DpaU9GvsiXmDdoNYMyyece9if7hnfLz7uqzWM" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol": { + "keccak256": "0x9d8da059267bac779a2dbbb9a26c2acf00ca83085e105d62d5d4ef96054a47f5", + "urls": [ + "bzz-raw://c78e2aa4313323cecd1ef12a8d6265b96beee1a199923abf55d9a2a9e291ad23", + "dweb:/ipfs/QmUTs2KStXucZezzFo3EYeqYu47utu56qrF7jj1Gue65vb" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Errors.sol": { + "keccak256": "0x6afa713bfd42cf0f7656efa91201007ac465e42049d7de1d50753a373648c123", + "urls": [ + "bzz-raw://ba1d02f4847670a1b83dec9f7d37f0b0418d6043447b69f3a29a5f9efc547fcf", + "dweb:/ipfs/QmQ7iH2keLNUKgq2xSWcRmuBE5eZ3F5whYAkAGzCNNoEWB" + ], + "license": "MIT" + }, + "lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol": { + "keccak256": "0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97", + "urls": [ + "bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b", + "dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM" + ], + "license": "MIT" + }, + "src/usernames/UsernamesV1.sol": { + "keccak256": "0x3d0012765a2c9a0a96b156052d6e530feb6b140af87c9e99f73526843751d8f7", + "urls": [ + "bzz-raw://8156867b0c788dc6ff3eebdd37e949dc9d3a5b5330359ecad6ebc38fc87946f4", + "dweb:/ipfs/QmemCY8hmvu5dGiW4k9ssJiwNekgWaHC7mzCWutNuJV7Rq" + ], + "license": "GNU GENERAL PUBLIC LICENSE" + } + }, + "version": 1 + }, + "id": 37 +} diff --git a/crypto/utils/abi_base.py b/crypto/utils/abi_base.py index 1641b38a..d810c551 100644 --- a/crypto/utils/abi_base.py +++ b/crypto/utils/abi_base.py @@ -4,16 +4,22 @@ import os import re from binascii import unhexlify +from typing import Optional from Cryptodome.Hash import keccak +from crypto.enums.contract_abi_type import ContractAbiType from crypto.identity.address import get_checksum_address class AbiBase: - def __init__(self): - # Cargar el ABI desde un archivo JSON - abi_file_path = os.path.join(os.path.dirname(__file__), 'Abi.Consensus.json') + def __init__(self, abi_type: ContractAbiType = ContractAbiType.CONSENSUS, path: Optional[str] = None): + abi_file_path = self.__contract_abi_path(abi_type, path) + + if abi_file_path is None: + raise Exception('ABI file path is not provided') + with open(abi_file_path, 'r') as f: abi_json = json.load(f) + self.abi = abi_json.get('abi', []) def get_array_components(self, type_str): @@ -51,3 +57,12 @@ def to_function_selector(self, abi_item): hash_ = self.keccak256(signature) selector = '0x' + self.strip_hex_prefix(hash_)[0:8] return selector + + def __contract_abi_path(self, abi_type: ContractAbiType, path: Optional[str] = None) -> Optional[str]: + if abi_type == ContractAbiType.CONSENSUS: + return os.path.join(os.path.dirname(__file__), 'abi/json', 'Abi.Consensus.json') + + if abi_type == ContractAbiType.USERNAMES: + return os.path.join(os.path.dirname(__file__), 'abi/json', 'Abi.Usernames.json') + + return path diff --git a/tests/transactions/builder/test_username_registration_builder.py b/tests/transactions/builder/test_username_registration_builder.py new file mode 100644 index 00000000..c8536466 --- /dev/null +++ b/tests/transactions/builder/test_username_registration_builder.py @@ -0,0 +1,77 @@ +from crypto.exceptions import InvalidUsernameException +from crypto.transactions.builder.username_registration_builder import UsernameRegistrationBuilder + +def test_username_registration_transaction(passphrase, load_transaction_fixture): + fixture = load_transaction_fixture('username-registration') + + builder = ( + UsernameRegistrationBuilder() + .gas_price(fixture['data']['gasPrice']) + .nonce(fixture['data']['nonce']) + .network(fixture['data']['network']) + .gas_limit(fixture['data']['gasLimit']) + .username('php') + .sign(passphrase) + ) + + assert builder.transaction.serialize().hex() == fixture['serialized'] + assert builder.transaction.data['id'] == fixture['data']['id'] + assert builder.verify() + +def test_it_accepts_valid_usernames(): + try: + UsernameRegistrationBuilder.is_valid_username('john') + UsernameRegistrationBuilder.is_valid_username('john123') + UsernameRegistrationBuilder.is_valid_username('john_doe') + UsernameRegistrationBuilder.is_valid_username('a') + UsernameRegistrationBuilder.is_valid_username('abcdefghijklmnopqrst') + UsernameRegistrationBuilder.is_valid_username('user_123_name') + except InvalidUsernameException as e: + raise Exception(f'Valid username threw an exception: {e}') + +def test_it_rejects_usernames_with_invalid_length(): + for username, character_count in {'': 0, 'abcdefghijklmnopqrstu': 21}.items(): + try: + UsernameRegistrationBuilder.is_valid_username(username) + except InvalidUsernameException as e: + assert str(e) == f'Username must be between 1 and 20 characters long. Got {character_count} characters.' + +def test_it_rejects_usernames_with_invalid_characters(): + usernames = [ + 'John', + 'john@doe', + 'john doe', + 'jöhn', + ] + + for username in usernames: + try: + UsernameRegistrationBuilder.is_valid_username(username) + except InvalidUsernameException as e: + assert str(e) == 'Username can only contain lowercase letters, numbers and underscores' + +def test_it_rejects_usernames_starting_or_ending_with_underscore(): + usernames = [ + '_john', + 'john_', + '_john_', + ] + + for username in usernames: + try: + UsernameRegistrationBuilder.is_valid_username(username) + except InvalidUsernameException as e: + assert str(e) == 'Username cannot start or end with an underscore' + +def test_it_rejects_usernames_with_consecutive_underscores(): + usernames = [ + 'john__doe', + 'john___doe', + 'john__doe__smith', + ] + + for username in usernames: + try: + UsernameRegistrationBuilder.is_valid_username(username) + except InvalidUsernameException as e: + assert str(e) == 'Username cannot contain consecutive underscores' diff --git a/tests/transactions/builder/test_username_resignation_builder.py b/tests/transactions/builder/test_username_resignation_builder.py new file mode 100644 index 00000000..048ec939 --- /dev/null +++ b/tests/transactions/builder/test_username_resignation_builder.py @@ -0,0 +1,17 @@ +from crypto.transactions.builder.username_resignation_builder import UsernameResignationBuilder + +def test_username_resignation_transaction(passphrase, load_transaction_fixture): + fixture = load_transaction_fixture('username-resignation') + + builder = ( + UsernameResignationBuilder() + .gas_price(fixture['data']['gasPrice']) + .nonce(fixture['data']['nonce']) + .network(fixture['data']['network']) + .gas_limit(fixture['data']['gasLimit']) + .sign(passphrase) + ) + + assert builder.transaction.serialize().hex() == fixture['serialized'] + assert builder.transaction.data['id'] == fixture['data']['id'] + assert builder.verify()