@evvm/testnet-contracts 2.2.2 → 2.3.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 +145 -118
  2. package/README.md +135 -42
  3. package/contracts/evvm/Evvm.sol +154 -181
  4. package/contracts/evvm/lib/ErrorsLib.sol +119 -6
  5. package/contracts/evvm/lib/EvvmStorage.sol +164 -9
  6. package/contracts/evvm/lib/EvvmStructs.sol +124 -6
  7. package/contracts/evvm/lib/SignatureUtils.sol +103 -61
  8. package/contracts/nameService/NameService.sol +165 -155
  9. package/contracts/nameService/lib/ErrorsLib.sol +142 -8
  10. package/contracts/nameService/lib/IdentityValidation.sol +21 -0
  11. package/contracts/nameService/lib/NameServiceStructs.sol +75 -19
  12. package/contracts/nameService/lib/SignatureUtils.sol +235 -60
  13. package/contracts/p2pSwap/P2PSwap.sol +205 -164
  14. package/contracts/staking/Estimator.sol +131 -24
  15. package/contracts/staking/Staking.sol +98 -113
  16. package/contracts/staking/lib/ErrorsLib.sol +79 -3
  17. package/contracts/staking/lib/SignatureUtils.sol +82 -16
  18. package/contracts/staking/lib/StakingStructs.sol +12 -0
  19. package/contracts/treasury/Treasury.sol +30 -12
  20. package/contracts/treasury/lib/ErrorsLib.sol +30 -0
  21. package/contracts/treasuryTwoChains/TreasuryHostChainStation.sol +3 -3
  22. package/interfaces/IEvvm.sol +9 -4
  23. package/interfaces/INameService.sol +12 -3
  24. package/interfaces/IStaking.sol +2 -1
  25. package/library/Erc191TestBuilder.sol +188 -0
  26. package/library/EvvmService.sol +55 -0
  27. package/library/primitives/SignatureRecover.sol +33 -0
  28. package/library/utils/AdvancedStrings.sol +61 -0
  29. package/library/utils/SignatureUtil.sol +34 -0
  30. package/library/utils/nonces/AsyncNonce.sol +42 -0
  31. package/library/utils/nonces/SyncNonce.sol +44 -0
  32. package/library/utils/service/EvvmPayments.sol +68 -1
  33. package/library/utils/service/StakingServiceUtils.sol +44 -0
  34. package/package.json +2 -1
@@ -29,40 +29,48 @@ pragma solidity ^0.8.0;
29
29
 
30
30
  import {IERC20} from "@evvm/testnet-contracts/library/primitives/IERC20.sol";
31
31
  import {SafeTransferLib} from "@solady/utils/SafeTransferLib.sol";
32
- import {IEvvm} from "@evvm/testnet-contracts/interfaces/IEvvm.sol";
32
+ import {Evvm} from "@evvm/testnet-contracts/contracts/evvm/Evvm.sol";
33
33
  import {
34
34
  ErrorsLib
35
35
  } from "@evvm/testnet-contracts/contracts/treasury/lib/ErrorsLib.sol";
36
36
 
