@evvm/testnet-contracts 2.1.3 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -2
- package/README.md +355 -55
- package/contracts/evvm/Evvm.sol +39 -38
- package/contracts/evvm/lib/ErrorsLib.sol +2 -1
- package/contracts/evvm/lib/EvvmStorage.sol +2 -0
- package/contracts/evvm/lib/EvvmStructs.sol +27 -1
- package/contracts/evvm/lib/SignatureUtils.sol +14 -17
- package/contracts/nameService/NameService.sol +124 -366
- package/contracts/nameService/lib/ErrorsLib.sol +2 -8
- package/contracts/nameService/lib/IdentityValidation.sol +182 -0
- package/contracts/nameService/lib/NameServiceStructs.sol +69 -0
- package/contracts/nameService/lib/SignatureUtils.sol +47 -41
- package/contracts/p2pSwap/P2PSwap.sol +54 -535
- package/contracts/p2pSwap/lib/P2PSwapStructs.sol +59 -0
- package/contracts/p2pSwap/lib/SignatureUtils.sol +16 -18
- package/contracts/staking/Estimator.sol +7 -6
- package/contracts/staking/Staking.sol +70 -159
- package/contracts/staking/lib/ErrorsLib.sol +0 -1
- package/contracts/staking/lib/SignatureUtils.sol +7 -36
- package/contracts/staking/lib/StakingStructs.sol +94 -0
- package/contracts/treasury/Treasury.sol +18 -20
- package/contracts/treasuryTwoChains/TreasuryExternalChainStation.sol +88 -35
- package/contracts/treasuryTwoChains/TreasuryHostChainStation.sol +81 -47
- package/contracts/treasuryTwoChains/lib/ErrorsLib.sol +2 -0
- package/contracts/treasuryTwoChains/lib/ExternalChainStationStructs.sol +3 -14
- package/contracts/treasuryTwoChains/lib/HostChainStationStructs.sol +3 -7
- package/contracts/treasuryTwoChains/lib/SignatureUtils.sol +12 -14
- package/interfaces/IEstimator.sol +7 -50
- package/interfaces/IEvvm.sol +17 -91
- package/interfaces/INameService.sol +37 -88
- package/interfaces/IP2PSwap.sol +19 -15
- package/interfaces/IStaking.sol +20 -50
- package/interfaces/ITreasury.sol +1 -4
- package/interfaces/ITreasuryExternalChainStation.sol +11 -15
- package/interfaces/ITreasuryHostChainStation.sol +7 -10
- package/library/Erc191TestBuilder.sol +56 -57
- package/library/EvvmService.sol +40 -0
- package/library/primitives/IERC20.sol +79 -0
- package/library/primitives/Math.sol +415 -0
- package/library/primitives/SignatureRecover.sol +42 -0
- package/library/utils/AdvancedStrings.sol +89 -0
- package/library/utils/GovernanceUtils.sol +81 -0
- package/library/utils/SignatureUtil.sol +29 -0
- package/library/utils/nonces/AsyncNonce.sol +32 -0
- package/library/utils/nonces/SyncNonce.sol +27 -0
- package/library/utils/service/EvvmPayments.sol +77 -0
- package/library/utils/service/StakingServiceUtils.sol +32 -0
- package/package.json +11 -13
- package/contracts/evvm/EvvmLegacy.sol +0 -1553
- package/library/AdvancedStrings.sol +0 -77
- package/library/SignatureRecover.sol +0 -140
- package/library/StakingServiceHooks.sol +0 -116
|
@@ -41,99 +41,15 @@ pragma solidity ^0.8.0;
|
|
|
41
41
|
* - Estimator integration for yield calculations
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
import {
|
|
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";
|
|
49
50
|
|
|
50
|
-
contract Staking {
|
|
51
|
-
|
|
52
|
-
* @dev Metadata for presale stakers
|
|
53
|
-
* @param isAllow Whether the address is allowed to participate in presale staking
|
|
54
|
-
* @param stakingAmount Current number of staking tokens staked (max 2 for presale)
|
|
55
|
-
*/
|
|
56
|
-
struct presaleStakerMetadata {
|
|
57
|
-
bool isAllow;
|
|
58
|
-
uint256 stakingAmount;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* @dev Struct to store the history of the user
|
|
63
|
-
* @param transactionType Type of transaction:
|
|
64
|
-
* - 0x01 for staking
|
|
65
|
-
* - 0x02 for unstaking
|
|
66
|
-
* - Other values for yield/reward transactions
|
|
67
|
-
* @param amount Amount of staking staked/unstaked or reward received
|
|
68
|
-
* @param timestamp Timestamp when the transaction occurred
|
|
69
|
-
* @param totalStaked Total amount of staking currently staked after this transaction
|
|
70
|
-
*/
|
|
71
|
-
struct HistoryMetadata {
|
|
72
|
-
bytes32 transactionType;
|
|
73
|
-
uint256 amount;
|
|
74
|
-
uint256 timestamp;
|
|
75
|
-
uint256 totalStaked;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* @dev Struct for managing address change proposals with time delay
|
|
80
|
-
* @param actual Current active address
|
|
81
|
-
* @param proposal Proposed new address
|
|
82
|
-
* @param timeToAccept Timestamp when the proposal can be accepted
|
|
83
|
-
*/
|
|
84
|
-
struct AddressTypeProposal {
|
|
85
|
-
address actual;
|
|
86
|
-
address proposal;
|
|
87
|
-
uint256 timeToAccept;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @dev Struct for managing uint256 change proposals with time delay
|
|
92
|
-
* @param actual Current active value
|
|
93
|
-
* @param proposal Proposed new value
|
|
94
|
-
* @param timeToAccept Timestamp when the proposal can be accepted
|
|
95
|
-
*/
|
|
96
|
-
struct UintTypeProposal {
|
|
97
|
-
uint256 actual;
|
|
98
|
-
uint256 proposal;
|
|
99
|
-
uint256 timeToAccept;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* @dev Struct for managing boolean flag changes with time delay
|
|
104
|
-
* @param flag Current boolean state
|
|
105
|
-
* @param timeToAccept Timestamp when the flag change can be executed
|
|
106
|
-
*/
|
|
107
|
-
struct BoolTypeProposal {
|
|
108
|
-
bool flag;
|
|
109
|
-
uint256 timeToAccept;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* @dev Struct to store service staking metadata during the staking process
|
|
114
|
-
* @param service Address of the service or contract account
|
|
115
|
-
* @param timestamp Timestamp when the prepareServiceStaking was called
|
|
116
|
-
* @param amountOfStaking Amount of staking tokens to be staked
|
|
117
|
-
* @param amountServiceBeforeStaking Service's Principal Token balance before staking
|
|
118
|
-
* @param amountStakingBeforeStaking Staking contract's Principal Token balance before staking
|
|
119
|
-
*/
|
|
120
|
-
struct ServiceStakingMetadata {
|
|
121
|
-
address service;
|
|
122
|
-
uint256 timestamp;
|
|
123
|
-
uint256 amountOfStaking;
|
|
124
|
-
uint256 amountServiceBeforeStaking;
|
|
125
|
-
uint256 amountStakingBeforeStaking;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* @dev Struct to encapsulate account metadata for staking operations
|
|
130
|
-
* @param Address Address of the account
|
|
131
|
-
* @param IsAService Boolean indicating if the account is a smart contract (service) account
|
|
132
|
-
*/
|
|
133
|
-
struct AccountMetadata {
|
|
134
|
-
address Address;
|
|
135
|
-
bool IsAService;
|
|
136
|
-
}
|
|
51
|
+
contract Staking is AsyncNonce, StakingStructs {
|
|
52
|
+
uint256 constant TIME_TO_ACCEPT_PROPOSAL = 1 days;
|
|
137
53
|
|
|
138
54
|
/// @dev Address of the EVVM core contract
|
|
139
55
|
address private EVVM_ADDRESS;
|
|
@@ -154,7 +70,7 @@ contract Staking {
|
|
|
154
70
|
/// @dev Golden Fisher address management with proposal system
|
|
155
71
|
AddressTypeProposal private goldenFisher;
|
|
156
72
|
/// @dev Estimator contract address management with proposal system
|
|
157
|
-
AddressTypeProposal private
|
|
73
|
+
AddressTypeProposal private estimatorAddress;
|
|
158
74
|
/// @dev Time delay for regular staking after unstaking
|
|
159
75
|
UintTypeProposal private secondsToUnlockStaking;
|
|
160
76
|
/// @dev Time delay for full unstaking (21 days default)
|
|
@@ -169,15 +85,15 @@ contract Staking {
|
|
|
169
85
|
/// @dev One-time setup breaker for estimator and EVVM addresses
|
|
170
86
|
bytes1 private breakerSetupEstimatorAndEvvm;
|
|
171
87
|
|
|
172
|
-
/// @dev Mapping to track used nonces for staking operations per user
|
|
173
|
-
mapping(address => mapping(uint256 => bool)) private stakingNonce;
|
|
174
|
-
|
|
175
88
|
/// @dev Mapping to store presale staker metadata
|
|
176
89
|
mapping(address => presaleStakerMetadata) private userPresaleStaker;
|
|
177
90
|
|
|
178
91
|
/// @dev Mapping to store complete staking history for each user
|
|
179
92
|
mapping(address => HistoryMetadata[]) private userHistory;
|
|
180
93
|
|
|
94
|
+
IEvvm private evvm;
|
|
95
|
+
IEstimator private estimator;
|
|
96
|
+
|
|
181
97
|
/// @dev Modifier to verify access to admin functions
|
|
182
98
|
modifier onlyOwner() {
|
|
183
99
|
if (msg.sender != admin.actual) revert ErrorsLib.SenderIsNotAdmin();
|
|
@@ -211,12 +127,12 @@ contract Staking {
|
|
|
211
127
|
|
|
212
128
|
goldenFisher.actual = initialGoldenFisher;
|
|
213
129
|
|
|
214
|
-
allowPublicStaking.flag =
|
|
215
|
-
allowPresaleStaking.flag =
|
|
130
|
+
allowPublicStaking.flag = false;
|
|
131
|
+
allowPresaleStaking.flag = true;
|
|
216
132
|
|
|
217
133
|
secondsToUnlockStaking.actual = 0;
|
|
218
134
|
|
|
219
|
-
secondsToUnllockFullUnstaking.actual =
|
|
135
|
+
secondsToUnllockFullUnstaking.actual = 5 days;
|
|
220
136
|
|
|
221
137
|
breakerSetupEstimatorAndEvvm = 0x01;
|
|
222
138
|
}
|
|
@@ -233,9 +149,11 @@ contract Staking {
|
|
|
233
149
|
) external {
|
|
234
150
|
if (breakerSetupEstimatorAndEvvm == 0x00) revert();
|
|
235
151
|
|
|
236
|
-
|
|
152
|
+
estimatorAddress.actual = _estimator;
|
|
237
153
|
EVVM_ADDRESS = _evvm;
|
|
238
154
|
breakerSetupEstimatorAndEvvm = 0x00;
|
|
155
|
+
evvm = IEvvm(_evvm);
|
|
156
|
+
estimator = IEstimator(_estimator);
|
|
239
157
|
}
|
|
240
158
|
|
|
241
159
|
/**
|
|
@@ -258,7 +176,7 @@ contract Staking {
|
|
|
258
176
|
isStaking,
|
|
259
177
|
amountOfStaking,
|
|
260
178
|
0,
|
|
261
|
-
|
|
179
|
+
evvm.getNextCurrentSyncNonce(msg.sender),
|
|
262
180
|
false,
|
|
263
181
|
signature_EVVM
|
|
264
182
|
);
|
|
@@ -288,7 +206,7 @@ contract Staking {
|
|
|
288
206
|
) external {
|
|
289
207
|
if (
|
|
290
208
|
!SignatureUtils.verifyMessageSignedForStake(
|
|
291
|
-
|
|
209
|
+
evvm.getEvvmID(),
|
|
292
210
|
user,
|
|
293
211
|
false,
|
|
294
212
|
isStaking,
|
|
@@ -298,8 +216,7 @@ contract Staking {
|
|
|
298
216
|
)
|
|
299
217
|
) revert ErrorsLib.InvalidSignatureOnStaking();
|
|
300
218
|
|
|
301
|
-
|
|
302
|
-
revert ErrorsLib.StakingNonceAlreadyUsed();
|
|
219
|
+
verifyAsyncNonce(user, nonce);
|
|
303
220
|
|
|
304
221
|
presaleClaims(isStaking, user);
|
|
305
222
|
|
|
@@ -316,7 +233,7 @@ contract Staking {
|
|
|
316
233
|
signature_EVVM
|
|
317
234
|
);
|
|
318
235
|
|
|
319
|
-
|
|
236
|
+
markAsyncNonceAsUsed(user, nonce);
|
|
320
237
|
}
|
|
321
238
|
|
|
322
239
|
/**
|
|
@@ -381,7 +298,7 @@ contract Staking {
|
|
|
381
298
|
|
|
382
299
|
if (
|
|
383
300
|
!SignatureUtils.verifyMessageSignedForStake(
|
|
384
|
-
|
|
301
|
+
evvm.getEvvmID(),
|
|
385
302
|
user,
|
|
386
303
|
true,
|
|
387
304
|
isStaking,
|
|
@@ -391,8 +308,7 @@ contract Staking {
|
|
|
391
308
|
)
|
|
392
309
|
) revert ErrorsLib.InvalidSignatureOnStaking();
|
|
393
310
|
|
|
394
|
-
|
|
395
|
-
revert ErrorsLib.StakingNonceAlreadyUsed();
|
|
311
|
+
verifyAsyncNonce(user, nonce);
|
|
396
312
|
|
|
397
313
|
stakingBaseProcess(
|
|
398
314
|
AccountMetadata({Address: user, IsAService: false}),
|
|
@@ -404,19 +320,19 @@ contract Staking {
|
|
|
404
320
|
signature_EVVM
|
|
405
321
|
);
|
|
406
322
|
|
|
407
|
-
|
|
323
|
+
markAsyncNonceAsUsed(user, nonce);
|
|
408
324
|
}
|
|
409
325
|
|
|
410
326
|
/**
|
|
411
327
|
* @notice Prepares a service/contract account for staking by recording pre-staking state
|
|
412
328
|
* @dev First step in the service staking process. Must be followed by payment via caPay and confirmServiceStaking in the same transaction
|
|
413
329
|
* @param amountOfStaking Amount of staking tokens the service intends to stake
|
|
414
|
-
*
|
|
330
|
+
*
|
|
415
331
|
* Service Staking Process:
|
|
416
332
|
* 1. Call prepareServiceStaking(amount) - Records balances and metadata
|
|
417
|
-
* 2. Use EVVM.caPay() to transfer the required Principal Tokens to this contract
|
|
333
|
+
* 2. Use EVVM.caPay() to transfer the required Principal Tokens to this contract
|
|
418
334
|
* 3. Call confirmServiceStaking() - Validates payment and completes staking
|
|
419
|
-
*
|
|
335
|
+
*
|
|
420
336
|
* @dev All three steps MUST occur in the same transaction or the staking will fail
|
|
421
337
|
* @dev CRITICAL WARNING: If the process is not completed properly (especially if caPay is called
|
|
422
338
|
* but confirmServiceStaking is not), the Principal Tokens will remain locked in the staking
|
|
@@ -428,11 +344,11 @@ contract Staking {
|
|
|
428
344
|
service: msg.sender,
|
|
429
345
|
timestamp: block.timestamp,
|
|
430
346
|
amountOfStaking: amountOfStaking,
|
|
431
|
-
amountServiceBeforeStaking:
|
|
347
|
+
amountServiceBeforeStaking: evvm.getBalance(
|
|
432
348
|
msg.sender,
|
|
433
349
|
PRINCIPAL_TOKEN_ADDRESS
|
|
434
350
|
),
|
|
435
|
-
amountStakingBeforeStaking:
|
|
351
|
+
amountStakingBeforeStaking: evvm.getBalance(
|
|
436
352
|
address(this),
|
|
437
353
|
PRINCIPAL_TOKEN_ADDRESS
|
|
438
354
|
)
|
|
@@ -442,13 +358,13 @@ contract Staking {
|
|
|
442
358
|
/**
|
|
443
359
|
* @notice Confirms and completes the service staking operation after payment verification
|
|
444
360
|
* @dev Final step in service staking. Validates that payment was made correctly and completes the staking process
|
|
445
|
-
*
|
|
361
|
+
*
|
|
446
362
|
* Validation checks:
|
|
447
363
|
* - Service balance decreased by the exact staking cost
|
|
448
|
-
* - Staking contract balance increased by the exact staking cost
|
|
364
|
+
* - Staking contract balance increased by the exact staking cost
|
|
449
365
|
* - Operation occurs in the same transaction as prepareServiceStaking
|
|
450
366
|
* - Caller matches the service that initiated the preparation
|
|
451
|
-
*
|
|
367
|
+
*
|
|
452
368
|
* @dev Only callable by the same contract that called prepareServiceStaking
|
|
453
369
|
* @dev Must be called in the same transaction as prepareServiceStaking
|
|
454
370
|
*/
|
|
@@ -456,12 +372,12 @@ contract Staking {
|
|
|
456
372
|
uint256 totalStakingRequired = PRICE_OF_STAKING *
|
|
457
373
|
serviceStakingData.amountOfStaking;
|
|
458
374
|
|
|
459
|
-
uint256 actualServiceBalance =
|
|
375
|
+
uint256 actualServiceBalance = evvm.getBalance(
|
|
460
376
|
msg.sender,
|
|
461
377
|
PRINCIPAL_TOKEN_ADDRESS
|
|
462
378
|
);
|
|
463
379
|
|
|
464
|
-
uint256 actualStakingBalance =
|
|
380
|
+
uint256 actualStakingBalance = evvm.getBalance(
|
|
465
381
|
address(this),
|
|
466
382
|
PRINCIPAL_TOKEN_ADDRESS
|
|
467
383
|
);
|
|
@@ -499,7 +415,7 @@ contract Staking {
|
|
|
499
415
|
* @notice Allows a service/contract account to unstake their staking tokens
|
|
500
416
|
* @dev Simplified unstaking process for services - no signature or payment required, just direct unstaking
|
|
501
417
|
* @param amountOfStaking Amount of staking tokens to unstake
|
|
502
|
-
*
|
|
418
|
+
*
|
|
503
419
|
* @dev The service will receive Principal Tokens equal to: amountOfStaking * PRICE_OF_STAKING
|
|
504
420
|
* @dev Subject to the same time locks as regular unstaking (21 days for full unstake)
|
|
505
421
|
* @dev Only callable by contract accounts (services), not EOAs
|
|
@@ -556,7 +472,7 @@ contract Staking {
|
|
|
556
472
|
signature_EVVM
|
|
557
473
|
);
|
|
558
474
|
|
|
559
|
-
|
|
475
|
+
evvm.pointStaker(account.Address, 0x01);
|
|
560
476
|
|
|
561
477
|
auxSMsteBalance = userHistory[account.Address].length == 0
|
|
562
478
|
? amountOfStaking
|
|
@@ -570,7 +486,7 @@ contract Staking {
|
|
|
570
486
|
block.timestamp
|
|
571
487
|
) revert ErrorsLib.AddressMustWaitToFullUnstake();
|
|
572
488
|
|
|
573
|
-
|
|
489
|
+
evvm.pointStaker(account.Address, 0x00);
|
|
574
490
|
}
|
|
575
491
|
|
|
576
492
|
if (priorityFee_EVVM != 0 && !account.IsAService)
|
|
@@ -608,13 +524,13 @@ contract Staking {
|
|
|
608
524
|
);
|
|
609
525
|
|
|
610
526
|
if (
|
|
611
|
-
|
|
527
|
+
evvm.isAddressStaker(msg.sender) &&
|
|
612
528
|
!account.IsAService
|
|
613
529
|
) {
|
|
614
530
|
makeCaPay(
|
|
615
531
|
PRINCIPAL_TOKEN_ADDRESS,
|
|
616
532
|
msg.sender,
|
|
617
|
-
(
|
|
533
|
+
(evvm.getRewardAmount() * 2) + priorityFee_EVVM
|
|
618
534
|
);
|
|
619
535
|
}
|
|
620
536
|
}
|
|
@@ -648,7 +564,7 @@ contract Staking {
|
|
|
648
564
|
amountTotalToBeRewarded,
|
|
649
565
|
idToOverwriteUserHistory,
|
|
650
566
|
timestampToBeOverwritten
|
|
651
|
-
) =
|
|
567
|
+
) = estimator.makeEstimation(user);
|
|
652
568
|
|
|
653
569
|
if (amountTotalToBeRewarded > 0) {
|
|
654
570
|
makeCaPay(tokenToBeRewarded, user, amountTotalToBeRewarded);
|
|
@@ -660,11 +576,11 @@ contract Staking {
|
|
|
660
576
|
userHistory[user][idToOverwriteUserHistory]
|
|
661
577
|
.timestamp = timestampToBeOverwritten;
|
|
662
578
|
|
|
663
|
-
if (
|
|
579
|
+
if (evvm.isAddressStaker(msg.sender)) {
|
|
664
580
|
makeCaPay(
|
|
665
581
|
PRINCIPAL_TOKEN_ADDRESS,
|
|
666
582
|
msg.sender,
|
|
667
|
-
(
|
|
583
|
+
(evvm.getRewardAmount() * 1)
|
|
668
584
|
);
|
|
669
585
|
}
|
|
670
586
|
}
|
|
@@ -693,7 +609,7 @@ contract Staking {
|
|
|
693
609
|
uint256 nonce,
|
|
694
610
|
bytes memory signature
|
|
695
611
|
) internal {
|
|
696
|
-
|
|
612
|
+
evvm.pay(
|
|
697
613
|
user,
|
|
698
614
|
address(this),
|
|
699
615
|
"",
|
|
@@ -719,7 +635,7 @@ contract Staking {
|
|
|
719
635
|
address user,
|
|
720
636
|
uint256 amount
|
|
721
637
|
) internal {
|
|
722
|
-
|
|
638
|
+
evvm.caPay(user, tokenAddress, amount);
|
|
723
639
|
}
|
|
724
640
|
|
|
725
641
|
//▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀
|
|
@@ -761,7 +677,7 @@ contract Staking {
|
|
|
761
677
|
*/
|
|
762
678
|
function proposeAdmin(address _newAdmin) external onlyOwner {
|
|
763
679
|
admin.proposal = _newAdmin;
|
|
764
|
-
admin.timeToAccept = block.timestamp +
|
|
680
|
+
admin.timeToAccept = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
|
|
765
681
|
}
|
|
766
682
|
|
|
767
683
|
/**
|
|
@@ -795,7 +711,7 @@ contract Staking {
|
|
|
795
711
|
*/
|
|
796
712
|
function proposeGoldenFisher(address _goldenFisher) external onlyOwner {
|
|
797
713
|
goldenFisher.proposal = _goldenFisher;
|
|
798
|
-
goldenFisher.timeToAccept = block.timestamp +
|
|
714
|
+
goldenFisher.timeToAccept = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
|
|
799
715
|
}
|
|
800
716
|
|
|
801
717
|
/**
|
|
@@ -829,7 +745,9 @@ contract Staking {
|
|
|
829
745
|
uint256 _secondsToUnlockStaking
|
|
830
746
|
) external onlyOwner {
|
|
831
747
|
secondsToUnlockStaking.proposal = _secondsToUnlockStaking;
|
|
832
|
-
secondsToUnlockStaking.timeToAccept =
|
|
748
|
+
secondsToUnlockStaking.timeToAccept =
|
|
749
|
+
block.timestamp +
|
|
750
|
+
TIME_TO_ACCEPT_PROPOSAL;
|
|
833
751
|
}
|
|
834
752
|
|
|
835
753
|
/**
|
|
@@ -863,7 +781,9 @@ contract Staking {
|
|
|
863
781
|
uint256 _secondsToUnllockFullUnstaking
|
|
864
782
|
) external onlyOwner {
|
|
865
783
|
secondsToUnllockFullUnstaking.proposal = _secondsToUnllockFullUnstaking;
|
|
866
|
-
secondsToUnllockFullUnstaking.timeToAccept =
|
|
784
|
+
secondsToUnllockFullUnstaking.timeToAccept =
|
|
785
|
+
block.timestamp +
|
|
786
|
+
TIME_TO_ACCEPT_PROPOSAL;
|
|
867
787
|
}
|
|
868
788
|
|
|
869
789
|
/**
|
|
@@ -894,7 +814,9 @@ contract Staking {
|
|
|
894
814
|
* @dev Initiates the time-delayed process to enable/disable public staking
|
|
895
815
|
*/
|
|
896
816
|
function prepareChangeAllowPublicStaking() external onlyOwner {
|
|
897
|
-
allowPublicStaking.timeToAccept =
|
|
817
|
+
allowPublicStaking.timeToAccept =
|
|
818
|
+
block.timestamp +
|
|
819
|
+
TIME_TO_ACCEPT_PROPOSAL;
|
|
898
820
|
}
|
|
899
821
|
|
|
900
822
|
/**
|
|
@@ -924,7 +846,9 @@ contract Staking {
|
|
|
924
846
|
* @dev Initiates the time-delayed process to enable/disable presale staking
|
|
925
847
|
*/
|
|
926
848
|
function prepareChangeAllowPresaleStaking() external onlyOwner {
|
|
927
|
-
allowPresaleStaking.timeToAccept =
|
|
849
|
+
allowPresaleStaking.timeToAccept =
|
|
850
|
+
block.timestamp +
|
|
851
|
+
TIME_TO_ACCEPT_PROPOSAL;
|
|
928
852
|
}
|
|
929
853
|
|
|
930
854
|
/**
|
|
@@ -955,8 +879,8 @@ contract Staking {
|
|
|
955
879
|
* @param _estimator Address of the proposed new estimator contract
|
|
956
880
|
*/
|
|
957
881
|
function proposeEstimator(address _estimator) external onlyOwner {
|
|
958
|
-
|
|
959
|
-
|
|
882
|
+
estimatorAddress.proposal = _estimator;
|
|
883
|
+
estimatorAddress.timeToAccept = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
|
|
960
884
|
}
|
|
961
885
|
|
|
962
886
|
/**
|
|
@@ -964,8 +888,8 @@ contract Staking {
|
|
|
964
888
|
* @dev Only current admin can reject the pending estimator contract proposal
|
|
965
889
|
*/
|
|
966
890
|
function rejectProposalEstimator() external onlyOwner {
|
|
967
|
-
|
|
968
|
-
|
|
891
|
+
estimatorAddress.proposal = address(0);
|
|
892
|
+
estimatorAddress.timeToAccept = 0;
|
|
969
893
|
}
|
|
970
894
|
|
|
971
895
|
/**
|
|
@@ -973,12 +897,13 @@ contract Staking {
|
|
|
973
897
|
* @dev Can only be called by the current admin after the 1-day time delay
|
|
974
898
|
*/
|
|
975
899
|
function acceptNewEstimator() external onlyOwner {
|
|
976
|
-
if (
|
|
900
|
+
if (estimatorAddress.timeToAccept > block.timestamp) {
|
|
977
901
|
revert();
|
|
978
902
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
903
|
+
estimatorAddress.actual = estimatorAddress.proposal;
|
|
904
|
+
estimatorAddress.proposal = address(0);
|
|
905
|
+
estimatorAddress.timeToAccept = 0;
|
|
906
|
+
estimator = IEstimator(estimatorAddress.actual);
|
|
982
907
|
}
|
|
983
908
|
|
|
984
909
|
//▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀▄▀
|
|
@@ -1113,20 +1038,6 @@ contract Staking {
|
|
|
1113
1038
|
return userHistory[_account][lengthOfHistory - 1].totalStaked;
|
|
1114
1039
|
}
|
|
1115
1040
|
|
|
1116
|
-
/**
|
|
1117
|
-
* @notice Checks if a specific nonce has been used for staking by a user
|
|
1118
|
-
* @dev Prevents replay attacks by tracking used nonces
|
|
1119
|
-
* @param _account Address to check the nonce for
|
|
1120
|
-
* @param _nonce Nonce value to check
|
|
1121
|
-
* @return True if the nonce has been used, false otherwise
|
|
1122
|
-
*/
|
|
1123
|
-
function checkIfStakeNonceUsed(
|
|
1124
|
-
address _account,
|
|
1125
|
-
uint256 _nonce
|
|
1126
|
-
) public view returns (bool) {
|
|
1127
|
-
return stakingNonce[_account][_nonce];
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
1041
|
/**
|
|
1131
1042
|
* @notice Returns the current golden fisher address
|
|
1132
1043
|
* @dev The golden fisher has special staking privileges
|
|
@@ -1167,7 +1078,7 @@ contract Staking {
|
|
|
1167
1078
|
* @return Address of the current estimator contract
|
|
1168
1079
|
*/
|
|
1169
1080
|
function getEstimatorAddress() external view returns (address) {
|
|
1170
|
-
return
|
|
1081
|
+
return estimatorAddress.actual;
|
|
1171
1082
|
}
|
|
1172
1083
|
|
|
1173
1084
|
/**
|
|
@@ -1176,7 +1087,7 @@ contract Staking {
|
|
|
1176
1087
|
* @return Address of the proposed estimator contract (zero address if none)
|
|
1177
1088
|
*/
|
|
1178
1089
|
function getEstimatorProposal() external view returns (address) {
|
|
1179
|
-
return
|
|
1090
|
+
return estimatorAddress.proposal;
|
|
1180
1091
|
}
|
|
1181
1092
|
|
|
1182
1093
|
/**
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EVVM-NONCOMMERCIAL-1.0
|
|
2
2
|
// Full license terms available at: https://www.evvm.info/docs/EVVMNoncommercialLicense
|
|
3
|
-
|
|
4
|
-
import {SignatureRecover} from "@evvm/testnet-contracts/library/SignatureRecover.sol";
|
|
5
|
-
import {AdvancedStrings} from "@evvm/testnet-contracts/library/AdvancedStrings.sol";
|
|
6
|
-
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
|
|
7
|
-
|
|
8
3
|
pragma solidity ^0.8.0;
|
|
9
4
|
|
|
5
|
+
import {SignatureUtil} from "@evvm/testnet-contracts/library/utils/SignatureUtil.sol";
|
|
6
|
+
import {AdvancedStrings} from "@evvm/testnet-contracts/library/utils/AdvancedStrings.sol";
|
|
7
|
+
|
|
10
8
|
library SignatureUtils {
|
|
11
9
|
/**
|
|
12
10
|
* @dev using EIP-191 (https://eips.ethereum.org/EIPS/eip-191) can be used to sign and
|
|
@@ -24,42 +22,15 @@ library SignatureUtils {
|
|
|
24
22
|
bytes memory signature
|
|
25
23
|
) internal pure returns (bool) {
|
|
26
24
|
return
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
SignatureUtil.verifySignature(
|
|
26
|
+
evvmID,
|
|
29
27
|
isExternalStaking ? "publicStaking" : "presaleStaking",
|
|
30
28
|
string.concat(
|
|
31
29
|
_isStaking ? "true" : "false",
|
|
32
30
|
",",
|
|
33
|
-
|
|
34
|
-
",",
|
|
35
|
-
Strings.toString(_nonce)
|
|
36
|
-
),
|
|
37
|
-
signature,
|
|
38
|
-
user
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function verifyMessageSignedForPublicServiceStake(
|
|
43
|
-
uint256 evvmID,
|
|
44
|
-
address user,
|
|
45
|
-
address serviceAddress,
|
|
46
|
-
bool _isStaking,
|
|
47
|
-
uint256 _amountOfStaking,
|
|
48
|
-
uint256 _nonce,
|
|
49
|
-
bytes memory signature
|
|
50
|
-
) internal pure returns (bool) {
|
|
51
|
-
return
|
|
52
|
-
SignatureRecover.signatureVerification(
|
|
53
|
-
Strings.toString(evvmID),
|
|
54
|
-
"publicServiceStaking",
|
|
55
|
-
string.concat(
|
|
56
|
-
AdvancedStrings.addressToString(serviceAddress),
|
|
57
|
-
",",
|
|
58
|
-
_isStaking ? "true" : "false",
|
|
59
|
-
",",
|
|
60
|
-
Strings.toString(_amountOfStaking),
|
|
31
|
+
AdvancedStrings.uintToString(_amountOfStaking),
|
|
61
32
|
",",
|
|
62
|
-
|
|
33
|
+
AdvancedStrings.uintToString(_nonce)
|
|
63
34
|
),
|
|
64
35
|
signature,
|
|
65
36
|
user
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EVVM-NONCOMMERCIAL-1.0
|
|
2
|
+
// Full license terms available at: https://www.evvm.info/docs/EVVMNoncommercialLicense
|
|
3
|
+
|
|
4
|
+
pragma solidity ^0.8.0;
|
|
5
|
+
|
|
6
|
+
abstract contract StakingStructs {
|
|
7
|
+
/**
|
|
8
|
+
* @dev Metadata for presale stakers
|
|
9
|
+
* @param isAllow Whether the address is allowed to participate in presale staking
|
|
10
|
+
* @param stakingAmount Current number of staking tokens staked (max 2 for presale)
|
|
11
|
+
*/
|
|
12
|
+
struct presaleStakerMetadata {
|
|
13
|
+
bool isAllow;
|
|
14
|
+
uint256 stakingAmount;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @dev Struct to store the history of the user
|
|
19
|
+
* @param transactionType Type of transaction:
|
|
20
|
+
* - 0x01 for staking
|
|
21
|
+
* - 0x02 for unstaking
|
|
22
|
+
* - Other values for yield/reward transactions
|
|
23
|
+
* @param amount Amount of staking staked/unstaked or reward received
|
|
24
|
+
* @param timestamp Timestamp when the transaction occurred
|
|
25
|
+
* @param totalStaked Total amount of staking currently staked after this transaction
|
|
26
|
+
*/
|
|
27
|
+
struct HistoryMetadata {
|
|
28
|
+
bytes32 transactionType;
|
|
29
|
+
uint256 amount;
|
|
30
|
+
uint256 timestamp;
|
|
31
|
+
uint256 totalStaked;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @dev Struct for managing address change proposals with time delay
|
|
36
|
+
* @param actual Current active address
|
|
37
|
+
* @param proposal Proposed new address
|
|
38
|
+
* @param timeToAccept Timestamp when the proposal can be accepted
|
|
39
|
+
*/
|
|
40
|
+
struct AddressTypeProposal {
|
|
41
|
+
address actual;
|
|
42
|
+
address proposal;
|
|
43
|
+
uint256 timeToAccept;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @dev Struct for managing uint256 change proposals with time delay
|
|
48
|
+
* @param actual Current active value
|
|
49
|
+
* @param proposal Proposed new value
|
|
50
|
+
* @param timeToAccept Timestamp when the proposal can be accepted
|
|
51
|
+
*/
|
|
52
|
+
struct UintTypeProposal {
|
|
53
|
+
uint256 actual;
|
|
54
|
+
uint256 proposal;
|
|
55
|
+
uint256 timeToAccept;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @dev Struct for managing boolean flag changes with time delay
|
|
60
|
+
* @param flag Current boolean state
|
|
61
|
+
* @param timeToAccept Timestamp when the flag change can be executed
|
|
62
|
+
*/
|
|
63
|
+
struct BoolTypeProposal {
|
|
64
|
+
bool flag;
|
|
65
|
+
uint256 timeToAccept;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @dev Struct to store service staking metadata during the staking process
|
|
70
|
+
* @param service Address of the service or contract account
|
|
71
|
+
* @param timestamp Timestamp when the prepareServiceStaking was called
|
|
72
|
+
* @param amountOfStaking Amount of staking tokens to be staked
|
|
73
|
+
* @param amountServiceBeforeStaking Service's Principal Token balance before staking
|
|
74
|
+
* @param amountStakingBeforeStaking Staking contract's Principal Token balance before staking
|
|
75
|
+
*/
|
|
76
|
+
struct ServiceStakingMetadata {
|
|
77
|
+
address service;
|
|
78
|
+
uint256 timestamp;
|
|
79
|
+
uint256 amountOfStaking;
|
|
80
|
+
uint256 amountServiceBeforeStaking;
|
|
81
|
+
uint256 amountStakingBeforeStaking;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @dev Struct to encapsulate account metadata for staking operations
|
|
86
|
+
* @param Address Address of the account
|
|
87
|
+
* @param IsAService Boolean indicating if the account is a smart contract (service) account
|
|
88
|
+
*/
|
|
89
|
+
struct AccountMetadata {
|
|
90
|
+
address Address;
|
|
91
|
+
bool IsAService;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
}
|