@evvm/testnet-contracts 2.3.0 → 3.0.1
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.
- package/README.md +44 -24
- package/contracts/core/Core.sol +1392 -0
- package/contracts/core/lib/CoreStorage.sol +171 -0
- package/contracts/nameService/NameService.sol +613 -543
- package/contracts/nameService/lib/IdentityValidation.sol +15 -21
- package/contracts/p2pSwap/P2PSwap.sol +258 -145
- package/contracts/staking/Estimator.sol +25 -44
- package/contracts/staking/Staking.sol +284 -262
- package/contracts/treasury/Treasury.sol +40 -47
- package/contracts/treasuryTwoChains/TreasuryExternalChainStation.sol +585 -198
- package/contracts/treasuryTwoChains/TreasuryHostChainStation.sol +425 -174
- package/contracts/treasuryTwoChains/lib/PayloadUtils.sol +2 -4
- package/interfaces/{IEvvm.sol → ICore.sol} +58 -25
- package/interfaces/IEstimator.sol +1 -1
- package/interfaces/INameService.sol +46 -49
- package/interfaces/IP2PSwap.sol +16 -17
- package/interfaces/IStaking.sol +21 -17
- package/interfaces/ITreasury.sol +2 -1
- package/interfaces/ITreasuryExternalChainStation.sol +15 -9
- package/interfaces/ITreasuryHostChainStation.sol +14 -11
- package/interfaces/IUserValidator.sol +6 -0
- package/library/Erc191TestBuilder.sol +336 -471
- package/library/EvvmService.sol +27 -71
- package/library/errors/CoreError.sol +116 -0
- package/library/errors/CrossChainTreasuryError.sol +36 -0
- package/library/errors/NameServiceError.sol +79 -0
- package/library/errors/StakingError.sol +79 -0
- package/{contracts/treasury/lib/ErrorsLib.sol → library/errors/TreasuryError.sol} +9 -17
- package/library/structs/CoreStructs.sol +146 -0
- package/library/structs/ExternalChainStationStructs.sol +92 -0
- package/library/structs/HostChainStationStructs.sol +77 -0
- package/library/structs/NameServiceStructs.sol +47 -0
- package/library/structs/P2PSwapStructs.sol +127 -0
- package/library/structs/StakingStructs.sol +67 -0
- package/library/utils/AdvancedStrings.sol +62 -44
- package/library/utils/CAUtils.sol +29 -0
- package/library/utils/governance/Admin.sol +66 -0
- package/library/utils/governance/ProposalStructs.sol +49 -0
- package/library/utils/service/CoreExecution.sol +158 -0
- package/library/utils/service/StakingServiceUtils.sol +20 -37
- package/library/utils/signature/CoreHashUtils.sol +73 -0
- package/library/utils/signature/NameServiceHashUtils.sol +156 -0
- package/library/utils/signature/P2PSwapHashUtils.sol +65 -0
- package/library/utils/signature/StakingHashUtils.sol +41 -0
- package/library/utils/signature/TreasuryCrossChainHashUtils.sol +40 -0
- package/package.json +1 -1
- package/contracts/evvm/Evvm.sol +0 -1300
- package/contracts/evvm/lib/ErrorsLib.sol +0 -131
- package/contracts/evvm/lib/EvvmStorage.sol +0 -217
- package/contracts/evvm/lib/EvvmStructs.sol +0 -208
- package/contracts/evvm/lib/SignatureUtils.sol +0 -162
- package/contracts/nameService/lib/ErrorsLib.sol +0 -155
- package/contracts/nameService/lib/NameServiceStructs.sol +0 -125
- package/contracts/nameService/lib/SignatureUtils.sol +0 -420
- package/contracts/p2pSwap/lib/P2PSwapStructs.sol +0 -59
- package/contracts/p2pSwap/lib/SignatureUtils.sol +0 -98
- package/contracts/staking/lib/ErrorsLib.sol +0 -98
- package/contracts/staking/lib/SignatureUtils.sol +0 -105
- package/contracts/staking/lib/StakingStructs.sol +0 -106
- package/contracts/treasuryTwoChains/lib/ErrorsLib.sol +0 -48
- package/contracts/treasuryTwoChains/lib/ExternalChainStationStructs.sol +0 -80
- package/contracts/treasuryTwoChains/lib/HostChainStationStructs.sol +0 -87
- package/contracts/treasuryTwoChains/lib/SignatureUtils.sol +0 -79
- package/library/utils/GovernanceUtils.sol +0 -81
- package/library/utils/nonces/AsyncNonce.sol +0 -74
- package/library/utils/nonces/SyncNonce.sol +0 -71
- package/library/utils/service/EvvmPayments.sol +0 -144
|
@@ -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,329 +48,260 @@ 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
|
|
32
|
-
* @dev
|
|
33
|
-
*
|
|
34
|
-
* Core
|
|
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
|
-
|
|
60
|
-
|
|
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
|
|
63
|
+
/// @dev Principal Tokens locked in pending marketplace
|
|
84
64
|
uint256 private principalTokenTokenLockedForWithdrawOffers;
|
|
85
65
|
|
|
86
|
-
/// @dev Nested mapping: username => offer ID => offer
|
|
87
|
-
mapping(string username => mapping(uint256 id => OfferMetadata))
|
|
66
|
+
/// @dev Nested mapping: username => offer ID => offer
|
|
67
|
+
mapping(string username => mapping(uint256 id => Structs.OfferMetadata))
|
|
88
68
|
private usernameOffers;
|
|
89
69
|
|
|
90
|
-
/// @dev Nested mapping: username =>
|
|
70
|
+
/// @dev Nested mapping: username => key => custom value
|
|
91
71
|
mapping(string username => mapping(uint256 numberKey => string customValue))
|
|
92
72
|
private identityCustomMetadata;
|
|
93
73
|
|
|
94
|
-
/// @dev Proposal system for token withdrawal
|
|
95
|
-
UintTypeProposal amountToWithdrawTokens;
|
|
74
|
+
/// @dev Proposal system for token withdrawal with delay
|
|
75
|
+
ProposalStructs.UintTypeProposal amountToWithdrawTokens;
|
|
96
76
|
|
|
97
|
-
/// @dev Proposal system for
|
|
98
|
-
AddressTypeProposal
|
|
77
|
+
/// @dev Proposal system for Core address changes
|
|
78
|
+
ProposalStructs.AddressTypeProposal coreAddress;
|
|
99
79
|
|
|
100
|
-
/// @dev Proposal system for admin address changes
|
|
101
|
-
AddressTypeProposal admin;
|
|
80
|
+
/// @dev Proposal system for admin address changes
|
|
81
|
+
ProposalStructs.AddressTypeProposal admin;
|
|
102
82
|
|
|
103
|
-
/// @dev Mapping from username to
|
|
104
|
-
mapping(string username => IdentityBaseMetadata basicMetadata)
|
|
83
|
+
/// @dev Mapping from username to core metadata
|
|
84
|
+
mapping(string username => Structs.IdentityBaseMetadata basicMetadata)
|
|
105
85
|
private identityDetails;
|
|
106
86
|
|
|
107
|
-
/// @dev
|
|
108
|
-
|
|
87
|
+
/// @dev EVVM contract for payment processing
|
|
88
|
+
Core private core;
|
|
109
89
|
|
|
110
|
-
/// @dev Restricts function access to
|
|
90
|
+
/// @dev Restricts function access to current admin only
|
|
111
91
|
modifier onlyAdmin() {
|
|
112
|
-
if (msg.sender != admin.current) revert
|
|
92
|
+
if (msg.sender != admin.current) revert Error.SenderIsNotAdmin();
|
|
113
93
|
|
|
114
94
|
_;
|
|
115
95
|
}
|
|
116
96
|
|
|
97
|
+
//█ Initialization ████████████████████████████████████████████████████████████████████████
|
|
98
|
+
|
|
117
99
|
/**
|
|
118
|
-
* @notice Initializes the NameService contract
|
|
119
|
-
* @
|
|
120
|
-
* @param
|
|
121
|
-
* @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.
|
|
122
103
|
*/
|
|
123
|
-
constructor(address
|
|
124
|
-
|
|
104
|
+
constructor(address _coreAddress, address _initialOwner) {
|
|
105
|
+
coreAddress.current = _coreAddress;
|
|
125
106
|
admin.current = _initialOwner;
|
|
126
|
-
|
|
107
|
+
core = Core(_coreAddress);
|
|
127
108
|
}
|
|
128
109
|
|
|
110
|
+
//█ Registration Functions ████████████████████████████████████████████████████████████████████████
|
|
111
|
+
|
|
129
112
|
/**
|
|
130
|
-
* @notice
|
|
131
|
-
* @dev
|
|
132
|
-
* @param user
|
|
133
|
-
* @param hashPreRegisteredUsername
|
|
134
|
-
* @param
|
|
135
|
-
* @param
|
|
136
|
-
* @param
|
|
137
|
-
* @param
|
|
138
|
-
* @param
|
|
139
|
-
* @param
|
|
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).
|
|
140
123
|
*/
|
|
141
124
|
function preRegistrationUsername(
|
|
142
125
|
address user,
|
|
143
126
|
bytes32 hashPreRegisteredUsername,
|
|
127
|
+
address originExecutor,
|
|
144
128
|
uint256 nonce,
|
|
145
129
|
bytes memory signature,
|
|
146
|
-
uint256
|
|
147
|
-
uint256
|
|
148
|
-
|
|
149
|
-
bytes memory signature_EVVM
|
|
130
|
+
uint256 priorityFeePay,
|
|
131
|
+
uint256 noncePay,
|
|
132
|
+
bytes memory signaturePay
|
|
150
133
|
) external {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (priorityFee_EVVM > 0)
|
|
164
|
-
requestPay(
|
|
165
|
-
user,
|
|
166
|
-
0,
|
|
167
|
-
priorityFee_EVVM,
|
|
168
|
-
nonce_EVVM,
|
|
169
|
-
priorityFlag_EVVM,
|
|
170
|
-
signature_EVVM
|
|
171
|
-
);
|
|
134
|
+
core.validateAndConsumeNonce(
|
|
135
|
+
user,
|
|
136
|
+
Hash.hashDataForPreRegistrationUsername(hashPreRegisteredUsername),
|
|
137
|
+
originExecutor,
|
|
138
|
+
nonce,
|
|
139
|
+
true,
|
|
140
|
+
signature
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
if (priorityFeePay > 0)
|
|
144
|
+
requestPay(user, 0, priorityFeePay, noncePay, signaturePay);
|
|
172
145
|
|
|
173
146
|
identityDetails[
|
|
174
147
|
string.concat(
|
|
175
148
|
"@",
|
|
176
149
|
AdvancedStrings.bytes32ToString(hashPreRegisteredUsername)
|
|
177
150
|
)
|
|
178
|
-
] = IdentityBaseMetadata({
|
|
151
|
+
] = Structs.IdentityBaseMetadata({
|
|
179
152
|
owner: user,
|
|
180
|
-
|
|
153
|
+
expirationDate: block.timestamp + 30 minutes,
|
|
181
154
|
customMetadataMaxSlots: 0,
|
|
182
155
|
offerMaxSlots: 0,
|
|
183
156
|
flagNotAUsername: 0x01
|
|
184
157
|
});
|
|
185
158
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (evvm.isAddressStaker(msg.sender))
|
|
189
|
-
makeCaPay(msg.sender, evvm.getRewardAmount() + priorityFee_EVVM);
|
|
159
|
+
if (core.isAddressStaker(msg.sender))
|
|
160
|
+
makeCaPay(msg.sender, core.getRewardAmount() + priorityFeePay);
|
|
190
161
|
}
|
|
191
162
|
|
|
192
163
|
/**
|
|
193
|
-
* @notice
|
|
194
|
-
* @dev
|
|
195
|
-
* @param user
|
|
196
|
-
* @param username The
|
|
197
|
-
* @param
|
|
198
|
-
* @param
|
|
199
|
-
* @param
|
|
200
|
-
* @param
|
|
201
|
-
* @param
|
|
202
|
-
* @param
|
|
203
|
-
* @param
|
|
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.
|
|
204
175
|
*/
|
|
205
176
|
function registrationUsername(
|
|
206
177
|
address user,
|
|
207
178
|
string memory username,
|
|
208
|
-
uint256
|
|
179
|
+
uint256 lockNumber,
|
|
180
|
+
address originExecutor,
|
|
209
181
|
uint256 nonce,
|
|
210
182
|
bytes memory signature,
|
|
211
|
-
uint256
|
|
212
|
-
uint256
|
|
213
|
-
|
|
214
|
-
bytes memory signature_EVVM
|
|
183
|
+
uint256 priorityFeePay,
|
|
184
|
+
uint256 noncePay,
|
|
185
|
+
bytes memory signaturePay
|
|
215
186
|
) external {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
)
|
|
225
|
-
) revert ErrorsLib.InvalidSignatureOnNameService();
|
|
187
|
+
core.validateAndConsumeNonce(
|
|
188
|
+
user,
|
|
189
|
+
Hash.hashDataForRegistrationUsername(username, lockNumber),
|
|
190
|
+
originExecutor,
|
|
191
|
+
nonce,
|
|
192
|
+
true,
|
|
193
|
+
signature
|
|
194
|
+
);
|
|
226
195
|
|
|
227
196
|
if (
|
|
228
197
|
admin.current != user &&
|
|
229
198
|
!IdentityValidation.isValidUsername(username)
|
|
230
|
-
) revert
|
|
199
|
+
) revert Error.InvalidUsername();
|
|
231
200
|
|
|
232
201
|
if (!isUsernameAvailable(username))
|
|
233
|
-
revert
|
|
234
|
-
|
|
235
|
-
verifyAsyncNonce(user, nonce);
|
|
202
|
+
revert Error.UsernameAlreadyRegistered();
|
|
236
203
|
|
|
237
204
|
requestPay(
|
|
238
205
|
user,
|
|
239
206
|
getPriceOfRegistration(username),
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
signature_EVVM
|
|
207
|
+
priorityFeePay,
|
|
208
|
+
noncePay,
|
|
209
|
+
signaturePay
|
|
244
210
|
);
|
|
245
211
|
|
|
246
212
|
string memory _key = string.concat(
|
|
247
213
|
"@",
|
|
248
|
-
AdvancedStrings.bytes32ToString(hashUsername(username,
|
|
214
|
+
AdvancedStrings.bytes32ToString(hashUsername(username, lockNumber))
|
|
249
215
|
);
|
|
250
216
|
|
|
251
217
|
if (
|
|
252
218
|
identityDetails[_key].owner != user ||
|
|
253
|
-
identityDetails[_key].
|
|
254
|
-
) revert
|
|
219
|
+
identityDetails[_key].expirationDate > block.timestamp
|
|
220
|
+
) revert Error.PreRegistrationNotValid();
|
|
255
221
|
|
|
256
|
-
identityDetails[username] = IdentityBaseMetadata({
|
|
222
|
+
identityDetails[username] = Structs.IdentityBaseMetadata({
|
|
257
223
|
owner: user,
|
|
258
|
-
|
|
224
|
+
expirationDate: block.timestamp + 366 days,
|
|
259
225
|
customMetadataMaxSlots: 0,
|
|
260
226
|
offerMaxSlots: 0,
|
|
261
227
|
flagNotAUsername: 0x00
|
|
262
228
|
});
|
|
263
229
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
if (evvm.isAddressStaker(msg.sender))
|
|
230
|
+
if (core.isAddressStaker(msg.sender))
|
|
267
231
|
makeCaPay(
|
|
268
232
|
msg.sender,
|
|
269
|
-
(50 *
|
|
233
|
+
(50 * core.getRewardAmount()) + priorityFeePay
|
|
270
234
|
);
|
|
271
235
|
|
|
272
236
|
delete identityDetails[_key];
|
|
273
237
|
}
|
|
274
238
|
|
|
239
|
+
//█ Marketplace Functions ████████████████████████████████████████████████████████████████████████
|
|
240
|
+
|
|
275
241
|
/**
|
|
276
|
-
* @notice
|
|
277
|
-
* @dev
|
|
278
|
-
* @param user
|
|
279
|
-
* @param username
|
|
280
|
-
* @param
|
|
281
|
-
* @param
|
|
282
|
-
* @param
|
|
283
|
-
* @param
|
|
284
|
-
* @param
|
|
285
|
-
* @param
|
|
286
|
-
* @param
|
|
287
|
-
* @param
|
|
288
|
-
* @return offerID
|
|
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.
|
|
289
255
|
*/
|
|
290
256
|
function makeOffer(
|
|
291
257
|
address user,
|
|
292
258
|
string memory username,
|
|
293
|
-
uint256 expireDate,
|
|
294
259
|
uint256 amount,
|
|
260
|
+
uint256 expirationDate,
|
|
261
|
+
address originExecutor,
|
|
295
262
|
uint256 nonce,
|
|
296
263
|
bytes memory signature,
|
|
297
|
-
uint256
|
|
298
|
-
uint256
|
|
299
|
-
|
|
300
|
-
bytes memory signature_EVVM
|
|
264
|
+
uint256 priorityFeePay,
|
|
265
|
+
uint256 noncePay,
|
|
266
|
+
bytes memory signaturePay
|
|
301
267
|
) external returns (uint256 offerID) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
signature
|
|
311
|
-
)
|
|
312
|
-
) revert ErrorsLib.InvalidSignatureOnNameService();
|
|
268
|
+
core.validateAndConsumeNonce(
|
|
269
|
+
user,
|
|
270
|
+
Hash.hashDataForMakeOffer(username, amount, expirationDate),
|
|
271
|
+
originExecutor,
|
|
272
|
+
nonce,
|
|
273
|
+
true,
|
|
274
|
+
signature
|
|
275
|
+
);
|
|
313
276
|
|
|
314
277
|
if (
|
|
315
278
|
identityDetails[username].flagNotAUsername == 0x01 ||
|
|
316
279
|
!verifyIfIdentityExists(username)
|
|
317
|
-
) revert
|
|
280
|
+
) revert Error.InvalidUsername();
|
|
318
281
|
|
|
319
|
-
if (
|
|
320
|
-
revert
|
|
282
|
+
if (expirationDate <= block.timestamp)
|
|
283
|
+
revert Error.CannotBeBeforeCurrentTime();
|
|
321
284
|
|
|
322
|
-
if (amount == 0) revert
|
|
285
|
+
if (amount == 0) revert Error.AmountMustBeGreaterThanZero();
|
|
323
286
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
requestPay(
|
|
327
|
-
user,
|
|
328
|
-
amount,
|
|
329
|
-
priorityFee_EVVM,
|
|
330
|
-
nonce_EVVM,
|
|
331
|
-
priorityFlag_EVVM,
|
|
332
|
-
signature_EVVM
|
|
333
|
-
);
|
|
287
|
+
requestPay(user, amount, priorityFeePay, noncePay, signaturePay);
|
|
334
288
|
|
|
335
289
|
while (usernameOffers[username][offerID].offerer != address(0))
|
|
336
290
|
offerID++;
|
|
337
291
|
|
|
338
292
|
uint256 amountToOffer = ((amount * 995) / 1000);
|
|
339
293
|
|
|
340
|
-
usernameOffers[username][offerID] = OfferMetadata({
|
|
294
|
+
usernameOffers[username][offerID] = Structs.OfferMetadata({
|
|
341
295
|
offerer: user,
|
|
342
|
-
|
|
296
|
+
expirationDate: expirationDate,
|
|
343
297
|
amount: amountToOffer
|
|
344
298
|
});
|
|
345
299
|
|
|
346
300
|
makeCaPay(
|
|
347
301
|
msg.sender,
|
|
348
|
-
|
|
302
|
+
core.getRewardAmount() +
|
|
349
303
|
((amount * 125) / 100_000) +
|
|
350
|
-
|
|
304
|
+
priorityFeePay
|
|
351
305
|
);
|
|
352
306
|
|
|
353
307
|
principalTokenTokenLockedForWithdrawOffers +=
|
|
@@ -359,59 +313,70 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
359
313
|
} else if (identityDetails[username].offerMaxSlots == 0) {
|
|
360
314
|
identityDetails[username].offerMaxSlots++;
|
|
361
315
|
}
|
|
362
|
-
|
|
363
|
-
markAsyncNonceAsUsed(user, nonce);
|
|
364
316
|
}
|
|
365
317
|
|
|
366
318
|
/**
|
|
367
|
-
* @notice Withdraws
|
|
368
|
-
* @dev Can only be called by
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
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
|
|
378
354
|
*/
|
|
379
355
|
function withdrawOffer(
|
|
380
356
|
address user,
|
|
381
357
|
string memory username,
|
|
382
358
|
uint256 offerID,
|
|
359
|
+
address originExecutor,
|
|
383
360
|
uint256 nonce,
|
|
384
361
|
bytes memory signature,
|
|
385
|
-
uint256
|
|
386
|
-
uint256
|
|
387
|
-
|
|
388
|
-
bytes memory signature_EVVM
|
|
362
|
+
uint256 priorityFeePay,
|
|
363
|
+
uint256 noncePay,
|
|
364
|
+
bytes memory signaturePay
|
|
389
365
|
) external {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
)
|
|
399
|
-
) revert ErrorsLib.InvalidSignatureOnNameService();
|
|
366
|
+
core.validateAndConsumeNonce(
|
|
367
|
+
user,
|
|
368
|
+
Hash.hashDataForWithdrawOffer(username, offerID),
|
|
369
|
+
originExecutor,
|
|
370
|
+
nonce,
|
|
371
|
+
true,
|
|
372
|
+
signature
|
|
373
|
+
);
|
|
400
374
|
|
|
401
375
|
if (usernameOffers[username][offerID].offerer != user)
|
|
402
|
-
revert
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
if (priorityFee_EVVM > 0)
|
|
407
|
-
requestPay(
|
|
408
|
-
user,
|
|
409
|
-
0,
|
|
410
|
-
priorityFee_EVVM,
|
|
411
|
-
nonce_EVVM,
|
|
412
|
-
priorityFlag_EVVM,
|
|
413
|
-
signature_EVVM
|
|
414
|
-
);
|
|
376
|
+
revert Error.UserIsNotOwnerOfOffer();
|
|
377
|
+
|
|
378
|
+
if (priorityFeePay > 0)
|
|
379
|
+
requestPay(user, 0, priorityFeePay, noncePay, signaturePay);
|
|
415
380
|
|
|
416
381
|
makeCaPay(user, usernameOffers[username][offerID].amount);
|
|
417
382
|
|
|
@@ -419,72 +384,91 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
419
384
|
|
|
420
385
|
makeCaPay(
|
|
421
386
|
msg.sender,
|
|
422
|
-
|
|
387
|
+
core.getRewardAmount() +
|
|
423
388
|
((usernameOffers[username][offerID].amount * 1) / 796) +
|
|
424
|
-
|
|
389
|
+
priorityFeePay
|
|
425
390
|
);
|
|
426
391
|
|
|
427
392
|
principalTokenTokenLockedForWithdrawOffers -=
|
|
428
393
|
(usernameOffers[username][offerID].amount) +
|
|
429
394
|
(((usernameOffers[username][offerID].amount * 1) / 199) / 4);
|
|
430
|
-
|
|
431
|
-
markAsyncNonceAsUsed(user, nonce);
|
|
432
395
|
}
|
|
433
396
|
|
|
434
397
|
/**
|
|
435
|
-
* @notice Accepts
|
|
436
|
-
* @dev Can only be called by
|
|
437
|
-
*
|
|
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
|
|
438
434
|
* @param username Username being sold
|
|
439
|
-
* @param offerID Unique identifier of
|
|
440
|
-
* @param nonce
|
|
441
|
-
* @param signature Signature
|
|
442
|
-
* @param
|
|
443
|
-
* @param
|
|
444
|
-
* @param
|
|
445
|
-
* @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
|
|
446
441
|
*/
|
|
447
442
|
function acceptOffer(
|
|
448
443
|
address user,
|
|
449
444
|
string memory username,
|
|
450
445
|
uint256 offerID,
|
|
446
|
+
address originExecutor,
|
|
451
447
|
uint256 nonce,
|
|
452
448
|
bytes memory signature,
|
|
453
|
-
uint256
|
|
454
|
-
uint256
|
|
455
|
-
|
|
456
|
-
bytes memory signature_EVVM
|
|
449
|
+
uint256 priorityFeePay,
|
|
450
|
+
uint256 noncePay,
|
|
451
|
+
bytes memory signaturePay
|
|
457
452
|
) external {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
)
|
|
467
|
-
) revert ErrorsLib.InvalidSignatureOnNameService();
|
|
453
|
+
core.validateAndConsumeNonce(
|
|
454
|
+
user,
|
|
455
|
+
Hash.hashDataForAcceptOffer(username, offerID),
|
|
456
|
+
originExecutor,
|
|
457
|
+
nonce,
|
|
458
|
+
true,
|
|
459
|
+
signature
|
|
460
|
+
);
|
|
468
461
|
|
|
469
462
|
if (identityDetails[username].owner != user)
|
|
470
|
-
revert
|
|
463
|
+
revert Error.UserIsNotOwnerOfIdentity();
|
|
471
464
|
|
|
472
465
|
if (
|
|
473
466
|
usernameOffers[username][offerID].offerer == address(0) ||
|
|
474
|
-
usernameOffers[username][offerID].
|
|
475
|
-
) revert
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
if (priorityFee_EVVM > 0) {
|
|
480
|
-
requestPay(
|
|
481
|
-
user,
|
|
482
|
-
0,
|
|
483
|
-
priorityFee_EVVM,
|
|
484
|
-
nonce_EVVM,
|
|
485
|
-
priorityFlag_EVVM,
|
|
486
|
-
signature_EVVM
|
|
487
|
-
);
|
|
467
|
+
usernameOffers[username][offerID].expirationDate < block.timestamp
|
|
468
|
+
) revert Error.OfferInactive();
|
|
469
|
+
|
|
470
|
+
if (priorityFeePay > 0) {
|
|
471
|
+
requestPay(user, 0, priorityFeePay, noncePay, signaturePay);
|
|
488
472
|
}
|
|
489
473
|
|
|
490
474
|
makeCaPay(user, usernameOffers[username][offerID].amount);
|
|
@@ -494,168 +478,192 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
494
478
|
|
|
495
479
|
usernameOffers[username][offerID].offerer = address(0);
|
|
496
480
|
|
|
497
|
-
if (
|
|
481
|
+
if (core.isAddressStaker(msg.sender)) {
|
|
498
482
|
makeCaPay(
|
|
499
483
|
msg.sender,
|
|
500
|
-
(
|
|
484
|
+
(core.getRewardAmount()) +
|
|
501
485
|
(((usernameOffers[username][offerID].amount * 1) / 199) /
|
|
502
486
|
4) +
|
|
503
|
-
|
|
487
|
+
priorityFeePay
|
|
504
488
|
);
|
|
505
489
|
}
|
|
506
490
|
|
|
507
491
|
principalTokenTokenLockedForWithdrawOffers -=
|
|
508
492
|
(usernameOffers[username][offerID].amount) +
|
|
509
493
|
(((usernameOffers[username][offerID].amount * 1) / 199) / 4);
|
|
510
|
-
|
|
511
|
-
markAsyncNonceAsUsed(user, nonce);
|
|
512
494
|
}
|
|
513
495
|
|
|
514
496
|
/**
|
|
515
|
-
* @notice Renews
|
|
516
|
-
* @dev
|
|
497
|
+
* @notice Renews username registration for another year
|
|
498
|
+
* @dev Dynamic pricing based on timing and market demand
|
|
517
499
|
*
|
|
518
500
|
* Pricing Rules:
|
|
519
|
-
* - Free
|
|
520
|
-
* - Variable
|
|
521
|
-
* - Fixed 500,000
|
|
522
|
-
* - Can
|
|
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
|
|
523
517
|
*
|
|
524
|
-
*
|
|
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
|
|
525
524
|
* @param username Username to renew
|
|
526
|
-
* @param nonce
|
|
527
|
-
* @param signature Signature
|
|
528
|
-
* @param
|
|
529
|
-
* @param
|
|
530
|
-
* @param
|
|
531
|
-
* @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
|
|
532
530
|
*/
|
|
533
531
|
function renewUsername(
|
|
534
532
|
address user,
|
|
535
533
|
string memory username,
|
|
534
|
+
address originExecutor,
|
|
536
535
|
uint256 nonce,
|
|
537
536
|
bytes memory signature,
|
|
538
|
-
uint256
|
|
539
|
-
uint256
|
|
540
|
-
|
|
541
|
-
bytes memory signature_EVVM
|
|
537
|
+
uint256 priorityFeePay,
|
|
538
|
+
uint256 noncePay,
|
|
539
|
+
bytes memory signaturePay
|
|
542
540
|
) external {
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
) revert ErrorsLib.InvalidSignatureOnNameService();
|
|
541
|
+
core.validateAndConsumeNonce(
|
|
542
|
+
user,
|
|
543
|
+
Hash.hashDataForRenewUsername(username),
|
|
544
|
+
originExecutor,
|
|
545
|
+
nonce,
|
|
546
|
+
true,
|
|
547
|
+
signature
|
|
548
|
+
);
|
|
552
549
|
|
|
553
550
|
if (identityDetails[username].owner != user)
|
|
554
|
-
revert
|
|
551
|
+
revert Error.UserIsNotOwnerOfIdentity();
|
|
555
552
|
|
|
556
553
|
if (identityDetails[username].flagNotAUsername == 0x01)
|
|
557
|
-
revert
|
|
558
|
-
|
|
559
|
-
if (identityDetails[username].expireDate > block.timestamp + 36500 days)
|
|
560
|
-
revert ErrorsLib.RenewalTimeLimitExceeded();
|
|
554
|
+
revert Error.IdentityIsNotAUsername();
|
|
561
555
|
|
|
562
|
-
|
|
556
|
+
if (
|
|
557
|
+
identityDetails[username].expirationDate >
|
|
558
|
+
block.timestamp + 36500 days
|
|
559
|
+
) revert Error.RenewalTimeLimitExceeded();
|
|
563
560
|
|
|
564
561
|
uint256 priceOfRenew = seePriceToRenew(username);
|
|
565
562
|
|
|
566
563
|
requestPay(
|
|
567
564
|
user,
|
|
568
565
|
priceOfRenew,
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
signature_EVVM
|
|
566
|
+
priorityFeePay,
|
|
567
|
+
noncePay,
|
|
568
|
+
signaturePay
|
|
573
569
|
);
|
|
574
570
|
|
|
575
|
-
if (
|
|
571
|
+
if (core.isAddressStaker(msg.sender)) {
|
|
576
572
|
makeCaPay(
|
|
577
573
|
msg.sender,
|
|
578
|
-
|
|
574
|
+
core.getRewardAmount() +
|
|
579
575
|
((priceOfRenew * 50) / 100) +
|
|
580
|
-
|
|
576
|
+
priorityFeePay
|
|
581
577
|
);
|
|
582
578
|
}
|
|
583
579
|
|
|
584
|
-
identityDetails[username].
|
|
585
|
-
markAsyncNonceAsUsed(user, nonce);
|
|
580
|
+
identityDetails[username].expirationDate += 366 days;
|
|
586
581
|
}
|
|
587
582
|
|
|
583
|
+
//█ Metadata Functions ████████████████████████████████████████████████████████████████████████
|
|
584
|
+
|
|
588
585
|
/**
|
|
589
|
-
* @notice Adds custom metadata to
|
|
590
|
-
* @dev Metadata
|
|
586
|
+
* @notice Adds custom metadata to username using schema format
|
|
587
|
+
* @dev Metadata format: [schema]:[subschema]>[value]
|
|
591
588
|
*
|
|
592
589
|
* Standard Format Examples:
|
|
593
590
|
* - memberOf:>EVVM
|
|
594
591
|
* - socialMedia:x>jistro (Twitter/X handle)
|
|
595
|
-
* - email:dev>jistro[at]evvm.org (
|
|
596
|
-
* - email:callme>contact[at]jistro.xyz (contact
|
|
592
|
+
* - email:dev>jistro[at]evvm.org (dev email)
|
|
593
|
+
* - email:callme>contact[at]jistro.xyz (contact)
|
|
597
594
|
*
|
|
598
595
|
* Schema Guidelines:
|
|
599
596
|
* - Based on https://schema.org/docs/schemas.html
|
|
600
597
|
* - ':' separates schema from subschema
|
|
601
598
|
* - '>' separates metadata from value
|
|
602
|
-
* - Pad
|
|
603
|
-
* - Use "socialMedia" for social networks
|
|
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
|
|
604
607
|
*
|
|
605
|
-
*
|
|
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
|
|
613
|
+
*
|
|
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
|
|
606
620
|
* @param identity Username to add metadata to
|
|
607
|
-
* @param value Metadata string following
|
|
608
|
-
* @param nonce
|
|
609
|
-
* @param signature Signature
|
|
610
|
-
* @param
|
|
611
|
-
* @param
|
|
612
|
-
* @param
|
|
613
|
-
* @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
|
|
614
627
|
*/
|
|
615
628
|
function addCustomMetadata(
|
|
616
629
|
address user,
|
|
617
630
|
string memory identity,
|
|
618
631
|
string memory value,
|
|
632
|
+
address originExecutor,
|
|
619
633
|
uint256 nonce,
|
|
620
634
|
bytes memory signature,
|
|
621
|
-
uint256
|
|
622
|
-
uint256
|
|
623
|
-
|
|
624
|
-
bytes memory signature_EVVM
|
|
635
|
+
uint256 priorityFeePay,
|
|
636
|
+
uint256 noncePay,
|
|
637
|
+
bytes memory signaturePay
|
|
625
638
|
) external {
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
)
|
|
635
|
-
) revert ErrorsLib.InvalidSignatureOnNameService();
|
|
639
|
+
core.validateAndConsumeNonce(
|
|
640
|
+
user,
|
|
641
|
+
Hash.hashDataForAddCustomMetadata(identity, value),
|
|
642
|
+
originExecutor,
|
|
643
|
+
nonce,
|
|
644
|
+
true,
|
|
645
|
+
signature
|
|
646
|
+
);
|
|
636
647
|
|
|
637
648
|
if (identityDetails[identity].owner != user)
|
|
638
|
-
revert
|
|
649
|
+
revert Error.UserIsNotOwnerOfIdentity();
|
|
639
650
|
|
|
640
|
-
if (bytes(value).length == 0) revert
|
|
641
|
-
|
|
642
|
-
verifyAsyncNonce(user, nonce);
|
|
651
|
+
if (bytes(value).length == 0) revert Error.EmptyCustomMetadata();
|
|
643
652
|
|
|
644
653
|
requestPay(
|
|
645
654
|
user,
|
|
646
655
|
getPriceToAddCustomMetadata(),
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
signature_EVVM
|
|
656
|
+
priorityFeePay,
|
|
657
|
+
noncePay,
|
|
658
|
+
signaturePay
|
|
651
659
|
);
|
|
652
660
|
|
|
653
|
-
if (
|
|
661
|
+
if (core.isAddressStaker(msg.sender)) {
|
|
654
662
|
makeCaPay(
|
|
655
663
|
msg.sender,
|
|
656
|
-
(5 *
|
|
664
|
+
(5 * core.getRewardAmount()) +
|
|
657
665
|
((getPriceToAddCustomMetadata() * 50) / 100) +
|
|
658
|
-
|
|
666
|
+
priorityFeePay
|
|
659
667
|
);
|
|
660
668
|
}
|
|
661
669
|
|
|
@@ -664,59 +672,77 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
664
672
|
] = value;
|
|
665
673
|
|
|
666
674
|
identityDetails[identity].customMetadataMaxSlots++;
|
|
667
|
-
markAsyncNonceAsUsed(user, nonce);
|
|
668
675
|
}
|
|
669
676
|
|
|
670
677
|
/**
|
|
671
|
-
* @notice Removes
|
|
672
|
-
* @dev Shifts all subsequent
|
|
673
|
-
*
|
|
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
|
|
674
706
|
* @param identity Username to remove metadata from
|
|
675
|
-
* @param key Index of
|
|
676
|
-
* @param nonce
|
|
677
|
-
* @param signature Signature
|
|
678
|
-
* @param
|
|
679
|
-
* @param
|
|
680
|
-
* @param
|
|
681
|
-
* @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
|
|
682
713
|
*/
|
|
683
714
|
function removeCustomMetadata(
|
|
684
715
|
address user,
|
|
685
716
|
string memory identity,
|
|
686
717
|
uint256 key,
|
|
718
|
+
address originExecutor,
|
|
687
719
|
uint256 nonce,
|
|
688
720
|
bytes memory signature,
|
|
689
|
-
uint256
|
|
690
|
-
uint256
|
|
691
|
-
|
|
692
|
-
bytes memory signature_EVVM
|
|
721
|
+
uint256 priorityFeePay,
|
|
722
|
+
uint256 noncePay,
|
|
723
|
+
bytes memory signaturePay
|
|
693
724
|
) external {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
)
|
|
703
|
-
) revert ErrorsLib.InvalidSignatureOnNameService();
|
|
725
|
+
core.validateAndConsumeNonce(
|
|
726
|
+
user,
|
|
727
|
+
Hash.hashDataForRemoveCustomMetadata(identity, key),
|
|
728
|
+
originExecutor,
|
|
729
|
+
nonce,
|
|
730
|
+
true,
|
|
731
|
+
signature
|
|
732
|
+
);
|
|
704
733
|
|
|
705
734
|
if (identityDetails[identity].owner != user)
|
|
706
|
-
revert
|
|
735
|
+
revert Error.UserIsNotOwnerOfIdentity();
|
|
707
736
|
|
|
708
737
|
if (identityDetails[identity].customMetadataMaxSlots <= key)
|
|
709
|
-
revert
|
|
710
|
-
|
|
711
|
-
verifyAsyncNonce(user, nonce);
|
|
738
|
+
revert Error.InvalidKey();
|
|
712
739
|
|
|
713
740
|
requestPay(
|
|
714
741
|
user,
|
|
715
742
|
getPriceToRemoveCustomMetadata(),
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
signature_EVVM
|
|
743
|
+
priorityFeePay,
|
|
744
|
+
noncePay,
|
|
745
|
+
signaturePay
|
|
720
746
|
);
|
|
721
747
|
|
|
722
748
|
if (identityDetails[identity].customMetadataMaxSlots == key) {
|
|
@@ -738,62 +764,81 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
738
764
|
|
|
739
765
|
identityDetails[identity].customMetadataMaxSlots--;
|
|
740
766
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
if (evvm.isAddressStaker(msg.sender))
|
|
767
|
+
if (core.isAddressStaker(msg.sender))
|
|
744
768
|
makeCaPay(
|
|
745
769
|
msg.sender,
|
|
746
|
-
(5 *
|
|
770
|
+
(5 * core.getRewardAmount()) + priorityFeePay
|
|
747
771
|
);
|
|
748
772
|
}
|
|
749
773
|
|
|
750
774
|
/**
|
|
751
|
-
* @notice Removes all custom metadata entries for
|
|
752
|
-
* @dev More gas-efficient than removing
|
|
753
|
-
*
|
|
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
|
|
756
|
-
* @param signature Signature
|
|
757
|
-
* @param
|
|
758
|
-
* @param
|
|
759
|
-
* @param
|
|
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
|
|
768
|
-
uint256
|
|
769
|
-
|
|
770
|
-
bytes memory signature_EVVM
|
|
817
|
+
uint256 priorityFeePay,
|
|
818
|
+
uint256 noncePay,
|
|
819
|
+
bytes memory signaturePay
|
|
771
820
|
) external {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
) revert ErrorsLib.InvalidSignatureOnNameService();
|
|
821
|
+
core.validateAndConsumeNonce(
|
|
822
|
+
user,
|
|
823
|
+
Hash.hashDataForFlushCustomMetadata(identity),
|
|
824
|
+
originExecutor,
|
|
825
|
+
nonce,
|
|
826
|
+
true,
|
|
827
|
+
signature
|
|
828
|
+
);
|
|
781
829
|
|
|
782
830
|
if (identityDetails[identity].owner != user)
|
|
783
|
-
revert
|
|
831
|
+
revert Error.UserIsNotOwnerOfIdentity();
|
|
784
832
|
|
|
785
833
|
if (identityDetails[identity].customMetadataMaxSlots == 0)
|
|
786
|
-
revert
|
|
787
|
-
|
|
788
|
-
verifyAsyncNonce(user, nonce);
|
|
834
|
+
revert Error.EmptyCustomMetadata();
|
|
789
835
|
|
|
790
836
|
requestPay(
|
|
791
837
|
user,
|
|
792
838
|
getPriceToFlushCustomMetadata(identity),
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
signature_EVVM
|
|
839
|
+
priorityFeePay,
|
|
840
|
+
noncePay,
|
|
841
|
+
signaturePay
|
|
797
842
|
);
|
|
798
843
|
|
|
799
844
|
for (
|
|
@@ -804,69 +849,96 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
804
849
|
delete identityCustomMetadata[identity][i];
|
|
805
850
|
}
|
|
806
851
|
|
|
807
|
-
if (
|
|
852
|
+
if (core.isAddressStaker(msg.sender)) {
|
|
808
853
|
makeCaPay(
|
|
809
854
|
msg.sender,
|
|
810
|
-
((5 *
|
|
855
|
+
((5 * core.getRewardAmount()) *
|
|
811
856
|
identityDetails[identity].customMetadataMaxSlots) +
|
|
812
|
-
|
|
857
|
+
priorityFeePay
|
|
813
858
|
);
|
|
814
859
|
}
|
|
815
860
|
|
|
816
861
|
identityDetails[identity].customMetadataMaxSlots = 0;
|
|
817
|
-
markAsyncNonceAsUsed(user, nonce);
|
|
818
862
|
}
|
|
819
863
|
|
|
820
864
|
/**
|
|
821
|
-
* @notice Completely removes
|
|
822
|
-
* @dev Deletes
|
|
823
|
-
*
|
|
824
|
-
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
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
|
|
831
907
|
*/
|
|
832
908
|
function flushUsername(
|
|
833
909
|
address user,
|
|
834
910
|
string memory username,
|
|
911
|
+
address originExecutor,
|
|
835
912
|
uint256 nonce,
|
|
836
913
|
bytes memory signature,
|
|
837
|
-
uint256
|
|
838
|
-
uint256
|
|
839
|
-
|
|
840
|
-
bytes memory signature_EVVM
|
|
914
|
+
uint256 priorityFeePay,
|
|
915
|
+
uint256 noncePay,
|
|
916
|
+
bytes memory signaturePay
|
|
841
917
|
) external {
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
) revert ErrorsLib.InvalidSignatureOnNameService();
|
|
918
|
+
core.validateAndConsumeNonce(
|
|
919
|
+
user,
|
|
920
|
+
Hash.hashDataForFlushUsername(username),
|
|
921
|
+
originExecutor,
|
|
922
|
+
nonce,
|
|
923
|
+
true,
|
|
924
|
+
signature
|
|
925
|
+
);
|
|
851
926
|
|
|
852
927
|
if (identityDetails[username].owner != user)
|
|
853
|
-
revert
|
|
928
|
+
revert Error.UserIsNotOwnerOfIdentity();
|
|
854
929
|
|
|
855
|
-
if (block.timestamp >= identityDetails[username].
|
|
856
|
-
revert
|
|
930
|
+
if (block.timestamp >= identityDetails[username].expirationDate)
|
|
931
|
+
revert Error.OwnershipExpired();
|
|
857
932
|
|
|
858
933
|
if (identityDetails[username].flagNotAUsername == 0x01)
|
|
859
|
-
revert
|
|
860
|
-
|
|
861
|
-
verifyAsyncNonce(user, nonce);
|
|
934
|
+
revert Error.IdentityIsNotAUsername();
|
|
862
935
|
|
|
863
936
|
requestPay(
|
|
864
937
|
user,
|
|
865
938
|
getPriceToFlushUsername(username),
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
signature_EVVM
|
|
939
|
+
priorityFeePay,
|
|
940
|
+
noncePay,
|
|
941
|
+
signaturePay
|
|
870
942
|
);
|
|
871
943
|
|
|
872
944
|
for (
|
|
@@ -879,31 +951,30 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
879
951
|
|
|
880
952
|
makeCaPay(
|
|
881
953
|
msg.sender,
|
|
882
|
-
((5 *
|
|
954
|
+
((5 * core.getRewardAmount()) *
|
|
883
955
|
identityDetails[username].customMetadataMaxSlots) +
|
|
884
|
-
|
|
956
|
+
priorityFeePay
|
|
885
957
|
);
|
|
886
958
|
|
|
887
|
-
identityDetails[username] = IdentityBaseMetadata({
|
|
959
|
+
identityDetails[username] = Structs.IdentityBaseMetadata({
|
|
888
960
|
owner: address(0),
|
|
889
|
-
|
|
961
|
+
expirationDate: 0,
|
|
890
962
|
customMetadataMaxSlots: 0,
|
|
891
963
|
offerMaxSlots: identityDetails[username].offerMaxSlots,
|
|
892
964
|
flagNotAUsername: 0x00
|
|
893
965
|
});
|
|
894
|
-
markAsyncNonceAsUsed(user, nonce);
|
|
895
966
|
}
|
|
896
967
|
|
|
897
|
-
//█ Administrative Functions
|
|
968
|
+
//█ Administrative Functions ████████████████████████████████████████████████████████████████████████
|
|
898
969
|
|
|
899
970
|
/**
|
|
900
|
-
* @notice Proposes
|
|
901
|
-
* @dev
|
|
971
|
+
* @notice Proposes new admin address with 1-day delay
|
|
972
|
+
* @dev Time-delayed governance system for admin changes
|
|
902
973
|
* @param _adminToPropose Address of the proposed new admin
|
|
903
974
|
*/
|
|
904
975
|
function proposeAdmin(address _adminToPropose) public onlyAdmin {
|
|
905
976
|
if (_adminToPropose == address(0) || _adminToPropose == admin.current)
|
|
906
|
-
revert
|
|
977
|
+
revert Error.InvalidAdminProposal();
|
|
907
978
|
|
|
908
979
|
admin.proposal = _adminToPropose;
|
|
909
980
|
admin.timeToAccept = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
|
|
@@ -924,12 +995,12 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
924
995
|
*/
|
|
925
996
|
function acceptProposeAdmin() public {
|
|
926
997
|
if (admin.proposal != msg.sender)
|
|
927
|
-
revert
|
|
998
|
+
revert Error.SenderIsNotProposedAdmin();
|
|
928
999
|
|
|
929
1000
|
if (block.timestamp < admin.timeToAccept)
|
|
930
|
-
revert
|
|
1001
|
+
revert Error.LockTimeNotExpired();
|
|
931
1002
|
|
|
932
|
-
admin = AddressTypeProposal({
|
|
1003
|
+
admin = ProposalStructs.AddressTypeProposal({
|
|
933
1004
|
current: admin.proposal,
|
|
934
1005
|
proposal: address(0),
|
|
935
1006
|
timeToAccept: 0
|
|
@@ -943,14 +1014,14 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
943
1014
|
*/
|
|
944
1015
|
function proposeWithdrawPrincipalTokens(uint256 _amount) public onlyAdmin {
|
|
945
1016
|
if (
|
|
946
|
-
|
|
1017
|
+
core.getBalance(address(this), core.getPrincipalTokenAddress()) -
|
|
947
1018
|
(5083 +
|
|
948
|
-
|
|
1019
|
+
core.getRewardAmount() +
|
|
949
1020
|
principalTokenTokenLockedForWithdrawOffers) <
|
|
950
1021
|
_amount ||
|
|
951
1022
|
_amount == 0
|
|
952
1023
|
) {
|
|
953
|
-
revert
|
|
1024
|
+
revert Error.InvalidWithdrawAmount();
|
|
954
1025
|
}
|
|
955
1026
|
|
|
956
1027
|
amountToWithdrawTokens.proposal = _amount;
|
|
@@ -974,7 +1045,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
974
1045
|
*/
|
|
975
1046
|
function claimWithdrawPrincipalTokens() public onlyAdmin {
|
|
976
1047
|
if (block.timestamp < amountToWithdrawTokens.timeToAccept)
|
|
977
|
-
revert
|
|
1048
|
+
revert Error.LockTimeNotExpired();
|
|
978
1049
|
|
|
979
1050
|
makeCaPay(admin.current, amountToWithdrawTokens.proposal);
|
|
980
1051
|
|
|
@@ -990,11 +1061,10 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
990
1061
|
function proposeChangeEvvmAddress(
|
|
991
1062
|
address _newEvvmAddress
|
|
992
1063
|
) public onlyAdmin {
|
|
993
|
-
if (_newEvvmAddress == address(0))
|
|
994
|
-
revert ErrorsLib.InvalidEvvmAddress();
|
|
1064
|
+
if (_newEvvmAddress == address(0)) revert Error.InvalidEvvmAddress();
|
|
995
1065
|
|
|
996
|
-
|
|
997
|
-
|
|
1066
|
+
coreAddress.proposal = _newEvvmAddress;
|
|
1067
|
+
coreAddress.timeToAccept = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
|
|
998
1068
|
}
|
|
999
1069
|
|
|
1000
1070
|
/**
|
|
@@ -1002,8 +1072,8 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1002
1072
|
* @dev Only the current admin can cancel pending proposals
|
|
1003
1073
|
*/
|
|
1004
1074
|
function cancelChangeEvvmAddress() public onlyAdmin {
|
|
1005
|
-
|
|
1006
|
-
|
|
1075
|
+
coreAddress.proposal = address(0);
|
|
1076
|
+
coreAddress.timeToAccept = 0;
|
|
1007
1077
|
}
|
|
1008
1078
|
|
|
1009
1079
|
/**
|
|
@@ -1011,16 +1081,16 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1011
1081
|
* @dev Can only be called after the time delay has passed
|
|
1012
1082
|
*/
|
|
1013
1083
|
function acceptChangeEvvmAddress() public onlyAdmin {
|
|
1014
|
-
if (block.timestamp <
|
|
1015
|
-
revert
|
|
1084
|
+
if (block.timestamp < coreAddress.timeToAccept)
|
|
1085
|
+
revert Error.LockTimeNotExpired();
|
|
1016
1086
|
|
|
1017
|
-
|
|
1018
|
-
current:
|
|
1087
|
+
coreAddress = ProposalStructs.AddressTypeProposal({
|
|
1088
|
+
current: coreAddress.proposal,
|
|
1019
1089
|
proposal: address(0),
|
|
1020
1090
|
timeToAccept: 0
|
|
1021
1091
|
});
|
|
1022
1092
|
|
|
1023
|
-
|
|
1093
|
+
core = Core(coreAddress.current);
|
|
1024
1094
|
}
|
|
1025
1095
|
|
|
1026
1096
|
//█ Utility Functions ████████████████████████████████████████████████████████████████████████
|
|
@@ -1034,27 +1104,26 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1034
1104
|
* @param amount Amount to pay in Principal Tokens
|
|
1035
1105
|
* @param priorityFee Additional priority fee for faster processing
|
|
1036
1106
|
* @param nonce Nonce for the EVVM transaction
|
|
1037
|
-
* @param priorityFlag True for async payment, false for sync payment
|
|
1038
1107
|
* @param signature Signature authorizing the payment
|
|
1108
|
+
* @dev all evvm nonce execution are async (true)
|
|
1039
1109
|
*/
|
|
1040
1110
|
function requestPay(
|
|
1041
1111
|
address user,
|
|
1042
1112
|
uint256 amount,
|
|
1043
1113
|
uint256 priorityFee,
|
|
1044
1114
|
uint256 nonce,
|
|
1045
|
-
bool priorityFlag,
|
|
1046
1115
|
bytes memory signature
|
|
1047
1116
|
) internal {
|
|
1048
|
-
|
|
1117
|
+
core.pay(
|
|
1049
1118
|
user,
|
|
1050
1119
|
address(this),
|
|
1051
1120
|
"",
|
|
1052
|
-
|
|
1121
|
+
core.getPrincipalTokenAddress(),
|
|
1053
1122
|
amount,
|
|
1054
1123
|
priorityFee,
|
|
1055
|
-
nonce,
|
|
1056
|
-
priorityFlag,
|
|
1057
1124
|
address(this),
|
|
1125
|
+
nonce,
|
|
1126
|
+
true,
|
|
1058
1127
|
signature
|
|
1059
1128
|
);
|
|
1060
1129
|
}
|
|
@@ -1066,7 +1135,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1066
1135
|
* @param amount Amount of Principal Tokens to distribute
|
|
1067
1136
|
*/
|
|
1068
1137
|
function makeCaPay(address user, uint256 amount) internal {
|
|
1069
|
-
|
|
1138
|
+
core.caPay(user, core.getPrincipalTokenAddress(), amount);
|
|
1070
1139
|
}
|
|
1071
1140
|
|
|
1072
1141
|
//█ Username Hashing Functions ███████████████████████████████████████████████████████████████████
|
|
@@ -1101,14 +1170,14 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1101
1170
|
if (identityDetails[_identity].flagNotAUsername == 0x01) {
|
|
1102
1171
|
if (
|
|
1103
1172
|
identityDetails[_identity].owner == address(0) ||
|
|
1104
|
-
identityDetails[_identity].
|
|
1173
|
+
identityDetails[_identity].expirationDate != 0
|
|
1105
1174
|
) {
|
|
1106
1175
|
return false;
|
|
1107
1176
|
} else {
|
|
1108
1177
|
return true;
|
|
1109
1178
|
}
|
|
1110
1179
|
} else {
|
|
1111
|
-
if (identityDetails[_identity].
|
|
1180
|
+
if (identityDetails[_identity].expirationDate == 0) {
|
|
1112
1181
|
return false;
|
|
1113
1182
|
} else {
|
|
1114
1183
|
return true;
|
|
@@ -1128,14 +1197,14 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1128
1197
|
if (identityDetails[_username].flagNotAUsername == 0x01) {
|
|
1129
1198
|
if (
|
|
1130
1199
|
identityDetails[_username].owner == address(0) ||
|
|
1131
|
-
identityDetails[_username].
|
|
1200
|
+
identityDetails[_username].expirationDate != 0
|
|
1132
1201
|
) {
|
|
1133
1202
|
revert();
|
|
1134
1203
|
} else {
|
|
1135
1204
|
return true;
|
|
1136
1205
|
}
|
|
1137
1206
|
} else {
|
|
1138
|
-
if (identityDetails[_username].
|
|
1207
|
+
if (identityDetails[_username].expirationDate == 0) {
|
|
1139
1208
|
revert();
|
|
1140
1209
|
} else {
|
|
1141
1210
|
return true;
|
|
@@ -1164,9 +1233,8 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1164
1233
|
function verifyStrictAndGetOwnerOfIdentity(
|
|
1165
1234
|
string memory _username
|
|
1166
1235
|
) public view returns (address answer) {
|
|
1167
|
-
if (strictVerifyIfIdentityExist(_username))
|
|
1236
|
+
if (strictVerifyIfIdentityExist(_username))
|
|
1168
1237
|
answer = identityDetails[_username].owner;
|
|
1169
|
-
}
|
|
1170
1238
|
}
|
|
1171
1239
|
|
|
1172
1240
|
/**
|
|
@@ -1181,15 +1249,15 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1181
1249
|
function seePriceToRenew(
|
|
1182
1250
|
string memory _identity
|
|
1183
1251
|
) public view returns (uint256 price) {
|
|
1184
|
-
if (identityDetails[_identity].
|
|
1185
|
-
if (usernameOffers[_identity][0].
|
|
1252
|
+
if (identityDetails[_identity].expirationDate >= block.timestamp) {
|
|
1253
|
+
if (usernameOffers[_identity][0].expirationDate != 0) {
|
|
1186
1254
|
for (
|
|
1187
1255
|
uint256 i = 0;
|
|
1188
1256
|
i < identityDetails[_identity].offerMaxSlots;
|
|
1189
1257
|
i++
|
|
1190
1258
|
) {
|
|
1191
1259
|
if (
|
|
1192
|
-
usernameOffers[_identity][i].
|
|
1260
|
+
usernameOffers[_identity][i].expirationDate >
|
|
1193
1261
|
block.timestamp &&
|
|
1194
1262
|
usernameOffers[_identity][i].offerer != address(0)
|
|
1195
1263
|
) {
|
|
@@ -1202,14 +1270,14 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1202
1270
|
if (price == 0) {
|
|
1203
1271
|
price = 500 * 10 ** 18;
|
|
1204
1272
|
} else {
|
|
1205
|
-
uint256 principalTokenReward =
|
|
1206
|
-
|
|
1273
|
+
uint256 principalTokenReward = core.getRewardAmount();
|
|
1274
|
+
|
|
1207
1275
|
price = ((price * 5) / 1000) > (500000 * principalTokenReward)
|
|
1208
1276
|
? (500000 * principalTokenReward)
|
|
1209
1277
|
: ((price * 5) / 1000);
|
|
1210
1278
|
}
|
|
1211
1279
|
} else {
|
|
1212
|
-
price = 500_000 *
|
|
1280
|
+
price = 500_000 * core.getRewardAmount();
|
|
1213
1281
|
}
|
|
1214
1282
|
}
|
|
1215
1283
|
|
|
@@ -1219,7 +1287,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1219
1287
|
* @return price Cost in Principal Tokens (10x current reward amount)
|
|
1220
1288
|
*/
|
|
1221
1289
|
function getPriceToAddCustomMetadata() public view returns (uint256 price) {
|
|
1222
|
-
price = 10 *
|
|
1290
|
+
price = 10 * core.getRewardAmount();
|
|
1223
1291
|
}
|
|
1224
1292
|
|
|
1225
1293
|
/**
|
|
@@ -1232,7 +1300,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1232
1300
|
view
|
|
1233
1301
|
returns (uint256 price)
|
|
1234
1302
|
{
|
|
1235
|
-
price = 10 *
|
|
1303
|
+
price = 10 * core.getRewardAmount();
|
|
1236
1304
|
}
|
|
1237
1305
|
|
|
1238
1306
|
/**
|
|
@@ -1245,7 +1313,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1245
1313
|
string memory _identity
|
|
1246
1314
|
) public view returns (uint256 price) {
|
|
1247
1315
|
price =
|
|
1248
|
-
(10 *
|
|
1316
|
+
(10 * core.getRewardAmount()) *
|
|
1249
1317
|
identityDetails[_identity].customMetadataMaxSlots;
|
|
1250
1318
|
}
|
|
1251
1319
|
|
|
@@ -1259,9 +1327,9 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1259
1327
|
string memory _identity
|
|
1260
1328
|
) public view returns (uint256 price) {
|
|
1261
1329
|
price =
|
|
1262
|
-
((10 *
|
|
1330
|
+
((10 * core.getRewardAmount()) *
|
|
1263
1331
|
identityDetails[_identity].customMetadataMaxSlots) +
|
|
1264
|
-
|
|
1332
|
+
core.getRewardAmount();
|
|
1265
1333
|
}
|
|
1266
1334
|
|
|
1267
1335
|
//█ Identity Availability Functions ██████████████████████████████████████████████████████████████
|
|
@@ -1275,11 +1343,11 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1275
1343
|
function isUsernameAvailable(
|
|
1276
1344
|
string memory _username
|
|
1277
1345
|
) public view returns (bool) {
|
|
1278
|
-
if (identityDetails[_username].
|
|
1346
|
+
if (identityDetails[_username].expirationDate == 0) {
|
|
1279
1347
|
return true;
|
|
1280
1348
|
} else {
|
|
1281
1349
|
return
|
|
1282
|
-
identityDetails[_username].
|
|
1350
|
+
identityDetails[_username].expirationDate + 60 days <
|
|
1283
1351
|
block.timestamp;
|
|
1284
1352
|
}
|
|
1285
1353
|
}
|
|
@@ -1295,7 +1363,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1295
1363
|
) public view returns (address, uint256) {
|
|
1296
1364
|
return (
|
|
1297
1365
|
identityDetails[_username].owner,
|
|
1298
|
-
identityDetails[_username].
|
|
1366
|
+
identityDetails[_username].expirationDate
|
|
1299
1367
|
);
|
|
1300
1368
|
}
|
|
1301
1369
|
|
|
@@ -1369,8 +1437,10 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1369
1437
|
*/
|
|
1370
1438
|
function getOffersOfUsername(
|
|
1371
1439
|
string memory _username
|
|
1372
|
-
) public view returns (OfferMetadata[] memory offers) {
|
|
1373
|
-
offers = new OfferMetadata[](
|
|
1440
|
+
) public view returns (Structs.OfferMetadata[] memory offers) {
|
|
1441
|
+
offers = new Structs.OfferMetadata[](
|
|
1442
|
+
identityDetails[_username].offerMaxSlots
|
|
1443
|
+
);
|
|
1374
1444
|
|
|
1375
1445
|
for (uint256 i = 0; i < identityDetails[_username].offerMaxSlots; i++) {
|
|
1376
1446
|
offers[i] = usernameOffers[_username][i];
|
|
@@ -1387,7 +1457,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1387
1457
|
function getSingleOfferOfUsername(
|
|
1388
1458
|
string memory _username,
|
|
1389
1459
|
uint256 _offerID
|
|
1390
|
-
) public view returns (OfferMetadata memory offer) {
|
|
1460
|
+
) public view returns (Structs.OfferMetadata memory offer) {
|
|
1391
1461
|
return usernameOffers[_username][_offerID];
|
|
1392
1462
|
}
|
|
1393
1463
|
|
|
@@ -1402,7 +1472,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1402
1472
|
) public view returns (uint256 length) {
|
|
1403
1473
|
do {
|
|
1404
1474
|
length++;
|
|
1405
|
-
} while (usernameOffers[_username][length].
|
|
1475
|
+
} while (usernameOffers[_username][length].expirationDate != 0);
|
|
1406
1476
|
}
|
|
1407
1477
|
|
|
1408
1478
|
/**
|
|
@@ -1414,7 +1484,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1414
1484
|
function getExpireDateOfIdentity(
|
|
1415
1485
|
string memory _identity
|
|
1416
1486
|
) public view returns (uint256) {
|
|
1417
|
-
return identityDetails[_identity].
|
|
1487
|
+
return identityDetails[_identity].expirationDate;
|
|
1418
1488
|
}
|
|
1419
1489
|
|
|
1420
1490
|
/**
|
|
@@ -1431,7 +1501,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1431
1501
|
return
|
|
1432
1502
|
identityDetails[username].offerMaxSlots > 0
|
|
1433
1503
|
? seePriceToRenew(username)
|
|
1434
|
-
:
|
|
1504
|
+
: core.getRewardAmount() * 100;
|
|
1435
1505
|
}
|
|
1436
1506
|
|
|
1437
1507
|
//█ Administrative Getters ███████████████████████████████████████████████████████████████████████
|
|
@@ -1490,7 +1560,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1490
1560
|
* @return Unique EvvmID string
|
|
1491
1561
|
*/
|
|
1492
1562
|
function getEvvmID() external view returns (uint256) {
|
|
1493
|
-
return
|
|
1563
|
+
return core.getEvvmID();
|
|
1494
1564
|
}
|
|
1495
1565
|
|
|
1496
1566
|
/**
|
|
@@ -1498,8 +1568,8 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1498
1568
|
* @dev Returns the address of the EVVM contract used for payment processing
|
|
1499
1569
|
* @return The current EVVM contract address
|
|
1500
1570
|
*/
|
|
1501
|
-
function
|
|
1502
|
-
return
|
|
1571
|
+
function getCoreAddress() public view returns (address) {
|
|
1572
|
+
return coreAddress.current;
|
|
1503
1573
|
}
|
|
1504
1574
|
|
|
1505
1575
|
/**
|
|
@@ -1509,7 +1579,7 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1509
1579
|
* @return proposalEvvmAddress Proposed new EVVM address (if any)
|
|
1510
1580
|
* @return timeToAcceptEvvmAddress Timestamp when proposal can be accepted
|
|
1511
1581
|
*/
|
|
1512
|
-
function
|
|
1582
|
+
function getCoreAddressFullDetails()
|
|
1513
1583
|
public
|
|
1514
1584
|
view
|
|
1515
1585
|
returns (
|
|
@@ -1519,9 +1589,9 @@ contract NameService is AsyncNonce, NameServiceStructs {
|
|
|
1519
1589
|
)
|
|
1520
1590
|
{
|
|
1521
1591
|
return (
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1592
|
+
coreAddress.current,
|
|
1593
|
+
coreAddress.proposal,
|
|
1594
|
+
coreAddress.timeToAccept
|
|
1525
1595
|
);
|
|
1526
1596
|
}
|
|
1527
1597
|
}
|