Contract Address Details

Contract
0x0000000000000000000000000000000000001001
Balance
0.1 @G ($0.02)
Tokens
0 Tokens
$0.0 USD
Transactions
Balance changes
51
Gas Used
0
Last Balance Update
Contract Source Code Verified
Contract NameKYCContract
Compiler Versionv0.8.19+commit.7dd6d404
Optimization EnabledYes
Other SettingsDefault evmVersion
Contract Source Code (Solidity)
1
// SPDX-License-Identifier: MIT
2
 
3
pragma solidity ^0.8.0;
4
 
5
/**
6
* @dev Provides information about the current execution context, including the
7
* sender of the transaction and its data. While these are generally available
8
* via msg.sender and msg.data, they should not be accessed in such a direct
9
* manner, since when dealing with meta-transactions the account sending and
10
* paying for execution may not be the actual sender (as far as an application
11
* is concerned).
12
*
13
* This contract is only required for intermediate, library-like contracts.
14
*/
15
abstract contract Context {
16
function _msgSender() internal view virtual returns (address) {
17
return msg.sender;
18
}
19
 
20
function _msgData() internal view virtual returns (bytes calldata) {
21
return msg.data;
22
}
23
}
24
 
25
pragma solidity ^0.8.0;
26
 
27
/**
28
* @dev Interface of the ERC165 standard, as defined in the
29
* https://eips.ethereum.org/EIPS/eip-165[EIP].
30
*
31
* Implementers can declare support of contract interfaces, which can then be
32
* queried by others ({ERC165Checker}).
33
*
34
* For an implementation, see {ERC165}.
35
*/
36
interface IERC165 {
37
/**
38
* @dev Returns true if this contract implements the interface defined by
39
* `interfaceId`. See the corresponding
40
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
41
* to learn more about how these ids are created.
42
*
43
* This function call must use less than 30 000 gas.
44
*/
45
function supportsInterface(bytes4 interfaceId) external view returns (bool);
46
}
47
 
48
pragma solidity ^0.8.0;
49
 
50
/**
51
* @dev Implementation of the {IERC165} interface.
52
*
53
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
54
* for the additional interface id that will be supported. For example:
55
*
56
* ```solidity
57
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
58
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
59
* }
60
* ```
61
*
62
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
63
*/
64
abstract contract ERC165 is IERC165 {
65
/**
66
* @dev See {IERC165-supportsInterface}.
67
*/
68
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
69
return interfaceId == type(IERC165).interfaceId;
70
}
71
}
72
 
73
pragma solidity ^0.8.0;
74
 
75
/**
76
* @dev External interface of AccessControl declared to support ERC165 detection.
77
*/
78
interface IAccessControl {
79
/**
80
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
81
*
82
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
83
* {RoleAdminChanged} not being emitted signaling this.
84
*
85
* _Available since v3.1._
86
*/
87
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
88
 
89
/**
90
* @dev Emitted when `account` is granted `role`.
91
*
92
* `sender` is the account that originated the contract call, an admin role
93
* bearer except when using {AccessControl-_setupRole}.
94
*/
95
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
96
 
97
/**
98
* @dev Emitted when `account` is revoked `role`.
99
*
100
* `sender` is the account that originated the contract call:
101
* - if using `revokeRole`, it is the admin role bearer
102
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
103
*/
104
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
105
 
106
/**
107
* @dev Returns `true` if `account` has been granted `role`.
108
*/
109
function hasRole(bytes32 role, address account) external view returns (bool);
110
 
111
/**
112
* @dev Returns the admin role that controls `role`. See {grantRole} and
113
* {revokeRole}.
114
*
115
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
116
*/
117
function getRoleAdmin(bytes32 role) external view returns (bytes32);
118
 
119
/**
120
* @dev Grants `role` to `account`.
121
*
122
* If `account` had not been already granted `role`, emits a {RoleGranted}
123
* event.
124
*
125
* Requirements:
126
*
127
* - the caller must have ``role``'s admin role.
128
*/
129
function grantRole(bytes32 role, address account) external;
130
 
131
/**
132
* @dev Revokes `role` from `account`.
133
*
134
* If `account` had been granted `role`, emits a {RoleRevoked} event.
135
*
136
* Requirements:
137
*
138
* - the caller must have ``role``'s admin role.
139
*/
140
function revokeRole(bytes32 role, address account) external;
141
 
142
/**
143
* @dev Revokes `role` from the calling account.
144
*
145
* Roles are often managed via {grantRole} and {revokeRole}: this function's
146
* purpose is to provide a mechanism for accounts to lose their privileges
147
* if they are compromised (such as when a trusted device is misplaced).
148
*
149
* If the calling account had been granted `role`, emits a {RoleRevoked}
150
* event.
151
*
152
* Requirements:
153
*
154
* - the caller must be `account`.
155
*/
156
function renounceRole(bytes32 role, address account) external;
157
}
158
 
159
pragma solidity ^0.8.0;
160
 
161
/**
162
* @dev String operations.
163
*/
164
library Strings {
165
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
166
 
167
/**
168
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
169
*/
170
function toString(uint256 value) internal pure returns (string memory) {
171
// Inspired by OraclizeAPI's implementation - MIT licence
172
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
173
 
174
if (value == 0) {
175
return "0";
176
}
177
uint256 temp = value;
178
uint256 digits;
179
while (temp != 0) {
180
digits++;
181
temp /= 10;
182
}
183
bytes memory buffer = new bytes(digits);
184
while (value != 0) {
185
digits -= 1;
186
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
187
value /= 10;
188
}
189
return string(buffer);
190
}
191
 
192
/**
193
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
194
*/
195
function toHexString(uint256 value) internal pure returns (string memory) {
196
if (value == 0) {
197
return "0x00";
198
}
199
uint256 temp = value;
200
uint256 length = 0;
201
while (temp != 0) {
202
length++;
203
temp >>= 8;
204
}
205
return toHexString(value, length);
206
}
207
 
208
/**
209
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
210
*/
211
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
212
bytes memory buffer = new bytes(2 * length + 2);
213
buffer[0] = "0";
214
buffer[1] = "x";
215
for (uint256 i = 2 * length + 1; i > 1; --i) {
216
buffer[i] = _HEX_SYMBOLS[value & 0xf];
217
value >>= 4;
218
}
219
require(value == 0, "Strings: hex length insufficient");
220
return string(buffer);
221
}
222
}
223
 
224
 
225
pragma solidity ^0.8.0;
226
 
227
/**
228
* @dev Contract module that allows children to implement role-based access
229
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
230
* members except through off-chain means by accessing the contract event logs. Some
231
* applications may benefit from on-chain enumerability, for those cases see
232
* {AccessControlEnumerable}.
233
*
234
* Roles are referred to by their `bytes32` identifier. These should be exposed
235
* in the external API and be unique. The best way to achieve this is by
236
* using `public constant` hash digests:
237
*
238
* ```
239
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
240
* ```
241
*
242
* Roles can be used to represent a set of permissions. To restrict access to a
243
* function call, use {hasRole}:
244
*
245
* ```
246
* function foo() public {
247
* require(hasRole(MY_ROLE, msg.sender));
248
* ...
249
* }
250
* ```
251
*
252
* Roles can be granted and revoked dynamically via the {grantRole} and
253
* {revokeRole} functions. Each role has an associated admin role, and only
254
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
255
*
256
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
257
* that only accounts with this role will be able to grant or revoke other
258
* roles. More complex role relationships can be created by using
259
* {_setRoleAdmin}.
260
*
261
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
262
* grant and revoke this role. Extra precautions should be taken to secure
263
* accounts that have been granted it.
264
*/
265
abstract contract AccessControl is Context, IAccessControl, ERC165 {
266
struct RoleData {
267
mapping(address => bool) members;
268
bytes32 adminRole;
269
}
270
 
271
mapping(bytes32 => RoleData) private _roles;
272
 
273
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
274
 
275
/**
276
* @dev Modifier that checks that an account has a specific role. Reverts
277
* with a standardized message including the required role.
278
*
279
* The format of the revert reason is given by the following regular expression:
280
*
281
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
282
*
283
* _Available since v4.1._
284
*/
285
modifier onlyRole(bytes32 role) {
286
_checkRole(role, _msgSender());
287
_;
288
}
289
 
290
/**
291
* @dev See {IERC165-supportsInterface}.
292
*/
293
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
294
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
295
}
296
 
