@evvm/testnet-contracts 1.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 (34) hide show
  1. package/LICENSE +166 -0
  2. package/README.md +216 -0
  3. package/package.json +51 -0
  4. package/src/contracts/evvm/Evvm.sol +1327 -0
  5. package/src/contracts/evvm/EvvmLegacy.sol +1553 -0
  6. package/src/contracts/evvm/lib/ErrorsLib.sol +17 -0
  7. package/src/contracts/evvm/lib/EvvmStorage.sol +60 -0
  8. package/src/contracts/evvm/lib/EvvmStructs.sol +64 -0
  9. package/src/contracts/evvm/lib/SignatureUtils.sol +124 -0
  10. package/src/contracts/nameService/NameService.sol +1751 -0
  11. package/src/contracts/nameService/lib/ErrorsLib.sol +27 -0
  12. package/src/contracts/nameService/lib/SignatureUtils.sol +239 -0
  13. package/src/contracts/staking/Estimator.sol +358 -0
  14. package/src/contracts/staking/Staking.sol +1148 -0
  15. package/src/contracts/staking/lib/ErrorsLib.sol +19 -0
  16. package/src/contracts/staking/lib/SignatureUtils.sol +68 -0
  17. package/src/contracts/treasury/Treasury.sol +104 -0
  18. package/src/contracts/treasury/lib/ErrorsLib.sol +11 -0
  19. package/src/contracts/treasuryTwoChains/TreasuryExternalChainStation.sol +551 -0
  20. package/src/contracts/treasuryTwoChains/TreasuryHostChainStation.sol +512 -0
  21. package/src/contracts/treasuryTwoChains/lib/ErrorsLib.sol +15 -0
  22. package/src/contracts/treasuryTwoChains/lib/ExternalChainStationStructs.sol +41 -0
  23. package/src/contracts/treasuryTwoChains/lib/HostChainStationStructs.sol +52 -0
  24. package/src/contracts/treasuryTwoChains/lib/SignatureUtils.sol +47 -0
  25. package/src/interfaces/IEstimator.sol +102 -0
  26. package/src/interfaces/IEvvm.sol +195 -0
  27. package/src/interfaces/INameService.sol +283 -0
  28. package/src/interfaces/IStaking.sol +202 -0
  29. package/src/interfaces/ITreasury.sol +17 -0
  30. package/src/interfaces/ITreasuryExternalChainStation.sol +262 -0
  31. package/src/interfaces/ITreasuryHostChainStation.sol +251 -0
  32. package/src/lib/AdvancedStrings.sol +77 -0
  33. package/src/lib/Erc191TestBuilder.sol +402 -0
  34. package/src/lib/SignatureRecover.sol +56 -0
