@evvm/testnet-contracts 2.2.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +145 -118
  2. package/README.md +162 -39
  3. package/contracts/core/Core.sol +1394 -0
  4. package/contracts/core/lib/CoreStorage.sol +171 -0
  5. package/contracts/nameService/NameService.sol +666 -586
  6. package/contracts/nameService/lib/IdentityValidation.sol +18 -3
  7. package/contracts/p2pSwap/P2PSwap.sol +439 -285
  8. package/contracts/staking/Estimator.sol +128 -40
  9. package/contracts/staking/Staking.sol +329 -322
  10. package/contracts/treasury/Treasury.sol +48 -37
  11. package/contracts/treasuryTwoChains/TreasuryExternalChainStation.sol +585 -198
  12. package/contracts/treasuryTwoChains/TreasuryHostChainStation.sol +425 -174
  13. package/contracts/treasuryTwoChains/lib/PayloadUtils.sol +2 -4
  14. package/interfaces/{IEvvm.sol → ICore.sol} +67 -29
  15. package/interfaces/IEstimator.sol +1 -1
  16. package/interfaces/INameService.sol +58 -52
  17. package/interfaces/IP2PSwap.sol +18 -17
  18. package/interfaces/IStaking.sol +22 -17
  19. package/interfaces/ITreasury.sol +2 -1
  20. package/interfaces/ITreasuryExternalChainStation.sol +15 -9
  21. package/interfaces/ITreasuryHostChainStation.sol +14 -11
  22. package/interfaces/IUserValidator.sol +6 -0
  23. package/library/Erc191TestBuilder.sol +350 -297
  24. package/library/EvvmService.sol +38 -27
  25. package/library/errors/CoreError.sol +116 -0
  26. package/library/errors/CrossChainTreasuryError.sol +36 -0
  27. package/library/errors/NameServiceError.sol +79 -0
  28. package/library/errors/StakingError.sol +79 -0
  29. package/library/errors/TreasuryError.sol +33 -0
  30. package/library/primitives/SignatureRecover.sol +33 -0
  31. package/library/structs/CoreStructs.sol +146 -0
  32. package/library/structs/ExternalChainStationStructs.sol +92 -0
  33. package/library/structs/HostChainStationStructs.sol +77 -0
  34. package/library/structs/NameServiceStructs.sol +47 -0
  35. package/library/structs/P2PSwapStructs.sol +127 -0
  36. package/library/structs/StakingStructs.sol +67 -0
  37. package/library/utils/AdvancedStrings.sol +84 -5
  38. package/library/utils/CAUtils.sol +29 -0
  39. package/library/utils/SignatureUtil.sol +34 -0
  40. package/library/utils/governance/Admin.sol +66 -0
  41. package/library/utils/governance/ProposalStructs.sol +49 -0
  42. package/library/utils/service/CoreExecution.sol +177 -0
  43. package/library/utils/service/StakingServiceUtils.sol +30 -3
  44. package/library/utils/signature/CoreHashUtils.sol +73 -0
  45. package/library/utils/signature/NameServiceHashUtils.sol +156 -0
  46. package/library/utils/signature/P2PSwapHashUtils.sol +65 -0
  47. package/library/utils/signature/StakingHashUtils.sol +41 -0
  48. package/library/utils/signature/TreasuryCrossChainHashUtils.sol +40 -0
  49. package/package.json +2 -1
  50. package/contracts/evvm/Evvm.sol +0 -1327
  51. package/contracts/evvm/lib/ErrorsLib.sol +0 -18
  52. package/contracts/evvm/lib/EvvmStorage.sol +0 -62
  53. package/contracts/evvm/lib/EvvmStructs.sol +0 -90
  54. package/contracts/evvm/lib/SignatureUtils.sol +0 -120
  55. package/contracts/nameService/lib/ErrorsLib.sol +0 -21
  56. package/contracts/nameService/lib/NameServiceStructs.sol +0 -69
  57. package/contracts/nameService/lib/SignatureUtils.sol +0 -245
  58. package/contracts/p2pSwap/lib/P2PSwapStructs.sol +0 -59
  59. package/contracts/p2pSwap/lib/SignatureUtils.sol +0 -98
  60. package/contracts/staking/lib/ErrorsLib.sol +0 -22
  61. package/contracts/staking/lib/SignatureUtils.sol +0 -39
  62. package/contracts/staking/lib/StakingStructs.sol +0 -94
  63. package/contracts/treasury/lib/ErrorsLib.sol +0 -11
  64. package/contracts/treasuryTwoChains/lib/ErrorsLib.sol +0 -48
  65. package/contracts/treasuryTwoChains/lib/ExternalChainStationStructs.sol +0 -80
  66. package/contracts/treasuryTwoChains/lib/HostChainStationStructs.sol +0 -87
  67. package/contracts/treasuryTwoChains/lib/SignatureUtils.sol +0 -79
  68. package/library/utils/GovernanceUtils.sol +0 -81
  69. package/library/utils/nonces/AsyncNonce.sol +0 -32
  70. package/library/utils/nonces/SyncNonce.sol +0 -27
  71. package/library/utils/service/EvvmPayments.sol +0 -79
@@ -2,6 +2,26 @@
2
2
  // Full license terms available at: https://www.evvm.info/docs/EVVMNoncommercialLicense
3
3
 
4
4
  pragma solidity ^0.8.0;
5
+
6
+ import {
7
+ StakingError as Error
8
+ } from "@evvm/testnet-contracts/library/errors/StakingError.sol";
9
+ import {
10
+ StakingHashUtils as Hash
11
+ } from "@evvm/testnet-contracts/library/utils/signature/StakingHashUtils.sol";
12
+ import {
13
+ StakingStructs as Structs
14
+ } from "@evvm/testnet-contracts/library/structs/StakingStructs.sol";
15
+
16
+ import {Core} from "@evvm/testnet-contracts/contracts/core/Core.sol";
17
+ import {
18
+ Estimator
19
+ } from "@evvm/testnet-contracts/contracts/staking/Estimator.sol";
20
+
21
+ import {
22
+ ProposalStructs
23
+ } from "@evvm/testnet-contracts/library/utils/governance/ProposalStructs.sol";
24
+
5
25
  /**
6
26
 
7
27
 
@@ -23,32 +43,14 @@ pragma solidity ^0.8.0;
23
43
  ██║ ██╔══╝ ╚════██║ ██║ ██║╚██╗██║██╔══╝ ██║
24
44
  ██║ ███████╗███████║ ██║ ██║ ╚████║███████╗ ██║
25
45
  ╚═╝ ╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝
26
- * @title Staking Mate contract
46
+ * @title EVVM Staking
27
47
  * @author Mate labs
28
- * @notice This contract manages the staking mechanism for the EVVM ecosystem
29
- * @dev Handles presale staking, public staking, and service staking with time locks and signature verification
30
- *
31
- * The contract supports three types of staking:
32
- * 1. Golden Staking: Exclusive to the goldenFisher address
33
- * 2. Presale Staking: Limited to 800 presale users with 2 staking token limit
34
- * 3. Public Staking: Open to all users when enabled
35
- * 4. Service Staking: Allows smart contracts to stake on behalf of users
36
- *
37
- * Key features:
38
- * - Time-locked unstaking mechanisms
39
- * - Signature-based authorization
40
- * - Integration with EVVM core contract for payments and rewards
41
- * - Estimator integration for yield calculations
48
+ * @notice Validator staking mechanism for the EVVM ecosystem.
49
+ * @dev Manages staking, unstaking, and yield distribution via the Estimator contract.
50
+ * Supports presale and public staking phases with time-locked security and nonce-based replay protection.
42
51
  */