297
/**
298
* @dev Returns `true` if `account` has been granted `role`.
299
*/
300
function hasRole(bytes32 role, address account) public view override returns (bool) {
301
return _roles[role].members[account];
302
}
303
 
304
/**
305
* @dev Revert with a standard message if `account` is missing `role`.
306
*
307
* The format of the revert reason is given by the following regular expression:
308
*
309
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
310
*/
311
function _checkRole(bytes32 role, address account) internal view {
312
if (!hasRole(role, account)) {
313
revert(
314
string(
315
abi.encodePacked(
316
"AccessControl: account ",
317
Strings.toHexString(uint160(account), 20),
318
" is missing role ",
319
Strings.toHexString(uint256(role), 32)
320
)
321
)
322
);
323
}
324
}
325
 
326
/**
327
* @dev Returns the admin role that controls `role`. See {grantRole} and
328
* {revokeRole}.
329
*
330
* To change a role's admin, use {_setRoleAdmin}.
331
*/
332
function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
333
return _roles[role].adminRole;
334
}
335
 
336
/**
337
* @dev Grants `role` to `account`.
338
*
339
* If `account` had not been already granted `role`, emits a {RoleGranted}
340
* event.
341
*
342
* Requirements:
343
*
344
* - the caller must have ``role``'s admin role.
345
*/
346
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
347
_grantRole(role, account);
348
}
349
 
350
/**
351
* @dev Revokes `role` from `account`.
352
*
353
* If `account` had been granted `role`, emits a {RoleRevoked} event.
354
*
355
* Requirements:
356
*
357
* - the caller must have ``role``'s admin role.
358
*/
359
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
360
_revokeRole(role, account);
361
}
362
 
363
/**
364
* @dev Revokes `role` from the calling account.
365
*
366
* Roles are often managed via {grantRole} and {revokeRole}: this function's
367
* purpose is to provide a mechanism for accounts to lose their privileges
368
* if they are compromised (such as when a trusted device is misplaced).
369
*
370
* If the calling account had been granted `role`, emits a {RoleRevoked}
371
* event.
372
*
373
* Requirements:
374
*
375
* - the caller must be `account`.
376
*/
377
function renounceRole(bytes32 role, address account) public virtual override {
378
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
379
 
380
_revokeRole(role, account);
381
}
382
 
383
/**
384
* @dev Grants `role` to `account`.
385
*
386
* If `account` had not been already granted `role`, emits a {RoleGranted}
387
* event. Note that unlike {grantRole}, this function doesn't perform any
388
* checks on the calling account.
389
*
390
* [WARNING]
391
* ====
392
* This function should only be called from the constructor when setting
393
* up the initial roles for the system.
394
*
395
* Using this function in any other way is effectively circumventing the admin
396
* system imposed by {AccessControl}.
397
* ====
398
*/
399
function _setupRole(bytes32 role, address account) internal virtual {
400
_grantRole(role, account);
401
}
402
 
403
/**
404
* @dev Sets `adminRole` as ``role``'s admin role.
405
*
406
* Emits a {RoleAdminChanged} event.
407
*/
408
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
409
bytes32 previousAdminRole = getRoleAdmin(role);
410
_roles[role].adminRole = adminRole;
411
emit RoleAdminChanged(role, previousAdminRole, adminRole);
412
}
413
 
414
function _grantRole(bytes32 role, address account) private {
415
if (!hasRole(role, account)) {
416
_roles[role].members[account] = true;
417
emit RoleGranted(role, account, _msgSender());
418
}
419
}
420
 
421
function _revokeRole(bytes32 role, address account) private {
422
if (hasRole(role, account)) {
423
_roles[role].members[account] = false;
424
emit RoleRevoked(role, account, _msgSender());
425
}
426
}
427
}
428
 
429
pragma solidity ^0.8.0;
430
 
431
/**
432
* @dev Library for managing
433
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
434
* types.
435
*
436
* Sets have the following properties:
437
*
438
* - Elements are added, removed, and checked for existence in constant time
439
* (O(1)).
440
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
441
*
442
* ```
443
* contract Example {
444
* // Add the library methods
445
* using EnumerableSet for EnumerableSet.AddressSet;
446
*
447
* // Declare a set state variable
448
* EnumerableSet.AddressSet private mySet;
449
* }
450
* ```
451
*
452
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
453
* and `uint256` (`UintSet`) are supported.
454
*/
455
library EnumerableSet {
456
// To implement this library for multiple types with as little code
457
// repetition as possible, we write it in terms of a generic Set type with
458
// bytes32 values.
459
// The Set implementation uses private functions, and user-facing
460
// implementations (such as AddressSet) are just wrappers around the
461
// underlying Set.
462
// This means that we can only create new EnumerableSets for types that fit
463
// in bytes32.
464
 
465
struct Set {
466
// Storage of set values
467
bytes32[] _values;
468
// Position of the value in the `values` array, plus 1 because index 0
469
// means a value is not in the set.
470
mapping(bytes32 => uint256) _indexes;
471
}
472
 
473
/**
474
* @dev Add a value to a set. O(1).
475
*
476
* Returns true if the value was added to the set, that is if it was not
477
* already present.
478
*/
479
function _add(Set storage set, bytes32 value) private returns (bool) {
480
if (!_contains(set, value)) {
481
set._values.push(value);
482
// The value is stored at length-1, but we add 1 to all indexes
483
// and use 0 as a sentinel value
484
set._indexes[value] = set._values.length;
485
return true;
486
} else {
487
return false;
488
}
489
}
490
 
491
/**
492
* @dev Removes a value from a set. O(1).
493
*
494
* Returns true if the value was removed from the set, that is if it was
495
* present.
496
*/
497
function _remove(Set storage set, bytes32 value) private returns (bool) {
498
// We read and store the value's index to prevent multiple reads from the same storage slot
499
uint256 valueIndex = set._indexes[value];
500
 
501
if (valueIndex != 0) {
502
// Equivalent to contains(set, value)
503
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
504
// the array, and then remove the last element (sometimes called as 'swap and pop').
505
// This modifies the order of the array, as noted in {at}.
506
 
507
uint256 toDeleteIndex = valueIndex - 1;
508
uint256 lastIndex = set._values.length - 1;
509
 
510
if (lastIndex != toDeleteIndex) {
511
bytes32 lastvalue = set._values[lastIndex];
512
 
513
// Move the last value to the index where the value to delete is
514
set._values[toDeleteIndex] = lastvalue;
515
// Update the index for the moved value
516
set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
517
}
518
 
519
// Delete the slot where the moved value was stored
520
set._values.pop();
521
 
522
// Delete the index for the deleted slot
523
delete set._indexes[value];
524
 
525
return true;
526
} else {
527
return false;
528
}
529
}
530
 
531
/**
532
* @dev Returns true if the value is in the set. O(1).
533
*/
534
function _contains(Set storage set, bytes32 value) private view returns (bool) {
535
return set._indexes[value] != 0;
536
}
537
 
538
/**
539
* @dev Returns the number of values on the set. O(1).
540
*/
541
function _length(Set storage set) private view returns (uint256) {
542
return set._values.length;
543
}
544
 
545
/**
546
* @dev Returns the value stored at position `index` in the set. O(1).
547
*
548
* Note that there are no guarantees on the ordering of values inside the
549
* array, and it may change when more values are added or removed.
550
*
551
* Requirements:
552
*
553
* - `index` must be strictly less than {length}.
554
*/
555
function _at(Set storage set, uint256 index) private view returns (bytes32) {
556
return set._values[index];
557
}
558
 
559
/**
560
* @dev Return the entire set in an array
561
*
562
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
563
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
564
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
565
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
566
*/
567
function _values(Set storage set) private view returns (bytes32[] memory) {
568
return set._values;
569
}
570
 
571
// Bytes32Set
572
 
573
struct Bytes32Set {
574
Set _inner;
575
}
576
 
577
/**
578
* @dev Add a value to a set. O(1).
579
*
580
* Returns true if the value was added to the set, that is if it was not
581
* already present.
582
*/
583
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
584
return _add(set._inner, value);
585
}
586
 