@@ -0,0 +1,1327 @@
1
+ // SPDX-License-Identifier: EVVM-NONCOMMERCIAL-1.0
2
+ // Full license terms available at: https://www.evvm.info/docs/EVVMNoncommercialLicense
3
+
4
+ pragma solidity ^0.8.0;
5
+ /**
6
+
7
+ ░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓██████████████▓▒░
8
+ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░
9
+ ░▒▓█▓▒░ ░▒▓█▓▒▒▓█▓▒░ ░▒▓█▓▒▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░
10
+ ░▒▓██████▓▒░ ░▒▓█▓▒▒▓█▓▒░ ░▒▓█▓▒▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░
11
+ ░▒▓█▓▒░ ░▒▓█▓▓█▓▒░ ░▒▓█▓▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░
12
+ ░▒▓█▓▒░ ░▒▓█▓▓█▓▒░ ░▒▓█▓▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░
13
+ ░▒▓████████▓▒░ ░▒▓██▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░
14
+
15
+ ████████╗███████╗███████╗████████╗███╗ ██╗███████╗████████╗
16
+ ╚══██╔══╝██╔════╝██╔════╝╚══██╔══╝████╗ ██║██╔════╝╚══██╔══╝
17
+ ██║ █████╗ ███████╗ ██║ ██╔██╗ ██║█████╗ ██║
18
+ ██║ ██╔══╝ ╚════██║ ██║ ██║╚██╗██║██╔══╝ ██║
19
+ ██║ ███████╗███████║ ██║ ██║ ╚████║███████╗ ██║
20
+ ╚═╝ ╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝
21
+
22
+ * @title EVVM (Ethereum Virtual Machine Virtualization) Core Contract
23
+ * @author jistro.eth ariutokintumi.eth
24
+ * @notice Core payment processing and token management system for the EVVM ecosystem
25
+ * @dev This contract serves as the central hub for:
26
+ * - Multi-token payment processing with signature verification
27
+ * - Staker reward distribution and incentive mechanisms
28
+ * - Cross-chain bridge functionality (Fisher Bridge)
29
+ * - Balance management across the EVVM ecosystem
30
+ * - Integration with NameService for identity-based payments
31
+ * - Treasury integration for privileged balance operations
32
+ *
33
+ * Key Features:
34
+ * - Synchronous and asynchronous payment processing with nonce management
35
+ * - Staker privilege system with enhanced rewards and transaction processing benefits
36
+ * - Multi-recipient payment batching (payMultiple, dispersePay)
37
+ * - Administrative payment distribution (caPay, disperseCaPay)
38
+ * - Proxy pattern support with delegatecall fallback for upgradeability
39
+ * - Cross-chain asset bridging capabilities through Fisher Bridge
40
+ * - Deflationary tokenomics with era-based reward halving mechanism
41
+ * - Treasury-controlled balance management for minting and burning operations
42
+ *
43
+ * Payment Types:
44
+ * - `payNoStaker_*`: Standard payments for non-stakers with basic functionality
45
+ * - `payStaker_*`: Enhanced payments for Principal Token stakers with priority fee rewards
46
+ * - `payMultiple`: Batch payments to multiple recipients with individual success tracking
47
+ * - `dispersePay`: Single-source multi-recipient distribution with signature verification
48
+ * - `caPay`: Administrative token distribution for smart contracts
49
+ * - Treasury functions: Direct balance manipulation for authorized operations
50
+ *
51
+ * Economic Model:
52
+ * - Principal Token as principal token with reward distribution system
53
+ * - Era-based reward halving when supply thresholds are reached
54
+ * - Staker incentives through transaction processing rewards
55
+ * - Random bonus rewards for triggering era transitions
56
+ *
57
+ * Security Features:
58
+ * - Signature-based transaction authorization with EIP-191 compliance
59
+ * - Dual nonce system: synchronous (sequential) and asynchronous (custom)
60
+ * - Executor validation for delegated transaction processing
61
+ * - Balance verification before transfers to prevent overdrafts
62
+ * - Time-delayed governance for critical upgrades (30-day implementation, 1-day admin)
63
+ * - Access control through admin and treasury authorization
64
+ *
65
+ * Integration Points:
66
+ * - NameService: Identity resolution for username-based payments
67
+ * - Staking Contract: Staker status management and reward distribution
68
+ * - Treasury Contract: Privileged balance operations and token management
69
+ * - Implementation Contract: Proxy pattern for contract upgradeability
70
+ *
71
+ * @custom:version 1.0.0
72
+ * @custom:testnet This contract is deployed on testnet for development and testing
73
+ * @custom:security Time-delayed governance, signature verification, access control
74
+ * @custom:upgrade-pattern Transparent proxy with admin-controlled implementation
75
+ */
76
+
77
+ import {NameService} from "@evvm/testnet-contracts/contracts/nameService/NameService.sol";
78
+ import {EvvmStorage} from "@evvm/testnet-contracts/contracts/evvm/lib/EvvmStorage.sol";
79
+ import {ErrorsLib} from "@evvm/testnet-contracts/contracts/evvm/lib/ErrorsLib.sol";
80
+ import {SignatureUtils} from "@evvm/testnet-contracts/contracts/evvm/lib/SignatureUtils.sol";
81
+ import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
82
+
83
+ contract Evvm is EvvmStorage {
84
+ /**
85
+ * @notice Access control modifier restricting function calls to the current admin
86
+ * @dev Validates that msg.sender matches the current admin address before function execution
87
+ *
88
+ * Access Control:
89
+ * - Only the current admin can call functions with this modifier
90
+ * - Uses the admin.current address from the storage structure
91
+ * - Reverts with no specific error message for unauthorized calls
92
+ *
93
+ * Usage:
94
+ * - Applied to critical administrative functions
95
+ * - Protects system configuration changes
96
+ * - Prevents unauthorized upgrades and parameter modifications
97
+ *
98
+ * Security:
99
+ * - Simple but effective access control mechanism
100
+ * - Used for proxy upgrades, admin transfers, and system configuration
101
+ * - Part of the time-delayed governance system for critical operations
102
+ */
103
+ modifier onlyAdmin() {
104
+ if (msg.sender != admin.current) {
105
+ revert();
106
+ }
107
+ _;
108
+ }
109
+
110
+ /**
111
+ * @notice Initializes the EVVM contract with essential configuration and token distributions
112
+ * @dev Sets up the core system parameters, admin roles, and initial Principal Token allocations
113
+ *
114
+ * Critical Initial Setup:
115
+ * - Configures admin address with full administrative privileges
116
+ * - Sets staking contract address for reward distribution and status management
117
+ * - Stores EVVM metadata including principal token address and reward parameters
118
+ * - Distributes initial MATE tokens to staking contract (2x reward amount)
119
+ * - Registers staking contract as privileged staker with full benefits
120
+ * - Activates breaker flag for one-time NameService and Treasury setup
121
+ *
122
+ * Token Distribution:
123
+ * - Staking contract receives 2x current reward amount in MATE tokens
124
+ * - Enables immediate reward distribution capabilities
125
+ * - Provides operational liquidity for staking rewards
126
+ *
127
+ * Security Initialization:
128
+ * - Sets admin.current for immediate administrative access
129
+ * - Prepares system for NameService and Treasury integration
130
+ * - Establishes staking privileges for the staking contract
131
+ *
132
+ * Post-Deployment Requirements:
133
+ * - Must call `_setupNameServiceAndTreasuryAddress()` to complete integration
134
+ * - NameService and Treasury addresses must be configured before full operation
135
+ * - Implementation contract should be set for proxy functionality
136
+ *
137
+ * @param _initialOwner Address that will have administrative privileges over the contract
138
+ * @param _stakingContractAddress Address of the staking contract for reward distribution and staker management
139
+ * @param _evvmMetadata Metadata structure containing principal token address, reward amounts, and system parameters
140
+ *
141
+ * @custom:deployment Must be followed by NameService and Treasury setup
142
+ * @custom:security Admin address has full control over system configuration
143
+ */
144
+ constructor(
145
+ address _initialOwner,
146
+ address _stakingContractAddress,
147
+ EvvmMetadata memory _evvmMetadata
148
+ ) {
149
+ stakingContractAddress = _stakingContractAddress;
150
+
151
+ admin.current = _initialOwner;
152
+
153
+ balances[_stakingContractAddress][evvmMetadata.principalTokenAddress] =
154
+ getRewardAmount() *
155
+ 2;
156
+
157
+ stakerList[_stakingContractAddress] = FLAG_IS_STAKER;
158
+
159
+ breakerSetupNameServiceAddress = FLAG_IS_STAKER;
160
+
161
+ evvmMetadata = _evvmMetadata;
162
+ }
163
+
164
+ /**
165
+ * @notice One-time setup function to configure NameService and Treasury contract addresses
166
+ * @dev Can only be called once due to breaker flag mechanism for security
167
+ *
168
+ * Critical Setup Process:
169
+ * - Validates the breaker flag is active (prevents multiple calls)
170
+ * - Sets the NameService contract address for identity resolution in payments
171
+ * - Configures the Treasury contract address for privileged balance operations
172
+ * - Provides initial Principal Token balance (10,000 MATE) to NameService for operations
173
+ * - Registers NameService as a privileged staker for enhanced functionality and rewards
174
+ *
175
+ * Security Features:
176
+ * - Single-use function protected by breaker flag
177
+ * - Prevents unauthorized reconfiguration of critical system addresses
178
+ * - Must be called during initial system deployment phase
179
+ *
180
+ * Initial Token Distribution:
181
+ * - NameService receives 10,000 MATE tokens for operational expenses
182
+ * - NameService gains staker privileges for transaction processing
183
+ * - Enables identity-based payment resolution throughout the ecosystem
184
+ *
185
+ * @param _nameServiceAddress Address of the deployed NameService contract for identity resolution
186
+ * @param _treasuryAddress Address of the Treasury contract for balance management operations
187
+ *
188
+ * @custom:security Single-use function - can only be called once
189
+ * @custom:access-control No explicit access control - relies on deployment sequence
190
+ * @custom:integration Critical for NameService and Treasury functionality
191
+ */
192
+ function _setupNameServiceAndTreasuryAddress(
193
+ address _nameServiceAddress,
194
+ address _treasuryAddress
195
+ ) external {
196
+ if (breakerSetupNameServiceAddress == 0x00) {
197
+ revert();
198
+ }
199
+ nameServiceAddress = _nameServiceAddress;
200
+ balances[nameServiceAddress][evvmMetadata.principalTokenAddress] =
201
+ 10000 *
202
+ 10 ** 18;
203
+ stakerList[nameServiceAddress] = FLAG_IS_STAKER;
204
+
205
+ treasuryAddress = _treasuryAddress;
206
+ }
207
+
208
+ /**
209
+ * @notice Updates the EVVM ID with a new value, restricted to admin and time-limited
210
+ * @dev Allows the admin to change the EVVM ID within a 1-day window after deployment
211
+ */
212
+ function setEvvmID(uint256 newEvvmID) external onlyAdmin {
213
+ if (newEvvmID == 0) {
214
+ if (block.timestamp > windowTimeToChangeEvvmID)
215
+ revert ErrorsLib.WindowToChangeEvvmIDExpired();
216
+ }
217
+
218
+ evvmMetadata.EvvmID = newEvvmID;
219
+
220
+ windowTimeToChangeEvvmID = block.timestamp + 1 days;
221
+ }
222
+
223
+ /**
224
+ * @notice Fallback function implementing proxy pattern with delegatecall to implementation
225
+ * @dev Routes all unrecognized function calls to the current implementation contract
226
+ *
227
+ * Proxy Mechanism:
228
+ * - Forwards all calls not handled by this contract to the implementation
229
+ * - Uses delegatecall to preserve storage context and msg.sender
230
+ * - Allows for contract upgrades without changing the main contract address
231
+ * - Maintains all state variables in the proxy contract storage
232
+ *
233
+ * Implementation Process:
234
+ * 1. Validates that an implementation contract is set
235
+ * 2. Copies all calldata to memory for forwarding
236
+ * 3. Executes delegatecall to implementation with full gas allowance
237
+ * 4. Copies the return data back from the implementation
238
+ * 5. Returns the result or reverts based on implementation response
239
+ *
240
+ * Security Features:
241
+ * - Reverts if no implementation is set (prevents undefined behavior)
242
+ * - Preserves all gas for the implementation call
243
+ * - Maintains exact return data and revert behavior from implementation
244
+ * - Uses storage slot reading for gas efficiency
245
+ *
246
+ * Upgrade Compatibility:
247
+ * - Enables seamless contract upgrades through implementation changes
248
+ * - Preserves all existing state and user balances
249
+ * - Allows new functionality addition without user migration
250
+ * - Supports time-delayed upgrade governance for security
251
+ *
252
+ * @custom:security Requires valid implementation address
253
+ * @custom:proxy Transparent proxy pattern implementation
254
+ * @custom:upgrade-safe Preserves storage layout between upgrades
255
+ */
256
+ fallback() external {
257
+ if (currentImplementation == address(0)) revert();
258
+
259
+ assembly {
260
+ /**
261
+ * Copy the data of the call
262
+ * copy s bytes of calldata from position
263
+ * f to mem in position t
264
+ * calldatacopy(t, f, s)
265
+ */
266
+ calldatacopy(0, 0, calldatasize())
267
+
268
+ /**
269
+ * 2. We make a delegatecall to the implementation
270
+ * and we copy the result
271
+ */
272
+ let result := delegatecall(
273
+ gas(), // Send all the available gas
274
+ sload(currentImplementation.slot), // Address of the implementation
275
+ 0, // Start of the memory where the data is
276
+ calldatasize(), // Size of the data
277
+ 0, // Where we will store the response
278
+ 0 // Initial size of the response
279
+ )
280
+
281
+ /// Copy the response
282
+ returndatacopy(0, 0, returndatasize())
283
+
284
+ /// Handle the result
285
+ switch result
286
+ case 0 {
287
+ revert(0, returndatasize()) // If it failed, revert
288
+ }
289
+ default {
290
+ return(0, returndatasize()) // If it worked, return
291
+ }
292
+ }
293
+ }
294
+
295
+ /**
296
+ * @notice Faucet function to add balance to a user's account for testing purposes
297
+ * @dev This function is intended for testnet use only to provide tokens for testing
298
+ * @param user The address of the user to receive the balance
299
+ * @param token The address of the token contract to add balance for
300
+ * @param quantity The amount of tokens to add to the user's balance
301
+ */
302
+ function addBalance(
303
+ address user,
304
+ address token,
305
+ uint256 quantity
306
+ ) external {
307
+ balances[user][token] += quantity;
308
+ }
309
+
310
+ /**
311
+ * @notice Faucet function to set point staker status for testing purposes
312
+ * @dev This function is intended for testnet use only to configure staker points for testing
313
+ * @param user The address of the user to set as point staker
314
+ * @param answer The bytes1 value representing the staker status or answer
315
+ */
316
+ function setPointStaker(address user, bytes1 answer) external {
317
+ stakerList[user] = answer;
318
+ }
319
+
320
+ //░▒▓█ Payment Functions ████████████████████████████████████████████████████████▓▒░
321
+
322
+ /**
323
+ * @notice Processes single payments
324
+ *
325
+ * Payment Flow:
326
+ * - Validates signature authorization for the payment
327
+ * (if synchronous nonce, uses nextSyncUsedNonce inside
328
+ * the signature verification to verify the correct nonce)
329
+ * - Checks executor permission if specified
330
+ * - Validates synchronous nonce matches expected value
331
+ * - Resolves recipient address (identity or direct address)
332
+ * - If the fisher (msg.sender) is a staker:
333
+ * - Transfers priority fee to the fisher
334
+ * - Rewards the fisher with Principal tokens
335
+ * - Updates balances and increments nonce
336
+ *
337
+ * @param from Address of the payment sender
338
+ * @param to_address Direct recipient address (used if to_identity is empty)
339
+ * @param to_identity Username/identity of recipient (resolved via NameService)
340
+ * @param token Address of the token contract to transfer
341
+ * @param amount Amount of tokens to transfer
342
+ * @param priorityFee Additional fee for transaction priority (not used in non-staker payments)
343
+ * @param nonce Transaction nonce
344
+ * @param priorityFlag Execution type flag (false = sync nonce, true = async nonce)
345
+ * @param executor Address authorized to execute this transaction (zero address = sender only)
346
+ * @param signature Cryptographic signature authorizing this payment
347
+ */
348
+ function pay(
349
+ address from,
350
+ address to_address,
351
+ string memory to_identity,
352
+ address token,
353
+ uint256 amount,
354
+ uint256 priorityFee,
355
+ uint256 nonce,
356
+ bool priorityFlag,
357
+ address executor,
358
+ bytes memory signature
359
+ ) external {
360
+ if (
361
+ !SignatureUtils.verifyMessageSignedForPay(
362
+ evvmMetadata.EvvmID,
363
+ from,
364
+ to_address,
365
+ to_identity,
366
+ token,
367
+ amount,
368
+ priorityFee,
369
+ priorityFlag ? nonce : nextSyncUsedNonce[from],
370
+ priorityFlag,
371
+ executor,
372
+ signature
373
+ )
374
+ ) revert ErrorsLib.InvalidSignature();
375
+
376
+ if (executor != address(0)) {
377
+ if (msg.sender != executor)
378
+ revert ErrorsLib.SenderIsNotTheExecutor();
379
+ }
380
+
381
+ if (priorityFlag && asyncUsedNonce[from][nonce])
382
+ revert ErrorsLib.InvalidAsyncNonce();
383
+
384
+ address to = !Strings.equal(to_identity, "")
385
+ ? NameService(nameServiceAddress).verifyStrictAndGetOwnerOfIdentity(
386
+ to_identity
387
+ )
388
+ : to_address;
389
+
390
+ if (!_updateBalance(from, to, token, amount))
391
+ revert ErrorsLib.UpdateBalanceFailed();
392
+
393
+ if (isAddressStaker(msg.sender)) {
394
+ if (priorityFee > 0) {
395
+ if (!_updateBalance(from, msg.sender, token, priorityFee))
396
+ revert ErrorsLib.UpdateBalanceFailed();
397
+ }
398
+ _giveReward(msg.sender, 1);
399
+ }
400
+
401
+ if (priorityFlag) {
402
+ asyncUsedNonce[from][nonce] = true;
403
+ } else {
404
+ nextSyncUsedNonce[from]++;
405
+ }
406
+ }
407
+
408
+ /**
409
+ * @notice Processes multiple payments in a single transaction batch
410
+ * @dev Executes an array of payment operations with individual success/failure tracking
411
+ *
412
+ * Batch Processing Features:
413
+ * - Processes each payment independently (partial success allowed)
414
+ * - Returns detailed results for each transaction
415
+ * - Supports both staker and non-staker payment types
416
+ * - Handles both sync and async nonce types per payment
417
+ * - Provides comprehensive transaction statistics
418
+ *
419
+ * Payment Validation:
420
+ * - Each payment signature is verified independently
421
+ * - Nonce management handled per payment type (sync/async)
422
+ * - Identity resolution performed for each recipient
423
+ * - Balance updates executed atomically per payment
424
+ *
425
+ * Return Values:
426
+ * - successfulTransactions: Count of completed payments
427
+ * - failedTransactions: Count of failed payments
428
+ * - results: Boolean array indicating success/failure for each payment
429
+ *
430
+ * @param payData Array of PayData structures containing payment details
431
+ * @return successfulTransactions Number of payments that completed successfully
432
+ * @return failedTransactions Number of payments that failed
433
+ * @return results Boolean array with success status for each payment
434
+ */
435
+ function payMultiple(
436
+ PayData[] memory payData
437
+ )
438
+ external
439
+ returns (
440
+ uint256 successfulTransactions,
441
+ uint256 failedTransactions,
442
+ bool[] memory results
443
+ )
444
+ {
445
+ address to_aux;
446
+ results = new bool[](payData.length);
447
+ for (uint256 iteration = 0; iteration < payData.length; iteration++) {
448
+ if (
449
+ !SignatureUtils.verifyMessageSignedForPay(
450
+ evvmMetadata.EvvmID,
451
+ payData[iteration].from,
452
+ payData[iteration].to_address,
453
+ payData[iteration].to_identity,
454
+ payData[iteration].token,
455
+ payData[iteration].amount,
456
+ payData[iteration].priorityFee,
457
+ payData[iteration].priorityFlag
458
+ ? payData[iteration].nonce
459
+ : nextSyncUsedNonce[payData[iteration].from],
460
+ payData[iteration].priorityFlag,
461
+ payData[iteration].executor,
462
+ payData[iteration].signature
463
+ )
464
+ ) revert ErrorsLib.InvalidSignature();
465
+
466
+ if (payData[iteration].executor != address(0)) {
467
+ if (msg.sender != payData[iteration].executor) {
468
+ failedTransactions++;
469
+ results[iteration] = false;
470
+ continue;
471
+ }
472
+ }
473
+
474
+ if (payData[iteration].priorityFlag) {
475
+ /// @dev priorityFlag == true (async)
476
+
477
+ if (
478
+ !asyncUsedNonce[payData[iteration].from][
479
+ payData[iteration].nonce
480
+ ]
481
+ ) {
482
+ asyncUsedNonce[payData[iteration].from][
483
+ payData[iteration].nonce
484
+ ] = true;
485
+ } else {
486
+ failedTransactions++;
487
+ results[iteration] = false;
488
+ continue;
489
+ }
490
+ } else {
491
+ /// @dev priorityFlag == false (sync)
492
+
493
+ if (
494
+ nextSyncUsedNonce[payData[iteration].from] ==
495
+ payData[iteration].nonce
496
+ ) {
497
+ nextSyncUsedNonce[payData[iteration].from]++;
498
+ } else {
499
+ failedTransactions++;
500
+ results[iteration] = false;
501
+ continue;
502
+ }
503
+ }
504
+
505
+ to_aux = !Strings.equal(payData[iteration].to_identity, "")
506
+ ? NameService(nameServiceAddress)
507
+ .verifyStrictAndGetOwnerOfIdentity(
508
+ payData[iteration].to_identity
509
+ )
510
+ : payData[iteration].to_address;
511
+
512
+ if (
513
+ payData[iteration].priorityFee + payData[iteration].amount >
514
+ balances[payData[iteration].from][payData[iteration].token]
515
+ ) {
516
+ failedTransactions++;
517
+ results[iteration] = false;
518
+ continue;
519
+ }
520
+
521
+ if (
522
+ !_updateBalance(
523
+ payData[iteration].from,
524
+ to_aux,
525
+ payData[iteration].token,
526
+ payData[iteration].amount
527
+ )
528
+ ) {
529
+ failedTransactions++;
530
+ results[iteration] = false;
531
+ continue;
532
+ } else {
533
+ if (
534
+ payData[iteration].priorityFee > 0 &&
535
+ isAddressStaker(msg.sender)
536
+ ) {
537
+ if (
538
+ !_updateBalance(
539
+ payData[iteration].from,
540
+ msg.sender,
541
+ payData[iteration].token,
542
+ payData[iteration].priorityFee
543
+ )
544
+ ) {
545
+ failedTransactions++;
546
+ results[iteration] = false;
547
+ continue;
548
+ }
549
+ }
550
+
551
+ successfulTransactions++;
552
+ results[iteration] = true;
553
+ }
554
+ }
555
+
556
+ if (isAddressStaker(msg.sender)) {
557
+ _giveReward(msg.sender, successfulTransactions);
558
+ }
559
+ }
560
+
561
+ /**
562
+ * @notice Distributes tokens from a single sender to multiple recipients
563
+ * @dev Efficient single-source multi-recipient payment distribution with signature verification
564
+ *
565
+ * Distribution Features:
566
+ * - Single signature authorizes distribution to multiple recipients
567
+ * - Supports both direct addresses and identity-based recipients
568
+ * - Proportional amount distribution based on recipient configurations
569
+ * - Integrated priority fee and staker reward system
570
+ * - Supports both sync and async nonce management
571
+ *
572
+ * Verification Process:
573
+ * - Validates single signature for entire distribution
574
+ * - Checks total amount and priority fee against sender balance
575
+ * - Ensures executor permissions and nonce validity
576
+ * - Processes each recipient distribution atomically
577
+ *
578
+ * Staker Benefits:
579
+ * - Executor receives priority fee (if staker)
580
+ * - MATE reward based on number of successful distributions
581
+ *
582
+ * @param from Address of the payment sender
583
+ * @param toData Array of recipient data with addresses/identities and amounts
584
+ * @param token Address of the token contract to distribute
585
+ * @param amount Total amount to distribute (must match sum of individual amounts)
586
+ * @param priorityFee Fee amount for the transaction executor
587
+ * @param nonce Transaction nonce for replay protection
588
+ * @param priorityFlag True for async nonce, false for sync nonce
589
+ * @param executor Address authorized to execute this distribution
590
+ * @param signature Cryptographic signature authorizing this distribution
591
+ */
592
+ function dispersePay(
593
+ address from,
594
+ DispersePayMetadata[] memory toData,
595
+ address token,
596
+ uint256 amount,
597
+ uint256 priorityFee,
598
+ uint256 nonce,
599
+ bool priorityFlag,
600
+ address executor,
601
+ bytes memory signature
602
+ ) external {
603
+ if (
604
+ !SignatureUtils.verifyMessageSignedForDispersePay(
605
+ evvmMetadata.EvvmID,
606
+ from,
607
+ sha256(abi.encode(toData)),
608
+ token,
609
+ amount,
610
+ priorityFee,
611
+ priorityFlag ? nonce : nextSyncUsedNonce[from],
612
+ priorityFlag,
613
+ executor,
614
+ signature
615
+ )
616
+ ) revert ErrorsLib.InvalidSignature();
617
+
618
+ if (executor != address(0)) {
619
+ if (msg.sender != executor)
620
+ revert ErrorsLib.SenderIsNotTheExecutor();
621
+ }
622
+
623
+ if (priorityFlag) {
624
+ if (asyncUsedNonce[from][nonce])
625
+ revert ErrorsLib.InvalidAsyncNonce();
626
+ }
627
+
628
+ if (balances[from][token] < amount + priorityFee)
629
+ revert ErrorsLib.InsufficientBalance();
630
+
631
+ uint256 acomulatedAmount = 0;
632
+ balances[from][token] -= (amount + priorityFee);
633
+ address to_aux;
634
+ for (uint256 i = 0; i < toData.length; i++) {
635
+ acomulatedAmount += toData[i].amount;
636
+
637
+ if (!Strings.equal(toData[i].to_identity, "")) {
638
+ if (
639
+ NameService(nameServiceAddress).strictVerifyIfIdentityExist(
640
+ toData[i].to_identity
641
+ )
642
+ ) {
643
+ to_aux = NameService(nameServiceAddress).getOwnerOfIdentity(
644
+ toData[i].to_identity
645
+ );
646
+ }
647
+ } else {
648
+ to_aux = toData[i].to_address;
649
+ }
650
+
651
+ balances[to_aux][token] += toData[i].amount;
652
+ }
653
+
654
+ if (acomulatedAmount != amount)
655
+ revert ErrorsLib.InvalidAmount(acomulatedAmount, amount);
656
+
657
+ if (isAddressStaker(msg.sender)) {
658
+ _giveReward(msg.sender, 1);
659
+ balances[msg.sender][token] += priorityFee;
660
+ } else {
661
+ balances[from][token] += priorityFee;
662
+ }
663
+
664
+ if (priorityFlag) {
665
+ asyncUsedNonce[from][nonce] = true;
666
+ } else {
667
+ nextSyncUsedNonce[from]++;
668
+ }
669
+ }
670
+
671
+ /**
672
+ * @notice Contract-to-address payment function for authorized smart contracts
673
+ * @dev Allows registered contracts to distribute tokens without signature verification
674
+ *
675
+ * Authorization Model:
676
+ * - Only smart contracts (non-EOA addresses) can call this function
677
+ * - Calling contract must have sufficient token balance
678
+ * - No signature verification required (contract-level authorization)
679
+ * - Used primarily for automated distributions and rewards
680
+ *
681
+ * Use Cases:
682
+ * - Staking contract reward distributions
683
+ * - NameService fee distributions
684
+ * - Automated system payouts
685
+ * - Cross-contract token transfers
686
+ *
687
+ * Security Features:
688
+ * - Validates caller is a contract (has bytecode)
689
+ * - Checks sufficient balance before transfer
690
+ * - Direct balance manipulation for efficiency
691
+ *
692
+ * @param to Address of the token recipient
693
+ * @param token Address of the token contract to transfer
694
+ * @param amount Amount of tokens to transfer from calling contract
695
+ */
696
+ function caPay(address to, address token, uint256 amount) external {
697
+ uint256 size;
698
+ address from = msg.sender;
699
+
700
+ assembly {
701
+ /// @dev check the size of the opcode of the address
702
+ size := extcodesize(from)
703
+ }
704
+
705
+ if (size == 0) revert ErrorsLib.NotAnCA();
706
+
707
+ if (!_updateBalance(from, to, token, amount))
708
+ revert ErrorsLib.UpdateBalanceFailed();
709
+
710
+ if (isAddressStaker(msg.sender)) {
711
+ _giveReward(msg.sender, 1);
712
+ }
713
+ }
714
+
715
+ /**
716
+ * @notice Contract-to-multiple-addresses payment distribution function
717
+ * @dev Allows authorized contracts to distribute tokens to multiple recipients efficiently
718
+ *
719
+ * Batch Distribution Features:
720
+ * - Single call distributes to multiple recipients
721
+ * - Supports both direct addresses and identity resolution
722
+ * - Validates total amount matches sum of individual distributions
723
+ * - Optimized for contract-based automated distributions
724
+ *
725
+ * Authorization Model:
726
+ * - Only smart contracts can call this function
727
+ * - No signature verification required (contract authorization)
728
+ * - Calling contract must have sufficient balance for total distribution
729
+ *
730
+ * Use Cases:
731
+ * - Bulk reward distributions from staking contracts
732
+ * - Multi-recipient fee distributions
733
+ * - Batch payroll or dividend distributions
734
+ * - Cross-contract multi-party settlements
735
+ *
736
+ * @param toData Array of recipient data containing addresses/identities and amounts
737
+ * @param token Address of the token contract to distribute
738
+ * @param amount Total amount to distribute (must equal sum of individual amounts)
739
+ */
740
+ function disperseCaPay(
741
+ DisperseCaPayMetadata[] memory toData,
742
+ address token,
743
+ uint256 amount
744
+ ) external {
745
+ uint256 size;
746
+ address from = msg.sender;
747
+
748
+ assembly {
749
+ /// @dev check the size of the opcode of the address
750
+ size := extcodesize(from)
751
+ }
752
+
753
+ if (size == 0) revert ErrorsLib.NotAnCA();
754
+
755
+ uint256 acomulatedAmount = 0;
756
+ if (balances[msg.sender][token] < amount)
757
+ revert ErrorsLib.InsufficientBalance();
758
+
759
+ balances[msg.sender][token] -= amount;
760
+
761
+ for (uint256 i = 0; i < toData.length; i++) {
762
+ acomulatedAmount += toData[i].amount;
763
+ if (acomulatedAmount > amount)
764
+ revert ErrorsLib.InvalidAmount(acomulatedAmount, amount);
765
+
766
+ balances[toData[i].toAddress][token] += toData[i].amount;
767
+ }
768
+
769
+ if (acomulatedAmount != amount)
770
+ revert ErrorsLib.InvalidAmount(acomulatedAmount, amount);
771
+
772
+ if (isAddressStaker(msg.sender)) {
773
+ _giveReward(msg.sender, 1);
774
+ }
775
+ }
776
+
777
+ //░▒▓█Treasury exclusive functions██████████████████████████████████████████▓▒░
778
+
779
+ /**
780
+ * @notice Adds tokens to a user's balance in the EVVM system
781
+ * @dev Restricted function that can only be called by the authorized treasury contract
782
+ *
783
+ * Treasury Operations:
784
+ * - Allows treasury to mint or credit tokens to user accounts
785
+ * - Used for reward distributions, airdrops, or token bridging
786
+ * - Direct balance manipulation bypasses normal transfer restrictions
787
+ * - No signature verification required (treasury authorization)
788
+ *
789
+ * Access Control:
790
+ * - Only the registered treasury contract can call this function
791
+ * - Reverts with SenderIsNotTreasury error for unauthorized callers
792
+ * - Provides centralized token distribution mechanism
793
+ *
794
+ * Use Cases:
795
+ * - Cross-chain bridge token minting
796
+ * - Administrative reward distributions
797
+ * - System-level token allocations
798
+ * - Emergency balance corrections
799
+ *
800
+ * @param user Address of the user to receive tokens
801
+ * @param token Address of the token contract to add balance for
802
+ * @param amount Amount of tokens to add to the user's balance
803
+ *
804
+ * @custom:access-control Only treasury contract
805
+ * @custom:security No overflow protection needed due to controlled access
806
+ */
807
+ function addAmountToUser(
808
+ address user,
809
+ address token,
810
+ uint256 amount
811
+ ) external {
812
+ if (msg.sender != treasuryAddress)
813
+ revert ErrorsLib.SenderIsNotTreasury();
814
+
815
+ balances[user][token] += amount;
816
+ }
817
+
818
+ /**
819
+ * @notice Removes tokens from a user's balance in the EVVM system
820
+ * @dev Restricted function that can only be called by the authorized treasury contract
821
+ *
822
+ * Treasury Operations:
823
+ * - Allows treasury to burn or debit tokens from user accounts
824
+ * - Used for cross-chain bridging, penalties, or system corrections
825
+ * - Direct balance manipulation bypasses normal transfer protections
826
+ * - Can potentially create negative balances if not carefully managed
827
+ *
828
+ * Access Control:
829
+ * - Only the registered treasury contract can call this function
830
+ * - Reverts with SenderIsNotTreasury error for unauthorized callers
831
+ * - Provides centralized token withdrawal mechanism
832
+ *
833
+ * Use Cases:
834
+ * - Cross-chain bridge token burning
835
+ * - Administrative penalty applications
836
+ * - System-level token reclamations
837
+ * - Emergency balance corrections
838
+ *
839
+ * Security Considerations:
840
+ * - No underflow protection: treasury must ensure sufficient balance
841
+ * - Can result in unexpected negative balances if misused
842
+ * - Treasury contract should implement additional validation
843
+ *
844
+ * @param user Address of the user to remove tokens from
845
+ * @param token Address of the token contract to remove balance for
846
+ * @param amount Amount of tokens to remove from the user's balance
847
+ *
848
+ * @custom:access-control Only treasury contract
849
+ * @custom:security No underflow protection - treasury responsibility
850
+ */
851
+ function removeAmountFromUser(
852
+ address user,
853
+ address token,
854
+ uint256 amount
855
+ ) external {
856
+ if (msg.sender != treasuryAddress)
857
+ revert ErrorsLib.SenderIsNotTreasury();
858
+
859
+ balances[user][token] -= amount;
860
+ }
861
+
862
+ //█ Internal Functions ███████████████████████████████████████████████████████████████████
863
+
864
+ //█ Balance Management Functions █████████████████████████████████████████████
865
+
866
+ /**
867
+ * @notice Internal function to safely transfer tokens between addresses
868
+ * @dev Performs balance validation and atomic transfer with overflow protection
869
+ *
870
+ * Transfer Process:
871
+ * - Validates sender has sufficient balance
872
+ * - Performs atomic balance updates using unchecked arithmetic
873
+ * - Returns success/failure status for error handling
874
+ *
875
+ * Security Features:
876
+ * - Balance validation prevents overdrafts
877
+ * - Unchecked arithmetic for gas optimization (overflow impossible)
878
+ * - Returns boolean for caller error handling
879
+ *
880
+ * @param from Address to transfer tokens from
881
+ * @param to Address to transfer tokens to
882
+ * @param token Address of the token contract
883
+ * @param value Amount of tokens to transfer
884
+ * @return success True if transfer completed, false if insufficient balance
885
+ */
886
+ function _updateBalance(
887
+ address from,
888
+ address to,
889
+ address token,
890
+ uint256 value
891
+ ) internal returns (bool) {
892
+ uint256 fromBalance = balances[from][token];
893
+ if (fromBalance < value) {
894
+ return false;
895
+ } else {
896
+ unchecked {
897
+ balances[from][token] = fromBalance - value;
898
+ balances[to][token] += value;
899
+ }
900
+ return true;
901
+ }
902
+ }
903
+
904
+ /**
905
+ * @notice Internal function to distribute Principal Token rewards to stakers
906
+ * @dev Provides incentive distribution for transaction processing and staking participation
907
+ *
908
+ * Reward System:
909
+ * - Calculates reward based on system reward rate and transaction count
910
+ * - Directly increases principal token balance for gas efficiency
911
+ * - Returns success status for error handling in calling functions
912
+ *
913
+ * Reward Calculation:
914
+ * - Base reward per transaction: evvmMetadata.reward
915
+ * - Total reward: base_reward × transaction_amount
916
+ * - Added directly to user's Principal Token balance
917
+ *
918
+ * @param user Address of the staker to receive principal tokenrewards
919
+ * @param amount Number of transactions or reward multiplier
920
+ * @return success True if reward distribution completed successfully
921
+ */
922
+ function _giveReward(address user, uint256 amount) internal returns (bool) {
923
+ uint256 principalReward = evvmMetadata.reward * amount;
924
+ uint256 userBalance = balances[user][
925
+ evvmMetadata.principalTokenAddress
926
+ ];
927
+
928
+ balances[user][evvmMetadata.principalTokenAddress] =
929
+ userBalance +
930
+ principalReward;
931
+
932
+ return (userBalance + principalReward ==
933
+ balances[user][evvmMetadata.principalTokenAddress]);
934
+ }
935
+
936
+ //█ Administrative Functions ██████████████████████████████████████████████████████████████
937
+
938
+ //█ Proxy Management Functions █████████████████████████████████████████████
939
+
940
+ /**
941
+ * @notice Proposes a new implementation contract for the proxy with time delay
942
+ * @dev Part of the time-delayed governance system for critical upgrades
943
+ *
944
+ * Upgrade Security:
945
+ * - 30-day time delay for implementation changes
946
+ * - Only admin can propose upgrades
947
+ * - Allows time for community review and validation
948
+ * - Can be rejected before acceptance deadline
949
+ *
950
+ * @param _newImpl Address of the new implementation contract
951
+ */
952
+ function proposeImplementation(address _newImpl) external onlyAdmin {
953
+ proposalImplementation = _newImpl;
954
+ timeToAcceptImplementation = block.timestamp + 30 days;
955
+ }
956
+
957
+ /**
958
+ * @notice Cancels a pending implementation upgrade proposal
959
+ * @dev Allows admin to reject proposed upgrades before the time delay expires
960
+ */
961
+ function rejectUpgrade() external onlyAdmin {
962
+ proposalImplementation = address(0);
963
+ timeToAcceptImplementation = 0;
964
+ }
965
+
966
+ /**
967
+ * @notice Accepts a pending implementation upgrade after the time delay
968
+ * @dev Executes the proxy upgrade to the new implementation contract
969
+ */
970
+ function acceptImplementation() external onlyAdmin {
971
+ if (block.timestamp < timeToAcceptImplementation) revert();
972
+ currentImplementation = proposalImplementation;
973
+ proposalImplementation = address(0);
974
+ timeToAcceptImplementation = 0;
975
+ }
976
+
977
+ //█ NameService Integration Functions ████████████████████████████████████████
978
+
979
+ /**
980
+ * @notice Updates the NameService contract address for identity resolution
981
+ * @dev Allows admin to change the NameService integration address
982
+ * @param _nameServiceAddress Address of the new NameService contract
983
+ */
984
+ function setNameServiceAddress(
985
+ address _nameServiceAddress
986
+ ) external onlyAdmin {
987
+ nameServiceAddress = _nameServiceAddress;
988
+ }
989
+
990
+ //█ Admin Management Functions ███████████████████████████████████████████████
991
+
992
+ /**
993
+ * @notice Proposes a new admin address with 1-day time delay
994
+ * @dev Part of the time-delayed governance system for admin changes
995
+ * @param _newOwner Address of the proposed new admin
996
+ */
997
+ function proposeAdmin(address _newOwner) external onlyAdmin {
998
+ if (_newOwner == address(0) || _newOwner == admin.current) {
999
+ revert();
1000
+ }
1001
+
1002
+ admin.proposal = _newOwner;
1003
+ admin.timeToAccept = block.timestamp + 1 days;
1004
+ }
1005
+
1006
+ /**
1007
+ * @notice Cancels a pending admin change proposal
1008
+ * @dev Allows current admin to reject proposed admin changes
1009
+ */
1010
+ function rejectProposalAdmin() external onlyAdmin {
1011
+ admin.proposal = address(0);
1012
+ admin.timeToAccept = 0;
1013
+ }
1014
+
1015
+ /**
1016
+ * @notice Accepts a pending admin proposal and becomes the new admin
1017
+ * @dev Can only be called by the proposed admin after the time delay
1018
+ */
1019
+ function acceptAdmin() external {
1020
+ if (block.timestamp < admin.timeToAccept) {
1021
+ revert();
1022
+ }
1023
+ if (msg.sender != admin.proposal) {
1024
+ revert();
1025
+ }
1026
+
1027
+ admin.current = admin.proposal;
1028
+
1029
+ admin.proposal = address(0);
1030
+ admin.timeToAccept = 0;
1031
+ }
1032
+
1033
+ //█ Reward System Functions ███████████████████████████████████████████████████████████████
1034
+
1035
+ /**
1036
+ * @notice Triggers a reward recalculation and era transition in the token economy
1037
+ * @dev Implements deflationary tokenomics with halving mechanism and random rewards
1038
+ *
1039
+ * Era Transition Mechanism:
1040
+ * - Activates when total supply exceeds current era token threshold
1041
+ * - Moves half of remaining tokens to next era threshold
1042
+ * - Halves the base reward amount for future transactions
1043
+ * - Provides random Principal Token bonus to caller (1-5083x reward)
1044
+ *
1045
+ * Economic Impact:
1046
+ * - Gradually reduces inflation through reward halving
1047
+ * - Creates scarcity as era thresholds become harder to reach
1048
+ * - Incentivizes early participation with higher rewards
1049
+ * - Provides lottery-style bonus for triggering era transitions
1050
+ *
1051
+ * Requirements:
1052
+ * - Total supply must exceed current era token threshold
1053
+ * - Can be called by anyone when conditions are met
1054
+ */
1055
+ function recalculateReward() public {
1056
+ if (evvmMetadata.totalSupply > evvmMetadata.eraTokens) {
1057
+ evvmMetadata.eraTokens += ((evvmMetadata.totalSupply -
1058
+ evvmMetadata.eraTokens) / 2);
1059
+ balances[msg.sender][evvmMetadata.principalTokenAddress] +=
1060
+ evvmMetadata.reward *
1061
+ getRandom(1, 5083);
1062
+ evvmMetadata.reward = evvmMetadata.reward / 2;
1063
+ } else {
1064
+ revert();
1065
+ }
1066
+ }
1067
+
1068
+ /**
1069
+ * @notice Generates a pseudo-random number within a specified range
1070
+ * @dev Uses block timestamp and prevrandao for randomness (suitable for non-critical randomness)
1071
+ *
1072
+ * Randomness Source:
1073
+ * - Combines block.timestamp and block.prevrandao
1074
+ * - Suitable for reward bonuses and non-security-critical randomness
1075
+ * - Not suitable for high-stakes randomness requiring true unpredictability
1076
+ *
1077
+ * @param min Minimum value (inclusive)
1078
+ * @param max Maximum value (inclusive)
1079
+ * @return Random number between min and max (inclusive)
1080
+ */
1081
+ function getRandom(
1082
+ uint256 min,
1083
+ uint256 max
1084
+ ) internal view returns (uint256) {
1085
+ return
1086
+ min +
1087
+ (uint256(
1088
+ keccak256(abi.encodePacked(block.timestamp, block.prevrandao))
1089
+ ) % (max - min + 1));
1090
+ }
1091
+
1092
+ //█ Staking Integration Functions █████████████████████████████████████████████████████████
1093
+
1094
+ /**
1095
+ * @notice Updates staker status for a user address
1096
+ * @dev Can only be called by the authorized staking contract
1097
+ *
1098
+ * Staker Status Management:
1099
+ * - Controls who can earn staking rewards and process transactions
1100
+ * - Integrates with external staking contract for validation
1101
+ * - Updates affect payment processing privileges and reward eligibility
1102
+ *
1103
+ * Access Control:
1104
+ * - Only the registered staking contract can call this function
1105
+ * - Ensures staker status changes are properly authorized
1106
+ *
1107
+ * @param user Address to update staker status for
1108
+ * @param answer Bytes1 flag indicating staker status/type
1109
+ */
1110
+ function pointStaker(address user, bytes1 answer) public {
1111
+ if (msg.sender != stakingContractAddress) {
1112
+ revert();
1113
+ }
1114
+ stakerList[user] = answer;
1115
+ }
1116
+
1117
+ //█ View Functions ████████████████████████████████████████████████████████████████████████
1118
+
1119
+ /**
1120
+ * @notice Returns the complete EVVM metadata configuration
1121
+ * @dev Provides access to system-wide configuration and economic parameters
1122
+ *
1123
+ * Metadata Contents:
1124
+ * - Principal token address (Principal Token)
1125
+ * - Current reward amount per transaction
1126
+ * - Total supply tracking
1127
+ * - Era tokens threshold for reward transitions
1128
+ * - System configuration parameters
1129
+ *
1130
+ * @return Complete EvvmMetadata struct with all system parameters
1131
+ */
1132
+ function getEvvmMetadata() external view returns (EvvmMetadata memory) {
1133
+ return evvmMetadata;
1134
+ }
1135
+
1136
+ /**
1137
+ * @notice Gets the unique identifier string for this EVVM instance
1138
+ * @dev Returns the EvvmID used for distinguishing different EVVM deployments
1139
+ * @return Unique EvvmID string
1140
+ */
1141
+ function getEvvmID() external view returns (uint256) {
1142
+ return evvmMetadata.EvvmID;
1143
+ }
1144
+
1145
+ /**
1146
+ * @notice Gets the acceptance deadline for pending token whitelist proposals
1147
+ * @dev Returns timestamp when prepared tokens can be added to whitelist
1148
+ * @return Timestamp when pending token can be whitelisted (0 if no pending proposal)
1149
+ */
1150
+ function getWhitelistTokenToBeAddedDateToSet()
1151
+ external
1152
+ view
1153
+ returns (uint256)
1154
+ {
1155
+ return whitelistTokenToBeAdded_dateToSet;
1156
+ }
1157
+
1158
+ /**
1159
+ * @notice Gets the current NameService contract address
1160
+ * @dev Returns the address used for identity resolution in payments
1161
+ * @return Address of the integrated NameService contract
1162
+ */
1163
+ function getNameServiceAddress() external view returns (address) {
1164
+ return nameServiceAddress;
1165
+ }
1166
+
1167
+ /**
1168
+ * @notice Gets the authorized staking contract address
1169
+ * @dev Returns the address that can modify staker status and receive rewards
1170
+ * @return Address of the integrated staking contract
1171
+ */
1172
+ function getStakingContractAddress() external view returns (address) {
1173
+ return stakingContractAddress;
1174
+ }
1175
+
1176
+ /**
1177
+ * @notice Gets the next synchronous nonce for a user
1178
+ * @dev Returns the expected nonce for the next sync payment transaction
1179
+ * @param user Address to check sync nonce for
1180
+ * @return Next synchronous nonce value
1181
+ */
1182
+ function getNextCurrentSyncNonce(
1183
+ address user
1184
+ ) external view returns (uint256) {
1185
+ return nextSyncUsedNonce[user];
1186
+ }
1187
+
1188
+ /**
1189
+ * @notice Checks if a specific async nonce has been used by a user
1190
+ * @dev Verifies nonce status to prevent replay attacks in async payments
1191
+ * @param user Address to check nonce usage for
1192
+ * @param nonce Specific nonce value to verify
1193
+ * @return True if the nonce has been used, false if still available
1194
+ */
1195
+ function getIfUsedAsyncNonce(
1196
+ address user,
1197
+ uint256 nonce
1198
+ ) external view returns (bool) {
1199
+ return asyncUsedNonce[user][nonce];
1200
+ }
1201
+
1202
+ /**
1203
+ * @notice Gets the next Fisher Bridge deposit nonce for a user
1204
+ * @dev Returns the expected nonce for the next cross-chain deposit
1205
+ * @param user Address to check deposit nonce for
1206
+ * @return Next Fisher Bridge deposit nonce
1207
+ */
1208
+ function getNextFisherDepositNonce(
1209
+ address user
1210
+ ) external view returns (uint256) {
1211
+ return nextFisherDepositNonce[user];
1212
+ }
1213
+
1214
+ /**
1215
+ * @notice Gets the balance of a specific token for a user
1216
+ * @dev Returns the current balance stored in the EVVM system
1217
+ * @param user Address to check balance for
1218
+ * @param token Token contract address to check
1219
+ * @return Current token balance for the user
1220
+ */
1221
+ function getBalance(
1222
+ address user,
1223
+ address token
1224
+ ) external view returns (uint) {
1225
+ return balances[user][token];
1226
+ }
1227
+
1228
+ /**
1229
+ * @notice Checks if an address is registered as a staker
1230
+ * @dev Verifies staker status for transaction processing privileges and rewards
1231
+ * @param user Address to check staker status for
1232
+ * @return True if the address is a registered staker
1233
+ */
1234
+ function isAddressStaker(address user) public view returns (bool) {
1235
+ return stakerList[user] == FLAG_IS_STAKER;
1236
+ }
1237
+
1238
+ /**
1239
+ * @notice Gets the current era token threshold for reward transitions
1240
+ * @dev Returns the token supply threshold that triggers the next reward halving
1241
+ * @return Current era tokens threshold
1242
+ */
1243
+ function getEraPrincipalToken() public view returns (uint256) {
1244
+ return evvmMetadata.eraTokens;
1245
+ }
1246
+
1247
+ /**
1248
+ * @notice Gets the current Principal Token reward amount per transaction
1249
+ * @dev Returns the base reward distributed to stakers for transaction processing
1250
+ * @return Current reward amount in MATE tokens
1251
+ */
1252
+ function getRewardAmount() public view returns (uint256) {
1253
+ return evvmMetadata.reward;
1254
+ }
1255
+
1256
+ /**
1257
+ * @notice Gets the total supply of the principal token (MATE)
1258
+ * @dev Returns the current total supply used for era transition calculations
1259
+ * @return Total supply of MATE tokens
1260
+ */
1261
+ function getPrincipalTokenTotalSupply() public view returns (uint256) {
1262
+ return evvmMetadata.totalSupply;
1263
+ }
1264
+
1265
+ /**
1266
+ * @notice Gets the current active implementation contract address
1267
+ * @dev Returns the implementation used by the proxy for delegatecalls
1268
+ * @return Address of the current implementation contract
1269
+ */
1270
+ function getCurrentImplementation() public view returns (address) {
1271
+ return currentImplementation;
1272
+ }
1273
+
1274
+ /**
1275
+ * @notice Gets the proposed implementation contract address
1276
+ * @dev Returns the implementation pending approval for proxy upgrade
1277
+ * @return Address of the proposed implementation contract (zero if none)
1278
+ */
1279
+ function getProposalImplementation() public view returns (address) {
1280
+ return proposalImplementation;
1281
+ }
1282
+
1283
+ /**
1284
+ * @notice Gets the acceptance deadline for the pending implementation upgrade
1285
+ * @dev Returns timestamp when the proposed implementation can be accepted
1286
+ * @return Timestamp when implementation upgrade can be executed (0 if no pending proposal)
1287
+ */
1288
+ function getTimeToAcceptImplementation() public view returns (uint256) {
1289
+ return timeToAcceptImplementation;
1290
+ }
1291
+
1292
+ /**
1293
+ * @notice Gets the current admin address
1294
+ * @dev Returns the address with administrative privileges over the contract
1295
+ * @return Address of the current admin
1296
+ */
1297
+ function getCurrentAdmin() public view returns (address) {
1298
+ return admin.current;
1299
+ }
1300
+
1301
+ /**
1302
+ * @notice Gets the proposed admin address
1303
+ * @dev Returns the address pending approval for admin privileges
1304
+ * @return Address of the proposed admin (zero if no pending proposal)
1305
+ */
1306
+ function getProposalAdmin() public view returns (address) {
1307
+ return admin.proposal;
1308
+ }
1309
+
1310
+ /**
1311
+ * @notice Gets the acceptance deadline for the pending admin change
1312
+ * @dev Returns timestamp when the proposed admin can accept the role
1313
+ * @return Timestamp when admin change can be executed (0 if no pending proposal)
1314
+ */
1315
+ function getTimeToAcceptAdmin() public view returns (uint256) {
1316
+ return admin.timeToAccept;
1317
+ }
1318
+
1319
+ /**
1320
+ * @notice Gets the address of the token pending whitelist approval
1321
+ * @dev Returns the token address that can be whitelisted after time delay
1322
+ * @return Address of the token prepared for whitelisting (zero if none)
1323
+ */
1324
+ function getWhitelistTokenToBeAdded() public view returns (address) {
1325
+ return whitelistTokenToBeAdded_address;
1326
+ }
1327
+ }