43
52
 
44
- import {IEvvm} from "@evvm/testnet-contracts/interfaces/IEvvm.sol";
45
- import {IEstimator} from "@evvm/testnet-contracts/interfaces/IEstimator.sol";
46
- import {AsyncNonce} from "@evvm/testnet-contracts/library/utils/nonces/AsyncNonce.sol";
47
- import {StakingStructs} from "@evvm/testnet-contracts/contracts/staking/lib/StakingStructs.sol";
48
- import {ErrorsLib} from "./lib/ErrorsLib.sol";
49
- import {SignatureUtils} from "./lib/SignatureUtils.sol";
50
-
51
- contract Staking is AsyncNonce, StakingStructs {
53
+ contract Staking {
52
54
  uint256 constant TIME_TO_ACCEPT_PROPOSAL = 1 days;
53
55
 
54
56
  /// @dev Address of the EVVM core contract
@@ -61,42 +63,38 @@ contract Staking is AsyncNonce, StakingStructs {
61
63
  /// @dev Price of one staking main token (5083 main token = 1 staking)
62
64
  uint256 private constant PRICE_OF_STAKING = 5083 * (10 ** 18);
63
65
 
64
- /// @dev Address representing the principal Principal Token
65
- address private constant PRINCIPAL_TOKEN_ADDRESS =
66
- 0x0000000000000000000000000000000000000001;
67
-
68
66
  /// @dev Admin address management with proposal system
69
- AddressTypeProposal private admin;
67
+ ProposalStructs.AddressTypeProposal private admin;
70
68
  /// @dev Golden Fisher address management with proposal system
71
- AddressTypeProposal private goldenFisher;
69
+ ProposalStructs.AddressTypeProposal private goldenFisher;
72
70
  /// @dev Estimator contract address management with proposal system
73
- AddressTypeProposal private estimatorAddress;
71
+ ProposalStructs.AddressTypeProposal private estimatorAddress;
74
72
  /// @dev Time delay for regular staking after unstaking
75
- UintTypeProposal private secondsToUnlockStaking;
73
+ ProposalStructs.UintTypeProposal private secondsToUnlockStaking;
76
74
  /// @dev Time delay for full unstaking (21 days default)
77
- UintTypeProposal private secondsToUnllockFullUnstaking;
75
+ ProposalStructs.UintTypeProposal private secondsToUnllockFullUnstaking;
78
76
  /// @dev Flag to enable/disable presale staking
79
- BoolTypeProposal private allowPresaleStaking;
77
+ ProposalStructs.BoolTypeProposal private allowPresaleStaking;
80
78
  /// @dev Flag to enable/disable public staking
81
- BoolTypeProposal private allowPublicStaking;
79
+ ProposalStructs.BoolTypeProposal private allowPublicStaking;
82
80
  /// @dev Variable to store service staking metadata
83
- ServiceStakingMetadata private serviceStakingData;
81
+ Structs.ServiceStakingMetadata private serviceStakingData;
84
82
 
85
83
  /// @dev One-time setup breaker for estimator and EVVM addresses
86
84
  bytes1 private breakerSetupEstimatorAndEvvm;
87
85
 
88
86
  /// @dev Mapping to store presale staker metadata
89
- mapping(address => presaleStakerMetadata) private userPresaleStaker;
87
+ mapping(address => Structs.PresaleStakerMetadata) private userPresaleStaker;
90
88
 
91
89
  /// @dev Mapping to store complete staking history for each user
92
- mapping(address => HistoryMetadata[]) private userHistory;
90
+ mapping(address => Structs.HistoryMetadata[]) private userHistory;
93
91
 
94
- IEvvm private evvm;
95
- IEstimator private estimator;
92
+ Core private core;
93
+ Estimator private estimator;
96
94
 
97
95
  /// @dev Modifier to verify access to admin functions
98
96
  modifier onlyOwner() {
99
- if (msg.sender != admin.actual) revert ErrorsLib.SenderIsNotAdmin();
97
+ if (msg.sender != admin.current) revert Error.SenderIsNotAdmin();
100
98
 
101
99
  _;
102
100
  }
@@ -111,297 +109,293 @@ contract Staking is AsyncNonce, StakingStructs {
111
109
  size := extcodesize(callerAddress)
112
110
  }
113
111
 
114
- if (size == 0) revert ErrorsLib.AddressIsNotAService();
112
+ if (size == 0) revert Error.AddressIsNotAService();
115
113
 
116
114
  _;
117
115
  }
118
116
 
119
117
  /**
120
- * @notice Contract constructor
121
- * @dev Initializes the staking contract with admin and golden fisher addresses
122
- * @param initialAdmin Address that will have admin privileges
123
- * @param initialGoldenFisher Address that will have golden fisher privileges
118
+ * @notice Initializes the staking contract.
119
+ * @param initialAdmin System administrator.
120
+ * @param initialGoldenFisher Authorized Golden Fisher address.
124
121
  */
125
122
  constructor(address initialAdmin, address initialGoldenFisher) {
126
- admin.actual = initialAdmin;
123
+ admin.current = initialAdmin;
127
124
 
128
- goldenFisher.actual = initialGoldenFisher;
125
+ goldenFisher.current = initialGoldenFisher;
129
126
 
130
- allowPublicStaking.flag = false;
131
- allowPresaleStaking.flag = true;
127
+ allowPublicStaking.flag = true;
128
+ allowPresaleStaking.flag = false;
132
129
 
133
- secondsToUnlockStaking.actual = 0;
130
+ secondsToUnlockStaking.current = 0;
134
131
 
135
- secondsToUnllockFullUnstaking.actual = 5 days;
132
+ secondsToUnllockFullUnstaking.current = 5 days;
136
133
 
137
134
  breakerSetupEstimatorAndEvvm = 0x01;
138
135
  }
139
136
 
140
137
  /**
141
- * @notice One-time setup function for estimator and EVVM addresses
142
- * @dev Can only be called once during contract initialization
143
- * @param _estimator Address of the Estimator contract
144
- * @param _evvm Address of the EVVM core contract
138
+ * @notice Configures system contract integrations once.
139
+ * @param _estimator Estimator contract address (yield calculations).
140
+ * @param _core EVVM Core contract address (payments).
145
141
  */
146
- function _setupEstimatorAndEvvm(
142
+ function initializeSystemContracts(
147
143
  address _estimator,
148
- address _evvm
144
+ address _core
149
145
  ) external {
150
146
  if (breakerSetupEstimatorAndEvvm == 0x00) revert();
151
147
 
152
- estimatorAddress.actual = _estimator;
153
- EVVM_ADDRESS = _evvm;
148
+ estimatorAddress.current = _estimator;
149
+ EVVM_ADDRESS = _core;
150
+
151
+ core = Core(_core);
152
+ estimator = Estimator(_estimator);
154
153
  breakerSetupEstimatorAndEvvm = 0x00;
155
- evvm = IEvvm(_evvm);
156
- estimator = IEstimator(_estimator);
157
154
  }
158
155
 
159
156
  /**
160
- * @notice Allows the golden fisher to stake/unstake with synchronized EVVM nonces
161
- * @dev Only the golden fisher address can call this function
162
- * @param isStaking True for staking, false for unstaking
163
- * @param amountOfStaking Amount of staking tokens to stake/unstake
164
- * @param signature_EVVM Signature for the EVVM contract transaction
157
+ * @notice Unlimited staking/unstaking for the Golden Fisher.
158
+ * @dev Uses sync nonces for coordination with Core operations.
159
+ * @param isStaking True to stake, false to unstake.
160
+ * @param amountOfStaking Number of staking tokens.
161
+ * @param signaturePay Authorization signature for Core payment.
165
162
  */
166
163
  function goldenStaking(
167
164
  bool isStaking,
168
165
  uint256 amountOfStaking,
169
- bytes memory signature_EVVM
166
+ bytes memory signaturePay
170
167
  ) external {
171
- if (msg.sender != goldenFisher.actual)
172
- revert ErrorsLib.SenderIsNotGoldenFisher();
168
+ if (msg.sender != goldenFisher.current)
169
+ revert Error.SenderIsNotGoldenFisher();
173
170
 
174
171
  stakingBaseProcess(
175
- AccountMetadata({Address: goldenFisher.actual, IsAService: false}),
172
+ Structs.AccountMetadata({
173
+ Address: goldenFisher.current,
174
+ IsAService: false
175
+ }),
176
176
  isStaking,
177
177
  amountOfStaking,
178
178
  0,
179
- evvm.getNextCurrentSyncNonce(msg.sender),
179
+ core.getNextCurrentSyncNonce(msg.sender),
180
180
  false,
181
- signature_EVVM
181
+ signaturePay
182
182
  );
183
183
  }
184
184
 
185
185
  /**
186
- * @notice Allows presale users to stake/unstake with a limit of 2 staking tokens
187
- * @dev Only registered presale users can call this function when presale staking is enabled
188
- * @param user Address of the user performing the staking operation
189
- * @param isStaking True for staking, false for unstaking
190
- * @param nonce Unique nonce for this staking operation
191
- * @param signature Signature proving authorization for this staking operation
192
- * @param priorityFee_EVVM Priority fee for the EVVM transaction
193
- * @param nonce_EVVM Nonce for the EVVM contract transaction
194
- * @param priorityFlag_EVVM True for async EVVM transaction, false for sync
195
- * @param signature_EVVM Signature for the EVVM contract transaction
186
+ * @notice White-listed presale staking (max 2 tokens per user).
187
+ * @param user Participant address.
188
+ * @param isStaking True to stake, false to unstake.
189
+ * @param nonce Async nonce for signature verification.
190
+ * @param signature Participant's authorization signature.
191
+ * @param priorityFeePay Optional priority fee.
192
+ * @param noncePay Nonce for the Core payment.
193
+ * @param signaturePay Signature for the Core payment.
196
194
  */
197
195
  function presaleStaking(
198
196
  address user,
199
197
  bool isStaking,
198
+ address originExecutor,
200
199
  uint256 nonce,
201
200
  bytes memory signature,
202
- uint256 priorityFee_EVVM,
203
- uint256 nonce_EVVM,
204
- bool priorityFlag_EVVM,
205
- bytes memory signature_EVVM
201
+ uint256 priorityFeePay,
202
+ uint256 noncePay,
203
+ bytes memory signaturePay
206
204
  ) external {
207
- if (
208
- !SignatureUtils.verifyMessageSignedForStake(
209
- evvm.getEvvmID(),
210
- user,
211
- false,
212
- isStaking,
213
- 1,
214
- nonce,
215
- signature
216
- )
217
- ) revert ErrorsLib.InvalidSignatureOnStaking();
205
+ if (!allowPresaleStaking.flag || allowPublicStaking.flag)
206
+ revert Error.PresaleStakingDisabled();
218
207
 
219
- verifyAsyncNonce(user, nonce);
208
+ core.validateAndConsumeNonce(
209
+ user,
210
+ Hash.hashDataForPresaleStake(isStaking, 1),
211
+ originExecutor,
212
+ nonce,
213
+ true,
214
+ signature
215
+ );
216
+
217
+ if (!userPresaleStaker[user].isAllow)
218
+ revert Error.UserIsNotPresaleStaker();
219
+
220
+ uint256 current = userPresaleStaker[user].stakingAmount;
220
221
 
221
- presaleClaims(isStaking, user);
222
+ if (isStaking ? current >= 2 : current == 0)
223
+ revert Error.UserPresaleStakerLimitExceeded();
222
224
 
223
- if (!allowPresaleStaking.flag)
224
- revert ErrorsLib.PresaleStakingDisabled();
225
+ userPresaleStaker[user].stakingAmount = isStaking
226
+ ? current + 1
227
+ : current - 1;
225
228
 
226
229
  stakingBaseProcess(
227
- AccountMetadata({Address: user, IsAService: false}),
230
+ Structs.AccountMetadata({Address: user, IsAService: false}),
228
231
  isStaking,
229
232
  1,
230
- priorityFee_EVVM,
231
- nonce_EVVM,
232
- priorityFlag_EVVM,
233
- signature_EVVM
233
+ priorityFeePay,
234
+ noncePay,
235
+ true,
236
+ signaturePay
234
237
  );
235
-
236
- markAsyncNonceAsUsed(user, nonce);
237
- }
238
-
239
- /**
240
- * @notice Internal function to manage presale staking limits and permissions
241
- * @dev Enforces the 2 staking token limit for presale users and tracks staking amounts
242
- * @param _isStaking True for staking (increments count), false for unstaking (decrements count)
243
- * @param _user Address of the presale user
244
- */
245
- function presaleClaims(bool _isStaking, address _user) internal {
246
- if (allowPublicStaking.flag) {
247
- revert ErrorsLib.PresaleStakingDisabled();
248
- } else {
249
- if (userPresaleStaker[_user].isAllow) {
250
- if (_isStaking) {
251
- // staking
252
-
253
- if (userPresaleStaker[_user].stakingAmount >= 2)
254
- revert ErrorsLib.UserPresaleStakerLimitExceeded();
255
-
256
- userPresaleStaker[_user].stakingAmount++;
257
- } else {
258
- // unstaking
259
-
260
- if (userPresaleStaker[_user].stakingAmount == 0)
261
- revert ErrorsLib.UserPresaleStakerLimitExceeded();
262
-
263
- userPresaleStaker[_user].stakingAmount--;
264
- }
265
- } else {
266
- revert ErrorsLib.UserIsNotPresaleStaker();
267
- }
268
- }
269
238
  }
270
239
 
271
240
  /**
272
- * @notice Allows any user to stake/unstake when public staking is enabled
273
- * @dev Requires signature verification and handles nonce management
274
- * @param user Address of the user performing the staking operation
275
- * @param isStaking True for staking, false for unstaking
276
- * @param amountOfStaking Amount of staking tokens to stake/unstake
277
- * @param nonce Unique nonce for this staking operation
278
- * @param signature Signature proving authorization for this staking operation
279
- * @param priorityFee_EVVM Priority fee for the EVVM transaction
280
- * @param nonce_EVVM Nonce for the EVVM contract transaction
281
- * @param priorityFlag_EVVM True for async EVVM transaction, false for sync
282
- * @param signature_EVVM Signature for the EVVM contract transaction
241
+ * @notice Public staking open to any user when enabled.
242
+ * @param user Participant address.
243
+ * @param isStaking True to stake, false to unstake.
244
+ * @param amountOfStaking Number of tokens.
245
+ * @param nonce Async nonce for signature verification.
246
+ * @param signature Participant's authorization signature.
247
+ * @param priorityFeePay Optional priority fee.
248
+ * @param noncePay Nonce for the Core payment.
249
+ * @param signaturePay Signature for the Core payment.
283
250
  */
284
251
  function publicStaking(
285
252
  address user,
286
253
  bool isStaking,
287
254
  uint256 amountOfStaking,
255
+ address originExecutor,
288
256
  uint256 nonce,
289
257
  bytes memory signature,
290
- uint256 priorityFee_EVVM,
291
- uint256 nonce_EVVM,
292
- bool priorityFlag_EVVM,
293
- bytes memory signature_EVVM
258
+ uint256 priorityFeePay,
259
+ uint256 noncePay,
260
+ bytes memory signaturePay
294
261
  ) external {
295
- if (!allowPublicStaking.flag) {
296
- revert();
297
- }
298
-
299
- if (
300
- !SignatureUtils.verifyMessageSignedForStake(
301
- evvm.getEvvmID(),
302
- user,
303
- true,
304
- isStaking,
305
- amountOfStaking,
306
- nonce,
307
- signature
308
- )
309
- ) revert ErrorsLib.InvalidSignatureOnStaking();
262
+ if (!allowPublicStaking.flag) revert Error.PublicStakingDisabled();
310
263
 
311
- verifyAsyncNonce(user, nonce);
264
+ core.validateAndConsumeNonce(
265
+ user,
266
+ Hash.hashDataForPublicStake(isStaking, amountOfStaking),
267
+ originExecutor,
268
+ nonce,
269
+ true,
270
+ signature
271
+ );
312
272
 
313
273
  stakingBaseProcess(
314
- AccountMetadata({Address: user, IsAService: false}),
274
+ Structs.AccountMetadata({Address: user, IsAService: false}),
315
275
  isStaking,
316
276
  amountOfStaking,
317
- priorityFee_EVVM,
318
- nonce_EVVM,
319
- priorityFlag_EVVM,
320
- signature_EVVM
277
+ priorityFeePay,
278
+ noncePay,
279
+ true,
280
+ signaturePay
321
281
  );
322
-
323
- markAsyncNonceAsUsed(user, nonce);
324
282
  }
325
283
 
326
284
  /**
327
- * @notice Prepares a service/contract account for staking by recording pre-staking state
328
- * @dev First step in the service staking process. Must be followed by payment via caPay and confirmServiceStaking in the same transaction
329
- * @param amountOfStaking Amount of staking tokens the service intends to stake
285
+ * @notice Step 1: Prepare service (contract) staking
286
+ * @dev Records pre-staking state for atomic validation
330
287
  *
331
- * Service Staking Process:
332
- * 1. Call prepareServiceStaking(amount) - Records balances and metadata
333
- * 2. Use EVVM.caPay() to transfer the required Principal Tokens to this contract
334
- * 3. Call confirmServiceStaking() - Validates payment and completes staking
288
+ * Service Staking Process (ATOMIC - Same TX):
289
+ * 1. prepareServiceStaking: Record balances
290
+ * 2. Evvm.caPay: Transfer Principal Tokens
291
+ * 3. confirmServiceStaking: Validate and complete
335
292
  *
336
- * @dev All three steps MUST occur in the same transaction or the staking will fail
337
- * @dev CRITICAL WARNING: If the process is not completed properly (especially if caPay is called
338
- * but confirmServiceStaking is not), the Principal Tokens will remain locked in the staking
339
- * contract with no way to recover them. The service will lose the tokens permanently.
340
- * @dev Only callable by contract accounts (services), not EOAs
293
+ * CRITICAL WARNING:
294
+ * - All 3 steps MUST occur in single transaction
295
+ * - If incomplete, tokens permanently locked
296
+ * - No recovery mechanism for failed process
297
+ * - Service loses tokens if not atomic
298
+ *
299
+ * Metadata Recorded:
300
+ * - service: msg.sender (contract address)
301
+ * - timestamp: block.timestamp (atomicity check)
302
+ * - amountOfStaking: Requested staking tokens
303
+ * - amountServiceBeforeStaking: Service PT balance
304
+ * - amountStakingBeforeStaking: Staking PT balance
305
+ *
306
+ * Core.sol Payment (Step 2):
307
+ * - Service must call Evvm.caPay after this
308
+ * - Transfer: PRICE_OF_STAKING * amountOfStaking
309
+ * - Recipient: address(this) (Staking contract)
310
+ * - Token: Principal Token from Core.sol
311
+ *
312
+ * Access Control:
313
+ * - onlyCA modifier: Only contracts allowed
314
+ * - Checks code size via assembly
315
+ * - EOAs rejected (size == 0)
316
+ *
317
+ * @param amountOfStaking Number of staking tokens to acquire
341
318
  */
342
319
  function prepareServiceStaking(uint256 amountOfStaking) external onlyCA {
343
- serviceStakingData = ServiceStakingMetadata({
320
+ serviceStakingData = Structs.ServiceStakingMetadata({
344
321
  service: msg.sender,
345
322
  timestamp: block.timestamp,
346
323
  amountOfStaking: amountOfStaking,
347
- amountServiceBeforeStaking: evvm.getBalance(
324
+ amountServiceBeforeStaking: core.getBalance(
348
325
  msg.sender,
349
- PRINCIPAL_TOKEN_ADDRESS
326
+ core.getPrincipalTokenAddress()
350
327
  ),
351
- amountStakingBeforeStaking: evvm.getBalance(
328
+ amountStakingBeforeStaking: core.getBalance(
352
329
  address(this),
353
- PRINCIPAL_TOKEN_ADDRESS
330
+ core.getPrincipalTokenAddress()
354
331
  )
355
332
  });
356
333
  }
357
334
 
358
335
  /**
359
- * @notice Confirms and completes the service staking operation after payment verification
360
- * @dev Final step in service staking. Validates that payment was made correctly and completes the staking process
336
+ * @notice Step 3: Confirm service staking after payment
337
+ * @dev Validates payment and completes atomic staking
361
338
  *
362
- * Validation checks:
363
- * - Service balance decreased by the exact staking cost
364
- * - Staking contract balance increased by the exact staking cost
365
- * - Operation occurs in the same transaction as prepareServiceStaking
366
- * - Caller matches the service that initiated the preparation
339
+ * Validation Checks:
340
+ * 1. Timestamp: Must equal prepareServiceStaking tx
341
+ * - Ensures atomicity (same transaction)
342
+ * - serviceStakingData.timestamp == block.timestamp
367
343
  *
368
- * @dev Only callable by the same contract that called prepareServiceStaking
369
- * @dev Must be called in the same transaction as prepareServiceStaking
344
+ * 2. Caller: Must match prepareServiceStaking caller
345
+ * - serviceStakingData.service == msg.sender
346
+ * - Prevents staking hijacking
347
+ *
348
+ * 3. Payment Amount: Validates exact transfer
349
+ * - Service balance decreased by exact amount
350
+ * - Staking balance increased by exact amount
351
+ * - totalStakingRequired = PRICE_OF_STAKING *
352
+ * amountOfStaking
353
+ *
354
+ * Core.sol Integration:
355
+ * - Validates caPay occurred between steps 1 and 3
356
+ * - Checks balance deltas via Evvm.getBalance
357
+ * - Token: core.getPrincipalTokenAddress()
358
+ * - Must be exact amount (no overpayment/underpayment)
359
+ *
360
+ * Completion:
361
+ * - Calls stakingBaseProcess on success
362
+ * - Records history with transaction type 0x01
363
+ * - Updates userHistory with staking event
364
+ * - Service becomes staker (isAddressStaker = true)
365
+ *
366
+ * Error Cases:
367
+ * - ServiceDoesNotStakeInSameTx: timestamp mismatch
368
+ * - AddressMismatch: caller mismatch
369
+ * - ServiceDoesNotFulfillCorrectStakingAmount:
370
+ * payment incorrect
371
+ *
372
+ * Access Control:
373
+ * - onlyCA modifier: Only contracts allowed
370
374
  */
371
375
  function confirmServiceStaking() external onlyCA {
372
376
  uint256 totalStakingRequired = PRICE_OF_STAKING *
373
377
  serviceStakingData.amountOfStaking;
374
378
 
375
- uint256 actualServiceBalance = evvm.getBalance(
376
- msg.sender,
377
- PRINCIPAL_TOKEN_ADDRESS
378
- );
379
-
380
- uint256 actualStakingBalance = evvm.getBalance(
381
- address(this),
382
- PRINCIPAL_TOKEN_ADDRESS
383
- );
384
-
385
379
  if (
386
380
  serviceStakingData.amountServiceBeforeStaking -
387
381
  totalStakingRequired !=
388
- actualServiceBalance &&
382
+ core.getBalance(msg.sender, core.getPrincipalTokenAddress()) &&
389
383
  serviceStakingData.amountStakingBeforeStaking +
390
384
  totalStakingRequired !=
391
- actualStakingBalance
385
+ core.getBalance(address(this), core.getPrincipalTokenAddress())
392
386
  )
393
- revert ErrorsLib.ServiceDoesNotFulfillCorrectStakingAmount(
387
+ revert Error.ServiceDoesNotFulfillCorrectStakingAmount(
394
388
  totalStakingRequired
395
389
  );
396
390
 
397
391
  if (serviceStakingData.timestamp != block.timestamp)
398
- revert ErrorsLib.ServiceDoesNotStakeInSameTx();
392
+ revert Error.ServiceDoesNotStakeInSameTx();
399
393
 
400
394
  if (serviceStakingData.service != msg.sender)
401
- revert ErrorsLib.AddressMismatch();
395
+ revert Error.AddressMismatch();
402
396
 
403
397
  stakingBaseProcess(
404
- AccountMetadata({Address: msg.sender, IsAService: true}),
398
+ Structs.AccountMetadata({Address: msg.sender, IsAService: true}),
405
399
  true,
406
400
  serviceStakingData.amountOfStaking,
407
401
  0,
@@ -422,7 +416,7 @@ contract Staking is AsyncNonce, StakingStructs {
422
416
  */
423
417
  function serviceUnstaking(uint256 amountOfStaking) external onlyCA {
424
418
  stakingBaseProcess(
425
- AccountMetadata({Address: msg.sender, IsAService: true}),
419
+ Structs.AccountMetadata({Address: msg.sender, IsAService: true}),
426
420
  false,
427
421
  amountOfStaking,
428
422
  0,
@@ -440,19 +434,18 @@ contract Staking is AsyncNonce, StakingStructs {
440
434
  * - IsAService: Boolean indicating if the account is a smart contract (service) account
441
435
  * @param isStaking True for staking (requires payment), false for unstaking (provides refund)
442
436
  * @param amountOfStaking Amount of staking tokens to stake/unstake
443
- * @param priorityFee_EVVM Priority fee for EVVM transaction
444
- * @param nonce_EVVM Nonce for EVVM contract transaction
445
- * @param priorityFlag_EVVM True for async EVVM transaction, false for sync
446
- * @param signature_EVVM Signature for EVVM contract transaction
437
+ * @param priorityFeePay Priority fee for EVVM transaction
438
+ * @param noncePay Nonce for EVVM contract transaction
439
+ * @param signaturePay Signature for EVVM contract transaction
447
440
  */
448
441
  function stakingBaseProcess(
449
- AccountMetadata memory account,
442
+ Structs.AccountMetadata memory account,
450
443
  bool isStaking,
451
444
  uint256 amountOfStaking,
452
- uint256 priorityFee_EVVM,
453
- uint256 nonce_EVVM,
454
- bool priorityFlag_EVVM,
455
- bytes memory signature_EVVM
445
+ uint256 priorityFeePay,
446
+ uint256 noncePay,
447
+ bool isAsyncExecEvvm,
448
+ bytes memory signaturePay
456
449
  ) internal {
457
450
  uint256 auxSMsteBalance;
458
451
 
@@ -460,19 +453,19 @@ contract Staking is AsyncNonce, StakingStructs {
460
453
  if (
461
454
  getTimeToUserUnlockStakingTime(account.Address) >
462
455
  block.timestamp
463
- ) revert ErrorsLib.AddressMustWaitToStakeAgain();
456
+ ) revert Error.AddressMustWaitToStakeAgain();
464
457
 
465
458
  if (!account.IsAService)
466
459
  makePay(
467
460
  account.Address,
468
461
  (PRICE_OF_STAKING * amountOfStaking),
469
- priorityFee_EVVM,
470
- priorityFlag_EVVM,
471
- nonce_EVVM,
472
- signature_EVVM
462
+ priorityFeePay,
463
+ isAsyncExecEvvm,
464
+ noncePay,
465
+ signaturePay
473
466
  );
474
467
 
475
- evvm.pointStaker(account.Address, 0x01);
468
+ core.pointStaker(account.Address, 0x01);
476
469
 
477
470
  auxSMsteBalance = userHistory[account.Address].length == 0
478
471
  ? amountOfStaking
@@ -484,19 +477,19 @@ contract Staking is AsyncNonce, StakingStructs {
484
477
  if (
485
478
  getTimeToUserUnlockFullUnstakingTime(account.Address) >
486
479
  block.timestamp
487
- ) revert ErrorsLib.AddressMustWaitToFullUnstake();
480
+ ) revert Error.AddressMustWaitToFullUnstake();
488
481
 
489
- evvm.pointStaker(account.Address, 0x00);
482
+ core.pointStaker(account.Address, 0x00);
490
483
  }
491
484
 
492
- if (priorityFee_EVVM != 0 && !account.IsAService)
485
+ if (priorityFeePay != 0 && !account.IsAService)
493
486
  makePay(
494
487
  account.Address,
495
- priorityFee_EVVM,
496
488
  0,
497
- priorityFlag_EVVM,
498
- nonce_EVVM,
499
- signature_EVVM
489
+ priorityFeePay,
490
+ isAsyncExecEvvm,
491
+ noncePay,
492
+ signaturePay
500
493
  );
501
494
 
502
495
  auxSMsteBalance =
@@ -506,14 +499,14 @@ contract Staking is AsyncNonce, StakingStructs {
506
499
  amountOfStaking;
507
500
 
508
501
  makeCaPay(
509
- PRINCIPAL_TOKEN_ADDRESS,
502
+ core.getPrincipalTokenAddress(),
510
503
  account.Address,
511
504
  (PRICE_OF_STAKING * amountOfStaking)
512
505
  );
513
506
  }
514
507
 
515
508
  userHistory[account.Address].push(
516
- HistoryMetadata({
509
+ Structs.HistoryMetadata({
517
510
  transactionType: isStaking
518
511
  ? bytes32(uint256(1))
519
512
  : bytes32(uint256(2)),
@@ -523,14 +516,11 @@ contract Staking is AsyncNonce, StakingStructs {
523
516
  })
524
517
  );
525
518
 
526
- if (
527
- evvm.isAddressStaker(msg.sender) &&
528
- !account.IsAService
529
- ) {
519
+ if (core.isAddressStaker(msg.sender) && !account.IsAService) {
530
520
  makeCaPay(
531
- PRINCIPAL_TOKEN_ADDRESS,
521
+ core.getPrincipalTokenAddress(),
532
522
  msg.sender,
533
- (evvm.getRewardAmount() * 2) + priorityFee_EVVM
523
+ (core.getRewardAmount() * 2) + priorityFeePay
534
524
  );
535
525
  }
536
526
  }
@@ -576,11 +566,11 @@ contract Staking is AsyncNonce, StakingStructs {
576
566
  userHistory[user][idToOverwriteUserHistory]
577
567
  .timestamp = timestampToBeOverwritten;
578
568
 
579
- if (evvm.isAddressStaker(msg.sender)) {
569
+ if (core.isAddressStaker(msg.sender)) {
580
570
  makeCaPay(
581
- PRINCIPAL_TOKEN_ADDRESS,
571
+ core.getPrincipalTokenAddress(),
582
572
  msg.sender,
583
- (evvm.getRewardAmount() * 1)
573
+ (core.getRewardAmount() * 1)
584
574
  );
585
575
  }
586
576
  }
@@ -597,7 +587,7 @@ contract Staking is AsyncNonce, StakingStructs {
597
587
  * @param user Address of the user making the payment
598
588
  * @param amount Amount to be paid in Principal Tokens
599
589
  * @param priorityFee Additional priority fee for the transaction
600
- * @param priorityFlag True for async payment, false for sync payment
590
+ * @param isAsyncExec True for async payment, false for sync payment
601
591
  * @param nonce Nonce for the EVVM transaction
602
592
  * @param signature Signature authorizing the payment
603
593
  */
@@ -605,20 +595,20 @@ contract Staking is AsyncNonce, StakingStructs {
605
595
  address user,
606
596
  uint256 amount,
607
597
  uint256 priorityFee,
608
- bool priorityFlag,
598
+ bool isAsyncExec,
609
599
  uint256 nonce,
610
600
  bytes memory signature
611
601
  ) internal {
612
- evvm.pay(
602
+ core.pay(
613
603
  user,
614
604
  address(this),
615
605
  "",
616
- PRINCIPAL_TOKEN_ADDRESS,
606
+ core.getPrincipalTokenAddress(),
617
607
  amount,
618
608
  priorityFee,
619
- nonce,
620
- priorityFlag,
621
609
  address(this),
610
+ nonce,
611
+ isAsyncExec,
622
612
  signature
623
613
  );
624
614
  }
@@ -635,7 +625,7 @@ contract Staking is AsyncNonce, StakingStructs {
635
625
  address user,
636
626
  uint256 amount
637
627
  ) internal {
638
- evvm.caPay(user, tokenAddress, amount);
628
+ core.caPay(user, tokenAddress, amount);
639
629
  }
640
630
 
641
631
  //▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀
@@ -648,9 +638,9 @@ contract Staking is AsyncNonce, StakingStructs {
648
638
  * @param _staker Address to be added to the presale staker list
649
639
  */
650
640
  function addPresaleStaker(address _staker) external onlyOwner {
651
- if (presaleStakerCount > LIMIT_PRESALE_STAKER) {
652
- revert();
653
- }
641
+ if (presaleStakerCount > LIMIT_PRESALE_STAKER)
642
+ revert Error.LimitPresaleStakersExceeded();
643
+
654
644
  userPresaleStaker[_staker].isAllow = true;
655
645
  presaleStakerCount++;
656
646
  }
@@ -662,9 +652,9 @@ contract Staking is AsyncNonce, StakingStructs {
662
652
  */
663
653
  function addPresaleStakers(address[] calldata _stakers) external onlyOwner {
664
654
  for (uint256 i = 0; i < _stakers.length; i++) {
665
- if (presaleStakerCount > LIMIT_PRESALE_STAKER) {
666
- revert();
667
- }
655
+ if (presaleStakerCount > LIMIT_PRESALE_STAKER)
656
+ revert Error.LimitPresaleStakersExceeded();
657
+
668
658
  userPresaleStaker[_stakers[i]].isAllow = true;
669
659
  presaleStakerCount++;
670
660
  }
@@ -694,12 +684,13 @@ contract Staking is AsyncNonce, StakingStructs {
694
684
  * @dev Can only be called by the proposed admin after the time delay has passed
695
685
  */
696
686
  function acceptNewAdmin() external {
697
- if (
698
- msg.sender != admin.proposal || admin.timeToAccept > block.timestamp
699
- ) {
700
- revert();
701
- }
702
- admin.actual = admin.proposal;
687
+ if (msg.sender != admin.proposal)
688
+ revert Error.SenderIsNotProposedAdmin();
689
+
690
+ if (admin.timeToAccept > block.timestamp)
691
+ revert Error.TimeToAcceptProposalNotReached();
692
+
693
+ admin.current = admin.proposal;
703
694
  admin.proposal = address(0);
704
695
  admin.timeToAccept = 0;
705
696
  }
@@ -728,10 +719,10 @@ contract Staking is AsyncNonce, StakingStructs {
728
719
  * @dev Can only be called by the current admin after the 1-day time delay
729
720
  */
730
721
  function acceptNewGoldenFisher() external onlyOwner {
731
- if (goldenFisher.timeToAccept > block.timestamp) {
732
- revert();
733
- }
734
- goldenFisher.actual = goldenFisher.proposal;
722
+ if (goldenFisher.timeToAccept > block.timestamp)
723
+ revert Error.TimeToAcceptProposalNotReached();
724
+
725
+ goldenFisher.current = goldenFisher.proposal;
735
726
  goldenFisher.proposal = address(0);
736
727
  goldenFisher.timeToAccept = 0;
737
728
  }
@@ -764,10 +755,10 @@ contract Staking is AsyncNonce, StakingStructs {
764
755
  * @dev Can only be called by the current admin after the 1-day time delay
765
756
  */
766
757
  function acceptSetSecondsToUnlockStaking() external onlyOwner {
767
- if (secondsToUnlockStaking.timeToAccept > block.timestamp) {
768
- revert();
769
- }
770
- secondsToUnlockStaking.actual = secondsToUnlockStaking.proposal;
758
+ if (secondsToUnlockStaking.timeToAccept > block.timestamp)
759
+ revert Error.TimeToAcceptProposalNotReached();
760
+
761
+ secondsToUnlockStaking.current = secondsToUnlockStaking.proposal;
771
762
  secondsToUnlockStaking.proposal = 0;
772
763
  secondsToUnlockStaking.timeToAccept = 0;
773
764
  }
@@ -800,10 +791,10 @@ contract Staking is AsyncNonce, StakingStructs {
800
791
  * @dev Can only be called by the current admin after the 1-day time delay
801
792
  */
802
793
  function confirmSetSecondsToUnllockFullUnstaking() external onlyOwner {
803
- if (secondsToUnllockFullUnstaking.timeToAccept > block.timestamp) {
804
- revert();
805
- }
806
- secondsToUnllockFullUnstaking.actual = secondsToUnllockFullUnstaking
794
+ if (secondsToUnllockFullUnstaking.timeToAccept > block.timestamp)
795
+ revert Error.TimeToAcceptProposalNotReached();
796
+
797
+ secondsToUnllockFullUnstaking.current = secondsToUnllockFullUnstaking
807
798
  .proposal;
808
799
  secondsToUnllockFullUnstaking.proposal = 0;
809
800
  secondsToUnllockFullUnstaking.timeToAccept = 0;
@@ -832,10 +823,10 @@ contract Staking is AsyncNonce, StakingStructs {
832
823
  * @dev Toggles between enabled/disabled state for public staking after 1-day delay
833
824
  */
834
825
  function confirmChangeAllowPublicStaking() external onlyOwner {
835
- if (allowPublicStaking.timeToAccept > block.timestamp) {
836
- revert();
837
- }
838
- allowPublicStaking = BoolTypeProposal({
826
+ if (allowPublicStaking.timeToAccept > block.timestamp)
827
+ revert Error.TimeToAcceptProposalNotReached();
828
+
829
+ allowPublicStaking = ProposalStructs.BoolTypeProposal({
839
830
  flag: !allowPublicStaking.flag,
840
831
  timeToAccept: 0
841
832
  });
@@ -864,13 +855,11 @@ contract Staking is AsyncNonce, StakingStructs {
864
855
  * @dev Toggles between enabled/disabled state for presale staking after 1-day delay
865
856
  */
866
857
  function confirmChangeAllowPresaleStaking() external onlyOwner {
867
- if (allowPresaleStaking.timeToAccept > block.timestamp) {
868
- revert();
869
- }
870
- allowPresaleStaking = BoolTypeProposal({
871
- flag: !allowPresaleStaking.flag,
872
- timeToAccept: 0
873
- });
858
+ if (allowPresaleStaking.timeToAccept > block.timestamp)
859
+ revert Error.TimeToAcceptProposalNotReached();
860
+
861
+ allowPresaleStaking.flag = !allowPresaleStaking.flag;
862
+ allowPresaleStaking.timeToAccept = 0;
874
863
  }
875
864
 
876
865
  /**
@@ -880,7 +869,9 @@ contract Staking is AsyncNonce, StakingStructs {
880
869
  */
881
870
  function proposeEstimator(address _estimator) external onlyOwner {
882
871
  estimatorAddress.proposal = _estimator;
883
- estimatorAddress.timeToAccept = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
872
+ estimatorAddress.timeToAccept =
873
+ block.timestamp +
874
+ TIME_TO_ACCEPT_PROPOSAL;
884
875
  }
885
876
 
886
877
  /**
@@ -897,13 +888,13 @@ contract Staking is AsyncNonce, StakingStructs {
897
888
  * @dev Can only be called by the current admin after the 1-day time delay
898
889
  */
899
890
  function acceptNewEstimator() external onlyOwner {
900
- if (estimatorAddress.timeToAccept > block.timestamp) {
901
- revert();
902
- }
903
- estimatorAddress.actual = estimatorAddress.proposal;
891
+ if (estimatorAddress.timeToAccept > block.timestamp)
892
+ revert Error.TimeToAcceptProposalNotReached();
893
+
894
+ estimatorAddress.current = estimatorAddress.proposal;
904
895
  estimatorAddress.proposal = address(0);
905
896
  estimatorAddress.timeToAccept = 0;
906
- estimator = IEstimator(estimatorAddress.actual);
897
+ estimator = Estimator(estimatorAddress.current);
907
898
  }
908
899
 
909
900
  //▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀
@@ -914,11 +905,11 @@ contract Staking is AsyncNonce, StakingStructs {
914
905
  * @notice Returns the complete staking history for an address
915
906
  * @dev Returns an array of all staking transactions and rewards for the user
916
907
  * @param _account Address to query the history for
917
- * @return Array of HistoryMetadata containing all transactions
908
+ * @return Array of Structs.HistoryMetadata containing all transactions
918
909
  */
919
910
  function getAddressHistory(
920
911
  address _account
921
- ) public view returns (HistoryMetadata[] memory) {
912
+ ) public view returns (Structs.HistoryMetadata[] memory) {
922
913
  return userHistory[_account];
923
914
  }
924
915
 
@@ -939,12 +930,12 @@ contract Staking is AsyncNonce, StakingStructs {
939
930
  * @dev Allows accessing individual transactions by index
940
931
  * @param _account Address to query the history for
941
932
  * @param _index Index of the transaction to retrieve (0-based)
942
- * @return HistoryMetadata of the transaction at the specified index
933
+ * @return Structs.HistoryMetadata of the transaction at the specified index
943
934
  */
944
935
  function getAddressHistoryByIndex(
945
936
  address _account,
946
937
  uint256 _index
947
- ) public view returns (HistoryMetadata memory) {
938
+ ) public view returns (Structs.HistoryMetadata memory) {
948
939
  return userHistory[_account][_index];
949
940
  }
950
941
 
@@ -970,13 +961,13 @@ contract Staking is AsyncNonce, StakingStructs {
970
961
  if (userHistory[_account][i - 1].totalStaked == 0) {
971
962
  return
972
963
  userHistory[_account][i - 1].timestamp +
973
- secondsToUnllockFullUnstaking.actual;
964
+ secondsToUnllockFullUnstaking.current;
974
965
  }
975
966
  }
976
967
 
977
968
  return
978
969
  userHistory[_account][0].timestamp +
979
- secondsToUnllockFullUnstaking.actual;
970
+ secondsToUnllockFullUnstaking.current;
980
971
  }
981
972
 
982
973
  /**
@@ -996,7 +987,7 @@ contract Staking is AsyncNonce, StakingStructs {
996
987
  if (userHistory[_account][lengthOfHistory - 1].totalStaked == 0) {
997
988
  return
998
989
  userHistory[_account][lengthOfHistory - 1].timestamp +
999
- secondsToUnlockStaking.actual;
990
+ secondsToUnlockStaking.current;
1000
991
  } else {
1001
992
  return 0;
1002
993
  }
@@ -1008,7 +999,7 @@ contract Staking is AsyncNonce, StakingStructs {
1008
999
  * @return Number of seconds required to wait for full unstaking
1009
1000
  */
1010
1001
  function getSecondsToUnlockFullUnstaking() external view returns (uint256) {
1011
- return secondsToUnllockFullUnstaking.actual;
1002
+ return secondsToUnllockFullUnstaking.current;
1012
1003
  }
1013
1004
 
1014
1005
  /**
@@ -1017,7 +1008,7 @@ contract Staking is AsyncNonce, StakingStructs {
1017
1008
  * @return Number of seconds required to wait between unstaking and staking
1018
1009
  */
1019
1010
  function getSecondsToUnlockStaking() external view returns (uint256) {
1020
- return secondsToUnlockStaking.actual;
1011
+ return secondsToUnlockStaking.current;
1021
1012
  }
1022
1013
 
1023
1014
  /**
@@ -1044,7 +1035,7 @@ contract Staking is AsyncNonce, StakingStructs {
1044
1035
  * @return Address of the current golden fisher
1045
1036
  */
1046
1037
  function getGoldenFisher() external view returns (address) {
1047
- return goldenFisher.actual;
1038
+ return goldenFisher.current;
1048
1039
  }
1049
1040
 
1050
1041
  /**
@@ -1078,7 +1069,7 @@ contract Staking is AsyncNonce, StakingStructs {
1078
1069
  * @return Address of the current estimator contract
1079
1070
  */
1080
1071
  function getEstimatorAddress() external view returns (address) {
1081
- return estimatorAddress.actual;
1072
+ return estimatorAddress.current;
1082
1073
  }
1083
1074
 
1084
1075
  /**
@@ -1102,12 +1093,12 @@ contract Staking is AsyncNonce, StakingStructs {
1102
1093
  /**
1103
1094
  * @notice Returns the complete public staking configuration and status
1104
1095
  * @dev Includes current flag state and any pending changes with timestamps
1105
- * @return BoolTypeProposal struct containing flag and timeToAccept
1096
+ * @return ProposalStructs.BoolTypeProposal struct containing flag and timeToAccept
1106
1097
  */
1107
- function getAllDataOfAllowPublicStaking()
1098
+ function getAllowPublicStaking()
1108
1099
  external
1109
1100
  view
1110
- returns (BoolTypeProposal memory)
1101
+ returns (ProposalStructs.BoolTypeProposal memory)
1111
1102
  {
1112
1103
  return allowPublicStaking;
1113
1104
  }
@@ -1115,32 +1106,48 @@ contract Staking is AsyncNonce, StakingStructs {
1115
1106
  /**
1116
1107
  * @notice Returns the complete presale staking configuration and status
1117
1108
  * @dev Includes current flag state and any pending changes with timestamps
1118
- * @return BoolTypeProposal struct containing flag and timeToAccept
1109
+ * @return ProposalStructs.BoolTypeProposal struct containing flag and timeToAccept
1119
1110
  */
1120
1111
  function getAllowPresaleStaking()
1121
1112
  external
1122
1113
  view
1123
- returns (BoolTypeProposal memory)
1114
+ returns (ProposalStructs.BoolTypeProposal memory)
1124
1115
  {
1125
1116
  return allowPresaleStaking;
1126
1117
  }
1127
1118
 
1119
+ /**
1120
+ * @notice Gets the unique identifier string for this EVVM instance
1121
+ * @dev Returns the EvvmID used for distinguishing different EVVM deployments
1122
+ * @return Unique EvvmID string
1123
+ */
1124
+ function getEvvmID() external view returns (uint256) {
1125
+ return core.getEvvmID();
1126
+ }
1127
+
1128
1128
  /**
1129
1129
  * @notice Returns the address of the EVVM core contract
1130
1130
  * @dev The EVVM contract handles payments and staker registration
1131
1131
  * @return Address of the EVVM core contract
1132
1132
  */
1133
- function getEvvmAddress() external view returns (address) {
1133
+ function getCoreAddress() external view returns (address) {
1134
1134
  return EVVM_ADDRESS;
1135
1135
  }
1136
1136
 
1137
+ function getIfUsedAsyncNonce(
1138
+ address user,
1139
+ uint256 nonce
1140
+ ) external view returns (bool) {
1141
+ return core.getIfUsedAsyncNonce(user, nonce);
1142
+ }
1143
+
1137
1144
  /**
1138
1145
  * @notice Returns the address representing the Principal Token
1139
1146
  * @dev This is a constant address used to represent the principal token
1140
1147
  * @return Address representing the Principal Token (0x...0001)
1141
1148
  */
1142
- function getMateAddress() external pure returns (address) {
1143
- return PRINCIPAL_TOKEN_ADDRESS;
1149
+ function getMateAddress() external view returns (address) {
1150
+ return core.getPrincipalTokenAddress();
1144
1151
  }
1145
1152
 
1146
1153
  /**
@@ -1149,6 +1156,6 @@ contract Staking is AsyncNonce, StakingStructs {
1149
1156
  * @return Address of the current contract admin
1150
1157
  */
1151
1158
  function getOwner() external view returns (address) {
1152
- return admin.actual;
1159
+ return admin.current;
1153
1160
  }
1154
1161
  }