587
/**
588
* @dev Removes a value from a set. O(1).
589
*
590
* Returns true if the value was removed from the set, that is if it was
591
* present.
592
*/
593
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
594
return _remove(set._inner, value);
595
}
596
 
597
/**
598
* @dev Returns true if the value is in the set. O(1).
599
*/
600
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
601
return _contains(set._inner, value);
602
}
603
 
604
/**
605
* @dev Returns the number of values in the set. O(1).
606
*/
607
function length(Bytes32Set storage set) internal view returns (uint256) {
608
return _length(set._inner);
609
}
610
 
611
/**
612
* @dev Returns the value stored at position `index` in the set. O(1).
613
*
614
* Note that there are no guarantees on the ordering of values inside the
615
* array, and it may change when more values are added or removed.
616
*
617
* Requirements:
618
*
619
* - `index` must be strictly less than {length}.
620
*/
621
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
622
return _at(set._inner, index);
623
}
624
 
625
/**
626
* @dev Return the entire set in an array
627
*
628
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
629
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
630
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
631
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
632
*/
633
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
634
return _values(set._inner);
635
}
636
 
637
// AddressSet
638
 
639
struct AddressSet {
640
Set _inner;
641
}
642
 
643
/**
644
* @dev Add a value to a set. O(1).
645
*
646
* Returns true if the value was added to the set, that is if it was not
647
* already present.
648
*/
649
function add(AddressSet storage set, address value) internal returns (bool) {
650
return _add(set._inner, bytes32(uint256(uint160(value))));
651
}
652
 
653
/**
654
* @dev Removes a value from a set. O(1).
655
*
656
* Returns true if the value was removed from the set, that is if it was
657
* present.
658
*/
659
function remove(AddressSet storage set, address value) internal returns (bool) {
660
return _remove(set._inner, bytes32(uint256(uint160(value))));
661
}
662
 
663
/**
664
* @dev Returns true if the value is in the set. O(1).
665
*/
666
function contains(AddressSet storage set, address value) internal view returns (bool) {
667
return _contains(set._inner, bytes32(uint256(uint160(value))));
668
}
669
 
670
/**
671
* @dev Returns the number of values in the set. O(1).
672
*/
673
function length(AddressSet storage set) internal view returns (uint256) {
674
return _length(set._inner);
675
}
676
 
677
/**
678
* @dev Returns the value stored at position `index` in the set. O(1).
679
*
680
* Note that there are no guarantees on the ordering of values inside the
681
* array, and it may change when more values are added or removed.
682
*
683
* Requirements:
684
*
685
* - `index` must be strictly less than {length}.
686
*/
687
function at(AddressSet storage set, uint256 index) internal view returns (address) {
688
return address(uint160(uint256(_at(set._inner, index))));
689
}
690
 
691
/**
692
* @dev Return the entire set in an array
693
*
694
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
695
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
696
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
697
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
698
*/
699
function values(AddressSet storage set) internal view returns (address[] memory) {
700
bytes32[] memory store = _values(set._inner);
701
address[] memory result;
702
 
703
assembly {
704
result := store
705
}
706
 
707
return result;
708
}
709
 
710
// UintSet
711
 
712
struct UintSet {
713
Set _inner;
714
}
715
 
716
/**
717
* @dev Add a value to a set. O(1).
718
*
719
* Returns true if the value was added to the set, that is if it was not
720
* already present.
721
*/
722
function add(UintSet storage set, uint256 value) internal returns (bool) {
723
return _add(set._inner, bytes32(value));
724
}
725
 
726
/**
727
* @dev Removes a value from a set. O(1).
728
*
729
* Returns true if the value was removed from the set, that is if it was
730
* present.
731
*/
732
function remove(UintSet storage set, uint256 value) internal returns (bool) {
733
return _remove(set._inner, bytes32(value));
734
}
735
 
736
/**
737
* @dev Returns true if the value is in the set. O(1).
738
*/
739
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
740
return _contains(set._inner, bytes32(value));
741
}
742
 
743
/**
744
* @dev Returns the number of values on the set. O(1).
745
*/
746
function length(UintSet storage set) internal view returns (uint256) {
747
return _length(set._inner);
748
}
749
 
750
/**
751
* @dev Returns the value stored at position `index` in the set. O(1).
752
*
753
* Note that there are no guarantees on the ordering of values inside the
754
* array, and it may change when more values are added or removed.
755
*
756
* Requirements:
757
*
758
* - `index` must be strictly less than {length}.
759
*/
760
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
761
return uint256(_at(set._inner, index));
762
}
763
 
764
/**
765
* @dev Return the entire set in an array
766
*
767
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
768
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
769
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
770
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
771
*/
772
function values(UintSet storage set) internal view returns (uint256[] memory) {
773
bytes32[] memory store = _values(set._inner);
774
uint256[] memory result;
775
 
776
assembly {
777
result := store
778
}
779
 
780
return result;
781
}
782
}
783
 
784
 
785
pragma solidity ^0.8.0;
786
 
787
/**
788
* @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
789
*/
790
interface IAccessControlEnumerable is IAccessControl {
791
/**
792
* @dev Returns one of the accounts that have `role`. `index` must be a
793
* value between 0 and {getRoleMemberCount}, non-inclusive.
794
*
795
* Role bearers are not sorted in any particular way, and their ordering may
796
* change at any point.
797
*
798
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
799
* you perform all queries on the same block. See the following
800
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
801
* for more information.
802
*/
803
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
804
 
805
/**
806
* @dev Returns the number of accounts that have `role`. Can be used
807
* together with {getRoleMember} to enumerate all bearers of a role.
808
*/
809
function getRoleMemberCount(bytes32 role) external view returns (uint256);
810
}
811
 
812
 
813
pragma solidity ^0.8.0;
814
 
815
/**
816
* @dev Extension of {AccessControl} that allows enumerating the members of each role.
817
*/
818
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
819
using EnumerableSet for EnumerableSet.AddressSet;
820
 
821
mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;
822
 
823
/**
824
* @dev See {IERC165-supportsInterface}.
825
*/
826
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
827
return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);
828
}
829
 
830
/**
831
* @dev Returns one of the accounts that have `role`. `index` must be a
832
* value between 0 and {getRoleMemberCount}, non-inclusive.
833
*
834
* Role bearers are not sorted in any particular way, and their ordering may
835
* change at any point.
836
*
837
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
838
* you perform all queries on the same block. See the following
839
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
840
* for more information.
841
*/
842
function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
843
return _roleMembers[role].at(index);
844
}
845
 
