@evvm/testnet-contracts 2.2.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +145 -118
  2. package/README.md +162 -39
  3. package/contracts/core/Core.sol +1394 -0
  4. package/contracts/core/lib/CoreStorage.sol +171 -0
  5. package/contracts/nameService/NameService.sol +666 -586
  6. package/contracts/nameService/lib/IdentityValidation.sol +18 -3
  7. package/contracts/p2pSwap/P2PSwap.sol +439 -285
  8. package/contracts/staking/Estimator.sol +128 -40
  9. package/contracts/staking/Staking.sol +329 -322
  10. package/contracts/treasury/Treasury.sol +48 -37
  11. package/contracts/treasuryTwoChains/TreasuryExternalChainStation.sol +585 -198
  12. package/contracts/treasuryTwoChains/TreasuryHostChainStation.sol +425 -174
  13. package/contracts/treasuryTwoChains/lib/PayloadUtils.sol +2 -4
  14. package/interfaces/{IEvvm.sol → ICore.sol} +67 -29
  15. package/interfaces/IEstimator.sol +1 -1
  16. package/interfaces/INameService.sol +58 -52
  17. package/interfaces/IP2PSwap.sol +18 -17
  18. package/interfaces/IStaking.sol +22 -17
  19. package/interfaces/ITreasury.sol +2 -1
  20. package/interfaces/ITreasuryExternalChainStation.sol +15 -9
  21. package/interfaces/ITreasuryHostChainStation.sol +14 -11
  22. package/interfaces/IUserValidator.sol +6 -0
  23. package/library/Erc191TestBuilder.sol +350 -297
  24. package/library/EvvmService.sol +38 -27
  25. package/library/errors/CoreError.sol +116 -0
  26. package/library/errors/CrossChainTreasuryError.sol +36 -0
  27. package/library/errors/NameServiceError.sol +79 -0
  28. package/library/errors/StakingError.sol +79 -0
  29. package/library/errors/TreasuryError.sol +33 -0
  30. package/library/primitives/SignatureRecover.sol +33 -0
  31. package/library/structs/CoreStructs.sol +146 -0
  32. package/library/structs/ExternalChainStationStructs.sol +92 -0
  33. package/library/structs/HostChainStationStructs.sol +77 -0
  34. package/library/structs/NameServiceStructs.sol +47 -0
  35. package/library/structs/P2PSwapStructs.sol +127 -0
  36. package/library/structs/StakingStructs.sol +67 -0
  37. package/library/utils/AdvancedStrings.sol +84 -5
  38. package/library/utils/CAUtils.sol +29 -0
  39. package/library/utils/SignatureUtil.sol +34 -0
  40. package/library/utils/governance/Admin.sol +66 -0
  41. package/library/utils/governance/ProposalStructs.sol +49 -0
  42. package/library/utils/service/CoreExecution.sol +177 -0
  43. package/library/utils/service/StakingServiceUtils.sol +30 -3
  44. package/library/utils/signature/CoreHashUtils.sol +73 -0
  45. package/library/utils/signature/NameServiceHashUtils.sol +156 -0
  46. package/library/utils/signature/P2PSwapHashUtils.sol +65 -0
  47. package/library/utils/signature/StakingHashUtils.sol +41 -0
  48. package/library/utils/signature/TreasuryCrossChainHashUtils.sol +40 -0
  49. package/package.json +2 -1
  50. package/contracts/evvm/Evvm.sol +0 -1327
  51. package/contracts/evvm/lib/ErrorsLib.sol +0 -18
  52. package/contracts/evvm/lib/EvvmStorage.sol +0 -62
  53. package/contracts/evvm/lib/EvvmStructs.sol +0 -90
  54. package/contracts/evvm/lib/SignatureUtils.sol +0 -120
  55. package/contracts/nameService/lib/ErrorsLib.sol +0 -21
  56. package/contracts/nameService/lib/NameServiceStructs.sol +0 -69
  57. package/contracts/nameService/lib/SignatureUtils.sol +0 -245
  58. package/contracts/p2pSwap/lib/P2PSwapStructs.sol +0 -59
  59. package/contracts/p2pSwap/lib/SignatureUtils.sol +0 -98
  60. package/contracts/staking/lib/ErrorsLib.sol +0 -22
  61. package/contracts/staking/lib/SignatureUtils.sol +0 -39
  62. package/contracts/staking/lib/StakingStructs.sol +0 -94
  63. package/contracts/treasury/lib/ErrorsLib.sol +0 -11
  64. package/contracts/treasuryTwoChains/lib/ErrorsLib.sol +0 -48
  65. package/contracts/treasuryTwoChains/lib/ExternalChainStationStructs.sol +0 -80
  66. package/contracts/treasuryTwoChains/lib/HostChainStationStructs.sol +0 -87
  67. package/contracts/treasuryTwoChains/lib/SignatureUtils.sol +0 -79
  68. package/library/utils/GovernanceUtils.sol +0 -81
  69. package/library/utils/nonces/AsyncNonce.sol +0 -32
  70. package/library/utils/nonces/SyncNonce.sol +0 -27
  71. package/library/utils/service/EvvmPayments.sol +0 -79
@@ -2,6 +2,29 @@
2
2
  // Full license terms available at: https://www.evvm.info/docs/EVVMNoncommercialLicense
3
3
 
4
4
  pragma solidity ^0.8.0;
5
+
6
+ import {
7
+ NameServiceError as Error
8
+ } from "@evvm/testnet-contracts/library/errors/NameServiceError.sol";
9
+ import {
10
+ NameServiceHashUtils as Hash
11
+ } from "@evvm/testnet-contracts/library/utils/signature/NameServiceHashUtils.sol";
12
+ import {
13
+ NameServiceStructs as Structs
14
+ } from "@evvm/testnet-contracts/library/structs/NameServiceStructs.sol";
15
+ import {
16
+ IdentityValidation
17
+ } from "@evvm/testnet-contracts/contracts/nameService/lib/IdentityValidation.sol";
18
+
19
+ import {Core} from "@evvm/testnet-contracts/contracts/core/Core.sol";
20
+
21
+ import {
22
+ AdvancedStrings
23
+ } from "@evvm/testnet-contracts/library/utils/AdvancedStrings.sol";
24
+ import {
25
+ ProposalStructs
26
+ } from "@evvm/testnet-contracts/library/utils/governance/ProposalStructs.sol";
27
+
5
28
  /**
6
29
  _ _
7
30
  | \ | |
@@ -25,346 +48,264 @@ pragma solidity ^0.8.0;
25
48
  ██║ ██╔══╝ ╚════██║ ██║ ██║╚██╗██║██╔══╝ ██║
26
49
  ██║ ███████╗███████║ ██║ ██║ ╚████║███████╗ ██║
27
50
  ╚═╝ ╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝
28
- *
29
- * @title EVVM Name Service Contract
51
+ * @title EVVM Name Service
30
52
  * @author Mate labs
31
- * @notice This contract manages username registration and domain name services for the EVVM ecosystem
32
- * @dev Provides a comprehensive domain name system with features including:
33
- *
34
- * Core Features:
35
- * - Username registration with pre-registration protection against front-running
36
- * - Custom metadata management with schema-based data storage
37
- * - Username trading system with offers and marketplace functionality
38
- * - Renewal system with dynamic pricing based on market demand
39
- * - Time-delayed governance for administrative functions
40
- *
41
- * Registration Process:
42
- * 1. Pre-register: Commit to a username hash to prevent front-running
43
- * 2. Register: Reveal the username and complete registration within 30 minutes
44
- * 3. Manage: Add custom metadata, handle offers, and renew as needed
45
- *
46
- * Security Features:
47
- * - Signature verification for all operations
48
- * - Nonce-based replay protection
49
- * - Time-locked administrative changes
50
- * - Integration with EVVM core for secure payments
51
- *
52
- * Economic Model:
53
- * - Registration costs 100x EVVM reward amount
54
- * - Custom metadata operations cost 10x EVVM reward amount
55
- * - Renewal pricing varies based on market demand and timing
56
- * - Marketplace takes 0.5% fee on username sales
53
+ * @notice Identity and username registration system for the EVVM ecosystem.
54
+ * @dev Manages username registration via a commit-reveal scheme (pre-registration),
55
+ * a secondary marketplace for domain trading, and customizable user metadata.
56
+ * Integrates with Core.sol for payment processing and uses async nonces for high throughput.
57
57
  */
58
58
 
