Address Contract Partially Verified
Address
0x60F2c9718E6a1Cabf20Bf9A9D4AC869595a160F8
Balance
0 ETH
Nonce
1
Code Size
10390 bytes
Creator
0x5AAA57b8...E4d3 at tx 0x6f0c6001...70f6fb
Indexed Transactions
0
Contract Bytecode
10390 bytes
0x608060405234801561000f575f5ffd5b50600436106101e7575f3560e01c80638ce1b19111610109578063b4f3fcb71161009e578063efeb5f1f1161006e578063efeb5f1f14610474578063f0eb5e5414610487578063f11abfd81461049a578063f2fde38b146104ab575f5ffd5b8063b4f3fcb71461042a578063b9209e331461043b578063cdb0ec6b1461044e578063e744d78914610461575f5ffd5b806397a6278e116100d957806397a6278e146103d1578063a75fe8e1146103e4578063a8d29d1d146103f7578063b43d87561461040a575f5ffd5b80638ce1b191146103875780638da5cb5b1461039a5780638e098ca1146103ab5780639740ae47146103be575f5ffd5b80633cc3c5461161017f5780637594bfa11161014f5780637594bfa11461031b57806378c0799f1461032e5780637e42683b1461034e57806384e7984214610374575f5ffd5b80633cc3c546146102da5780635dbe47e8146102ed578063670af6a914610300578063715018a614610313575f5ffd5b806326d941ae116101ba57806326d941ae1461027b5780632dbe0a821461028e5780633b239a7f146102b65780633b3e12f4146102c9575f5ffd5b80631825626b146101eb578063184b95591461021b5780631ffbb06414610230578063231a615914610253575b5f5ffd5b6101fe6101f9366004611e11565b6104be565b6040516001600160a01b0390911681526020015b60405180910390f35b61022e610229366004611e3b565b6104f2565b005b61024361023e366004611e83565b61071e565b6040519015158152602001610212565b6101fe610261366004611e83565b609b6020525f90815260409020546001600160a01b031681565b61022e610289366004611e83565b610730565b6101fe61029c366004611e83565b609c6020525f90815260409020546001600160a01b031681565b61022e6102c4366004611eb4565b610781565b6066546001600160a01b03166101fe565b61022e6102e8366004612010565b610847565b6102436102fb366004611e83565b6108fa565b61022e61030e366004611e83565b610922565b61022e610973565b61022e61032936600461214c565b610986565b61034161033c366004611e83565b610bfc565b60405161021291906121ea565b61036161035c366004611e83565b610ca5565b60405161ffff9091168152602001610212565b61022e610382366004611e83565b610d11565b6101fe610395366004611e11565b610d80565b6033546001600160a01b03166101fe565b61022e6103b93660046121fc565b610d99565b6103416103cc366004611e83565b610e68565b61022e6103df366004611e83565b610eff565b61022e6103f2366004611e83565b610f6e565b61022e610405366004611e83565b611132565b61041d610418366004611e83565b6111f8565b6040516102129190612228565b6067546001600160a01b03166101fe565b610243610449366004611e83565b61126a565b61041d61045c366004611e83565b611714565b61022e61046f366004611e83565b611785565b61022e610482366004611e83565b6117d6565b6101fe610495366004611e83565b611999565b6068546001600160a01b03166101fe565b61022e6104b9366004611e83565b611a05565b609e602052815f5260405f2081815481106104d7575f80fd5b5f918252602090912001546001600160a01b03169150829050565b5f54610100900460ff161580801561051057505f54600160ff909116105b806105295750303b15801561052957505f5460ff166001145b6105915760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b5f805460ff1916600117905580156105b2575f805461ff0019166101001790555b6001600160a01b038416158015906105d257506001600160a01b03831615155b80156105e657506001600160a01b03821615155b6106025760405162461bcd60e51b815260040161058890612273565b606680546001600160a01b038086166001600160a01b031992831681179093556067805488831690841617905560688054918616919092161790556040517f7170bf15b246e880b2369cd7c67d057760d8a35149e8c64dde91efa22bcc76d0905f90a26040516001600160a01b038516907f1b98cb79e6f73020175fe87333f1b91ad6a881519c0afe30340c2599b2b4bde0905f90a26040516001600160a01b038316907f2fa8b95c1db7afe99e3398f3792f008135cedc1fa26b0bb2ecd2352cd166d53c905f90a26106d3611a7e565b8015610718575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b5f61072a606583611aac565b92915050565b610738611b2d565b606880546001600160a01b0319166001600160a01b0383169081179091556040517f2fa8b95c1db7afe99e3398f3792f008135cedc1fa26b0bb2ecd2352cd166d53c905f90a250565b61078a3361071e565b6107a65760405162461bcd60e51b8152600401610588906122aa565b606854604051639f3418d560e01b81526001600160a01b03848116600483015261ffff8416602483015290911690639f3418d5906044015f604051808303815f87803b1580156107f4575f5ffd5b505af1158015610806573d5f5f3e3d5ffd5b505060405161ffff841692506001600160a01b03851691507f04ed3b726495c2dca1ff1215d9ca54e1a4030abb5e82b0f6ce55702416cee853905f90a35050565b5f5b868110156108f0576108e8888883818110610866576108666122f8565b905060200201602081019061087b9190611e83565b87878481811061088d5761088d6122f8565b90506020020160208101906108a29190611e83565b8686858181106108b4576108b46122f8565b90506020020160208101906108c9919061230c565b8585815181106108db576108db6122f8565b6020026020010151610986565b600101610849565b5050505050505050565b5f8061090583611999565b6001600160a01b03160361091a57505f919050565b506001919050565b61092a611b2d565b606680546001600160a01b0319166001600160a01b0383169081179091556040517f7170bf15b246e880b2369cd7c67d057760d8a35149e8c64dde91efa22bcc76d0905f90a250565b61097b611b2d565b6109845f611b87565b565b61098f3361071e565b6109ab5760405162461bcd60e51b8152600401610588906122aa565b60405169456e637279707465643160b01b6020820152602a0160405160208183030381529060405280519060200120816040516020016109eb9190612327565b604051602081830303815290604052805190602001201480610a6057506040516922b731b93cb83a32b21960b11b6020820152602a016040516020818303038152906040528051906020012081604051602001610a489190612327565b60405160208183030381529060405280519060200120145b80610abe575060405169456e637279707465643360b01b6020820152602a016040516020818303038152906040528051906020012081604051602001610aa69190612327565b60405160208183030381529060405280519060200120145b610b025760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420696e766573746f72207479706560581b6044820152606401610588565b606854604051631c0eed9960e11b81526001600160a01b039091169063381ddb3290610b3890879087908790879060040161233d565b5f604051808303815f87803b158015610b4f575f5ffd5b505af1158015610b61573d5f5f3e3d5ffd5b505050506001600160a01b0384165f908152609a60205260409020610b8682826123ff565b506001600160a01b038084165f818152609c602090815260408083208054958a166001600160a01b03199687168117909155808452609b9092528083208054909516841790945592519192917f6ae73635c50d24a45af6fbd5e016ac4bed179addbc8bf24e04ff0fcc6d33af199190a350505050565b6001600160a01b0381165f908152609a60205260409020805460609190610c229061237c565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4e9061237c565b8015610c995780601f10610c7057610100808354040283529160200191610c99565b820191905f5260205f20905b815481529060010190602001808311610c7c57829003601f168201915b50505050509050919050565b606854604051631c9f84ef60e21b81526001600160a01b0383811660048301525f92169063727e13bc90602401602060405180830381865afa158015610ced573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061072a91906124b9565b610d19611b2d565b6001600160a01b038116610d3f5760405162461bcd60e51b815260040161058890612273565b610d4a606582611bd8565b6040516001600160a01b038216907ff68e73cec97f2d70aa641fb26e87a4383686e2efacb648f2165aeb02ac562ec5905f90a250565b609d602052815f5260405f2081815481106104d7575f80fd5b610da23361071e565b610dbe5760405162461bcd60e51b8152600401610588906122aa565b5f610dc883611999565b606854604051637402e7c360e11b81526001600160a01b038681166004830152858116602483015292935091169063e805cf86906044015f604051808303815f87803b158015610e16575f5ffd5b505af1158015610e28573d5f5f3e3d5ffd5b50506040516001600160a01b038086169350841691507fe98082932c8056a0f514da9104e4a66bc2cbaef102ad59d90c4b24220ebf6010905f90a3505050565b609a6020525f908152604090208054610e809061237c565b80601f0160208091040260200160405190810160405280929190818152602001828054610eac9061237c565b8015610ef75780601f10610ece57610100808354040283529160200191610ef7565b820191905f5260205f20905b815481529060010190602001808311610eda57829003601f168201915b505050505081565b610f07611b2d565b6001600160a01b038116610f2d5760405162461bcd60e51b815260040161058890612273565b610f38606582611c53565b6040516001600160a01b038216907fed9c8ad8d5a0a66898ea49d2956929c93ae2e8bd50281b2ed897c5d1a6737e0b905f90a250565b335f908152609b60205260409020546001600160a01b031680610fa35760405162461bcd60e51b8152600401610588906124d4565b6001600160a01b038181165f908152609c602052604090205416331461100b5760405162461bcd60e51b815260206004820181905260248201527f43616c6c6572206973206e6f7420746865207072696d6172792077616c6c65746044820152606401610588565b6001600160a01b038281165f908152609b60205260409020548116908216146110825760405162461bcd60e51b8152602060048201526024808201527f57616c6c6574206973206e6f74206c696e6b656420746f20746865206964656e6044820152637469747960e01b6064820152608401610588565b6001600160a01b038083165f908152609b6020908152604080832080546001600160a01b03191690559284168252609d9052206110bf9083611cd4565b6001600160a01b038082165f908152609c6020908152604080832054909316808352609e9091529190206110f39084611cd4565b6040516001600160a01b03808416919085169033907ff52e304ee7082aa0b2670f8c232ce7af9ec722205c349de2216d3d8757ed9693905f90a4505050565b61113b3361071e565b6111575760405162461bcd60e51b8152600401610588906122aa565b5f61116182611999565b60685460405163cf191bcd60e01b81526001600160a01b03858116600483015292935091169063cf191bcd906024015f604051808303815f87803b1580156111a7575f5ffd5b505af11580156111b9573d5f5f3e3d5ffd5b50506040516001600160a01b038085169350851691507f59d6590e225b81befe259af056324092801080acbb7feab310eb34678871f327905f90a35050565b6001600160a01b0381165f908152609e6020908152604091829020805483518184028101840190945280845260609392830182828015610c9957602002820191905f5260205f20905b81546001600160a01b031681526001909101906020018083116112415750505050509050919050565b6001600160a01b038082165f908152609b602052604081205490911680156112b6576001600160a01b038082165f908152609c6020526040902054811690841681146112b4578093505b505b5f6112c084611999565b6001600160a01b0316036112d657505f92915050565b606654604080516337c2758160e21b815290515f926001600160a01b03169163df09d60491600480830192869291908290030181865afa15801561131c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526113439190810190612518565b905080515f03611357575060019392505050565b5f8080606080825b86518110156117045760675487515f916001600160a01b0316906352c111d1908a9085908110611391576113916122f8565b60200260200101516040518263ffffffff1660e01b81526004016113b791815260200190565b5f60405180830381865afa1580156113d1573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526113f8919081019061259e565b905080515f0361141257505f9a9950505050505050505050565b5f81516001600160401b0381111561142c5761142c611f32565b604051908082528060200260200182016040528015611455578160200160208202803683370190505b5090505f5b82518110156114f757828181518110611475576114756122f8565b60200260200101518a858151811061148f5761148f6122f8565b60200260200101516040516020016114bc9291906001600160a01b03929092168252602082015260400190565b604051602081830303815290604052805190602001208282815181106114e4576114e46122f8565b602090810291909101015260010161145a565b505f5b81518110156116f95761150c8d611999565b6001600160a01b031663c9100bcb83838151811061152c5761152c6122f8565b60200260200101516040518263ffffffff1660e01b815260040161155291815260200190565b5f60405180830381865afa15801561156c573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526115939190810190612681565b508e51949d50929b50909950975095508a90859081106115b5576115b56122f8565b602002602001015189036116c157866001600160a01b031663c0969a6e6115db8f611999565b8c87815181106115ed576115ed6122f8565b602002602001015189896040518563ffffffff1660e01b81526004016116169493929190612745565b602060405180830381865afa92505050801561164f575060408051601f3d908101601f1916820190925261164c91810190612788565b60015b61167e576001825161166191906127bb565b810361167957505f9c9b505050505050505050505050565b6116e7565b801561168957825191505b801580156116a35750600183516116a091906127bb565b82145b156116bb57505f9d9c50505050505050505050505050565b506116e7565b600182516116cf91906127bb565b81036116e757505f9c9b505050505050505050505050565b806116f1816127ce565b9150506114fa565b50505060010161135f565b5060019998505050505050505050565b6001600160a01b0381165f908152609d6020908152604091829020805483518184028101840190945280845260609392830182828015610c9957602002820191905f5260205f209081546001600160a01b031681526001909101906020018083116112415750505050509050919050565b61178d611b2d565b606780546001600160a01b0319166001600160a01b0383169081179091556040517f1b98cb79e6f73020175fe87333f1b91ad6a881519c0afe30340c2599b2b4bde0905f90a250565b6001600160a01b038181165f908152609b6020526040902054161561184c5760405162461bcd60e51b815260206004820152602660248201527f57616c6c657420697320616c72656164792072656769737465726564206f72206044820152651b1a5b9ad95960d21b6064820152608401610588565b335f908152609b60205260409020546001600160a01b0316806118815760405162461bcd60e51b8152600401610588906124d4565b6001600160a01b038181165f908152609c60205260409020541633146118e95760405162461bcd60e51b815260206004820181905260248201527f43616c6c6572206973206e6f7420746865207072696d6172792077616c6c65746044820152606401610588565b6001600160a01b038083165f818152609b6020908152604080832080548688166001600160a01b03199182168117909255818552609c845282852054609d85528386208054600181810183559188528688200180548416891790559716808652609e855283862080549889018155865293852090960180549096168517909555519093929133917fab5e58da9d3260e1f73a5b4f6a270e75b7230b399ec2e3b3879089e10a15799c9190a4505050565b606854604051637988d3a560e01b81526001600160a01b0383811660048301525f921690637988d3a590602401602060405180830381865afa1580156119e1573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061072a91906127e6565b611a0d611b2d565b6001600160a01b038116611a725760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610588565b611a7b81611b87565b50565b5f54610100900460ff16611aa45760405162461bcd60e51b815260040161058890612801565b610984611dce565b5f6001600160a01b038216611b0e5760405162461bcd60e51b815260206004820152602260248201527f526f6c65733a206163636f756e7420697320746865207a65726f206164647265604482015261737360f01b6064820152608401610588565b506001600160a01b03165f908152602091909152604090205460ff1690565b6033546001600160a01b031633146109845760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610588565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b611be28282611aac565b15611c2f5760405162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006044820152606401610588565b6001600160a01b03165f90815260209190915260409020805460ff19166001179055565b611c5d8282611aac565b611cb35760405162461bcd60e51b815260206004820152602160248201527f526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c6044820152606560f81b6064820152608401610588565b6001600160a01b03165f90815260209190915260409020805460ff19169055565b5f5b8254811015611dc957816001600160a01b0316838281548110611cfb57611cfb6122f8565b5f918252602090912001546001600160a01b031603611dc15782548390611d24906001906127bb565b81548110611d3457611d346122f8565b905f5260205f20015f9054906101000a90046001600160a01b0316838281548110611d6157611d616122f8565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555082805480611d9c57611d9c61284c565b5f8281526020902081015f1990810180546001600160a01b0319169055019055505050565b600101611cd6565b505050565b5f54610100900460ff16611df45760405162461bcd60e51b815260040161058890612801565b61098433611b87565b6001600160a01b0381168114611a7b575f5ffd5b5f5f60408385031215611e22575f5ffd5b8235611e2d81611dfd565b946020939093013593505050565b5f5f5f60608486031215611e4d575f5ffd5b8335611e5881611dfd565b92506020840135611e6881611dfd565b91506040840135611e7881611dfd565b809150509250925092565b5f60208284031215611e93575f5ffd5b8135611e9e81611dfd565b9392505050565b61ffff81168114611a7b575f5ffd5b5f5f60408385031215611ec5575f5ffd5b8235611ed081611dfd565b91506020830135611ee081611ea5565b809150509250929050565b5f5f83601f840112611efb575f5ffd5b5081356001600160401b03811115611f11575f5ffd5b6020830191508360208260051b8501011115611f2b575f5ffd5b9250929050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715611f6e57611f6e611f32565b604052919050565b5f6001600160401b03821115611f8e57611f8e611f32565b5060051b60200190565b5f6001600160401b03821115611fb057611fb0611f32565b50601f01601f191660200190565b5f82601f830112611fcd575f5ffd5b8135611fe0611fdb82611f98565b611f46565b818152846020838601011115611ff4575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f5f5f5f5f5f6080888a031215612026575f5ffd5b87356001600160401b0381111561203b575f5ffd5b6120478a828b01611eeb565b90985096505060208801356001600160401b03811115612065575f5ffd5b6120718a828b01611eeb565b90965094505060408801356001600160401b0381111561208f575f5ffd5b61209b8a828b01611eeb565b90945092505060608801356001600160401b038111156120b9575f5ffd5b8801601f81018a136120c9575f5ffd5b80356120d7611fdb82611f76565b8082825260208201915060208360051b85010192508c8311156120f8575f5ffd5b602084015b838110156121385780356001600160401b0381111561211a575f5ffd5b6121298f602083890101611fbe565b845250602092830192016120fd565b508094505050505092959891949750929550565b5f5f5f5f6080858703121561215f575f5ffd5b843561216a81611dfd565b9350602085013561217a81611dfd565b9250604085013561218a81611ea5565b915060608501356001600160401b038111156121a4575f5ffd5b6121b087828801611fbe565b91505092959194509250565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611e9e60208301846121bc565b5f5f6040838503121561220d575f5ffd5b823561221881611dfd565b91506020830135611ee081611dfd565b602080825282518282018190525f918401906040840190835b818110156122685783516001600160a01b0316835260209384019390920191600101612241565b509095945050505050565b6020808252601f908201527f696e76616c696420617267756d656e74202d207a65726f206164647265737300604082015260600190565b6020808252602e908201527f4167656e74526f6c653a2063616c6c657220646f6573206e6f7420686176652060408201526d746865204167656e7420726f6c6560901b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b5f6020828403121561231c575f5ffd5b8135611e9e81611ea5565b5f82518060208501845e5f920191825250919050565b6001600160a01b0385811682528416602082015261ffff831660408201526080606082018190525f90612372908301846121bc565b9695505050505050565b600181811c9082168061239057607f821691505b6020821081036123ae57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115611dc957805f5260205f20601f840160051c810160208510156123d95750805b601f840160051c820191505b818110156123f8575f81556001016123e5565b5050505050565b81516001600160401b0381111561241857612418611f32565b61242c81612426845461237c565b846123b4565b6020601f82116001811461245e575f83156124475750848201515b5f19600385901b1c1916600184901b1784556123f8565b5f84815260208120601f198516915b8281101561248d578785015182556020948501946001909201910161246d565b50848210156124aa57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f602082840312156124c9575f5ffd5b8151611e9e81611ea5565b60208082526024908201527f43616c6c6572206973206e6f74206c696e6b656420746f20616e79206964656e6040820152637469747960e01b606082015260800190565b5f60208284031215612528575f5ffd5b81516001600160401b0381111561253d575f5ffd5b8201601f8101841361254d575f5ffd5b805161255b611fdb82611f76565b8082825260208201915060208360051b85010192508683111561257c575f5ffd5b6020840193505b82841015612372578351825260209384019390910190612583565b5f602082840312156125ae575f5ffd5b81516001600160401b038111156125c3575f5ffd5b8201601f810184136125d3575f5ffd5b80516125e1611fdb82611f76565b8082825260208201915060208360051b850101925086831115612602575f5ffd5b6020840193505b8284101561237257835161261c81611dfd565b825260209384019390910190612609565b5f61263a611fdb84611f98565b905082815283838301111561264d575f5ffd5b8282602083015e5f602084830101529392505050565b5f82601f830112612672575f5ffd5b611e9e8383516020850161262d565b5f5f5f5f5f5f60c08789031215612696575f5ffd5b86516020880151604089015191975095506126b081611dfd565b60608801519094506001600160401b038111156126cb575f5ffd5b6126d789828a01612663565b93505060808701516001600160401b038111156126f2575f5ffd5b6126fe89828a01612663565b92505060a08701516001600160401b03811115612719575f5ffd5b8701601f81018913612729575f5ffd5b6127388982516020840161262d565b9150509295509295509295565b60018060a01b0385168152836020820152608060408201525f61276b60808301856121bc565b828103606084015261277d81856121bc565b979650505050505050565b5f60208284031215612798575f5ffd5b81518015158114611e9e575f5ffd5b634e487b7160e01b5f52601160045260245ffd5b8181038181111561072a5761072a6127a7565b5f600182016127df576127df6127a7565b5060010190565b5f602082840312156127f6575f5ffd5b8151611e9e81611dfd565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b5f52603160045260245ffdfea26469706673582212204bd9aea97de2787d2730285ee772b5a10bc025bcae4add74727be80f07ad62a564736f6c634300081c0033
Verified Source Code Partial Match
Compiler: v0.8.28+commit.7893614a
EVM: cancun
Optimization: Yes (200 runs)
IdentityRegistry.sol 1992 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.28;
/**
* @title Roles
* @dev Library for managing addresses assigned to a Role.
*/
library Roles {
struct Role {
mapping(address => bool) bearer;
}
/**
* @dev Give an account access to this role.
*/
function add(Role storage role, address account) internal {
require(!has(role, account), "Roles: account already has role");
role.bearer[account] = true;
}
/**
* @dev Remove an account's access to this role.
*/
function remove(Role storage role, address account) internal {
require(has(role, account), "Roles: account does not have role");
role.bearer[account] = false;
}
/**
* @dev Check if an account has this role.
* @return bool
*/
function has(Role storage role, address account)
internal
view
returns (bool)
{
require(account != address(0), "Roles: account is the zero address");
return role.bearer[account];
}
}
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) ||
(!AddressUpgradeable.isContract(address(this)) &&
_initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(
!_initializing && _initialized < version,
"Initializable: contract is already initialized"
);
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {}
function __Context_init_unchained() internal onlyInitializing {}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev 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.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
contract AgentRoleUpgradeable is OwnableUpgradeable {
using Roles for Roles.Role;
Roles.Role private _agents;
event AgentAdded(address indexed _agent);
event AgentRemoved(address indexed _agent);
modifier onlyAgent() {
require(
isAgent(msg.sender),
"AgentRole: caller does not have the Agent role"
);
_;
}
function addAgent(address _agent) public onlyOwner {
require(_agent != address(0), "invalid argument - zero address");
_agents.add(_agent);
emit AgentAdded(_agent);
}
function removeAgent(address _agent) public onlyOwner {
require(_agent != address(0), "invalid argument - zero address");
_agents.remove(_agent);
emit AgentRemoved(_agent);
}
function isAgent(address _agent) public view returns (bool) {
return _agents.has(_agent);
}
}
contract IRStorage {
/// @dev Address of the ClaimTopicsRegistry Contract
IClaimTopicsRegistry internal _tokenTopicsRegistry;
/// @dev Address of the TrustedIssuersRegistry Contract
ITrustedIssuersRegistry internal _tokenIssuersRegistry;
/// @dev Address of the IdentityRegistryStorage Contract
IIdentityRegistryStorage internal _tokenIdentityStorage;
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
*/
uint256[49] private __gap;
}
interface ITrustedIssuersRegistry {
/**
* this event is emitted when a trusted issuer is added in the registry.
* the event is emitted by the addTrustedIssuer function
* `trustedIssuer` is the address of the trusted issuer's ClaimIssuer contract
* `claimTopics` is the set of claims that the trusted issuer is allowed to emit
*/
event TrustedIssuerAdded(
IClaimIssuer indexed trustedIssuer,
uint256[] claimTopics
);
/**
* this event is emitted when a trusted issuer is removed from the registry.
* the event is emitted by the removeTrustedIssuer function
* `trustedIssuer` is the address of the trusted issuer's ClaimIssuer contract
*/
event TrustedIssuerRemoved(IClaimIssuer indexed trustedIssuer);
/**
* this event is emitted when the set of claim topics is changed for a given trusted issuer.
* the event is emitted by the updateIssuerClaimTopics function
* `trustedIssuer` is the address of the trusted issuer's ClaimIssuer contract
* `claimTopics` is the set of claims that the trusted issuer is allowed to emit
*/
event ClaimTopicsUpdated(
IClaimIssuer indexed trustedIssuer,
uint256[] claimTopics
);
/**
* @dev registers a ClaimIssuer contract as trusted claim issuer.
* Requires that a ClaimIssuer contract doesn't already exist
* Requires that the claimTopics set is not empty
* Requires that there is no more than 15 claimTopics
* Requires that there is no more than 50 Trusted issuers
* @param _trustedIssuer The ClaimIssuer contract address of the trusted claim issuer.
* @param _claimTopics the set of claim topics that the trusted issuer is allowed to emit
* This function can only be called by the owner of the Trusted Issuers Registry contract
* emits a `TrustedIssuerAdded` event
*/
function addTrustedIssuer(
IClaimIssuer _trustedIssuer,
uint256[] calldata _claimTopics
) external;
/**
* @dev Removes the ClaimIssuer contract of a trusted claim issuer.
* Requires that the claim issuer contract to be registered first
* @param _trustedIssuer the claim issuer to remove.
* This function can only be called by the owner of the Trusted Issuers Registry contract
* emits a `TrustedIssuerRemoved` event
*/
function removeTrustedIssuer(IClaimIssuer _trustedIssuer) external;
/**
* @dev Updates the set of claim topics that a trusted issuer is allowed to emit.
* Requires that this ClaimIssuer contract already exists in the registry
* Requires that the provided claimTopics set is not empty
* Requires that there is no more than 15 claimTopics
* @param _trustedIssuer the claim issuer to update.
* @param _claimTopics the set of claim topics that the trusted issuer is allowed to emit
* This function can only be called by the owner of the Trusted Issuers Registry contract
* emits a `ClaimTopicsUpdated` event
*/
function updateIssuerClaimTopics(
IClaimIssuer _trustedIssuer,
uint256[] calldata _claimTopics
) external;
/**
* @dev Function for getting all the trusted claim issuers stored.
* @return array of all claim issuers registered.
*/
function getTrustedIssuers() external view returns (IClaimIssuer[] memory);
/**
* @dev Function for getting all the trusted issuer allowed for a given claim topic.
* @param claimTopic the claim topic to get the trusted issuers for.
* @return array of all claim issuer addresses that are allowed for the given claim topic.
*/
function getTrustedIssuersForClaimTopic(uint256 claimTopic)
external
view
returns (IClaimIssuer[] memory);
/**
* @dev Checks if the ClaimIssuer contract is trusted
* @param _issuer the address of the ClaimIssuer contract
* @return true if the issuer is trusted, false otherwise.
*/
function isTrustedIssuer(address _issuer) external view returns (bool);
/**
* @dev Function for getting all the claim topic of trusted claim issuer
* Requires the provided ClaimIssuer contract to be registered in the trusted issuers registry.
* @param _trustedIssuer the trusted issuer concerned.
* @return The set of claim topics that the trusted issuer is allowed to emit
*/
function getTrustedIssuerClaimTopics(IClaimIssuer _trustedIssuer)
external
view
returns (uint256[] memory);
/**
* @dev Function for checking if the trusted claim issuer is allowed
* to emit a certain claim topic
* @param _issuer the address of the trusted issuer's ClaimIssuer contract
* @param _claimTopic the Claim Topic that has to be checked to know if the `issuer` is allowed to emit it
* @return true if the issuer is trusted for this claim topic.
*/
function hasClaimTopic(address _issuer, uint256 _claimTopic)
external
view
returns (bool);
}
interface IIdentityRegistryStorage {
/// events
/**
* this event is emitted when an Identity is registered into the storage contract.
* the event is emitted by the 'registerIdentity' function
* `investorAddress` is the address of the investor's wallet
* `identity` is the address of the Identity smart contract (onchainID)
*/
event IdentityStored(
address indexed investorAddress,
IIdentity indexed identity
);
/**
* this event is emitted when an Identity is removed from the storage contract.
* the event is emitted by the 'deleteIdentity' function
* `investorAddress` is the address of the investor's wallet
* `identity` is the address of the Identity smart contract (onchainID)
*/
event IdentityUnstored(
address indexed investorAddress,
IIdentity indexed identity
);
/**
* this event is emitted when an Identity has been updated
* the event is emitted by the 'updateIdentity' function
* `oldIdentity` is the old Identity contract's address to update
* `newIdentity` is the new Identity contract's
*/
event IdentityModified(
IIdentity indexed oldIdentity,
IIdentity indexed newIdentity
);
/**
* this event is emitted when an Identity's country has been updated
* the event is emitted by the 'updateCountry' function
* `investorAddress` is the address on which the country has been updated
* `country` is the numeric code (ISO 3166-1) of the new country
*/
event CountryModified(
address indexed investorAddress,
uint16 indexed country
);
/**
* this event is emitted when an Identity Registry is bound to the storage contract
* the event is emitted by the 'addIdentityRegistry' function
* `identityRegistry` is the address of the identity registry added
*/
event IdentityRegistryBound(address indexed identityRegistry);
/**
* this event is emitted when an Identity Registry is unbound from the storage contract
* the event is emitted by the 'removeIdentityRegistry' function
* `identityRegistry` is the address of the identity registry removed
*/
event IdentityRegistryUnbound(address indexed identityRegistry);
/// functions
/**
* @dev adds an identity contract corresponding to a user address in the storage.
* Requires that the user doesn't have an identity contract already registered.
* This function can only be called by an address set as agent of the smart contract
* @param _userAddress The address of the user
* @param _identity The address of the user's identity contract
* @param _country The country of the investor
* emits `IdentityStored` event
*/
function addIdentityToStorage(
address _userAddress,
IIdentity _identity,
uint16 _country,
string memory investorType
) external;
/**
* @dev Removes an user from the storage.
* Requires that the user have an identity contract already deployed that will be deleted.
* This function can only be called by an address set as agent of the smart contract
* @param _userAddress The address of the user to be removed
* emits `IdentityUnstored` event
*/
function removeIdentityFromStorage(address _userAddress) external;
/**
* @dev Updates the country corresponding to a user address.
* Requires that the user should have an identity contract already deployed that will be replaced.
* This function can only be called by an address set as agent of the smart contract
* @param _userAddress The address of the user
* @param _country The new country of the user
* emits `CountryModified` event
*/
function modifyStoredInvestorCountry(address _userAddress, uint16 _country)
external;
/**
* @dev Updates an identity contract corresponding to a user address.
* Requires that the user address should be the owner of the identity contract.
* Requires that the user should have an identity contract already deployed that will be replaced.
* This function can only be called by an address set as agent of the smart contract
* @param _userAddress The address of the user
* @param _identity The address of the user's new identity contract
* emits `IdentityModified` event
*/
function modifyStoredIdentity(address _userAddress, IIdentity _identity)
external;
/**
* @notice Adds an identity registry as agent of the Identity Registry Storage Contract.
* This function can only be called by the wallet set as owner of the smart contract
* This function adds the identity registry to the list of identityRegistries linked to the storage contract
* cannot bind more than 300 IR to 1 IRS
* @param _identityRegistry The identity registry address to add.
*/
function bindIdentityRegistry(address _identityRegistry) external;
/**
* @notice Removes an identity registry from being agent of the Identity Registry Storage Contract.
* This function can only be called by the wallet set as owner of the smart contract
* This function removes the identity registry from the list of identityRegistries linked to the storage contract
* @param _identityRegistry The identity registry address to remove.
*/
function unbindIdentityRegistry(address _identityRegistry) external;
/**
* @dev Returns the identity registries linked to the storage contract
*/
function linkedIdentityRegistries()
external
view
returns (address[] memory);
/**
* @dev Returns the onchainID of an investor.
* @param _userAddress The wallet of the investor
*/
function storedIdentity(address _userAddress)
external
view
returns (IIdentity);
/**
* @dev Returns the country code of an investor.
* @param _userAddress The wallet of the investor
*/
function storedInvestorCountry(address _userAddress)
external
view
returns (uint16);
}
interface IIdentityRegistry {
/**
* this event is emitted when the ClaimTopicsRegistry has been set for the IdentityRegistry
* the event is emitted by the IdentityRegistry constructor
* `claimTopicsRegistry` is the address of the Claim Topics Registry contract
*/
event ClaimTopicsRegistrySet(address indexed claimTopicsRegistry);
/**
* this event is emitted when the IdentityRegistryStorage has been set for the IdentityRegistry
* the event is emitted by the IdentityRegistry constructor
* `identityStorage` is the address of the Identity Registry Storage contract
*/
event IdentityStorageSet(address indexed identityStorage);
/**
* this event is emitted when the TrustedIssuersRegistry has been set for the IdentityRegistry
* the event is emitted by the IdentityRegistry constructor
* `trustedIssuersRegistry` is the address of the Trusted Issuers Registry contract
*/
event TrustedIssuersRegistrySet(address indexed trustedIssuersRegistry);
/**
* this event is emitted when an Identity is registered into the Identity Registry.
* the event is emitted by the 'registerIdentity' function
* `investorAddress` is the address of the investor's wallet
* `identity` is the address of the Identity smart contract (onchainID)
*/
event IdentityRegistered(
address indexed investorAddress,
IIdentity indexed identity
);
/**
* this event is emitted when an Identity is removed from the Identity Registry.
* the event is emitted by the 'deleteIdentity' function
* `investorAddress` is the address of the investor's wallet
* `identity` is the address of the Identity smart contract (onchainID)
*/
event IdentityRemoved(
address indexed investorAddress,
IIdentity indexed identity
);
/**
* this event is emitted when an Identity has been updated
* the event is emitted by the 'updateIdentity' function
* `oldIdentity` is the old Identity contract's address to update
* `newIdentity` is the new Identity contract's
*/
event IdentityUpdated(
IIdentity indexed oldIdentity,
IIdentity indexed newIdentity
);
/**
* this event is emitted when an Identity's country has been updated
* the event is emitted by the 'updateCountry' function
* `investorAddress` is the address on which the country has been updated
* `country` is the numeric code (ISO 3166-1) of the new country
*/
event CountryUpdated(
address indexed investorAddress,
uint16 indexed country
);
/**
* @dev Register an identity contract corresponding to a user address.
* Requires that the user doesn't have an identity contract already registered.
* This function can only be called by a wallet set as agent of the smart contract
* @param _userAddress The address of the user
* @param _identity The address of the user's identity contract
* @param _country The country of the investor
* emits `IdentityRegistered` event
*/
function registerIdentity(
address _userAddress,
IIdentity _identity,
uint16 _country,
string memory investorType
) external;
/**
* @dev Removes an user from the identity registry.
* Requires that the user have an identity contract already deployed that will be deleted.
* This function can only be called by a wallet set as agent of the smart contract
* @param _userAddress The address of the user to be removed
* emits `IdentityRemoved` event
*/
function deleteIdentity(address _userAddress) external;
/**
* @dev Replace the actual identityRegistryStorage contract with a new one.
* This function can only be called by the wallet set as owner of the smart contract
* @param _identityRegistryStorage The address of the new Identity Registry Storage
* emits `IdentityStorageSet` event
*/
function setIdentityRegistryStorage(address _identityRegistryStorage)
external;
/**
* @dev Replace the actual claimTopicsRegistry contract with a new one.
* This function can only be called by the wallet set as owner of the smart contract
* @param _claimTopicsRegistry The address of the new claim Topics Registry
* emits `ClaimTopicsRegistrySet` event
*/
function setClaimTopicsRegistry(address _claimTopicsRegistry) external;
/**
* @dev Replace the actual trustedIssuersRegistry contract with a new one.
* This function can only be called by the wallet set as owner of the smart contract
* @param _trustedIssuersRegistry The address of the new Trusted Issuers Registry
* emits `TrustedIssuersRegistrySet` event
*/
function setTrustedIssuersRegistry(address _trustedIssuersRegistry)
external;
/**
* @dev Updates the country corresponding to a user address.
* Requires that the user should have an identity contract already deployed that will be replaced.
* This function can only be called by a wallet set as agent of the smart contract
* @param _userAddress The address of the user
* @param _country The new country of the user
* emits `CountryUpdated` event
*/
function updateCountry(address _userAddress, uint16 _country) external;
/**
* @dev Updates an identity contract corresponding to a user address.
* Requires that the user address should be the owner of the identity contract.
* Requires that the user should have an identity contract already deployed that will be replaced.
* This function can only be called by a wallet set as agent of the smart contract
* @param _userAddress The address of the user
* @param _identity The address of the user's new identity contract
* emits `IdentityUpdated` event
*/
function updateIdentity(address _userAddress, IIdentity _identity) external;
/**
* @dev function allowing to register identities in batch
* This function can only be called by a wallet set as agent of the smart contract
* Requires that none of the users has an identity contract already registered.
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_userAddresses.length` IS TOO HIGH,
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
* @param _userAddresses The addresses of the users
* @param _identities The addresses of the corresponding identity contracts
* @param _countries The countries of the corresponding investors
* emits _userAddresses.length `IdentityRegistered` events
*/
function batchRegisterIdentity(
address[] calldata _userAddresses,
IIdentity[] calldata _identities,
uint16[] calldata _countries,
string[] memory investorTypes
) external;
/**
* @dev This functions checks whether a wallet has its Identity registered or not
* in the Identity Registry.
* @param _userAddress The address of the user to be checked.
* @return 'True' if the address is contained in the Identity Registry, 'false' if not.
*/
function contains(address _userAddress) external view returns (bool);
/**
* @dev This functions checks whether an identity contract
* corresponding to the provided user address has the required claims or not based
* on the data fetched from trusted issuers registry and from the claim topics registry
* @param _userAddress The address of the user to be verified.
* @return 'True' if the address is verified, 'false' if not.
*/
function isVerified(address _userAddress) external view returns (bool);
/**
* @dev Returns the onchainID of an investor.
* @param _userAddress The wallet of the investor
*/
function identity(address _userAddress) external view returns (IIdentity);
/**
* @dev Returns the country code of an investor.
* @param _userAddress The wallet of the investor
*/
function investorCountry(address _userAddress)
external
view
returns (uint16);
/**
* @dev Returns the IdentityRegistryStorage linked to the current IdentityRegistry.
*/
function identityStorage() external view returns (IIdentityRegistryStorage);
/**
* @dev Returns the TrustedIssuersRegistry linked to the current IdentityRegistry.
*/
function issuersRegistry() external view returns (ITrustedIssuersRegistry);
/**
* @dev Returns the ClaimTopicsRegistry linked to the current IdentityRegistry.
*/
function topicsRegistry() external view returns (IClaimTopicsRegistry);
}
interface IClaimTopicsRegistry {
/**
* this event is emitted when a claim topic has been added to the ClaimTopicsRegistry
* the event is emitted by the 'addClaimTopic' function
* `claimTopic` is the required claim added to the Claim Topics Registry
*/
event ClaimTopicAdded(uint256 indexed claimTopic);
/**
* this event is emitted when a claim topic has been removed from the ClaimTopicsRegistry
* the event is emitted by the 'removeClaimTopic' function
* `claimTopic` is the required claim removed from the Claim Topics Registry
*/
event ClaimTopicRemoved(uint256 indexed claimTopic);
/**
* @dev Add a trusted claim topic (For example: KYC=1, AML=2).
* Only owner can call.
* emits `ClaimTopicAdded` event
* cannot add more than 15 topics for 1 token as adding more could create gas issues
* @param _claimTopic The claim topic index
*/
function addClaimTopic(uint256 _claimTopic) external;
/**
* @dev Remove a trusted claim topic (For example: KYC=1, AML=2).
* Only owner can call.
* emits `ClaimTopicRemoved` event
* @param _claimTopic The claim topic index
*/
function removeClaimTopic(uint256 _claimTopic) external;
/**
* @dev Get the trusted claim topics for the security token
* @return Array of trusted claim topics
*/
function getClaimTopics() external view returns (uint256[] memory);
}
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(
address(this).balance >= amount,
"Address: insufficient balance"
);
(bool success, ) = recipient.call{value: amount}("");
require(
success,
"Address: unable to send value, recipient may have reverted"
);
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data)
internal
returns (bytes memory)
{
return
functionCallWithValue(
target,
data,
0,
"Address: low-level call failed"
);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return
functionCallWithValue(
target,
data,
value,
"Address: low-level call with value failed"
);
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(
address(this).balance >= value,
"Address: insufficient balance for call"
);
(bool success, bytes memory returndata) = target.call{value: value}(
data
);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data)
internal
view
returns (bytes memory)
{
return
functionStaticCall(
target,
data,
"Address: low-level static call failed"
);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data)
internal
returns (bytes memory)
{
return
functionDelegateCall(
target,
data,
"Address: low-level delegate call failed"
);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage)
private
pure
{
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
/**
* @dev interface of the ERC734 (Key Holder) standard as defined in the EIP.
*/
interface IERC734 {
/**
* @dev Emitted when an execution request was approved.
*
* Specification: MUST be triggered when approve was successfully called.
*/
event Approved(uint256 indexed executionId, bool approved);
/**
* @dev Emitted when an execute operation was approved and successfully performed.
*
* Specification: MUST be triggered when approve was called and the execution was successfully approved.
*/
event Executed(
uint256 indexed executionId,
address indexed to,
uint256 indexed value,
bytes data
);
/**
* @dev Emitted when an execution request was performed via `execute`.
*
* Specification: MUST be triggered when execute was successfully called.
*/
event ExecutionRequested(
uint256 indexed executionId,
address indexed to,
uint256 indexed value,
bytes data
);
/**
* @dev Emitted when an execute operation was called and failed
*
* Specification: MUST be triggered when execute call failed
*/
event ExecutionFailed(
uint256 indexed executionId,
address indexed to,
uint256 indexed value,
bytes data
);
/**
* @dev Emitted when a key was added to the Identity.
*
* Specification: MUST be triggered when addKey was successfully called.
*/
event KeyAdded(
bytes32 indexed key,
uint256 indexed purpose,
uint256 indexed keyType
);
/**
* @dev Emitted when a key was removed from the Identity.
*
* Specification: MUST be triggered when removeKey was successfully called.
*/
event KeyRemoved(
bytes32 indexed key,
uint256 indexed purpose,
uint256 indexed keyType
);
/**
* @dev Adds a _key to the identity. The _purpose specifies the purpose of the key.
*
* Triggers Event: `KeyAdded`
*
* Specification: MUST only be done by keys of purpose 1, or the identity
* itself. If it's the identity itself, the approval process will determine its approval.
*/
function addKey(
bytes32 _key,
uint256 _purpose,
uint256 _keyType
) external returns (bool success);
/**
* @dev Approves an execution.
*
* Triggers Event: `Approved`
* Triggers on execution successful Event: `Executed`
* Triggers on execution failure Event: `ExecutionFailed`
*/
function approve(uint256 _id, bool _approve)
external
returns (bool success);
/**
* @dev Removes _purpose for _key from the identity.
*
* Triggers Event: `KeyRemoved`
*
* Specification: MUST only be done by keys of purpose 1, or the identity itself.
* If it's the identity itself, the approval process will determine its approval.
*/
function removeKey(bytes32 _key, uint256 _purpose)
external
returns (bool success);
/**
* @dev Passes an execution instruction to an ERC734 identity.
* How the execution is handled is up to the identity implementation:
* An execution COULD be requested and require `approve` to be called with one or more keys of purpose 1 or 2 to
* approve this execution.
* Execute COULD be used as the only accessor for `addKey` and `removeKey`.
*
* Triggers Event: ExecutionRequested
* Triggers on direct execution Event: Executed
*/
function execute(
address _to,
uint256 _value,
bytes calldata _data
) external payable returns (uint256 executionId);
/**
* @dev Returns the full key data, if present in...
// [truncated — 71134 bytes total]
Read Contract
IdentityToPrimaryWallet 0x2dbe0a82 → address
InvestorType 0x9740ae47 → string
PrimaryToLinked 0x1825626b → address
contains 0x5dbe47e8 → bool
getInvestorType 0x78c0799f → string
getLinkedWallets 0xcdb0ec6b → address[]
getprimaryTOLinkedWallets 0xb43d8756 → address[]
identity 0xf0eb5e54 → address
identityStorage 0xf11abfd8 → address
investorCountry 0x7e42683b → uint16
isAgent 0x1ffbb064 → bool
isVerified 0xb9209e33 → bool
issuersRegistry 0xb4f3fcb7 → address
linkedWallets 0x8ce1b191 → address
owner 0x8da5cb5b → address
topicsRegistry 0x3b3e12f4 → address
walletToIdentity 0x231a6159 → address
Write Contract 15 functions
These functions modify contract state and require a wallet transaction to execute.
addAgent 0x84e79842
address _agent
addWallet 0xefeb5f1f
address newWallet
batchRegisterIdentity 0x3cc3c546
address[] _userAddresses
address[] _identities
uint16[] _countries
string[] investorTypes
deleteIdentity 0xa8d29d1d
address _userAddress
init 0x184b9559
address _trustedIssuersRegistry
address _claimTopicsRegistry
address _identityStorage
registerIdentity 0x7594bfa1
address _userAddress
address _identity
uint16 _country
string investorType
removeAgent 0x97a6278e
address _agent
removeWallet 0xa75fe8e1
address walletToRemove
renounceOwnership 0x715018a6
No parameters
setClaimTopicsRegistry 0x670af6a9
address _claimTopicsRegistry
setIdentityRegistryStorage 0x26d941ae
address _identityRegistryStorage
setTrustedIssuersRegistry 0xe744d789
address _trustedIssuersRegistry
transferOwnership 0xf2fde38b
address newOwner
updateCountry 0x3b239a7f
address _userAddress
uint16 _country
updateIdentity 0x8e098ca1
address _userAddress
address _identity
Recent Transactions
No transactions found for this address