846
/**
847
* @dev Returns the number of accounts that have `role`. Can be used
848
* together with {getRoleMember} to enumerate all bearers of a role.
849
*/
850
function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
851
return _roleMembers[role].length();
852
}
853
 
854
/**
855
* @dev Overload {grantRole} to track enumerable memberships
856
*/
857
function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
858
super.grantRole(role, account);
859
_roleMembers[role].add(account);
860
}
861
 
862
/**
863
* @dev Overload {revokeRole} to track enumerable memberships
864
*/
865
function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
866
super.revokeRole(role, account);
867
_roleMembers[role].remove(account);
868
}
869
 
870
/**
871
* @dev Overload {renounceRole} to track enumerable memberships
872
*/
873
function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
874
super.renounceRole(role, account);
875
_roleMembers[role].remove(account);
876
}
877
 
878
/**
879
* @dev Overload {_setupRole} to track enumerable memberships
880
*/
881
function _setupRole(bytes32 role, address account) internal virtual override {
882
super._setupRole(role, account);
883
_roleMembers[role].add(account);
884
}
885
}
886
 
887
 
888
pragma solidity ^0.8.6;
889
 
890
/**
891
* @title KYCContract
892
* @dev KYC (Know Your Customer) system contract allowing users to submit KYC requests,
893
* which are processed by approved KYC centers.
894
*/
895
contract KYCContract is AccessControlEnumerable {
896
 
897
// Tracks the KYC level of each user (0 = no KYC).
898
mapping(address => uint) public level;
899
 
900
// prices for each KYC level.
901
mapping(uint => uint) public levelPrices;
902
903
// Role identifier for KYC centers.
904
bytes32 public constant KYCCentre = keccak256("KYCCentre");
905
 
906
 
907
/**
908
* @dev Emitted when a user's KYC level is updated.
909
* @param _address The user's address.
910
* @param level The updated KYC level.
911
*/
912
event KYCLevelChanged(address indexed _address, uint indexed level);
913
 
914
/**
915
* @dev Emitted when a new KYC request is created.
916
* @param index The global index of the created request.
917
*/
918
event RequestCreated(uint indexed index);
919
 
920
/**
921
* @dev Emitted when a KYC request is approved by a KYC center.
922
* @param index The global index of the approved request.
923
*/
924
event RequestApproved(uint indexed index);
925
 
926
/**
927
* @dev Emitted when a KYC request is declined by a KYC center.
928
* @param index The global index of the declined request.
929
*/
930
event RequestDeclined(uint indexed index);
931
 
932
/**
933
* @dev Emitted when a KYC request is withdrawn.
934
* @param index The global index of the withdrawn request.
935
*/
936
event RequestWithdrawn(uint indexed index);
937
 
938
/**
939
* @dev Emitted when the price of a KYC level is updated.
940
* @param level The KYC level.
941
* @param price The updated price for the level.
942
*/
943
event SetLevelPrice(uint indexed level, uint indexed price);
944
 
945
 
946
// Requests assigned to KYC centers.
947
mapping(address => uint[]) public kycCentreRequests;
948
 
949
// User-specific requests.
950
mapping(address => uint[]) public userKYCRequests;
951
 
952
// Enum for representing the status of a KYC request.
953
enum Status {
954
Pending,
955
Declined,
956
Approved,
957
Withdrawn
958
}
959
 
960
// Struct representing a KYC request.
961
struct KYCRequest {
962
address user; // User who submitted the request.
963
bytes32 data; // Encrypted data provided by the user.
964
uint level; // Requested KYC level.
965
Status status; // Current status of the request.
966
address centre; // Assigned KYC center.
967
uint deposit; // Fee paid for the request.
968
}
969
 
970
// List of all KYC requests.
971
KYCRequest[] public kycRequests;
972
 
973
/**
974
* @notice Modifier to ensure the user pays the required amount or more.
975
* @param _amount The required amount to proceed.
976
*/
977
modifier costs(uint _amount) {
978
require(msg.value >= _amount, "G001");
979
_;
980
if (msg.value > _amount)
981
payable(msg.sender).transfer(msg.value - _amount); // Refund excess.
982
}
983
 
984
/**
985
* @notice Sets the price for a specific KYC level.
986
* @param _level The KYC level to update.
987
* @param price The new price for the level.
988
* @dev Only callable by an admin.
989
*/
990
function setLevelPrice(uint _level, uint price) external {
991
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "G053");
992
levelPrices[_level] = price;
993
emit SetLevelPrice(_level, price);
994
}
995
 
996
/**
997
* @notice Creates a new KYC request.
998
* @param _level The requested KYC level.
999
* @param _data The encrypted KYC data.
1000
* @dev Selects a random KYC center for processing and assigns the request.
1001
*/
1002
function createKYCRequest(uint _level, bytes32 _data) external payable costs(levelPrices[_level]) {
1003
require(level[msg.sender] < _level, "G002");
1004
 
1005
uint length = userKYCRequests[msg.sender].length;
1006
if (length > 0) {
1007
uint requestIndex = userKYCRequests[msg.sender][length-1];
1008
require(kycRequests[requestIndex].status != Status.Pending, "G120");
1009
}
1010
 
1011
uint count = getRoleMemberCount(KYCCentre);
1012
require(count > 0, "G111");
1013
 
1014
uint index = uint(blockhash(block.number-1)) % count;
1015
address chosenKYCCentre = getRoleMember(KYCCentre, index);
1016
 
1017
KYCRequest memory request = KYCRequest({
1018
user: msg.sender,
1019
data: _data,
1020
level: _level,
1021
status: Status.Pending,
1022
centre: chosenKYCCentre,
1023
deposit: levelPrices[_level]
1024
});
1025
 
1026
kycRequests.push(request);
1027
 
1028
uint indexInAll = kycRequests.length-1;
1029
 
1030
kycCentreRequests[chosenKYCCentre].push(indexInAll);
1031
 
1032
// Store the index in the all list.
1033
userKYCRequests[msg.sender].push(indexInAll);
1034
emit RequestCreated(kycRequests.length-1);
1035
}
1036
 
1037
/**
1038
* @notice Approves a KYC request.
1039
* @param _index The global index of the request.
1040
* @dev Can only be called by the assigned KYC center.
1041
*/
1042
function approveKYCRequest(uint _index) external {
1043
require(hasRole(KYCCentre, msg.sender), "G052");
1044
KYCRequest storage request = kycRequests[_index];
1045
 
1046
require(msg.sender == request.centre, "G114");
1047
require(request.status == Status.Pending, "G121");
1048
request.status = Status.Approved;
1049
level[request.user] = request.level;
1050
 
1051
// We pay half of the deposit back to user if KYC centre approved request
1052
uint halvedDeposit = request.deposit / 2;
1053
payable(request.user).transfer(halvedDeposit);
1054
payable(msg.sender).transfer(request.deposit - halvedDeposit);
1055
 
1056
emit KYCLevelChanged(request.user, request.level);
1057
emit RequestApproved(_index);
1058
}
1059
 