59
- import {IEvvm} from "@evvm/testnet-contracts/interfaces/IEvvm.sol";
60
- import {
61
- AsyncNonce
62
- } from "@evvm/testnet-contracts/library/utils/nonces/AsyncNonce.sol";
63
- import {
64
- NameServiceStructs
65
- } from "@evvm/testnet-contracts/contracts/nameService/lib/NameServiceStructs.sol";
66
- import {
67
- AdvancedStrings
68
- } from "@evvm/testnet-contracts/library/utils/AdvancedStrings.sol";
69
- import {
70
- ErrorsLib
71
- } from "@evvm/testnet-contracts/contracts/nameService/lib/ErrorsLib.sol";
72
- import {
73
- SignatureUtils
74
- } from "@evvm/testnet-contracts/contracts/nameService/lib/SignatureUtils.sol";
75
- import {
76
- IdentityValidation
77
- } from "@evvm/testnet-contracts/contracts/nameService/lib/IdentityValidation.sol";
78
-
79
- contract NameService is AsyncNonce, NameServiceStructs {
80
- /// @dev Time delay constant for accepting proposals
59
+ contract NameService {
60
+ /// @dev Time delay for accepting proposals (1 day)
81
61
  uint256 constant TIME_TO_ACCEPT_PROPOSAL = 1 days;
82
62
 
83
- /// @dev Constant address representing the Principal Token in the EVVM ecosystem
84
- address private constant PRINCIPAL_TOKEN_ADDRESS =
85
- 0x0000000000000000000000000000000000000001;
86
-
87
- /// @dev Amount of Principal Tokens locked in pending marketplace offers
63
+ /// @dev Principal Tokens locked in pending marketplace
88
64
  uint256 private principalTokenTokenLockedForWithdrawOffers;
89
65
 
90
- /// @dev Nested mapping: username => offer ID => offer details
91
- mapping(string username => mapping(uint256 id => OfferMetadata))
66
+ /// @dev Nested mapping: username => offer ID => offer
67
+ mapping(string username => mapping(uint256 id => Structs.OfferMetadata))
92
68
  private usernameOffers;
93
69
 
94
- /// @dev Nested mapping: username => metadata key => custom value string
70
+ /// @dev Nested mapping: username => key => custom value
95
71
  mapping(string username => mapping(uint256 numberKey => string customValue))
96
72
  private identityCustomMetadata;
97
73
 
98
- /// @dev Proposal system for token withdrawal amounts with time delay
99
- UintTypeProposal amountToWithdrawTokens;
74
+ /// @dev Proposal system for token withdrawal with delay
75
+ ProposalStructs.UintTypeProposal amountToWithdrawTokens;
100
76
 
101
- /// @dev Proposal system for EVVM contract address changes with time delay
102
- AddressTypeProposal evvmAddress;
77
+ /// @dev Proposal system for Core address changes
78
+ ProposalStructs.AddressTypeProposal coreAddress;
103
79
 
104
- /// @dev Proposal system for admin address changes with time delay
105
- AddressTypeProposal admin;
80
+ /// @dev Proposal system for admin address changes
81
+ ProposalStructs.AddressTypeProposal admin;
106
82
 
107
- /// @dev Mapping from username to its core metadata and registration details
108
- mapping(string username => IdentityBaseMetadata basicMetadata)
83
+ /// @dev Mapping from username to core metadata
84
+ mapping(string username => Structs.IdentityBaseMetadata basicMetadata)
109
85
  private identityDetails;
110
86
 
111
- IEvvm private evvm;
87
+ /// @dev EVVM contract for payment processing
88
+ Core private core;
112
89
 
113
- /// @dev Restricts function access to the current admin address only
90
+ /// @dev Restricts function access to current admin only
114
91
  modifier onlyAdmin() {
115
- if (msg.sender != admin.current) revert ErrorsLib.SenderIsNotAdmin();
92
+ if (msg.sender != admin.current) revert Error.SenderIsNotAdmin();
116
93
 
117
94
  _;
118
95
  }
119
96
 
120
- /// @dev Verifies that the caller owns the specified identity/username
121
- modifier onlyOwnerOfIdentity(address _user, string memory _identity) {
122
- if (identityDetails[_identity].owner != _user)
123
- revert ErrorsLib.UserIsNotOwnerOfIdentity();
124
-
125
- _;
126
- }
97
+ //█ Initialization ████████████████████████████████████████████████████████████████████████
127
98
 
128
99
  /**
129
- * @notice Initializes the NameService contract
130
- * @dev Sets up the EVVM integration and initial admin
131
- * @param _evvmAddress Address of the EVVM core contract for payment processing
132
- * @param _initialOwner Address that will have admin privileges
100
+ * @notice Initializes the NameService with the Core contract and initial administrator.
101
+ * @param _coreAddress The address of the EVVM Core contract.
102
+ * @param _initialOwner The address granted administrative privileges.
133
103
  */
134
- constructor(address _evvmAddress, address _initialOwner) {
135
- evvmAddress.current = _evvmAddress;
104
+ constructor(address _coreAddress, address _initialOwner) {
105
+ coreAddress.current = _coreAddress;
136
106
  admin.current = _initialOwner;
137
- evvm = IEvvm(_evvmAddress);
107
+ core = Core(_coreAddress);
138
108
  }
139
109
 
110
+ //█ Registration Functions ████████████████████████████████████████████████████████████████████████
111
+
140
112
  /**
141
- * @notice Pre-registers a username hash to prevent front-running attacks
142
- * @dev Creates a temporary reservation that can be registered 30 minutes later
143
- * @param user Address of the user making the pre-registration
144
- * @param hashPreRegisteredUsername Keccak256 hash of username + random number
145
- * @param nonce Unique nonce to prevent replay attacks
146
- * @param signature Signature proving authorization for this operation
147
- * @param priorityFee_EVVM Priority fee for faster transaction processing
148
- * @param nonce_EVVM Nonce for the EVVM payment transaction
149
- * @param priorityFlag_EVVM True for async payment, false for sync payment
150
- * @param signature_EVVM Signature for the EVVM payment transaction
113
+ * @notice Commits a username hash to prevent front-running before registration.
114
+ * @dev Part of the commit-reveal scheme. Valid for 30 minutes.
115
+ * @param user The address of the registrant.
116
+ * @param hashPreRegisteredUsername The keccak256 hash of (username + secret).
117
+ * @param originExecutor Optional tx.origin restriction.
118
+ * @param nonce Async nonce for signature verification.
119
+ * @param signature Registrant's authorization signature.
120
+ * @param priorityFeePay Optional priority fee for the executor.
121
+ * @param noncePay Nonce for the Core payment (if fee is paid).
122
+ * @param signaturePay Signature for the Core payment (if fee is paid).
151
123
  */
152
124
  function preRegistrationUsername(
153
125
  address user,
154
126
  bytes32 hashPreRegisteredUsername,
127
+ address originExecutor,
155
128
  uint256 nonce,
156
129
  bytes memory signature,
157
- uint256 priorityFee_EVVM,
158
- uint256 nonce_EVVM,
159
- bool priorityFlag_EVVM,
160
- bytes memory signature_EVVM
130
+ uint256 priorityFeePay,
131
+ uint256 noncePay,
132
+ bytes memory signaturePay
161
133
  ) external {
162
- if (
163
- !SignatureUtils.verifyMessageSignedForPreRegistrationUsername(
164
- IEvvm(evvmAddress.current).getEvvmID(),
165
- user,
166
- hashPreRegisteredUsername,
167
- nonce,
168
- signature
169
- )
170
- ) revert ErrorsLib.InvalidSignatureOnNameService();
171
-
172
- verifyAsyncNonce(user, nonce);
173
-
174
- if (priorityFee_EVVM > 0) {
175
- makePay(
176
- user,
177
- 0,
178
- priorityFee_EVVM,
179
- nonce_EVVM,
180
- priorityFlag_EVVM,
181
- signature_EVVM
182
- );
183
- }
184
-
185
- string memory key = string.concat(
186
- "@",
187
- AdvancedStrings.bytes32ToString(hashPreRegisteredUsername)
134
+ core.validateAndConsumeNonce(
135
+ user,
136
+ Hash.hashDataForPreRegistrationUsername(hashPreRegisteredUsername),
137
+ originExecutor,
138
+ nonce,
139
+ true,
140
+ signature
188
141
  );
189
142
 
190
- identityDetails[key] = IdentityBaseMetadata({
143
+ if (priorityFeePay > 0)
144
+ requestPay(user, 0, priorityFeePay, noncePay, signaturePay);
145
+
146
+ identityDetails[
147
+ string.concat(
148
+ "@",
149
+ AdvancedStrings.bytes32ToString(hashPreRegisteredUsername)
150
+ )
151
+ ] = Structs.IdentityBaseMetadata({
191
152
  owner: user,
192
- expireDate: block.timestamp + 30 minutes,
153
+ expirationDate: block.timestamp + 30 minutes,
193
154
  customMetadataMaxSlots: 0,
194
155
  offerMaxSlots: 0,
195
156
  flagNotAUsername: 0x01
196
157
  });
197
158
 
198
- markAsyncNonceAsUsed(user, nonce);
199
-
200
- if (IEvvm(evvmAddress.current).isAddressStaker(msg.sender)) {
201
- makeCaPay(
202
- msg.sender,
203
- IEvvm(evvmAddress.current).getRewardAmount() + priorityFee_EVVM
204
- );
205
- }
159
+ if (core.isAddressStaker(msg.sender))
160
+ makeCaPay(msg.sender, core.getRewardAmount() + priorityFeePay);
206
161
  }
207
162
 
208
163
  /**
209
- * @notice Completes username registration using a pre-registration commitment
210
- * @dev Must be called after the pre-registration period (30 minutes) has reached
211
- * @param user Address of the user completing the registration
212
- * @param username The actual username being registered (revealed from hash)
213
- * @param clowNumber Random number used in the pre-registration hash
214
- * @param nonce Unique nonce to prevent replay attacks
215
- * @param signature Signature proving authorization for this operation
216
- * @param priorityFee_EVVM Priority fee for faster transaction processing
217
- * @param nonce_EVVM Nonce for the EVVM payment transaction
218
- * @param priorityFlag_EVVM True for async payment, false for sync payment
219
- * @param signature_EVVM Signature for the EVVM payment transaction
164
+ * @notice Finalizes username registration by revealing the secret associated with a pre-registration.
165
+ * @dev Validates format, availability, and payment. Grants 1 year of ownership.
166
+ * @param user The address of the registrant.
167
+ * @param username The plain-text username being registered.
168
+ * @param lockNumber The secret used in the pre-registration hash.
169
+ * @param originExecutor Optional tx.origin restriction.
170
+ * @param nonce Async nonce for signature verification.
171
+ * @param signature Registrant's authorization signature.
172
+ * @param priorityFeePay Optional priority fee for the executor.
173
+ * @param noncePay Nonce for the Core payment (registration fee + priority fee).
174
+ * @param signaturePay Signature for the Core payment.
220
175
  */
221
176
  function registrationUsername(
222
177
  address user,
223
178
  string memory username,
224
- uint256 clowNumber,
179
+ uint256 lockNumber,
180
+ address originExecutor,
225
181
  uint256 nonce,
226
182
  bytes memory signature,
227
- uint256 priorityFee_EVVM,
228
- uint256 nonce_EVVM,
229
- bool priorityFlag_EVVM,
230
- bytes memory signature_EVVM
183
+ uint256 priorityFeePay,
184
+ uint256 noncePay,
185
+ bytes memory signaturePay
231
186
  ) external {
187
+ core.validateAndConsumeNonce(
188
+ user,
189
+ Hash.hashDataForRegistrationUsername(username, lockNumber),
190
+ originExecutor,
191
+ nonce,
192
+ true,
193
+ signature
194
+ );
195
+
232
196
  if (
233
197
  admin.current != user &&
234
198
  !IdentityValidation.isValidUsername(username)
235
- ) revert ErrorsLib.InvalidUsername();
199
+ ) revert Error.InvalidUsername();
236
200
 
237
201
  if (!isUsernameAvailable(username))
238
- revert ErrorsLib.UsernameAlreadyRegistered();
239
-
240
- if (
241
- !SignatureUtils.verifyMessageSignedForRegistrationUsername(
242
- IEvvm(evvmAddress.current).getEvvmID(),
243
- user,
244
- username,
245
- clowNumber,
246
- nonce,
247
- signature
248
- )
249
- ) revert ErrorsLib.InvalidSignatureOnNameService();
250
-
251
- verifyAsyncNonce(user, nonce);
202
+ revert Error.UsernameAlreadyRegistered();
252
203
 
253
- makePay(
204
+ requestPay(
254
205
  user,
255
206
  getPriceOfRegistration(username),
256
- priorityFee_EVVM,
257
- nonce_EVVM,
258
- priorityFlag_EVVM,
259
- signature_EVVM
207
+ priorityFeePay,
208
+ noncePay,
209
+ signaturePay
260
210
  );
261
211
 
262
212
  string memory _key = string.concat(
263
213
  "@",
264
- AdvancedStrings.bytes32ToString(hashUsername(username, clowNumber))
214
+ AdvancedStrings.bytes32ToString(hashUsername(username, lockNumber))
265
215
  );
266
216
 
267
217
  if (
268
218
  identityDetails[_key].owner != user ||
269
- identityDetails[_key].expireDate > block.timestamp
270
- ) revert ErrorsLib.PreRegistrationNotValid();
219
+ identityDetails[_key].expirationDate > block.timestamp
220
+ ) revert Error.PreRegistrationNotValid();
271
221
 
272
- identityDetails[username] = IdentityBaseMetadata({
222
+ identityDetails[username] = Structs.IdentityBaseMetadata({
273
223
  owner: user,
274
- expireDate: block.timestamp + 366 days,
224
+ expirationDate: block.timestamp + 366 days,
275
225
  customMetadataMaxSlots: 0,
276
226
  offerMaxSlots: 0,
277
227
  flagNotAUsername: 0x00
278
228
  });
279
229
 
280
- markAsyncNonceAsUsed(user, nonce);
281
-
282
- if (IEvvm(evvmAddress.current).isAddressStaker(msg.sender)) {
230
+ if (core.isAddressStaker(msg.sender))
283
231
  makeCaPay(
284
232
  msg.sender,
285
- (50 * IEvvm(evvmAddress.current).getRewardAmount()) +
286
- priorityFee_EVVM
233
+ (50 * core.getRewardAmount()) + priorityFeePay
287
234
  );
288
- }
289
235
 
290
236
  delete identityDetails[_key];
291
237
  }
292
238
 
239
+ //█ Marketplace Functions ████████████████████████████████████████████████████████████████████████
240
+
293
241
  /**
294
- * @notice Creates a marketplace offer to purchase a username
295
- * @dev Locks the offer amount in the contract until withdrawn or accepted
296
- * @param user Address making the offer
297
- * @param username Target username for the offer
298
- * @param expireDate Timestamp when the offer expires
299
- * @param amount Amount being offered in Principal Tokens
300
- * @param nonce Unique nonce to prevent replay attacks
301
- * @param signature Signature proving authorization for this operation
302
- * @param priorityFee_EVVM Priority fee for faster transaction processing
303
- * @param nonce_EVVM Nonce for the EVVM payment transaction
304
- * @param priorityFlag_EVVM True for async payment, false for sync payment
305
- * @param signature_EVVM Signature for the EVVM payment transaction
306
- * @return offerID Unique identifier for the created offer
242
+ * @notice Places a purchase offer on an existing username.
243
+ * @dev Tokens are locked in the contract. A 0.5% marketplace fee is applied upon successful sale.
244
+ * @param user The address of the offerer.
245
+ * @param username The target username.
246
+ * @param amount Total amount offered (including fee).
247
+ * @param expirationDate When the offer expires.
248
+ * @param originExecutor Optional tx.origin restriction.
249
+ * @param nonce Async nonce for signature verification.
250
+ * @param signature Offerer's authorization signature.
251
+ * @param priorityFeePay Optional priority fee for the executor.
252
+ * @param noncePay Nonce for the Core payment (locks tokens).
253
+ * @param signaturePay Signature for the Core payment.
254
+ * @return offerID The unique ID of the created offer.
307
255
  */
308
256
  function makeOffer(
309
257
  address user,
310
258
  string memory username,
311
- uint256 expireDate,
312
259
  uint256 amount,
260
+ uint256 expirationDate,
261
+ address originExecutor,
313
262
  uint256 nonce,
314
263
  bytes memory signature,
315
- uint256 priorityFee_EVVM,
316
- uint256 nonce_EVVM,
317
- bool priorityFlag_EVVM,
318
- bytes memory signature_EVVM
264
+ uint256 priorityFeePay,
265
+ uint256 noncePay,
266
+ bytes memory signaturePay
319
267
  ) external returns (uint256 offerID) {
268
+ core.validateAndConsumeNonce(
269
+ user,
270
+ Hash.hashDataForMakeOffer(username, amount, expirationDate),
271
+ originExecutor,
272
+ nonce,
273
+ true,
274
+ signature
275
+ );
276
+
320
277
  if (
321
278
  identityDetails[username].flagNotAUsername == 0x01 ||
322
- !verifyIfIdentityExists(username) ||
323
- amount == 0 ||
324
- expireDate <= block.timestamp
325
- ) revert ErrorsLib.PreRegistrationNotValid();
279
+ !verifyIfIdentityExists(username)
280
+ ) revert Error.InvalidUsername();
326
281
 
327
- if (
328
- !SignatureUtils.verifyMessageSignedForMakeOffer(
329
- IEvvm(evvmAddress.current).getEvvmID(),
330
- user,
331
- username,
332
- expireDate,
333
- amount,
334
- nonce,
335
- signature
336
- )
337
- ) revert ErrorsLib.InvalidSignatureOnNameService();
282
+ if (expirationDate <= block.timestamp)
283
+ revert Error.CannotBeBeforeCurrentTime();
338
284
 
339
- verifyAsyncNonce(user, nonce);
285
+ if (amount == 0) revert Error.AmountMustBeGreaterThanZero();
340
286
 
341
- makePay(
342
- user,
343
- amount,
344
- priorityFee_EVVM,
345
- nonce_EVVM,
346
- priorityFlag_EVVM,
347
- signature_EVVM
348
- );
287
+ requestPay(user, amount, priorityFeePay, noncePay, signaturePay);
349
288
 
350
- while (usernameOffers[username][offerID].offerer != address(0)) {
289
+ while (usernameOffers[username][offerID].offerer != address(0))
351
290
  offerID++;
352
- }
353
291
 
354
- usernameOffers[username][offerID] = OfferMetadata({
292
+ uint256 amountToOffer = ((amount * 995) / 1000);
293
+
294
+ usernameOffers[username][offerID] = Structs.OfferMetadata({
355
295
  offerer: user,
356
- expireDate: expireDate,
357
- amount: ((amount * 995) / 1000)
296
+ expirationDate: expirationDate,
297
+ amount: amountToOffer
358
298
  });
359
299
 
360
300
  makeCaPay(
361
301
  msg.sender,
362
- IEvvm(evvmAddress.current).getRewardAmount() +
302
+ core.getRewardAmount() +
363
303
  ((amount * 125) / 100_000) +
364
- priorityFee_EVVM
304
+ priorityFeePay
365
305
  );
306
+
366
307
  principalTokenTokenLockedForWithdrawOffers +=
367
- ((amount * 995) / 1000) +
308
+ amountToOffer +
368
309
  (amount / 800);
369
310
 
370
311
  if (offerID > identityDetails[username].offerMaxSlots) {
@@ -372,60 +313,70 @@ contract NameService is AsyncNonce, NameServiceStructs {
372
313
  } else if (identityDetails[username].offerMaxSlots == 0) {
373
314
  identityDetails[username].offerMaxSlots++;
374
315
  }
375
-
376
- markAsyncNonceAsUsed(user, nonce);
377
316
  }
378
317
 
379
318
  /**
380
- * @notice Withdraws a marketplace offer and refunds the locked tokens
381
- * @dev Can only be called by the offer creator before expiration
382
- * @param user Address that made the original offer
383
- * @param username Username the offer was made for
384
- * @param offerID Unique identifier of the offer to withdraw
385
- * @param nonce Unique nonce to prevent replay attacks
386
- * @param signature Signature proving authorization for this operation
387
- * @param priorityFee_EVVM Priority fee for faster transaction processing
388
- * @param nonce_EVVM Nonce for the EVVM payment transaction
389
- * @param priorityFlag_EVVM True for async payment, false for sync payment
390
- * @param signature_EVVM Signature for the EVVM payment transaction
319
+ * @notice Withdraws marketplace offer and refunds tokens
320
+ * @dev Can only be called by offer creator or after expire
321
+ *
322
+ * Withdrawal Flow:
323
+ * 1. Validates offer exists and belongs to user
324
+ * 2. Optionally validates expiration date passed
325
+ * 3. Refunds locked tokens to offerer
326
+ * 4. Processes optional priority fee
327
+ * 5. Deletes offer and updates slot count
328
+ *
329
+ * Core.sol Integration:
330
+ * - Validates signature with State.validateAndConsumeNonce
331
+ * - Uses async nonce (isAsyncExec = true)
332
+ * - Hash includes username + offer ID
333
+ * - Prevents replay attacks and double withdrawals
334
+ *
335
+ * Core.sol Integration:
336
+ * - Refund: offer amount via makeTransfer to offerer
337
+ * - Priority fee: via requestPay (if > 0)
338
+ * - Staker reward: 1x reward + priority fee
339
+ * - makeCaPay distributes to caller if staker
340
+ *
341
+ * Token Unlocking:
342
+ * - Decreases principalTokenTokenLockedForWithdrawOffers
343
+ * - Releases both offer amount and marketplace fee
344
+ * - Returns funds to original offerer
345
+ *
346
+ * @param user Address that made original offer
347
+ * @param username Username offer was made for
348
+ * @param offerID Unique identifier of offer to withdraw
349
+ * @param nonce Async nonce for replay protection
350
+ * @param signature Signature for Core.sol validation
351
+ * @param priorityFeePay Priority fee for faster processing
352
+ * @param noncePay Nonce for EVVM payment transaction
353
+ * @param signaturePay Signature for EVVM payment
391
354
  */
392
355
  function withdrawOffer(
393
356
  address user,
394
357
  string memory username,
395
358
  uint256 offerID,
359
+ address originExecutor,
396
360
  uint256 nonce,
397
361
  bytes memory signature,
398
- uint256 priorityFee_EVVM,
399
- uint256 nonce_EVVM,
400
- bool priorityFlag_EVVM,
401
- bytes memory signature_EVVM
362
+ uint256 priorityFeePay,
363
+ uint256 noncePay,
364
+ bytes memory signaturePay
402
365
  ) external {
366
+ core.validateAndConsumeNonce(
367
+ user,
368
+ Hash.hashDataForWithdrawOffer(username, offerID),
369
+ originExecutor,
370
+ nonce,
371
+ true,
372
+ signature
373
+ );
374
+
403
375
  if (usernameOffers[username][offerID].offerer != user)
404
- revert ErrorsLib.UserIsNotOwnerOfOffer();
376
+ revert Error.UserIsNotOwnerOfOffer();
405
377
 
406
- if (
407
- !SignatureUtils.verifyMessageSignedForWithdrawOffer(
408
- IEvvm(evvmAddress.current).getEvvmID(),
409
- user,
410
- username,
411
- offerID,
412
- nonce,
413
- signature
414
- )
415
- ) revert ErrorsLib.InvalidSignatureOnNameService();
416
-
417
- verifyAsyncNonce(user, nonce);
418
-
419
- if (priorityFee_EVVM > 0) {
420
- makePay(
421
- user,
422
- 0,
423
- priorityFee_EVVM,
424
- nonce_EVVM,
425
- priorityFlag_EVVM,
426
- signature_EVVM
427
- );
428
- }
378
+ if (priorityFeePay > 0)
379
+ requestPay(user, 0, priorityFeePay, noncePay, signaturePay);
429
380
 
430
381
  makeCaPay(user, usernameOffers[username][offerID].amount);
431
382
 
@@ -433,69 +384,91 @@ contract NameService is AsyncNonce, NameServiceStructs {
433
384
 
434
385
  makeCaPay(
435
386
  msg.sender,
436
- IEvvm(evvmAddress.current).getRewardAmount() +
387
+ core.getRewardAmount() +
437
388
  ((usernameOffers[username][offerID].amount * 1) / 796) +
438
- priorityFee_EVVM
389
+ priorityFeePay
439
390
  );
440
391
 
441
392
  principalTokenTokenLockedForWithdrawOffers -=
442
393
  (usernameOffers[username][offerID].amount) +
443
394
  (((usernameOffers[username][offerID].amount * 1) / 199) / 4);
444
-
445
- markAsyncNonceAsUsed(user, nonce);
446
395
  }
447
396
 
448
397
  /**
449
- * @notice Accepts a marketplace offer and transfers username ownership
450
- * @dev Can only be called by the current username owner before offer expiration
451
- * @param user Address of the current username owner
398
+ * @notice Accepts marketplace offer and transfers ownership
399
+ * @dev Can only be called by current owner before expiration
400
+ *
401
+ * Acceptance Flow:
402
+ * 1. Validates user is current username owner
403
+ * 2. Validates offer exists and not expired
404
+ * 3. Transfers offer amount to seller
405
+ * 4. Transfers ownership to offerer
406
+ * 5. Processes optional priority fee
407
+ * 6. Deletes offer and unlocks tokens
408
+ *
409
+ * Core.sol Integration:
410
+ * - Validates signature with State.validateAndConsumeNonce
411
+ * - Uses async nonce (isAsyncExec = true)
412
+ * - Hash includes username + offer ID
413
+ * - Prevents replay attacks and double acceptance
414
+ *
415
+ * Core.sol Integration:
416
+ * - Payment: offer amount via makeCaPay to seller
417
+ * - Priority fee: via requestPay (if > 0)
418
+ * - Fee Distribution:
419
+ * * 99.5% to seller (locked amount)
420
+ * * 0.5% + reward to staker (if applicable)
421
+ * - makeCaPay transfers from locked funds
422
+ *
423
+ * Ownership Transfer:
424
+ * - Changes identityDetails[username].owner
425
+ * - Preserves all metadata and expiration
426
+ * - Transfers all custom metadata slots
427
+ *
428
+ * Token Unlocking:
429
+ * - Decreases principalTokenTokenLockedForWithdrawOffers
430
+ * - Releases offer amount + marketplace fee
431
+ * - Distributes to seller and staker
432
+ *
433
+ * @param user Address of current username owner
452
434
  * @param username Username being sold
453
- * @param offerID Unique identifier of the offer to accept
454
- * @param nonce Unique nonce to prevent replay attacks
455
- * @param signature Signature proving authorization for this operation
456
- * @param priorityFee_EVVM Priority fee for faster transaction processing
457
- * @param nonce_EVVM Nonce for the EVVM payment transaction
458
- * @param priorityFlag_EVVM True for async payment, false for sync payment
459
- * @param signature_EVVM Signature for the EVVM payment transaction
435
+ * @param offerID Unique identifier of offer to accept
436
+ * @param nonce Async nonce for replay protection
437
+ * @param signature Signature for Core.sol validation
438
+ * @param priorityFeePay Priority fee for faster processing
439
+ * @param noncePay Nonce for EVVM payment transaction
440
+ * @param signaturePay Signature for EVVM payment
460
441
  */
461
442
  function acceptOffer(
462
443
  address user,
463
444
  string memory username,
464
445
  uint256 offerID,
446
+ address originExecutor,
465
447
  uint256 nonce,
466
448
  bytes memory signature,
467
- uint256 priorityFee_EVVM,
468
- uint256 nonce_EVVM,
469
- bool priorityFlag_EVVM,
470
- bytes memory signature_EVVM
471
- ) external onlyOwnerOfIdentity(user, username) {
449
+ uint256 priorityFeePay,
450
+ uint256 noncePay,
451
+ bytes memory signaturePay
452
+ ) external {
453
+ core.validateAndConsumeNonce(
454
+ user,
455
+ Hash.hashDataForAcceptOffer(username, offerID),
456
+ originExecutor,
457
+ nonce,
458
+ true,
459
+ signature
460
+ );
461
+
462
+ if (identityDetails[username].owner != user)
463
+ revert Error.UserIsNotOwnerOfIdentity();
464
+
472
465
  if (
473
466
  usernameOffers[username][offerID].offerer == address(0) ||
474
- usernameOffers[username][offerID].expireDate < block.timestamp
475
- ) revert ErrorsLib.AcceptOfferVerificationFailed();
467
+ usernameOffers[username][offerID].expirationDate < block.timestamp
468
+ ) revert Error.OfferInactive();
476
469
 
477
- if (
478
- !SignatureUtils.verifyMessageSignedForAcceptOffer(
479
- IEvvm(evvmAddress.current).getEvvmID(),
480
- user,
481
- username,
482
- offerID,
483
- nonce,
484
- signature
485
- )
486
- ) revert ErrorsLib.InvalidSignatureOnNameService();
487
-
488
- verifyAsyncNonce(user, nonce);
489
-
490
- if (priorityFee_EVVM > 0) {
491
- makePay(
492
- user,
493
- 0,
494
- priorityFee_EVVM,
495
- nonce_EVVM,
496
- priorityFlag_EVVM,
497
- signature_EVVM
498
- );
470
+ if (priorityFeePay > 0) {
471
+ requestPay(user, 0, priorityFeePay, noncePay, signaturePay);
499
472
  }
500
473
 
501
474
  makeCaPay(user, usernameOffers[username][offerID].amount);
@@ -505,161 +478,192 @@ contract NameService is AsyncNonce, NameServiceStructs {
505
478
 
506
479
  usernameOffers[username][offerID].offerer = address(0);
507
480
 
508
- if (IEvvm(evvmAddress.current).isAddressStaker(msg.sender)) {
481
+ if (core.isAddressStaker(msg.sender)) {
509
482
  makeCaPay(
510
483
  msg.sender,
511
- (IEvvm(evvmAddress.current).getRewardAmount()) +
484
+ (core.getRewardAmount()) +
512
485
  (((usernameOffers[username][offerID].amount * 1) / 199) /
513
486
  4) +
514
- priorityFee_EVVM
487
+ priorityFeePay
515
488
  );
516
489
  }
517
490
 
518
491
  principalTokenTokenLockedForWithdrawOffers -=
519
492
  (usernameOffers[username][offerID].amount) +
520
493
  (((usernameOffers[username][offerID].amount * 1) / 199) / 4);
521
-
522
- markAsyncNonceAsUsed(user, nonce);
523
494
  }
524
495
 
525
496
  /**
526
- * @notice Renews a username registration for another year
527
- * @dev Pricing varies based on timing and market demand for the username
497
+ * @notice Renews username registration for another year
498
+ * @dev Dynamic pricing based on timing and market demand
528
499
  *
529
500
  * Pricing Rules:
530
- * - Free renewal if done within 1 year of expiration (limited time offer)
531
- * - Variable cost based on highest active offer (minimum 500 Principal Token)
532
- * - Fixed 500,000 Principal Token if renewed more than 1 year before expiration
533
- * - Can be renewed up to 100 years in advance
501
+ * - Free: Renewed within grace period after expiration
502
+ * - Variable: Based on highest active offer (min 500 PT)
503
+ * - Fixed: 500,000 PT if renewed >1 year early
504
+ * - Can renew up to 100 years in advance
505
+ *
506
+ * Core.sol Integration:
507
+ * - Validates signature with State.validateAndConsumeNonce
508
+ * - Uses async nonce (isAsyncExec = true)
509
+ * - Hash includes username only
510
+ * - Prevents replay attacks
511
+ *
512
+ * Core.sol Integration:
513
+ * - Payment: seePriceToRenew calculates cost
514
+ * - Paid through requestPay (locks tokens)
515
+ * - Staker reward: 1x reward + 50% of price + fee
516
+ * - makeCaPay distributes rewards
534
517
  *
535
- * @param user Address of the username owner
518
+ * Renewal Logic:
519
+ * - Extends expirationDate by 366 days
520
+ * - Preserves ownership and all metadata
521
+ * - Cannot exceed 100 years (36500 days)
522
+ *
523
+ * @param user Address of username owner
536
524
  * @param username Username to renew
537
- * @param nonce Unique nonce to prevent replay attacks
538
- * @param signature Signature proving authorization for this operation
539
- * @param priorityFee_EVVM Priority fee for faster transaction processing
540
- * @param nonce_EVVM Nonce for the EVVM payment transaction
541
- * @param priorityFlag_EVVM True for async payment, false for sync payment
542
- * @param signature_EVVM Signature for the EVVM payment transaction
525
+ * @param nonce Async nonce for replay protection
526
+ * @param signature Signature for Core.sol validation
527
+ * @param priorityFeePay Priority fee for faster processing
528
+ * @param noncePay Nonce for EVVM payment transaction
529
+ * @param signaturePay Signature for EVVM payment
543
530
  */
544
531
  function renewUsername(
545
532
  address user,
546
533
  string memory username,
534
+ address originExecutor,
547
535
  uint256 nonce,
548
536
  bytes memory signature,
549
- uint256 priorityFee_EVVM,
550
- uint256 nonce_EVVM,
551
- bool priorityFlag_EVVM,
552
- bytes memory signature_EVVM
553
- ) external onlyOwnerOfIdentity(user, username) {
554
- if (
555
- identityDetails[username].flagNotAUsername == 0x01 ||
556
- identityDetails[username].expireDate > block.timestamp + 36500 days
557
- ) revert ErrorsLib.RenewUsernameVerificationFailed();
537
+ uint256 priorityFeePay,
538
+ uint256 noncePay,
539
+ bytes memory signaturePay
540
+ ) external {
541
+ core.validateAndConsumeNonce(
542
+ user,
543
+ Hash.hashDataForRenewUsername(username),
544
+ originExecutor,
545
+ nonce,
546
+ true,
547
+ signature
548
+ );
558
549
 
559
- if (
560
- !SignatureUtils.verifyMessageSignedForRenewUsername(
561
- IEvvm(evvmAddress.current).getEvvmID(),
562
- user,
563
- username,
564
- nonce,
565
- signature
566
- )
567
- ) revert ErrorsLib.InvalidSignatureOnNameService();
550
+ if (identityDetails[username].owner != user)
551
+ revert Error.UserIsNotOwnerOfIdentity();
552
+
553
+ if (identityDetails[username].flagNotAUsername == 0x01)
554
+ revert Error.IdentityIsNotAUsername();
568
555
 
569
- verifyAsyncNonce(user, nonce);
556
+ if (
557
+ identityDetails[username].expirationDate >
558
+ block.timestamp + 36500 days
559
+ ) revert Error.RenewalTimeLimitExceeded();
570
560
 
571
561
  uint256 priceOfRenew = seePriceToRenew(username);
572
562
 
573
- makePay(
563
+ requestPay(
574
564
  user,
575
565
  priceOfRenew,
576
- priorityFee_EVVM,
577
- nonce_EVVM,
578
- priorityFlag_EVVM,
579
- signature_EVVM
566
+ priorityFeePay,
567
+ noncePay,
568
+ signaturePay
580
569
  );
581
570
 
582
- if (IEvvm(evvmAddress.current).isAddressStaker(msg.sender)) {
571
+ if (core.isAddressStaker(msg.sender)) {
583
572
  makeCaPay(
584
573
  msg.sender,
585
- IEvvm(evvmAddress.current).getRewardAmount() +
574
+ core.getRewardAmount() +
586
575
  ((priceOfRenew * 50) / 100) +
587
- priorityFee_EVVM
576
+ priorityFeePay
588
577
  );
589
578
  }
590
579
 
591
- identityDetails[username].expireDate += 366 days;
592
- markAsyncNonceAsUsed(user, nonce);
580
+ identityDetails[username].expirationDate += 366 days;
593
581
  }
594
582
 
583
+ //█ Metadata Functions ████████████████████████████████████████████████████████████████████████
584
+
595
585
  /**
596
- * @notice Adds custom metadata to a username following a standardized schema format
597
- * @dev Metadata follows format: [schema]:[subschema]>[value]
586
+ * @notice Adds custom metadata to username using schema format
587
+ * @dev Metadata format: [schema]:[subschema]>[value]
598
588
  *
599
589
  * Standard Format Examples:
600
590
  * - memberOf:>EVVM
601
591
  * - socialMedia:x>jistro (Twitter/X handle)
602
- * - email:dev>jistro[at]evvm.org (development email)
603
- * - email:callme>contact[at]jistro.xyz (contact email)
592
+ * - email:dev>jistro[at]evvm.org (dev email)
593
+ * - email:callme>contact[at]jistro.xyz (contact)
604
594
  *
605
595
  * Schema Guidelines:
606
596
  * - Based on https://schema.org/docs/schemas.html
607
597
  * - ':' separates schema from subschema
608
598
  * - '>' separates metadata from value
609
- * - Pad with spaces if schema/subschema < 5 characters
610
- * - Use "socialMedia" for social networks with network name as subschema
599
+ * - Pad spaces if schema/subschema < 5 chars
600
+ * - Use "socialMedia" for social networks
601
+ *
602
+ * Core.sol Integration:
603
+ * - Validates signature with State.validateAndConsumeNonce
604
+ * - Uses async nonce (isAsyncExec = true)
605
+ * - Hash includes identity + value
606
+ * - Prevents replay attacks
607
+ *
608
+ * Core.sol Integration:
609
+ * - Payment: 10x EVVM reward amount
610
+ * - Paid through requestPay (locks tokens)
611
+ * - Staker reward: 5x reward + priority fee
612
+ * - makeCaPay distributes rewards
611
613
  *
612
- * @param user Address of the username owner
614
+ * Slot Management:
615
+ * - Increments customMetadataMaxSlots
616
+ * - Each slot holds one metadata entry
617
+ * - No limit on number of slots
618
+ *
619
+ * @param user Address of username owner
613
620
  * @param identity Username to add metadata to
614
- * @param value Metadata string following the standardized format
615
- * @param nonce Unique nonce to prevent replay attacks
616
- * @param signature Signature proving authorization for this operation
617
- * @param priorityFee_EVVM Priority fee for faster transaction processing
618
- * @param nonce_EVVM Nonce for the EVVM payment transaction
619
- * @param priorityFlag_EVVM True for async payment, false for sync payment
620
- * @param signature_EVVM Signature for the EVVM payment transaction
621
+ * @param value Metadata string following format
622
+ * @param nonce Async nonce for replay protection
623
+ * @param signature Signature for Core.sol validation
624
+ * @param priorityFeePay Priority fee for faster processing
625
+ * @param noncePay Nonce for EVVM payment transaction
626
+ * @param signaturePay Signature for EVVM payment
621
627
  */
622
628
  function addCustomMetadata(
623
629
  address user,
624
630
  string memory identity,
625
631
  string memory value,
632
+ address originExecutor,
626
633
  uint256 nonce,
627
634
  bytes memory signature,
628
- uint256 priorityFee_EVVM,
629
- uint256 nonce_EVVM,
630
- bool priorityFlag_EVVM,
631
- bytes memory signature_EVVM
632
- ) external onlyOwnerOfIdentity(user, identity) {
633
- if (bytes(value).length == 0) revert ErrorsLib.EmptyCustomMetadata();
635
+ uint256 priorityFeePay,
636
+ uint256 noncePay,
637
+ bytes memory signaturePay
638
+ ) external {
639
+ core.validateAndConsumeNonce(
640
+ user,
641
+ Hash.hashDataForAddCustomMetadata(identity, value),
642
+ originExecutor,
643
+ nonce,
644
+ true,
645
+ signature
646
+ );
634
647
 
635
- if (
636
- !SignatureUtils.verifyMessageSignedForAddCustomMetadata(
637
- IEvvm(evvmAddress.current).getEvvmID(),
638
- user,
639
- identity,
640
- value,
641
- nonce,
642
- signature
643
- )
644
- ) revert ErrorsLib.InvalidSignatureOnNameService();
648
+ if (identityDetails[identity].owner != user)
649
+ revert Error.UserIsNotOwnerOfIdentity();
645
650
 
646
- verifyAsyncNonce(user, nonce);
651
+ if (bytes(value).length == 0) revert Error.EmptyCustomMetadata();
647
652
 
648
- makePay(
653
+ requestPay(
649
654
  user,
650
655
  getPriceToAddCustomMetadata(),
651
- priorityFee_EVVM,
652
- nonce_EVVM,
653
- priorityFlag_EVVM,
654
- signature_EVVM
656
+ priorityFeePay,
657
+ noncePay,
658
+ signaturePay
655
659
  );
656
660
 
657
- if (IEvvm(evvmAddress.current).isAddressStaker(msg.sender)) {
661
+ if (core.isAddressStaker(msg.sender)) {
658
662
  makeCaPay(
659
663
  msg.sender,
660
- (5 * IEvvm(evvmAddress.current).getRewardAmount()) +
664
+ (5 * core.getRewardAmount()) +
661
665
  ((getPriceToAddCustomMetadata() * 50) / 100) +
662
- priorityFee_EVVM
666
+ priorityFeePay
663
667
  );
664
668
  }
665
669
 
@@ -668,56 +672,77 @@ contract NameService is AsyncNonce, NameServiceStructs {
668
672
  ] = value;
669
673
 
670
674
  identityDetails[identity].customMetadataMaxSlots++;
671
- markAsyncNonceAsUsed(user, nonce);
672
675
  }
673
676
 
674
677
  /**
675
- * @notice Removes a specific custom metadata entry by key and reorders the array
676
- * @dev Shifts all subsequent metadata entries to fill the gap after removal
677
- * @param user Address of the username owner
678
+ * @notice Removes specific custom metadata entry by key
679
+ * @dev Shifts all subsequent entries to fill gap
680
+ *
681
+ * Removal Process:
682
+ * 1. Validates user owns username
683
+ * 2. Validates key exists in metadata slots
684
+ * 3. Deletes entry at key position
685
+ * 4. Shifts all entries after key down by 1
686
+ * 5. Decrements customMetadataMaxSlots
687
+ *
688
+ * Core.sol Integration:
689
+ * - Validates signature with State.validateAndConsumeNonce
690
+ * - Uses async nonce (isAsyncExec = true)
691
+ * - Hash includes identity + key
692
+ * - Prevents replay attacks
693
+ *
694
+ * Core.sol Integration:
695
+ * - Payment: 10x EVVM reward amount
696
+ * - Paid through requestPay (locks tokens)
697
+ * - Staker reward: 5x reward + priority fee
698
+ * - makeCaPay distributes rewards
699
+ *
700
+ * Array Reordering:
701
+ * - Shifts entries from key+1 to maxSlots
702
+ * - Maintains continuous slot indexing
703
+ * - No gaps in metadata array
704
+ *
705
+ * @param user Address of username owner
678
706
  * @param identity Username to remove metadata from
679
- * @param key Index of the metadata entry to remove
680
- * @param nonce Unique nonce to prevent replay attacks
681
- * @param signature Signature proving authorization for this operation
682
- * @param priorityFee_EVVM Priority fee for faster transaction processing
683
- * @param nonce_EVVM Nonce for the EVVM payment transaction
684
- * @param priorityFlag_EVVM True for async payment, false for sync payment
685
- * @param signature_EVVM Signature for the EVVM payment transaction
707
+ * @param key Index of metadata entry to remove
708
+ * @param nonce Async nonce for replay protection
709
+ * @param signature Signature for Core.sol validation
710
+ * @param priorityFeePay Priority fee for faster processing
711
+ * @param noncePay Nonce for EVVM payment transaction
712
+ * @param signaturePay Signature for EVVM payment
686
713
  */
687
714
  function removeCustomMetadata(
688
715
  address user,
689
716
  string memory identity,
690
717
  uint256 key,
718
+ address originExecutor,
691
719
  uint256 nonce,
692
720
  bytes memory signature,
693
- uint256 priorityFee_EVVM,
694
- uint256 nonce_EVVM,
695
- bool priorityFlag_EVVM,
696
- bytes memory signature_EVVM
697
- ) external onlyOwnerOfIdentity(user, identity) {
698
- if (
699
- !SignatureUtils.verifyMessageSignedForRemoveCustomMetadata(
700
- IEvvm(evvmAddress.current).getEvvmID(),
701
- user,
702
- identity,
703
- key,
704
- nonce,
705
- signature
706
- )
707
- ) revert ErrorsLib.InvalidSignatureOnNameService();
721
+ uint256 priorityFeePay,
722
+ uint256 noncePay,
723
+ bytes memory signaturePay
724
+ ) external {
725
+ core.validateAndConsumeNonce(
726
+ user,
727
+ Hash.hashDataForRemoveCustomMetadata(identity, key),
728
+ originExecutor,
729
+ nonce,
730
+ true,
731
+ signature
732
+ );
708
733
 
709
- verifyAsyncNonce(user, nonce);
734
+ if (identityDetails[identity].owner != user)
735
+ revert Error.UserIsNotOwnerOfIdentity();
710
736
 
711
737
  if (identityDetails[identity].customMetadataMaxSlots <= key)
712
- revert ErrorsLib.InvalidKey();
738
+ revert Error.InvalidKey();
713
739
 
714
- makePay(
740
+ requestPay(
715
741
  user,
716
742
  getPriceToRemoveCustomMetadata(),
717
- priorityFee_EVVM,
718
- nonce_EVVM,
719
- priorityFlag_EVVM,
720
- signature_EVVM
743
+ priorityFeePay,
744
+ noncePay,
745
+ signaturePay
721
746
  );
722
747
 
723
748
  if (identityDetails[identity].customMetadataMaxSlots == key) {
@@ -736,61 +761,84 @@ contract NameService is AsyncNonce, NameServiceStructs {
736
761
  identityDetails[identity].customMetadataMaxSlots
737
762
  ];
738
763
  }
764
+
739
765
  identityDetails[identity].customMetadataMaxSlots--;
740
- markAsyncNonceAsUsed(user, nonce);
741
- if (IEvvm(evvmAddress.current).isAddressStaker(msg.sender)) {
766
+
767
+ if (core.isAddressStaker(msg.sender))
742
768
  makeCaPay(
743
769
  msg.sender,
744
- (5 * IEvvm(evvmAddress.current).getRewardAmount()) +
745
- priorityFee_EVVM
770
+ (5 * core.getRewardAmount()) + priorityFeePay
746
771
  );
747
- }
748
772
  }
749
773
 
750
774
  /**
751
- * @notice Removes all custom metadata entries for a username
752
- * @dev More gas-efficient than removing entries individually
753
- * @param user Address of the username owner
775
+ * @notice Removes all custom metadata entries for username
776
+ * @dev More gas-efficient than removing individually
777
+ *
778
+ * Flush Process:
779
+ * 1. Validates user owns username
780
+ * 2. Validates metadata slots exist (not empty)
781
+ * 3. Calculates cost based on slot count
782
+ * 4. Deletes all metadata entries in loop
783
+ * 5. Resets customMetadataMaxSlots to 0
784
+ *
785
+ * Core.sol Integration:
786
+ * - Validates signature with State.validateAndConsumeNonce
787
+ * - Uses async nonce (isAsyncExec = true)
788
+ * - Hash includes identity only
789
+ * - Prevents replay attacks
790
+ *
791
+ * Core.sol Integration:
792
+ * - Payment: getPriceToFlushCustomMetadata (per slot)
793
+ * - Cost: 10x EVVM reward per metadata entry
794
+ * - Paid through requestPay (locks tokens)
795
+ * - Staker reward: 5x reward per slot + priority
796
+ * - makeCaPay distributes batch rewards
797
+ *
798
+ * Efficiency:
799
+ * - Single transaction for all metadata
800
+ * - Batch pricing for multiple entries
801
+ * - Cheaper than calling removeCustomMetadata N times
802
+ *
803
+ * @param user Address of username owner
754
804
  * @param identity Username to flush all metadata from
755
- * @param nonce Unique nonce to prevent replay attacks
756
- * @param signature Signature proving authorization for this operation
757
- * @param priorityFee_EVVM Priority fee for faster transaction processing
758
- * @param nonce_EVVM Nonce for the EVVM payment transaction
759
- * @param priorityFlag_EVVM True for async payment, false for sync payment
760
- * @param signature_EVVM Signature for the EVVM payment transaction
805
+ * @param nonce Async nonce for replay protection
806
+ * @param signature Signature for Core.sol validation
807
+ * @param priorityFeePay Priority fee for faster processing
808
+ * @param noncePay Nonce for EVVM payment transaction
809
+ * @param signaturePay Signature for EVVM payment
761
810
  */
762
811
  function flushCustomMetadata(
763
812
  address user,
764
813
  string memory identity,
814
+ address originExecutor,
765
815
  uint256 nonce,
766
816
  bytes memory signature,
767
- uint256 priorityFee_EVVM,
768
- uint256 nonce_EVVM,
769
- bool priorityFlag_EVVM,
770
- bytes memory signature_EVVM
771
- ) external onlyOwnerOfIdentity(user, identity) {
772
- if (
773
- !SignatureUtils.verifyMessageSignedForFlushCustomMetadata(
774
- IEvvm(evvmAddress.current).getEvvmID(),
775
- user,
776
- identity,
777
- nonce,
778
- signature
779
- )
780
- ) revert ErrorsLib.InvalidSignatureOnNameService();
817
+ uint256 priorityFeePay,
818
+ uint256 noncePay,
819
+ bytes memory signaturePay
820
+ ) external {
821
+ core.validateAndConsumeNonce(
822
+ user,
823
+ Hash.hashDataForFlushCustomMetadata(identity),
824
+ originExecutor,
825
+ nonce,
826
+ true,
827
+ signature
828
+ );
781
829
 
782
- verifyAsyncNonce(user, nonce);
830
+ if (identityDetails[identity].owner != user)
831
+ revert Error.UserIsNotOwnerOfIdentity();
783
832
 
784
833
  if (identityDetails[identity].customMetadataMaxSlots == 0)
785
- revert ErrorsLib.EmptyCustomMetadata();
834
+ revert Error.EmptyCustomMetadata();
786
835
 
787
- makePay(
836
+ requestPay(
788
837
  user,
789
838
  getPriceToFlushCustomMetadata(identity),
790
- priorityFee_EVVM,
791
- nonce_EVVM,
792
- priorityFlag_EVVM,
793
- signature_EVVM
839
+ priorityFeePay,
840
+ noncePay,
841
+ signaturePay
794
842
  );
795
843
 
796
844
  for (
@@ -801,65 +849,96 @@ contract NameService is AsyncNonce, NameServiceStructs {
801
849
  delete identityCustomMetadata[identity][i];
802
850
  }
803
851
 
804
- if (IEvvm(evvmAddress.current).isAddressStaker(msg.sender)) {
852
+ if (core.isAddressStaker(msg.sender)) {
805
853
  makeCaPay(
806
854
  msg.sender,
807
- ((5 * IEvvm(evvmAddress.current).getRewardAmount()) *
855
+ ((5 * core.getRewardAmount()) *
808
856
  identityDetails[identity].customMetadataMaxSlots) +
809
- priorityFee_EVVM
857
+ priorityFeePay
810
858
  );
811
859
  }
812
860
 
813
861
  identityDetails[identity].customMetadataMaxSlots = 0;
814
- markAsyncNonceAsUsed(user, nonce);
815
862
  }
816
863
 
817
864
  /**
818
- * @notice Completely removes a username registration and all associated data
819
- * @dev Deletes the username, all custom metadata, and makes it available for re-registration
820
- * @param user Address of the username owner
821
- * @param username Username to completely remove from the system
822
- * @param nonce Unique nonce to prevent replay attacks
823
- * @param signature Signature proving authorization for this operation
824
- * @param priorityFee_EVVM Priority fee for faster transaction processing
825
- * @param nonce_EVVM Nonce for the EVVM payment transaction
826
- * @param priorityFlag_EVVM True for async payment, false for sync payment
827
- * @param signature_EVVM Signature for the EVVM payment transaction
865
+ * @notice Completely removes username and all data
866
+ * @dev Deletes username, metadata, makes available for
867
+ * re-registration
868
+ *
869
+ * Flush Process:
870
+ * 1. Validates user owns username
871
+ * 2. Validates not expired (must be active)
872
+ * 3. Validates is actual username (not temp hash)
873
+ * 4. Calculates cost based on metadata + username
874
+ * 5. Deletes all metadata entries
875
+ * 6. Resets username to default state
876
+ * 7. Preserves offerMaxSlots history
877
+ *
878
+ * Core.sol Integration:
879
+ * - Validates signature with State.validateAndConsumeNonce
880
+ * - Uses async nonce (isAsyncExec = true)
881
+ * - Hash includes username only
882
+ * - Prevents replay attacks
883
+ *
884
+ * Core.sol Integration:
885
+ * - Payment: getPriceToFlushUsername
886
+ * - Cost: Base + (10x reward per metadata slot)
887
+ * - Paid through requestPay (locks tokens)
888
+ * - Staker reward: 5x reward per slot + priority
889
+ * - makeCaPay distributes to caller
890
+ *
891
+ * Cleanup:
892
+ * - Deletes all custom metadata slots
893
+ * - Sets owner to address(0)
894
+ * - Sets expirationDate to 0
895
+ * - Resets customMetadataMaxSlots to 0
896
+ * - Keeps offerMaxSlots for history
897
+ * - Sets flagNotAUsername to 0x00
898
+ * - Username becomes available for re-registration
899
+ *
900
+ * @param user Address of username owner
901
+ * @param username Username to completely remove
902
+ * @param nonce Async nonce for replay protection
903
+ * @param signature Signature for Core.sol validation
904
+ * @param priorityFeePay Priority fee for faster processing
905
+ * @param noncePay Nonce for EVVM payment transaction
906
+ * @param signaturePay Signature for EVVM payment
828
907
  */
829
908
  function flushUsername(
830
909
  address user,
831
910
  string memory username,
911
+ address originExecutor,
832
912
  uint256 nonce,
833
913
  bytes memory signature,
834
- uint256 priorityFee_EVVM,
835
- uint256 nonce_EVVM,
836
- bool priorityFlag_EVVM,
837
- bytes memory signature_EVVM
838
- ) external onlyOwnerOfIdentity(user, username) {
839
- if (
840
- block.timestamp >= identityDetails[username].expireDate ||
841
- identityDetails[username].flagNotAUsername == 0x01
842
- ) revert ErrorsLib.FlushUsernameVerificationFailed();
914
+ uint256 priorityFeePay,
915
+ uint256 noncePay,
916
+ bytes memory signaturePay
917
+ ) external {
918
+ core.validateAndConsumeNonce(
919
+ user,
920
+ Hash.hashDataForFlushUsername(username),
921
+ originExecutor,
922
+ nonce,
923
+ true,
924
+ signature
925
+ );
843
926
 
844
- if (
845
- !SignatureUtils.verifyMessageSignedForFlushUsername(
846
- IEvvm(evvmAddress.current).getEvvmID(),
847
- user,
848
- username,
849
- nonce,
850
- signature
851
- )
852
- ) revert ErrorsLib.InvalidSignatureOnNameService();
927
+ if (identityDetails[username].owner != user)
928
+ revert Error.UserIsNotOwnerOfIdentity();
929
+
930
+ if (block.timestamp >= identityDetails[username].expirationDate)
931
+ revert Error.OwnershipExpired();
853
932
 
854
- verifyAsyncNonce(user, nonce);
933
+ if (identityDetails[username].flagNotAUsername == 0x01)
934
+ revert Error.IdentityIsNotAUsername();
855
935
 
856
- makePay(
936
+ requestPay(
857
937
  user,
858
938
  getPriceToFlushUsername(username),
859
- priorityFee_EVVM,
860
- nonce_EVVM,
861
- priorityFlag_EVVM,
862
- signature_EVVM
939
+ priorityFeePay,
940
+ noncePay,
941
+ signaturePay
863
942
  );
864
943
 
865
944
  for (
@@ -872,32 +951,30 @@ contract NameService is AsyncNonce, NameServiceStructs {
872
951
 
873
952
  makeCaPay(
874
953
  msg.sender,
875
- ((5 * IEvvm(evvmAddress.current).getRewardAmount()) *
954
+ ((5 * core.getRewardAmount()) *
876
955
  identityDetails[username].customMetadataMaxSlots) +
877
- priorityFee_EVVM
956
+ priorityFeePay
878
957
  );
879
958
 
880
- identityDetails[username] = IdentityBaseMetadata({
959
+ identityDetails[username] = Structs.IdentityBaseMetadata({
881
960
  owner: address(0),
882
- expireDate: 0,
961
+ expirationDate: 0,
883
962
  customMetadataMaxSlots: 0,
884
963
  offerMaxSlots: identityDetails[username].offerMaxSlots,
885
964
  flagNotAUsername: 0x00
886
965
  });
887
- markAsyncNonceAsUsed(user, nonce);
888
966
  }
889
967
 
890
- //█ Administrative Functions with Time-Delayed Governance ████████████████████████████████████
968
+ //█ Administrative Functions ████████████████████████████████████████████████████████████████████████
891
969
 
892
970
  /**
893
- * @notice Proposes a new admin address with 1-day time delay
894
- * @dev Part of the time-delayed governance system for admin changes
971
+ * @notice Proposes new admin address with 1-day delay
972
+ * @dev Time-delayed governance system for admin changes
895
973
  * @param _adminToPropose Address of the proposed new admin
896
974
  */
897
975
  function proposeAdmin(address _adminToPropose) public onlyAdmin {
898
- if (_adminToPropose == address(0) || _adminToPropose == admin.current) {
899
- revert();
900
- }
976
+ if (_adminToPropose == address(0) || _adminToPropose == admin.current)
977
+ revert Error.InvalidAdminProposal();
901
978
 
902
979
  admin.proposal = _adminToPropose;
903
980
  admin.timeToAccept = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
@@ -917,14 +994,13 @@ contract NameService is AsyncNonce, NameServiceStructs {
917
994
  * @dev Can only be called by the proposed admin after the time delay has passed
918
995
  */
919
996
  function acceptProposeAdmin() public {
920
- if (admin.proposal != msg.sender) {
921
- revert();
922
- }
923
- if (block.timestamp < admin.timeToAccept) {
924
- revert();
925
- }
997
+ if (admin.proposal != msg.sender)
998
+ revert Error.SenderIsNotProposedAdmin();
999
+
1000
+ if (block.timestamp < admin.timeToAccept)
1001
+ revert Error.LockTimeNotExpired();
926
1002
 
927
- admin = AddressTypeProposal({
1003
+ admin = ProposalStructs.AddressTypeProposal({
928
1004
  current: admin.proposal,
929
1005
  proposal: address(0),
930
1006
  timeToAccept: 0
@@ -938,17 +1014,14 @@ contract NameService is AsyncNonce, NameServiceStructs {
938
1014
  */
939
1015
  function proposeWithdrawPrincipalTokens(uint256 _amount) public onlyAdmin {
940
1016
  if (
941
- IEvvm(evvmAddress.current).getBalance(
942
- address(this),
943
- PRINCIPAL_TOKEN_ADDRESS
944
- ) -
1017
+ core.getBalance(address(this), core.getPrincipalTokenAddress()) -
945
1018
  (5083 +
946
- IEvvm(evvmAddress.current).getRewardAmount() +
1019
+ core.getRewardAmount() +
947
1020
  principalTokenTokenLockedForWithdrawOffers) <
948
1021
  _amount ||
949
1022
  _amount == 0
950
1023
  ) {
951
- revert();
1024
+ revert Error.InvalidWithdrawAmount();
952
1025
  }
953
1026
 
954
1027
  amountToWithdrawTokens.proposal = _amount;
@@ -971,9 +1044,8 @@ contract NameService is AsyncNonce, NameServiceStructs {
971
1044
  * @dev Can only be called after the time delay has passed
972
1045
  */
973
1046
  function claimWithdrawPrincipalTokens() public onlyAdmin {
974
- if (block.timestamp < amountToWithdrawTokens.timeToAccept) {
975
- revert();
976
- }
1047
+ if (block.timestamp < amountToWithdrawTokens.timeToAccept)
1048
+ revert Error.LockTimeNotExpired();
977
1049
 
978
1050
  makeCaPay(admin.current, amountToWithdrawTokens.proposal);
979
1051
 
@@ -989,11 +1061,10 @@ contract NameService is AsyncNonce, NameServiceStructs {
989
1061
  function proposeChangeEvvmAddress(
990
1062
  address _newEvvmAddress
991
1063
  ) public onlyAdmin {
992
- if (_newEvvmAddress == address(0)) {
993
- revert();
994
- }
995
- evvmAddress.proposal = _newEvvmAddress;
996
- evvmAddress.timeToAccept = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
1064
+ if (_newEvvmAddress == address(0)) revert Error.InvalidEvvmAddress();
1065
+
1066
+ coreAddress.proposal = _newEvvmAddress;
1067
+ coreAddress.timeToAccept = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
997
1068
  }
998
1069
 
999
1070
  /**
@@ -1001,8 +1072,8 @@ contract NameService is AsyncNonce, NameServiceStructs {
1001
1072
  * @dev Only the current admin can cancel pending proposals
1002
1073
  */
1003
1074
  function cancelChangeEvvmAddress() public onlyAdmin {
1004
- evvmAddress.proposal = address(0);
1005
- evvmAddress.timeToAccept = 0;
1075
+ coreAddress.proposal = address(0);
1076
+ coreAddress.timeToAccept = 0;
1006
1077
  }
1007
1078
 
1008
1079
  /**
@@ -1010,16 +1081,16 @@ contract NameService is AsyncNonce, NameServiceStructs {
1010
1081
  * @dev Can only be called after the time delay has passed
1011
1082
  */
1012
1083
  function acceptChangeEvvmAddress() public onlyAdmin {
1013
- if (block.timestamp < evvmAddress.timeToAccept) {
1014
- revert();
1015
- }
1016
- evvmAddress = AddressTypeProposal({
1017
- current: evvmAddress.proposal,
1084
+ if (block.timestamp < coreAddress.timeToAccept)
1085
+ revert Error.LockTimeNotExpired();
1086
+
1087
+ coreAddress = ProposalStructs.AddressTypeProposal({
1088
+ current: coreAddress.proposal,
1018
1089
  proposal: address(0),
1019
1090
  timeToAccept: 0
1020
1091
  });
1021
1092
 
1022
- evvm = IEvvm(evvmAddress.current);
1093
+ core = Core(coreAddress.current);
1023
1094
  }
1024
1095
 
1025
1096
  //█ Utility Functions ████████████████████████████████████████████████████████████████████████
@@ -1033,27 +1104,26 @@ contract NameService is AsyncNonce, NameServiceStructs {
1033
1104
  * @param amount Amount to pay in Principal Tokens
1034
1105
  * @param priorityFee Additional priority fee for faster processing
1035
1106
  * @param nonce Nonce for the EVVM transaction
1036
- * @param priorityFlag True for async payment, false for sync payment
1037
1107
  * @param signature Signature authorizing the payment
1108
+ * @dev all evvm nonce execution are async (true)
1038
1109
  */
1039
- function makePay(
1110
+ function requestPay(
1040
1111
  address user,
1041
1112
  uint256 amount,
1042
1113
  uint256 priorityFee,
1043
1114
  uint256 nonce,
1044
- bool priorityFlag,
1045
1115
  bytes memory signature
1046
1116
  ) internal {
1047
- IEvvm(evvmAddress.current).pay(
1117
+ core.pay(
1048
1118
  user,
1049
1119
  address(this),
1050
1120
  "",
1051
- PRINCIPAL_TOKEN_ADDRESS,
1121
+ core.getPrincipalTokenAddress(),
1052
1122
  amount,
1053
1123
  priorityFee,
1054
- nonce,
1055
- priorityFlag,
1056
1124
  address(this),
1125
+ nonce,
1126
+ true,
1057
1127
  signature
1058
1128
  );
1059
1129
  }
@@ -1065,7 +1135,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
1065
1135
  * @param amount Amount of Principal Tokens to distribute
1066
1136
  */
1067
1137
  function makeCaPay(address user, uint256 amount) internal {
1068
- IEvvm(evvmAddress.current).caPay(user, PRINCIPAL_TOKEN_ADDRESS, amount);
1138
+ core.caPay(user, core.getPrincipalTokenAddress(), amount);
1069
1139
  }
1070
1140
 
1071
1141
  //█ Username Hashing Functions ███████████████████████████████████████████████████████████████████
@@ -1100,14 +1170,14 @@ contract NameService is AsyncNonce, NameServiceStructs {
1100
1170
  if (identityDetails[_identity].flagNotAUsername == 0x01) {
1101
1171
  if (
1102
1172
  identityDetails[_identity].owner == address(0) ||
1103
- identityDetails[_identity].expireDate != 0
1173
+ identityDetails[_identity].expirationDate != 0
1104
1174
  ) {
1105
1175
  return false;
1106
1176
  } else {
1107
1177
  return true;
1108
1178
  }
1109
1179
  } else {
1110
- if (identityDetails[_identity].expireDate == 0) {
1180
+ if (identityDetails[_identity].expirationDate == 0) {
1111
1181
  return false;
1112
1182
  } else {
1113
1183
  return true;
@@ -1127,14 +1197,14 @@ contract NameService is AsyncNonce, NameServiceStructs {
1127
1197
  if (identityDetails[_username].flagNotAUsername == 0x01) {
1128
1198
  if (
1129
1199
  identityDetails[_username].owner == address(0) ||
1130
- identityDetails[_username].expireDate != 0
1200
+ identityDetails[_username].expirationDate != 0
1131
1201
  ) {
1132
1202
  revert();
1133
1203
  } else {
1134
1204
  return true;
1135
1205
  }
1136
1206
  } else {
1137
- if (identityDetails[_username].expireDate == 0) {
1207
+ if (identityDetails[_username].expirationDate == 0) {
1138
1208
  revert();
1139
1209
  } else {
1140
1210
  return true;
@@ -1163,9 +1233,8 @@ contract NameService is AsyncNonce, NameServiceStructs {
1163
1233
  function verifyStrictAndGetOwnerOfIdentity(
1164
1234
  string memory _username
1165
1235
  ) public view returns (address answer) {
1166
- if (strictVerifyIfIdentityExist(_username)) {
1236
+ if (strictVerifyIfIdentityExist(_username))
1167
1237
  answer = identityDetails[_username].owner;
1168
- }
1169
1238
  }
1170
1239
 
1171
1240
  /**
@@ -1180,15 +1249,15 @@ contract NameService is AsyncNonce, NameServiceStructs {
1180
1249
  function seePriceToRenew(
1181
1250
  string memory _identity
1182
1251
  ) public view returns (uint256 price) {
1183
- if (identityDetails[_identity].expireDate >= block.timestamp) {
1184
- if (usernameOffers[_identity][0].expireDate != 0) {
1252
+ if (identityDetails[_identity].expirationDate >= block.timestamp) {
1253
+ if (usernameOffers[_identity][0].expirationDate != 0) {
1185
1254
  for (
1186
1255
  uint256 i = 0;
1187
1256
  i < identityDetails[_identity].offerMaxSlots;
1188
1257
  i++
1189
1258
  ) {
1190
1259
  if (
1191
- usernameOffers[_identity][i].expireDate >
1260
+ usernameOffers[_identity][i].expirationDate >
1192
1261
  block.timestamp &&
1193
1262
  usernameOffers[_identity][i].offerer != address(0)
1194
1263
  ) {
@@ -1201,14 +1270,14 @@ contract NameService is AsyncNonce, NameServiceStructs {
1201
1270
  if (price == 0) {
1202
1271
  price = 500 * 10 ** 18;
1203
1272
  } else {
1204
- uint256 principalTokenReward = IEvvm(evvmAddress.current)
1205
- .getRewardAmount();
1273
+ uint256 principalTokenReward = core.getRewardAmount();
1274
+
1206
1275
  price = ((price * 5) / 1000) > (500000 * principalTokenReward)
1207
1276
  ? (500000 * principalTokenReward)
1208
1277
  : ((price * 5) / 1000);
1209
1278
  }
1210
1279
  } else {
1211
- price = 500_000 * IEvvm(evvmAddress.current).getRewardAmount();
1280
+ price = 500_000 * core.getRewardAmount();
1212
1281
  }
1213
1282
  }
1214
1283
 
@@ -1218,7 +1287,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
1218
1287
  * @return price Cost in Principal Tokens (10x current reward amount)
1219
1288
  */
1220
1289
  function getPriceToAddCustomMetadata() public view returns (uint256 price) {
1221
- price = 10 * IEvvm(evvmAddress.current).getRewardAmount();
1290
+ price = 10 * core.getRewardAmount();
1222
1291
  }
1223
1292
 
1224
1293
  /**
@@ -1231,7 +1300,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
1231
1300
  view
1232
1301
  returns (uint256 price)
1233
1302
  {
1234
- price = 10 * IEvvm(evvmAddress.current).getRewardAmount();
1303
+ price = 10 * core.getRewardAmount();
1235
1304
  }
1236
1305
 
1237
1306
  /**
@@ -1244,7 +1313,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
1244
1313
  string memory _identity
1245
1314
  ) public view returns (uint256 price) {
1246
1315
  price =
1247
- (10 * IEvvm(evvmAddress.current).getRewardAmount()) *
1316
+ (10 * core.getRewardAmount()) *
1248
1317
  identityDetails[_identity].customMetadataMaxSlots;
1249
1318
  }
1250
1319
 
@@ -1258,9 +1327,9 @@ contract NameService is AsyncNonce, NameServiceStructs {
1258
1327
  string memory _identity
1259
1328
  ) public view returns (uint256 price) {
1260
1329
  price =
1261
- ((10 * IEvvm(evvmAddress.current).getRewardAmount()) *
1330
+ ((10 * core.getRewardAmount()) *
1262
1331
  identityDetails[_identity].customMetadataMaxSlots) +
1263
- IEvvm(evvmAddress.current).getRewardAmount();
1332
+ core.getRewardAmount();
1264
1333
  }
1265
1334
 
1266
1335
  //█ Identity Availability Functions ██████████████████████████████████████████████████████████████
@@ -1274,11 +1343,11 @@ contract NameService is AsyncNonce, NameServiceStructs {
1274
1343
  function isUsernameAvailable(
1275
1344
  string memory _username
1276
1345
  ) public view returns (bool) {
1277
- if (identityDetails[_username].expireDate == 0) {
1346
+ if (identityDetails[_username].expirationDate == 0) {
1278
1347
  return true;
1279
1348
  } else {
1280
1349
  return
1281
- identityDetails[_username].expireDate + 60 days <
1350
+ identityDetails[_username].expirationDate + 60 days <
1282
1351
  block.timestamp;
1283
1352
  }
1284
1353
  }
@@ -1294,7 +1363,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
1294
1363
  ) public view returns (address, uint256) {
1295
1364
  return (
1296
1365
  identityDetails[_username].owner,
1297
- identityDetails[_username].expireDate
1366
+ identityDetails[_username].expirationDate
1298
1367
  );
1299
1368
  }
1300
1369
 
@@ -1368,8 +1437,10 @@ contract NameService is AsyncNonce, NameServiceStructs {
1368
1437
  */
1369
1438
  function getOffersOfUsername(
1370
1439
  string memory _username
1371
- ) public view returns (OfferMetadata[] memory offers) {
1372
- offers = new OfferMetadata[](identityDetails[_username].offerMaxSlots);
1440
+ ) public view returns (Structs.OfferMetadata[] memory offers) {
1441
+ offers = new Structs.OfferMetadata[](
1442
+ identityDetails[_username].offerMaxSlots
1443
+ );
1373
1444
 
1374
1445
  for (uint256 i = 0; i < identityDetails[_username].offerMaxSlots; i++) {
1375
1446
  offers[i] = usernameOffers[_username][i];
@@ -1386,7 +1457,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
1386
1457
  function getSingleOfferOfUsername(
1387
1458
  string memory _username,
1388
1459
  uint256 _offerID
1389
- ) public view returns (OfferMetadata memory offer) {
1460
+ ) public view returns (Structs.OfferMetadata memory offer) {
1390
1461
  return usernameOffers[_username][_offerID];
1391
1462
  }
1392
1463
 
@@ -1401,7 +1472,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
1401
1472
  ) public view returns (uint256 length) {
1402
1473
  do {
1403
1474
  length++;
1404
- } while (usernameOffers[_username][length].expireDate != 0);
1475
+ } while (usernameOffers[_username][length].expirationDate != 0);
1405
1476
  }
1406
1477
 
1407
1478
  /**
@@ -1413,7 +1484,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
1413
1484
  function getExpireDateOfIdentity(
1414
1485
  string memory _identity
1415
1486
  ) public view returns (uint256) {
1416
- return identityDetails[_identity].expireDate;
1487
+ return identityDetails[_identity].expirationDate;
1417
1488
  }
1418
1489
 
1419
1490
  /**
@@ -1430,7 +1501,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
1430
1501
  return
1431
1502
  identityDetails[username].offerMaxSlots > 0
1432
1503
  ? seePriceToRenew(username)
1433
- : IEvvm(evvmAddress.current).getRewardAmount() * 100;
1504
+ : core.getRewardAmount() * 100;
1434
1505
  }
1435
1506
 
1436
1507
  //█ Administrative Getters ███████████████████████████████████████████████████████████████████████
@@ -1483,13 +1554,22 @@ contract NameService is AsyncNonce, NameServiceStructs {
1483
1554
  );
1484
1555
  }
1485
1556
 
1557
+ /**
1558
+ * @notice Gets the unique identifier string for this EVVM instance
1559
+ * @dev Returns the EvvmID used for distinguishing different EVVM deployments
1560
+ * @return Unique EvvmID string
1561
+ */
1562
+ function getEvvmID() external view returns (uint256) {
1563
+ return core.getEvvmID();
1564
+ }
1565
+
1486
1566
  /**
1487
1567
  * @notice Gets the current EVVM contract address
1488
1568
  * @dev Returns the address of the EVVM contract used for payment processing
1489
1569
  * @return The current EVVM contract address
1490
1570
  */
1491
- function getEvvmAddress() public view returns (address) {
1492
- return evvmAddress.current;
1571
+ function getCoreAddress() public view returns (address) {
1572
+ return coreAddress.current;
1493
1573
  }
1494
1574
 
1495
1575
  /**
@@ -1499,7 +1579,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
1499
1579
  * @return proposalEvvmAddress Proposed new EVVM address (if any)
1500
1580
  * @return timeToAcceptEvvmAddress Timestamp when proposal can be accepted
1501
1581
  */
1502
- function getEvvmAddressFullDetails()
1582
+ function getCoreAddressFullDetails()
1503
1583
  public
1504
1584
  view
1505
1585
  returns (
@@ -1509,9 +1589,9 @@ contract NameService is AsyncNonce, NameServiceStructs {
1509
1589
  )
1510
1590
  {
1511
1591
  return (
1512
- evvmAddress.current,
1513
- evvmAddress.proposal,
1514
- evvmAddress.timeToAccept
1592
+ coreAddress.current,
1593
+ coreAddress.proposal,
1594
+ coreAddress.timeToAccept
1515
1595
  );
1516
1596
  }
1517
1597
  }