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