1060
/**
1061
* @notice Declines a KYC request.
1062
* @param _index The global index of the request.
1063
* @dev Can only be called by the assigned KYC center.
1064
*/
1065
function declineKYCRequest(uint _index) external {
1066
require(hasRole(KYCCentre, msg.sender), "G050");
1067
KYCRequest storage request = kycRequests[_index];
1068
 
1069
require(msg.sender == request.centre, "G114");
1070
require(request.status == Status.Pending, "G121");
1071
request.status = Status.Declined;
1072
 
1073
payable(msg.sender).transfer(request.deposit);
1074
emit RequestDeclined(_index);
1075
}
1076
1077
/**
1078
* @notice Decrease the KYC level of a user.
1079
* @dev Only callable by an authorized KYC centre. The caller must be the centre that processed the user's last KYC request.
1080
* @param user The address of the user whose KYC level is to be decreased.
1081
* @param _level The new KYC level for the user, which must be less than the user's current level.
1082
*/
1083
function decreaseKYCLevel(address user, uint _level) external {
1084
require(hasRole(KYCCentre, msg.sender), "G051");
1085
1086
uint length = userKYCRequests[user].length;
1087
uint requestIndex = userKYCRequests[user][length-1];
1088
require(msg.sender == kycRequests[requestIndex].centre, "G114");
1089
 
1090
require(_level < level[user], "G112");
1091
level[user] = _level;
1092
 
1093
emit KYCLevelChanged(user, _level);
1094
}
1095
 
1096
/**
1097
* @notice Allows a user to withdraw their KYC request if the associated KYC centre has renounced its role.
1098
* @dev This function ensures that users can recover their deposit if the KYC centre is no longer active.
1099
*/
1100
function repairLostRequest() external {
1101
uint length = userKYCRequests[msg.sender].length;
1102
uint requestIndex = userKYCRequests[msg.sender][length-1];
1103
 
1104
KYCRequest storage request = kycRequests[requestIndex];
1105
require(msg.sender == request.user, "G053");
1106
require(!hasRole(KYCCentre, request.centre), "G110");
1107
require(request.status == Status.Pending, "G122");
1108
 
1109
request.status = Status.Withdrawn;
1110
 
1111
payable(request.user).transfer(request.deposit);
1112
emit RequestWithdrawn(requestIndex);
1113
}
1114
 
1115
/**
1116
* @notice Allows a user to cancel their KYC request.
1117
* @dev The user can only cancel requests that are still in the `Pending` status and assigned to an active KYC centre.
1118
*/
1119
function cancelUsersRequest() external {
1120
uint length = userKYCRequests[msg.sender].length;
1121
uint requestIndex = userKYCRequests[msg.sender][length-1];
1122
 
1123
KYCRequest storage request = kycRequests[requestIndex];
1124
require(msg.sender == request.user, "G053");
1125
require(hasRole(KYCCentre, request.centre), "G113");
1126
require(request.status == Status.Pending, "G123");
1127
 
1128
request.status = Status.Withdrawn;
1129
 
1130
payable(request.centre).transfer(request.deposit);
1131
emit RequestWithdrawn(requestIndex);
1132
}
1133
 
1134
/**
1135
* @notice View details of a user's KYC request by index.
1136
* @param userIndex The index of the user's request in their personal request history.
1137
* @return The `KYCRequest` object corresponding to the specified index.
1138
*/
1139
function viewMyRequest(uint userIndex) external view returns(KYCRequest memory) {
1140
uint indexInAll = userKYCRequests[msg.sender][userIndex];
1141
return kycRequests[indexInAll];
1142
}
1143
 
1144
/**
1145
* @notice View details of a KYC request assigned to a specific centre.
1146
* @param _centre The address of the KYC centre.
1147
* @param _localIndex The local index of the request in the centre's request history.
1148
* returns atuple containing the `KYCRequest` object and its global index in the `kycRequests` array.
1149
*/
1150
function viewRequestAssignedToCentre(address _centre, uint _localIndex) external view returns (KYCRequest memory, uint) {
1151
uint globalIndex = kycCentreRequests[_centre][_localIndex];
1152
KYCRequest memory request = kycRequests[globalIndex];
1153
return (request, globalIndex);
1154
}
1155
 
1156
/**
1157
* @notice View the most recent KYC request submitted by the caller.
1158
* @return The `KYCRequest` object corresponding to the caller's most recent request.
1159
*/
1160
function viewMyLastRequest() external view returns(KYCRequest memory) {
1161
uint len = userKYCRequests[msg.sender].length;
1162
uint indexInAll = userKYCRequests[msg.sender][len-1];
1163
return kycRequests[indexInAll];
1164
}
1165
 
1166
/**
1167
* @notice Get the global index of the most recent KYC request submitted by a specified user.
1168
* @param _address The address of the user.
1169
* @return The global index of the user's most recent KYC request in the `kycRequests` array.
1170
*/
1171
function getLastGlobalRequestIndexOfAddress(address _address) external view returns(uint){
1172
uint len = userKYCRequests[_address].length;
1173
uint index = userKYCRequests[_address][len-1];
1174
return index;
1175
}
1176
}
1177
 