37
37
  contract Treasury {
38
-
39
- IEvvm evvm;
38
+ /// @dev Reference to the EVVM core contract for balance management
39
+ Evvm evvm;
40
40
 
41
41
  /**
42
42
  * @notice Initialize Treasury with EVVM contract address
43
43
  * @param _evvmAddress Address of the EVVM core contract
44
44
  */
45
45
  constructor(address _evvmAddress) {
46
- evvm = IEvvm(_evvmAddress);
46
+ evvm = Evvm(_evvmAddress);
47
47
  }
48
48
 
49
49
  /**
50
- * @notice Deposit ETH or ERC20 tokens
51
- * @param token ERC20 token address (ignored for ETH deposits)
52
- * @param amount Token amount (ignored for ETH deposits)
50
+ * @notice Deposit ETH or ERC20 tokens into the EVVM ecosystem
51
+ * @dev For ETH deposits: token must be address(0) and amount must equal msg.value
52
+ * For ERC20 deposits: msg.value must be 0 and token must be a valid ERC20 contract
53
+ * Deposited funds are credited to the user's EVVM balance and can be used for
54
+ * gasless transactions within the ecosystem.
55
+ * @param token ERC20 token address (use address(0) for ETH deposits)
56
+ * @param amount Token amount to deposit (must match msg.value for ETH deposits)
57
+ * @custom:throws DepositAmountMustBeGreaterThanZero If amount/msg.value is zero
58
+ * @custom:throws InvalidDepositAmount If amount doesn't match msg.value (ETH) or msg.value != 0 (ERC20)
53
59
  */
54
60
  function deposit(address token, uint256 amount) external payable {
55
61
  if (address(0) == token) {
56
62
  /// user is sending host native coin
57
63
  if (msg.value == 0)
58
64
  revert ErrorsLib.DepositAmountMustBeGreaterThanZero();
65
+
59
66
  if (amount != msg.value) revert ErrorsLib.InvalidDepositAmount();
60
67
 
61
68
  evvm.addAmountToUser(msg.sender, address(0), msg.value);
62
69
  } else {
63
70
  /// user is sending ERC20 tokens
64
71
 
65
- if (msg.value != 0) revert ErrorsLib.InvalidDepositAmount();
72
+ if (msg.value != 0) revert ErrorsLib.DepositCoinWithToken();
73
+
66
74
  if (amount == 0)
67
75
  revert ErrorsLib.DepositAmountMustBeGreaterThanZero();
68
76
 
@@ -72,12 +80,17 @@ contract Treasury {
72
80
  }
73
81
 
74
82
  /**
75
- * @notice Withdraw ETH or ERC20 tokens
76
- * @param token Token address (address(0) for ETH)
77
- * @param amount Amount to withdraw
83
+ * @notice Withdraw ETH or ERC20 tokens from the EVVM ecosystem
84
+ * @dev Withdraws tokens from the user's EVVM balance back to their wallet.
85
+ * Principal Tokens cannot be withdrawn through this function - they can
86
+ * only be transferred via EVVM pay operations.
87
+ * @param token Token address to withdraw (use address(0) for ETH)
88
+ * @param amount Amount of tokens to withdraw
89
+ * @custom:throws PrincipalTokenIsNotWithdrawable If attempting to withdraw Principal Tokens
90
+ * @custom:throws InsufficientBalance If user's EVVM balance is less than withdrawal amount
78
91
  */
79
92
  function withdraw(address token, uint256 amount) external {
80
- if (token == evvm.getEvvmMetadata().principalTokenAddress)
93
+ if (token == evvm.getPrincipalTokenAddress())
81
94
  revert ErrorsLib.PrincipalTokenIsNotWithdrawable();
82
95
 
83
96
  if (evvm.getBalance(msg.sender, token) < amount)
@@ -96,6 +109,11 @@ contract Treasury {
96
109
  }
97
110
  }
98
111
 
112
+ /**
113
+ * @notice Returns the address of the connected EVVM core contract
114
+ * @dev Used for verification and integration purposes
115
+ * @return Address of the EVVM contract managing balances
116
+ */
99
117
  function getEvvmAddress() external view returns (address) {
100
118
  return address(evvm);
101
119
  }
@@ -2,10 +2,40 @@
2
2
  // Full license terms available at: https://www.evvm.info/docs/EVVMNoncommercialLicense
3
3
 
4
4
  pragma solidity ^0.8.0;
5
+ /**
6
+ * @title ErrorsLib
7
+ * @author Mate Labs
8
+ * @notice Library containing all custom error definitions for the Treasury contract
9
+ * @dev This library is exclusive to the Treasury.sol contract and provides descriptive
10
+ * error types for deposit and withdrawal operations.
11
+ *
12
+ * Error Categories:
13
+ * - Balance Errors: Insufficient funds for operations
14
+ * - Deposit Errors: Invalid deposit amounts or configurations
15
+ * - Withdrawal Restrictions: Token withdrawal limitations
16
+ */
5
17
 
6
18
  library ErrorsLib {
19
+ //█ Balance Errors ███████████████████████████████████████████████████████████████████████████████
20
+
21
+ /// @dev Thrown when a user attempts to withdraw more tokens than their available balance
7
22
  error InsufficientBalance();
23
+
24
+ //█ Withdrawal Restriction Errors ████████████████████████████████████████████████████████████████
25
+
26
+ /// @dev Thrown when attempting to withdraw Principal Tokens through the Treasury
27
+ /// @notice Principal Tokens can only be transferred through EVVM pay operations, not direct withdrawal
8
28
  error PrincipalTokenIsNotWithdrawable();
29
+
30
+ //█ Deposit Errors ███████████████████████████████████████████████████████████████████████████████
31
+
32
+ /// @dev Thrown when the deposit amount doesn't match msg.value for ETH deposits,
33
+ /// or when msg.value is non-zero for ERC20 deposits
9
34
  error InvalidDepositAmount();
35
+
36
+ /// @dev Thrown when attempting to deposit zero amount of tokens or ETH
10
37
  error DepositAmountMustBeGreaterThanZero();
38
+
39
+ /// @dev Thrown when attempting to deposit blockchain native coin while also sending ERC20 tokens
40
+ error DepositCoinWithToken();
11
41
  }
@@ -32,7 +32,7 @@ pragma solidity ^0.8.0;
32
32
  */
33
33
 
34
34
  import {IERC20} from "@evvm/testnet-contracts/library/primitives/IERC20.sol";
35
- import {IEvvm} from "@evvm/testnet-contracts/interfaces/IEvvm.sol";
35
+ import {Evvm} from "@evvm/testnet-contracts/contracts/evvm/Evvm.sol";
36
36
  import {
37
37
  ErrorsLib
38
38
  } from "@evvm/testnet-contracts/contracts/treasuryTwoChains/lib/ErrorsLib.sol";
@@ -87,7 +87,7 @@ contract TreasuryHostChainStation is
87
87
  {
88
88
  /// @notice EVVM core contract for balance operations
89
89
  /// @dev Used to integrate with EVVM's balance management and token operations
90
- IEvvm evvm;
90
+ Evvm evvm;
91
91
 
92
92
  /// @notice Admin address management with time-delayed proposals
93
93
  /// @dev Stores current admin, proposed admin, and acceptance timestamp
@@ -178,7 +178,7 @@ contract TreasuryHostChainStation is
178
178
  Ownable(_admin)
179
179
  AxelarExecutable(_crosschainConfig.axelar.gatewayAddress)
180
180
  {
181
- evvm = IEvvm(_evvmAddress);
181
+ evvm = Evvm(_evvmAddress);
182
182
 
183
183
  admin = AddressTypeProposal({
184
184
  current: _admin,
@@ -40,16 +40,22 @@ library EvvmStructs {
40
40
  }
41
41
 
42
42
  interface IEvvm {
43
+ error AddressCantBeZero();
43
44
  error AsyncNonceAlreadyUsed();
45
+ error BreakerExploded();
46
+ error ImplementationIsNotActive();
47
+ error IncorrectAddressInput();
44
48
  error InsufficientBalance();
45
- error InvalidAmount(uint256, uint256);
49
+ error InvalidAmount();
46
50
  error InvalidSignature();
47
51
  error NotAnCA();
52
+ error SenderIsNotAdmin();
48
53
  error SenderIsNotTheExecutor();
54
+ error SenderIsNotTheProposedAdmin();
49
55
  error SenderIsNotTreasury();
50
56
  error SyncNonceMismatch();
51
- error UpdateBalanceFailed();
52
- error WindowToChangeEvvmIDExpired();
57
+ error TimeLockNotExpired();
58
+ error WindowExpired();
53
59
 
54
60
  fallback() external;
55
61
 
@@ -116,6 +122,5 @@ interface IEvvm {
116
122
  function rejectUpgrade() external;
117
123
  function removeAmountFromUser(address user, address token, uint256 amount) external;
118
124
  function setEvvmID(uint256 newEvvmID) external;
119
- function setNameServiceAddress(address _nameServiceAddress) external;
120
125
  function setPointStaker(address user, bytes1 answer) external;
121
126
  }
@@ -11,16 +11,24 @@ library NameServiceStructs {
11
11
  }
12
12
 
13
13
  interface INameService {
14
- error AcceptOfferVerificationFailed();
14
+ error AmountMustBeGreaterThanZero();
15
15
  error AsyncNonceAlreadyUsed();
16
+ error CannotBeBeforeCurrentTime();
16
17
  error EmptyCustomMetadata();
17
- error FlushUsernameVerificationFailed();
18
+ error IdentityIsNotAUsername();
19
+ error InvalidAdminProposal();
20
+ error InvalidEvvmAddress();
18
21
  error InvalidKey();
19
22
  error InvalidSignatureOnNameService();
20
23
  error InvalidUsername();
24
+ error InvalidWithdrawAmount();
25
+ error LockTimeNotExpired();
26
+ error OfferInactive();
27
+ error OwnershipExpired();
21
28
  error PreRegistrationNotValid();
22
- error RenewUsernameVerificationFailed();
29
+ error RenewalTimeLimitExceeded();
23
30
  error SenderIsNotAdmin();
31
+ error SenderIsNotProposedAdmin();
24
32
  error UserIsNotOwnerOfIdentity();
25
33
  error UserIsNotOwnerOfOffer();
26
34
  error UsernameAlreadyRegistered();
@@ -85,6 +93,7 @@ interface INameService {
85
93
  external
86
94
  view
87
95
  returns (address currentEvvmAddress, address proposalEvvmAddress, uint256 timeToAcceptEvvmAddress);
96
+ function getEvvmID() external view returns (uint256);
88
97
  function getExpireDateOfIdentity(string memory _identity) external view returns (uint256);
89
98
  function getFullCustomMetadataOfIdentity(string memory _username) external view returns (string[] memory);
90
99
  function getIdentityBasicMetadata(string memory _username) external view returns (address, uint256);
@@ -50,11 +50,12 @@ interface IStaking {
50
50
  external
51
51
  view
52
52
  returns (StakingStructs.HistoryMetadata memory);
53
- function getAllDataOfAllowPublicStaking() external view returns (StakingStructs.BoolTypeProposal memory);
54
53
  function getAllowPresaleStaking() external view returns (StakingStructs.BoolTypeProposal memory);
54
+ function getAllowPublicStaking() external view returns (StakingStructs.BoolTypeProposal memory);
55
55
  function getEstimatorAddress() external view returns (address);
56
56
  function getEstimatorProposal() external view returns (address);
57
57
  function getEvvmAddress() external view returns (address);
58
+ function getEvvmID() external view returns (uint256);
58
59
  function getGoldenFisher() external view returns (address);
59
60
  function getGoldenFisherProposal() external view returns (address);
60
61
  function getIfUsedAsyncNonce(address user, uint256 nonce) external view returns (bool);
@@ -17,6 +17,21 @@ library Erc191TestBuilder {
17
17
  //-----------------------------------------------------------------------------------
18
18
  // EVVM
19
19
  //-----------------------------------------------------------------------------------
20
+
21
+ /**
22
+ * @notice Builds the message hash for a pay operation signature
23
+ * @dev Creates an EIP-191 compatible hash for EVVM pay function
24
+ * @param evvmID Unique identifier of the EVVM instance
25
+ * @param _receiverAddress Address of the payment receiver (use address(0) if using identity)
26
+ * @param _receiverIdentity String identity of receiver (used if address is zero)
27
+ * @param _token Token address being transferred
28
+ * @param _amount Amount of tokens to transfer
29
+ * @param _priorityFee Priority fee for transaction processing
30
+ * @param _nonce Nonce for replay protection
31
+ * @param _priority_boolean True for async nonce, false for sync nonce
32
+ * @param _executor Address authorized to execute the transaction
33
+ * @return messageHash The EIP-191 formatted hash ready for signing
34
+ */
20
35
  function buildMessageSignedForPay(
21
36
  uint256 evvmID,
22
37
  address _receiverAddress,
@@ -52,6 +67,19 @@ library Erc191TestBuilder {
52
67
  messageHash = buildHashForSign(messageToSign);
53
68
  }
54
69
 
70
+ /**
71
+ * @notice Builds the message hash for a disperse pay operation signature
72
+ * @dev Creates an EIP-191 compatible hash for EVVM dispersePay function
73
+ * @param evvmID Unique identifier of the EVVM instance
74
+ * @param hashList Hash of the recipient list for batch payment
75
+ * @param _token Token address being transferred
76
+ * @param _amount Total amount of tokens to transfer
77
+ * @param _priorityFee Priority fee for transaction processing
78
+ * @param _nonce Nonce for replay protection
79
+ * @param _priority_boolean True for async nonce, false for sync nonce
80
+ * @param _executor Address authorized to execute the transaction
81
+ * @return messageHash The EIP-191 formatted hash ready for signing
82
+ */
55
83
  function buildMessageSignedForDispersePay(
56
84
  uint256 evvmID,
57
85
  bytes32 hashList,
@@ -90,6 +118,14 @@ library Erc191TestBuilder {
90
118
  // MATE NAME SERVICE
91
119
  //-----------------------------------------------------------------------------------
92
120
 
121
+ /**
122
+ * @notice Builds the message hash for username pre-registration
123
+ * @dev Creates an EIP-191 compatible hash for NameService preRegistrationUsername
124
+ * @param evvmID Unique identifier of the EVVM instance
125
+ * @param _hashUsername Hash of username + random number for commit-reveal
126
+ * @param _nameServiceNonce Nonce for NameService replay protection
127
+ * @return messageHash The EIP-191 formatted hash ready for signing
128
+ */
93
129
  function buildMessageSignedForPreRegistrationUsername(
94
130
  uint256 evvmID,
95
131
  bytes32 _hashUsername,
@@ -109,6 +145,15 @@ library Erc191TestBuilder {
109
145
  );
110
146
  }
111
147
 
148
+ /**
149
+ * @notice Builds the message hash for username registration
150
+ * @dev Creates an EIP-191 compatible hash for NameService registrationUsername
151
+ * @param evvmID Unique identifier of the EVVM instance
152
+ * @param _username The username being registered
153
+ * @param _clowNumber Random number from pre-registration
154
+ * @param _nameServiceNonce Nonce for NameService replay protection
155
+ * @return messageHash The EIP-191 formatted hash ready for signing
156
+ */
112
157
  function buildMessageSignedForRegistrationUsername(
113
158
  uint256 evvmID,
114
159
  string memory _username,
@@ -131,6 +176,16 @@ library Erc191TestBuilder {
131
176
  );
132
177
  }
133
178
 
179
+ /**
180
+ * @notice Builds the message hash for making a username offer
181
+ * @dev Creates an EIP-191 compatible hash for NameService makeOffer
182
+ * @param evvmID Unique identifier of the EVVM instance
183
+ * @param _username Target username for the offer
184
+ * @param _dateExpire Timestamp when the offer expires
185
+ * @param _amount Amount being offered in Principal Tokens
186
+ * @param _nameServiceNonce Nonce for NameService replay protection
187
+ * @return messageHash The EIP-191 formatted hash ready for signing
188
+ */
134
189
  function buildMessageSignedForMakeOffer(
135
190
  uint256 evvmID,
136
191
  string memory _username,
@@ -156,6 +211,15 @@ library Erc191TestBuilder {
156
211
  );
157
212
  }
158
213
 
214
+ /**
215
+ * @notice Builds the message hash for withdrawing a username offer
216
+ * @dev Creates an EIP-191 compatible hash for NameService withdrawOffer
217
+ * @param evvmID Unique identifier of the EVVM instance
218
+ * @param _username Username the offer was made for
219
+ * @param _offerId ID of the offer to withdraw
220
+ * @param _nameServiceNonce Nonce for NameService replay protection
221
+ * @return messageHash The EIP-191 formatted hash ready for signing
222
+ */
159
223
  function buildMessageSignedForWithdrawOffer(
160
224
  uint256 evvmID,
161
225
  string memory _username,
@@ -178,6 +242,15 @@ library Erc191TestBuilder {
178
242
  );
179
243
  }
180
244
 
245
+ /**
246
+ * @notice Builds the message hash for accepting a username offer
247
+ * @dev Creates an EIP-191 compatible hash for NameService acceptOffer
248
+ * @param evvmID Unique identifier of the EVVM instance
249
+ * @param _username Username being sold
250
+ * @param _offerId ID of the offer to accept
251
+ * @param _nameServiceNonce Nonce for NameService replay protection
252
+ * @return messageHash The EIP-191 formatted hash ready for signing
253
+ */
181
254
  function buildMessageSignedForAcceptOffer(
182
255
  uint256 evvmID,
183
256
  string memory _username,
@@ -200,6 +273,14 @@ library Erc191TestBuilder {
200
273
  );
201
274
  }
202
275
 
276
+ /**
277
+ * @notice Builds the message hash for renewing a username
278
+ * @dev Creates an EIP-191 compatible hash for NameService renewUsername
279
+ * @param evvmID Unique identifier of the EVVM instance
280
+ * @param _username Username to renew
281
+ * @param _nameServiceNonce Nonce for NameService replay protection
282
+ * @return messageHash The EIP-191 formatted hash ready for signing
283
+ */
203
284
  function buildMessageSignedForRenewUsername(
204
285
  uint256 evvmID,
205
286
  string memory _username,
@@ -219,6 +300,15 @@ library Erc191TestBuilder {
219
300
  );
220
301
  }
221
302
 
303
+ /**
304
+ * @notice Builds the message hash for adding custom metadata
305
+ * @dev Creates an EIP-191 compatible hash for NameService addCustomMetadata
306
+ * @param evvmID Unique identifier of the EVVM instance
307
+ * @param _username Username to add metadata to
308
+ * @param _value Metadata value following schema format
309
+ * @param _nameServiceNonce Nonce for NameService replay protection
310
+ * @return messageHash The EIP-191 formatted hash ready for signing
311
+ */
222
312
  function buildMessageSignedForAddCustomMetadata(
223
313
  uint256 evvmID,
224
314
  string memory _username,
@@ -241,6 +331,15 @@ library Erc191TestBuilder {
241
331
  );
242
332
  }
243
333
 
334
+ /**
335
+ * @notice Builds the message hash for removing custom metadata
336
+ * @dev Creates an EIP-191 compatible hash for NameService removeCustomMetadata
337
+ * @param evvmID Unique identifier of the EVVM instance
338
+ * @param _username Username to remove metadata from
339
+ * @param _key Index of the metadata entry to remove
340
+ * @param _nonce Nonce for NameService replay protection
341
+ * @return messageHash The EIP-191 formatted hash ready for signing
342
+ */
244
343
  function buildMessageSignedForRemoveCustomMetadata(
245
344
  uint256 evvmID,
246
345
  string memory _username,
@@ -263,6 +362,14 @@ library Erc191TestBuilder {
263
362
  );
264
363
  }
265
364
 
365
+ /**
366
+ * @notice Builds the message hash for flushing all custom metadata
367
+ * @dev Creates an EIP-191 compatible hash for NameService flushCustomMetadata
368
+ * @param evvmID Unique identifier of the EVVM instance
369
+ * @param _username Username to flush metadata from
370
+ * @param _nonce Nonce for NameService replay protection
371
+ * @return messageHash The EIP-191 formatted hash ready for signing
372
+ */
266
373
  function buildMessageSignedForFlushCustomMetadata(
267
374
  uint256 evvmID,
268
375
  string memory _username,
@@ -282,6 +389,14 @@ library Erc191TestBuilder {
282
389
  );
283
390
  }
284
391
 
392
+ /**
393
+ * @notice Builds the message hash for flushing a username
394
+ * @dev Creates an EIP-191 compatible hash for NameService flushUsername
395
+ * @param evvmID Unique identifier of the EVVM instance
396
+ * @param _username Username to completely remove
397
+ * @param _nonce Nonce for NameService replay protection
398
+ * @return messageHash The EIP-191 formatted hash ready for signing
399
+ */
285
400
  function buildMessageSignedForFlushUsername(
286
401
  uint256 evvmID,
287
402
  string memory _username,
@@ -305,6 +420,16 @@ library Erc191TestBuilder {
305
420
  // staking functions
306
421
  //-----------------------------------------------------------------------------------
307
422
 
423
+ /**
424
+ * @notice Builds the message hash for public service staking
425
+ * @dev Creates an EIP-191 compatible hash for Staking publicServiceStaking
426
+ * @param evvmID Unique identifier of the EVVM instance
427
+ * @param _serviceAddress Address of the service to stake for
428
+ * @param _isStaking True for staking, false for unstaking
429
+ * @param _amountOfStaking Amount of staking units
430
+ * @param _nonce Nonce for replay protection
431
+ * @return messageHash The EIP-191 formatted hash ready for signing
432
+ */
308
433
  function buildMessageSignedForPublicServiceStake(
309
434
  uint256 evvmID,
310
435
  address _serviceAddress,
@@ -330,6 +455,15 @@ library Erc191TestBuilder {
330
455
  );
331
456
  }
332
457
 
458
+ /**
459
+ * @notice Builds the message hash for public staking
460
+ * @dev Creates an EIP-191 compatible hash for Staking publicStaking
461
+ * @param evvmID Unique identifier of the EVVM instance
462
+ * @param _isStaking True for staking, false for unstaking
463
+ * @param _amountOfStaking Amount of staking units
464
+ * @param _nonce Nonce for replay protection
465
+ * @return messageHash The EIP-191 formatted hash ready for signing
466
+ */
333
467
  function buildMessageSignedForPublicStaking(
334
468
  uint256 evvmID,
335
469
  bool _isStaking,
@@ -352,6 +486,15 @@ library Erc191TestBuilder {
352
486
  );
353
487
  }
354
488
 
489
+ /**
490
+ * @notice Builds the message hash for presale staking
491
+ * @dev Creates an EIP-191 compatible hash for Staking presaleStaking
492
+ * @param evvmID Unique identifier of the EVVM instance
493
+ * @param _isStaking True for staking, false for unstaking
494
+ * @param _amountOfStaking Amount of staking units
495
+ * @param _nonce Nonce for replay protection
496
+ * @return messageHash The EIP-191 formatted hash ready for signing
497
+ */
355
498
  function buildMessageSignedForPresaleStaking(
356
499
  uint256 evvmID,
357
500
  bool _isStaking,
@@ -378,6 +521,17 @@ library Erc191TestBuilder {
378
521
  // P2PSwap functions
379
522
  //-----------------------------------------------------------------------------------
380
523
 
524
+ /**
525
+ * @notice Builds the message hash for making a P2P swap order
526
+ * @dev Creates an EIP-191 compatible hash for P2PSwap makeOrder
527
+ * @param evvmID Unique identifier of the EVVM instance
528
+ * @param _nonce Nonce for replay protection
529
+ * @param _tokenA Token address being offered
530
+ * @param _tokenB Token address being requested
531
+ * @param _amountA Amount of tokenA being offered
532
+ * @param _amountB Amount of tokenB being requested
533
+ * @return messageHash The EIP-191 formatted hash ready for signing
534
+ */
381
535
  function buildMessageSignedForMakeOrder(
382
536
  uint256 evvmID,
383
537
  uint256 _nonce,
@@ -406,6 +560,16 @@ library Erc191TestBuilder {
406
560
  );
407
561
  }
408
562
 
563
+ /**
564
+ * @notice Builds the message hash for canceling a P2P swap order
565
+ * @dev Creates an EIP-191 compatible hash for P2PSwap cancelOrder
566
+ * @param evvmID Unique identifier of the EVVM instance
567
+ * @param _nonce Nonce for replay protection
568
+ * @param _tokenA Token address that was offered
569
+ * @param _tokenB Token address that was requested
570
+ * @param _orderId ID of the order to cancel
571
+ * @return messageHash The EIP-191 formatted hash ready for signing
572
+ */
409
573
  function buildMessageSignedForCancelOrder(
410
574
  uint256 evvmID,
411
575
  uint256 _nonce,
@@ -431,6 +595,16 @@ library Erc191TestBuilder {
431
595
  );
432
596
  }
433
597
 
598
+ /**
599
+ * @notice Builds the message hash for dispatching (accepting) a P2P swap order
600
+ * @dev Creates an EIP-191 compatible hash for P2PSwap dispatchOrder
601
+ * @param evvmID Unique identifier of the EVVM instance
602
+ * @param _nonce Nonce for replay protection
603
+ * @param _tokenA Token address that was offered
604
+ * @param _tokenB Token address that was requested
605
+ * @param _orderId ID of the order to dispatch
606
+ * @return messageHash The EIP-191 formatted hash ready for signing
607
+ */
434
608
  function buildMessageSignedForDispatchOrder(
435
609
  uint256 evvmID,
436
610
  uint256 _nonce,
@@ -460,6 +634,12 @@ library Erc191TestBuilder {
460
634
  // General functions
461
635
  //-----------------------------------------------------------------------------------
462
636
 
637
+ /**
638
+ * @notice Creates an EIP-191 formatted hash from a message string
639
+ * @dev Prepends the Ethereum Signed Message prefix and message length
640
+ * @param messageToSign The message string to hash
641
+ * @return The EIP-191 formatted hash ready for signature verification
642
+ */
463
643
  function buildHashForSign(
464
644
  string memory messageToSign
465
645
  ) internal pure returns (bytes32) {
@@ -473,6 +653,14 @@ library Erc191TestBuilder {
473
653
  );
474
654
  }
475
655
 
656
+ /**
657
+ * @notice Combines signature components into a 65-byte signature
658
+ * @dev Packs r, s, and v into the standard EIP-191 signature format
659
+ * @param v Recovery identifier (27 or 28)
660
+ * @param r First 32 bytes of the signature
661
+ * @param s Second 32 bytes of the signature
662
+ * @return 65-byte encoded signature in (r, s, v) format
663
+ */
476
664
  function buildERC191Signature(
477
665
  uint8 v,
478
666
  bytes32 r,
@@ -2,6 +2,36 @@
2
2
  // Full license terms available at: https://www.evvm.info/docs/EVVMNoncommercialLicense
3
3
 
4
4
  pragma solidity ^0.8.0;
5
+ /**
6
+ * @title EvvmService
7
+ * @author Mate Labs
8
+ * @notice Abstract base contract for building services on the EVVM ecosystem
9
+ * @dev This contract provides a complete foundation for creating EVVM-compatible services.
10
+ * It combines multiple utility contracts to offer:
11
+ *
12
+ * Core Capabilities:
13
+ * - Async nonce management for replay protection (AsyncNonce)
14
+ * - Staking utilities for service-level staking (StakingServiceUtils)
15
+ * - Payment processing through the EVVM core (EvvmPayments)
16
+ * - EIP-191 signature verification for gasless transactions
17
+ *
18
+ * Usage:
19
+ * Inherit from this contract and implement your service logic. All signature
20
+ * verification, payment processing, and nonce management are handled automatically.
21
+ *
22
+ * Example:
23
+ * ```solidity
24
+ * contract MyService is EvvmService {
25
+ * constructor(address evvm, address staking)
26
+ * EvvmService(evvm, staking) {}
27
+ *
28
+ * function myFunction(address user, ..., bytes memory sig) external {
29
+ * validateServiceSignature("myFunction", "...", sig, user);
30
+ * // Your logic here
31
+ * }
32
+ * }
33
+ * ```
34
+ */
5
35
 
6
36
  import {EvvmStructs} from "@evvm/testnet-contracts/interfaces/IEvvm.sol";
7
37
  import {SignatureUtil} from "@evvm/testnet-contracts/library/utils/SignatureUtil.sol";
@@ -14,13 +44,29 @@ abstract contract EvvmService is
14
44
  StakingServiceUtils,
15
45
  EvvmPayments
16
46
  {
47
+ /// @dev Thrown when a signature verification fails for a service operation
17
48
  error InvalidServiceSignature();
18
49
 
50
+ /**
51
+ * @notice Initializes the EvvmService with EVVM and Staking contract addresses
52
+ * @param evvmAddress Address of the EVVM core contract for payment processing
53
+ * @param stakingAddress Address of the Staking contract for service staking operations
54
+ */
19
55
  constructor(
20
56
  address evvmAddress,
21
57
  address stakingAddress
22
58
  ) StakingServiceUtils(stakingAddress) EvvmPayments(evvmAddress) {}
23
59
 
60
+ /**
61
+ * @notice Validates an EIP-191 signature for a service operation
62
+ * @dev Verifies that the signature was created by the expected signer using the EVVM ID,
63
+ * function name, and inputs as the signed message
64
+ * @param functionName Name of the function being called (used in signature message)
65
+ * @param inputs Comma-separated string of function inputs (used in signature message)
66
+ * @param signature The EIP-191 signature to verify
67
+ * @param expectedSigner Address that should have signed the message
68
+ * @custom:throws InvalidServiceSignature If signature verification fails
69
+ */
24
70
  function validateServiceSignature(
25
71
  string memory functionName,
26
72
  string memory inputs,
@@ -37,4 +83,13 @@ abstract contract EvvmService is
37
83
  )
38
84
  ) revert InvalidServiceSignature();
39
85
  }
86
+
87
+ /**
88
+ * @notice Retrieves the unique EVVM instance identifier
89
+ * @dev Used internally for signature verification to ensure signatures are chain-specific
90
+ * @return The unique identifier of the connected EVVM instance
91
+ */
92
+ function getEvvmID() internal view returns (uint256) {
93
+ return evvm.getEvvmID();
94
+ }
40
95
  }