Contract ABI
[{"name": "KYCLevelChanged", "type": "event", "inputs": [{"name": "_address", "type": "address", "indexed": true, "internalType": "address"}, {"name": "level", "type": "uint256", "indexed": true, "internalType": "uint256"}], "anonymous": false}, {"name": "RequestApproved", "type": "event", "inputs": [{"name": "index", "type": "uint256", "indexed": true, "internalType": "uint256"}], "anonymous": false}, {"name": "RequestCreated", "type": "event", "inputs": [{"name": "index", "type": "uint256", "indexed": true, "internalType": "uint256"}], "anonymous": false}, {"name": "RequestDeclined", "type": "event", "inputs": [{"name": "index", "type": "uint256", "indexed": true, "internalType": "uint256"}], "anonymous": false}, {"name": "RequestWithdrawn", "type": "event", "inputs": [{"name": "index", "type": "uint256", "indexed": true, "internalType": "uint256"}], "anonymous": false}, {"name": "RoleAdminChanged", "type": "event", "inputs": [{"name": "role", "type": "bytes32", "indexed": true, "internalType": "bytes32"}, {"name": "previousAdminRole", "type": "bytes32", "indexed": true, "internalType": "bytes32"}, {"name": "newAdminRole", "type": "bytes32", "indexed": true, "internalType": "bytes32"}], "anonymous": false}, {"name": "RoleGranted", "type": "event", "inputs": [{"name": "role", "type": "bytes32", "indexed": true, "internalType": "bytes32"}, {"name": "account", "type": "address", "indexed": true, "internalType": "address"}, {"name": "sender", "type": "address", "indexed": true, "internalType": "address"}], "anonymous": false}, {"name": "RoleRevoked", "type": "event", "inputs": [{"name": "role", "type": "bytes32", "indexed": true, "internalType": "bytes32"}, {"name": "account", "type": "address", "indexed": true, "internalType": "address"}, {"name": "sender", "type": "address", "indexed": true, "internalType": "address"}], "anonymous": false}, {"name": "SetLevelPrice", "type": "event", "inputs": [{"name": "level", "type": "uint256", "indexed": true, "internalType": "uint256"}, {"name": "price", "type": "uint256", "indexed": true, "internalType": "uint256"}], "anonymous": false}, {"name": "DEFAULT_ADMIN_ROLE", "type": "function", "inputs": [], "outputs": [{"name": "", "type": "bytes32", "internalType": "bytes32"}], "stateMutability": "view"}, {"name": "KYCCentre", "type": "function", "inputs": [], "outputs": [{"name": "", "type": "bytes32", "internalType": "bytes32"}], "stateMutability": "view"}, {"name": "approveKYCRequest", "type": "function", "inputs": [{"name": "_index", "type": "uint256", "internalType": "uint256"}], "outputs": [], "stateMutability": "nonpayable"}, {"name": "cancelUsersRequest", "type": "function", "inputs": [], "outputs": [], "stateMutability": "nonpayable"}, {"name": "createKYCRequest", "type": "function", "inputs": [{"name": "_level", "type": "uint256", "internalType": "uint256"}, {"name": "_data", "type": "bytes32", "internalType": "bytes32"}], "outputs": [], "stateMutability": "payable"}, {"name": "declineKYCRequest", "type": "function", "inputs": [{"name": "_index", "type": "uint256", "internalType": "uint256"}], "outputs": [], "stateMutability": "nonpayable"}, {"name": "decreaseKYCLevel", "type": "function", "inputs": [{"name": "user", "type": "address", "internalType": "address"}, {"name": "_level", "type": "uint256", "internalType": "uint256"}], "outputs": [], "stateMutability": "nonpayable"}, {"name": "getLastGlobalRequestIndexOfAddress", "type": "function", "inputs": [{"name": "_address", "type": "address", "internalType": "address"}], "outputs": [{"name": "", "type": "uint256", "internalType": "uint256"}], "stateMutability": "view"}, {"name": "getRoleAdmin", "type": "function", "inputs": [{"name": "role", "type": "bytes32", "internalType": "bytes32"}], "outputs": [{"name": "", "type": "bytes32", "internalType": "bytes32"}], "stateMutability": "view"}, {"name": "getRoleMember", "type": "function", "inputs": [{"name": "role", "type": "bytes32", "internalType": "bytes32"}, {"name": "index", "type": "uint256", "internalType": "uint256"}], "outputs": [{"name": "", "type": "address", "internalType": "address"}], "stateMutability": "view"}, {"name": "getRoleMemberCount", "type": "function", "inputs": [{"name": "role", "type": "bytes32", "internalType": "bytes32"}], "outputs": [{"name": "", "type": "uint256", "internalType": "uint256"}], "stateMutability": "view"}, {"name": "grantRole", "type": "function", "inputs": [{"name": "role", "type": "bytes32", "internalType": "bytes32"}, {"name": "account", "type": "address", "internalType": "address"}], "outputs": [], "stateMutability": "nonpayable"}, {"name": "hasRole", "type": "function", "inputs": [{"name": "role", "type": "bytes32", "internalType": "bytes32"}, {"name": "account", "type": "address", "internalType": "address"}], "outputs": [{"name": "", "type": "bool", "internalType": "bool"}], "stateMutability": "view"}, {"name": "kycCentreRequests", "type": "function", "inputs": [{"name": "", "type": "address", "internalType": "address"}, {"name": "", "type": "uint256", "internalType": "uint256"}], "outputs": [{"name": "", "type": "uint256", "internalType": "uint256"}], "stateMutability": "view"}, {"name": "kycRequests", "type": "function", "inputs": [{"name": "", "type": "uint256", "internalType": "uint256"}], "outputs": [{"name": "user", "type": "address", "internalType": "address"}, {"name": "data", "type": "bytes32", "internalType": "bytes32"}, {"name": "level", "type": "uint256", "internalType": "uint256"}, {"name": "status", "type": "uint8", "internalType": "enum KYCContract.Status"}, {"name": "centre", "type": "address", "internalType": "address"}, {"name": "deposit", "type": "uint256", "internalType": "uint256"}], "stateMutability": "view"}, {"name": "level", "type": "function", "inputs": [{"name": "", "type": "address", "internalType": "address"}], "outputs": [{"name": "", "type": "uint256", "internalType": "uint256"}], "stateMutability": "view"}, {"name": "levelPrices", "type": "function", "inputs": [{"name": "", "type": "uint256", "internalType": "uint256"}], "outputs": [{"name": "", "type": "uint256", "internalType": "uint256"}], "stateMutability": "view"}, {"name": "renounceRole", "type": "function", "inputs": [{"name": "role", "type": "bytes32", "internalType": "bytes32"}, {"name": "account", "type": "address", "internalType": "address"}], "outputs": [], "stateMutability": "nonpayable"}, {"name": "repairLostRequest", "type": "function", "inputs": [], "outputs": [], "stateMutability": "nonpayable"}, {"name": "revokeRole", "type": "function", "inputs": [{"name": "role", "type": "bytes32", "internalType": "bytes32"}, {"name": "account", "type": "address", "internalType": "address"}], "outputs": [], "stateMutability": "nonpayable"}, {"name": "setLevelPrice", "type": "function", "inputs": [{"name": "_level", "type": "uint256", "internalType": "uint256"}, {"name": "price", "type": "uint256", "internalType": "uint256"}], "outputs": [], "stateMutability": "nonpayable"}, {"name": "supportsInterface", "type": "function", "inputs": [{"name": "interfaceId", "type": "bytes4", "internalType": "bytes4"}], "outputs": [{"name": "", "type": "bool", "internalType": "bool"}], "stateMutability": "view"}, {"name": "userKYCRequests", "type": "function", "inputs": [{"name": "", "type": "address", "internalType": "address"}, {"name": "", "type": "uint256", "internalType": "uint256"}], "outputs": [{"name": "", "type": "uint256", "internalType": "uint256"}], "stateMutability": "view"}, {"name": "viewMyLastRequest", "type": "function", "inputs": [], "outputs": [{"name": "", "type": "tuple", "components": [{"name": "user", "type": "address", "internalType": "address"}, {"name": "data", "type": "bytes32", "internalType": "bytes32"}, {"name": "level", "type": "uint256", "internalType": "uint256"}, {"name": "status", "type": "uint8", "internalType": "enum KYCContract.Status"}, {"name": "centre", "type": "address", "internalType": "address"}, {"name": "deposit", "type": "uint256", "internalType": "uint256"}], "internalType": "struct KYCContract.KYCRequest"}], "stateMutability": "view"}, {"name": "viewMyRequest", "type": "function", "inputs": [{"name": "userIndex", "type": "uint256", "internalType": "uint256"}], "outputs": [{"name": "", "type": "tuple", "components": [{"name": "user", "type": "address", "internalType": "address"}, {"name": "data", "type": "bytes32", "internalType": "bytes32"}, {"name": "level", "type": "uint256", "internalType": "uint256"}, {"name": "status", "type": "uint8", "internalType": "enum KYCContract.Status"}, {"name": "centre", "type": "address", "internalType": "address"}, {"name": "deposit", "type": "uint256", "internalType": "uint256"}], "internalType": "struct KYCContract.KYCRequest"}], "stateMutability": "view"}, {"name": "viewRequestAssignedToCentre", "type": "function", "inputs": [{"name": "_centre", "type": "address", "internalType": "address"}, {"name": "_localIndex", "type": "uint256", "internalType": "uint256"}], "outputs": [{"name": "", "type": "tuple", "components": [{"name": "user", "type": "address", "internalType": "address"}, {"name": "data", "type": "bytes32", "internalType": "bytes32"}, {"name": "level", "type": "uint256", "internalType": "uint256"}, {"name": "status", "type": "uint8", "internalType": "enum KYCContract.Status"}, {"name": "centre", "type": "address", "internalType": "address"}, {"name": "deposit", "type": "uint256", "internalType": "uint256"}], "internalType": "struct KYCContract.KYCRequest"}, {"name": "", "type": "uint256", "internalType": "uint256"}], "stateMutability": "view"}]
Contract Creation Code
0x6080604052600436106101815760003560e01c8063847192d9116100d1578063b74091e81161008a578063d547741f11610064578063d547741f146104ac578063d56f5003146104cc578063e3fe29ee146104ee578063f5eb43521461050357600080fd5b8063b74091e81461043f578063ca15c8731461045f578063d41b6db61461047f57600080fd5b8063847192d9146103705780638e6156a1146103925780639010d07c146103b257806390ec8f7e146103ea57806391d148541461040a578063a217fddf1461042a57600080fd5b8063248a9ca31161013e57806348135df01161011857806348135df0146102ee578063599bd4e31461031b578063620472cf1461033b57806375e4107f1461035b57600080fd5b8063248a9ca31461027e5780632f2ff15d146102ae57806336568abe146102ce57600080fd5b806301ffc9a7146101865780630e8723dc146101bb5780631019c5a3146101e9578063192416cb1461020b5780631a710673146102395780632470cfe01461024c575b600080fd5b34801561019257600080fd5b506101a66101a1366004611bde565b610523565b60405190151581526020015b60405180910390f35b3480156101c757600080fd5b506101db6101d6366004611c24565b61054e565b6040516101b2929190611cd2565b3480156101f557600080fd5b50610209610204366004611ced565b61064a565b005b34801561021757600080fd5b5061022b610226366004611c24565b6107cd565b6040519081526020016101b2565b610209610247366004611d06565b6107fe565b34801561025857600080fd5b5061026c610267366004611ced565b610c1e565b6040516101b296959493929190611d28565b34801561028a57600080fd5b5061022b610299366004611ced565b60009081526020819052604090206001015490565b3480156102ba57600080fd5b506102096102c9366004611d6a565b610c76565b3480156102da57600080fd5b506102096102e9366004611d6a565b610c98565b3480156102fa57600080fd5b5061022b610309366004611ced565b60036020526000908152604090205481565b34801561032757600080fd5b5061022b610336366004611c24565b610cba565b34801561034757600080fd5b5061022b610356366004611d96565b610cd6565b34801561036757600080fd5b50610209610d22565b34801561037c57600080fd5b50610385610edf565b6040516101b29190611db1565b34801561039e57600080fd5b506102096103ad366004611c24565b610fd5565b3480156103be57600080fd5b506103d26103cd366004611d06565b611152565b6040516001600160a01b0390911681526020016101b2565b3480156103f657600080fd5b50610209610405366004611ced565b611171565b34801561041657600080fd5b506101a6610425366004611d6a565b6113ac565b34801561043657600080fd5b5061022b600081565b34801561044b57600080fd5b5061038561045a366004611ced565b6113d5565b34801561046b57600080fd5b5061022b61047a366004611ced565b6113fe565b34801561048b57600080fd5b5061022b61049a366004611d96565b60026020526000908152604090205481565b3480156104b857600080fd5b506102096104c7366004611d6a565b611415565b3480156104d857600080fd5b5061022b600080516020611fb283398151915281565b3480156104fa57600080fd5b5061020961141f565b34801561050f57600080fd5b5061020961051e366004611d06565b6115ae565b60006001600160e01b03198216635a05180f60e01b1480610548575061054882611614565b92915050565b610556611ba8565b6001600160a01b038316600090815260046020526040812080548291908590811061058357610583611dbf565b906000526020600020015490506000600682815481106105a5576105a5611dbf565b60009182526020918290206040805160c081018252600590930290910180546001600160a01b03168352600181015493830193909352600283015490820152600380830154919291606084019160ff9091169081111561060757610607611c4e565b600381111561061857610618611c4e565b8152600382015461010090046001600160a01b0316602082015260049091015460409091015296919550909350505050565b610662600080516020611fb2833981519152336113ac565b6106a05760405162461bcd60e51b8152600401610697906020808252600490820152630473035360e41b604082015260600190565b60405180910390fd5b6000600682815481106106b5576106b5611dbf565b906000526020600020906005020190508060030160019054906101000a90046001600160a01b03166001600160a01b0316336001600160a01b03161461070d5760405162461bcd60e51b815260040161069790611dd5565b600060038083015460ff169081111561072857610728611c4e565b1461075e5760405162461bcd60e51b8152600401610697906020808252600490820152634731323160e01b604082015260600190565b60038101805460ff19166001179055600481015460405133916108fc811502916000818181858888f1935050505015801561079d573d6000803e3d6000fd5b5060405182907fb04b82d30acceb062562e2eefee6f28c38f71cf9c6d4fce7884b883fe038825890600090a25050565b600460205281600052604060002081815481106107e957600080fd5b90600052602060002001600091509150505481565b600082815260036020526040902054348111156108465760405162461bcd60e51b8152600401610697906020808252600490820152634730303160e01b604082015260600190565b33600090815260026020526040902054831161088d5760405162461bcd60e51b8152600401610697906020808252600490820152632398181960e11b604082015260600190565b33600090815260056020526040902054801561094d573360009081526005602052604081206108bd600184611e09565b815481106108cd576108cd611dbf565b60009182526020822001549150600682815481106108ed576108ed611dbf565b60009182526020909120600360059092020181015460ff169081111561091557610915611c4e565b0361094b5760405162461bcd60e51b8152600401610697906020808252600490820152630473132360e41b604082015260600190565b505b6000610966600080516020611fb28339815191526113fe565b9050600081116109a15760405162461bcd60e51b8152600401610697906020808252600490820152634731313160e01b604082015260600190565b6000816109af600143611e09565b6109ba919040611e32565b905060006109d6600080516020611fb283398151915283611152565b6040805160c08101825233815260208082018a81528284018c81526000606085018181526001600160a01b0388811660808801528f83526003958690529682205460a087015260068054600180820183559190935286517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f600590940293840180546001600160a01b0319169190991617885593517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d4083015591517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d4182015590517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d42909101805496975093958695949193919260ff19909116918490811115610b0157610b01611c4e565b021790555060808201516003820180546001600160a01b0390921661010002610100600160a81b031990921691909117905560a090910151600490910155600654600090610b5190600190611e09565b6001600160a01b03841660009081526004602090815260408083208054600181810183559185528385200185905533845260058352908320805480830182559084529190922001829055600654919250610baa91611e09565b6040517f97890542421e06ad80deca7ba945fd211a48ec6d89da2510960446025b78e32490600090a250505050505080341115610c1957336108fc610bef8334611e09565b6040518115909202916000818181858888f19350505050158015610c17573d6000803e3d6000fd5b505b505050565b60068181548110610c2e57600080fd5b6000918252602090912060059091020180546001820154600283015460038401546004909401546001600160a01b0393841695509193909260ff821692610100909204169086565b610c808282611649565b6000828152600160205260409020610c19908261166f565b610ca28282611684565b6000828152600160205260409020610c199082611702565b600560205281600052604060002081815481106107e957600080fd5b6001600160a01b03811660009081526005602052604081208054908290610cfe600184611e09565b81548110610d0e57610d0e611dbf565b600091825260209091200154949350505050565b33600090815260056020526040812080549190610d40600184611e09565b81548110610d5057610d50611dbf565b90600052602060002001549050600060068281548110610d7257610d72611dbf565b6000918252602090912060059091020180549091506001600160a01b03163314610dae5760405162461bcd60e51b815260040161069790611e46565b6003810154610dda90600080516020611fb28339815191529061010090046001600160a01b03166113ac565b15610e105760405162461bcd60e51b8152600401610697906020808252600490820152630473131360e41b604082015260600190565b600060038083015460ff1690811115610e2b57610e2b611c4e565b14610e615760405162461bcd60e51b8152600401610697906020808252600490820152632398991960e11b604082015260600190565b6003818101805460ff19169091179055805460048201546040516001600160a01b03909216916108fc82150291906000818181858888f19350505050158015610eae573d6000803e3d6000fd5b5060405182907fa96b5d0d7f26bd7262aefaa969b62e7b98f59439bca50822d598df9c16a20d6790600090a2505050565b610ee7611ba8565b33600090815260056020526040812080549190610f05600184611e09565b81548110610f1557610f15611dbf565b9060005260206000200154905060068181548110610f3557610f35611dbf565b60009182526020918290206040805160c081018252600590930290910180546001600160a01b03168352600181015493830193909352600283015490820152600380830154919291606084019160ff90911690811115610f9757610f97611c4e565b6003811115610fa857610fa8611c4e565b8152600382015461010090046001600160a01b031660208201526004909101546040909101529392505050565b610fed600080516020611fb2833981519152336113ac565b6110225760405162461bcd60e51b8152600401610697906020808252600490820152634730353160e01b604082015260600190565b6001600160a01b038216600090815260056020526040812080549190611049600184611e09565b8154811061105957611059611dbf565b906000526020600020015490506006818154811061107957611079611dbf565b600091825260209091206005909102016003015461010090046001600160a01b031633146110b95760405162461bcd60e51b815260040161069790611dd5565b6001600160a01b03841660009081526002602052604090205483106111095760405162461bcd60e51b8152600401610697906020808252600490820152632398989960e11b604082015260600190565b6001600160a01b038416600081815260026020526040808220869055518592917fc3ef28acb401a3dc5b2e85f6179659f2a493effb762b56133e7b69bc49c9570791a350505050565b600082815260016020526040812061116a9083611717565b9392505050565b611189600080516020611fb2833981519152336113ac565b6111be5760405162461bcd60e51b81526004016106979060208082526004908201526323981a9960e11b604082015260600190565b6000600682815481106111d3576111d3611dbf565b906000526020600020906005020190508060030160019054906101000a90046001600160a01b03166001600160a01b0316336001600160a01b03161461122b5760405162461bcd60e51b815260040161069790611dd5565b600060038083015460ff169081111561124657611246611c4e565b1461127c5760405162461bcd60e51b8152600401610697906020808252600490820152634731323160e01b604082015260600190565b60038101805460ff191660029081179091558082015482546001600160a01b0316600090815260208390526040812091909155600483015490916112bf91611e64565b82546040519192506001600160a01b03169082156108fc029083906000818181858888f193505050501580156112f9573d6000803e3d6000fd5b50336001600160a01b03166108fc8284600401546113179190611e09565b6040518115909202916000818181858888f1935050505015801561133f573d6000803e3d6000fd5b50600282015482546040516001600160a01b03909116907fc3ef28acb401a3dc5b2e85f6179659f2a493effb762b56133e7b69bc49c9570790600090a360405183907fbecbbd7543b68baaaf7e9c3fd12e4719f1f506f4253abef4a6573d0adf3a73ed90600090a2505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6113dd611ba8565b336000908152600560205260408120805484908110610f1557610f15611dbf565b600081815260016020526040812061054890611723565b610ca2828261172d565b3360009081526005602052604081208054919061143d600184611e09565b8154811061144d5761144d611dbf565b9060005260206000200154905060006006828154811061146f5761146f611dbf565b6000918252602090912060059091020180549091506001600160a01b031633146114ab5760405162461bcd60e51b815260040161069790611e46565b60038101546114d790600080516020611fb28339815191529061010090046001600160a01b03166113ac565b61150c5760405162461bcd60e51b8152600401610697906020808252600490820152634731313360e01b604082015260600190565b600060038083015460ff169081111561152757611527611c4e565b1461155d5760405162461bcd60e51b8152600401610697906020808252600490820152634731323360e01b604082015260600190565b6003818101805460ff19169091179081905560048201546040516101009092046001600160a01b0316916108fc82150291906000818181858888f19350505050158015610eae573d6000803e3d6000fd5b6115b96000336113ac565b6115d55760405162461bcd60e51b815260040161069790611e46565b60008281526003602052604080822083905551829184917f3f88291f93d4b81e09bd18b48548609fd00030880a5fc63ce32049867eaf49da9190a35050565b60006001600160e01b03198216637965db0b60e01b148061054857506301ffc9a760e01b6001600160e01b0319831614610548565b6000828152602081905260409020600101546116658133611753565b610c1983836117b7565b600061116a836001600160a01b03841661183b565b6001600160a01b03811633146116f45760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610697565b6116fe828261188a565b5050565b600061116a836001600160a01b0384166118ef565b600061116a83836119e2565b6000610548825490565b6000828152602081905260409020600101546117498133611753565b610c19838361188a565b61175d82826113ac565b6116fe57611775816001600160a01b03166014611a0c565b611780836020611a0c565b604051602001611791929190611e9c565b60408051601f198184030181529082905262461bcd60e51b825261069791600401611f11565b6117c182826113ac565b6116fe576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556117f73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600081815260018301602052604081205461188257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610548565b506000610548565b61189482826113ac565b156116fe576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600081815260018301602052604081205480156119d8576000611913600183611e09565b855490915060009061192790600190611e09565b905081811461198c57600086600001828154811061194757611947611dbf565b906000526020600020015490508087600001848154811061196a5761196a611dbf565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061199d5761199d611f44565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610548565b6000915050610548565b60008260000182815481106119f9576119f9611dbf565b9060005260206000200154905092915050565b60606000611a1b836002611f5a565b611a26906002611f71565b67ffffffffffffffff811115611a3e57611a3e611f84565b6040519080825280601f01601f191660200182016040528015611a68576020820181803683370190505b509050600360fc1b81600081518110611a8357611a83611dbf565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611ab257611ab2611dbf565b60200101906001600160f81b031916908160001a9053506000611ad6846002611f5a565b611ae1906001611f71565b90505b6001811115611b59576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611b1557611b15611dbf565b1a60f81b828281518110611b2b57611b2b611dbf565b60200101906001600160f81b031916908160001a90535060049490941c93611b5281611f9a565b9050611ae4565b50831561116a5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610697565b6040805160c081018252600080825260208201819052918101829052906060820190815260006020820181905260409091015290565b600060208284031215611bf057600080fd5b81356001600160e01b03198116811461116a57600080fd5b80356001600160a01b0381168114611c1f57600080fd5b919050565b60008060408385031215611c3757600080fd5b611c4083611c08565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b60048110611c8257634e487b7160e01b600052602160045260246000fd5b9052565b60018060a01b0380825116835260208201516020840152604082015160408401526060820151611cb96060850182611c64565b506080828101519091169083015260a090810151910152565b60e08101611ce08285611c86565b8260c08301529392505050565b600060208284031215611cff57600080fd5b5035919050565b60008060408385031215611d1957600080fd5b50508035926020909101359150565b6001600160a01b038781168252602082018790526040820186905260c0820190611d556060840187611c64565b93909316608082015260a00152949350505050565b60008060408385031215611d7d57600080fd5b82359150611d8d60208401611c08565b90509250929050565b600060208284031215611da857600080fd5b61116a82611c08565b60c081016105488284611c86565b634e487b7160e01b600052603260045260246000fd5b60208082526004908201526311cc4c4d60e21b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561054857610548611df3565b634e487b7160e01b600052601260045260246000fd5b600082611e4157611e41611e1c565b500690565b6020808252600490820152634730353360e01b604082015260600190565b600082611e7357611e73611e1c565b500490565b60005b83811015611e93578181015183820152602001611e7b565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611ed4816017850160208801611e78565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611f05816028840160208801611e78565b01602801949350505050565b6020815260008251806020840152611f30816040850160208701611e78565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603160045260246000fd5b808202811582820484141761054857610548611df3565b8082018082111561054857610548611df3565b634e487b7160e01b600052604160045260246000fd5b600081611fa957611fa9611df3565b50600019019056fe79fce87046aae5e678100c84cc5c4708df4209fab036250bb81408ada9b857efa26469706673582212208409034ef128e8ba4357e44d36db46639221dc82467277c29472d57ad2a95d8264736f6c63430008130033
©2022-now by Graphite