@evvm/testnet-contracts 3.0.0 → 3.0.2
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/README.md +3 -1
- package/contracts/core/Core.sol +327 -133
- package/contracts/core/lib/CoreStorage.sol +60 -24
- package/contracts/p2pSwap/P2PSwap.sol +183 -141
- package/interfaces/ICore.sol +1 -1
- package/interfaces/IP2PSwap.sol +0 -2
- package/library/errors/CoreError.sol +25 -11
- package/library/structs/P2PSwapStructs.sol +1 -57
- package/library/utils/governance/ProposalStructs.sol +6 -0
- package/library/utils/service/CoreExecution.sol +0 -19
- package/package.json +1 -1
package/contracts/core/Core.sol
CHANGED
|
@@ -88,9 +88,9 @@ contract Core is Storage {
|
|
|
88
88
|
|
|
89
89
|
admin.current = _initialOwner;
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
rewardFlowDistribution.flag = true;
|
|
92
|
+
|
|
93
|
+
_giveReward(_stakingContractAddress, 2);
|
|
94
94
|
|
|
95
95
|
stakerList[_stakingContractAddress] = FLAG_IS_STAKER;
|
|
96
96
|
|
|
@@ -114,9 +114,9 @@ contract Core is Storage {
|
|
|
114
114
|
revert Error.AddressCantBeZero();
|
|
115
115
|
|
|
116
116
|
nameServiceAddress = _nameServiceAddress;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
|
|
118
|
+
_giveReward(_nameServiceAddress, 20);
|
|
119
|
+
|
|
120
120
|
stakerList[nameServiceAddress] = FLAG_IS_STAKER;
|
|
121
121
|
|
|
122
122
|
treasuryAddress = _treasuryAddress;
|
|
@@ -182,6 +182,8 @@ contract Core is Storage {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
//░▒▓█ Testnet Functions ██████████████████████████████████████████████████████▓▒░
|
|
186
|
+
|
|
185
187
|
/**
|
|
186
188
|
* @notice Faucet: Adds balance to a user for testing (Testnet only).
|
|
187
189
|
* @param user Recipient address.
|
|
@@ -194,6 +196,9 @@ contract Core is Storage {
|
|
|
194
196
|
uint256 quantity
|
|
195
197
|
) external {
|
|
196
198
|
balances[user][token] += quantity;
|
|
199
|
+
|
|
200
|
+
if (token == evvmMetadata.principalTokenAddress)
|
|
201
|
+
currentSupply += quantity;
|
|
197
202
|
}
|
|
198
203
|
|
|
199
204
|
/**
|
|
@@ -254,7 +259,7 @@ contract Core is Storage {
|
|
|
254
259
|
) != from
|
|
255
260
|
) revert Error.InvalidSignature();
|
|
256
261
|
|
|
257
|
-
if (!
|
|
262
|
+
if (!_canExecuteUserTransaction(from))
|
|
258
263
|
revert Error.UserCannotExecuteTransaction();
|
|
259
264
|
|
|
260
265
|
if (isAsyncExec) {
|
|
@@ -288,9 +293,9 @@ contract Core is Storage {
|
|
|
288
293
|
_updateBalance(from, to, token, amount);
|
|
289
294
|
|
|
290
295
|
if (isAddressStaker(msg.sender)) {
|
|
291
|
-
if (priorityFee > 0)
|
|
296
|
+
if (priorityFee > 0)
|
|
292
297
|
_updateBalance(from, msg.sender, token, priorityFee);
|
|
293
|
-
|
|
298
|
+
|
|
294
299
|
_giveReward(msg.sender, 1);
|
|
295
300
|
}
|
|
296
301
|
}
|
|
@@ -332,7 +337,7 @@ contract Core is Storage {
|
|
|
332
337
|
payment.signature
|
|
333
338
|
) !=
|
|
334
339
|
payment.from ||
|
|
335
|
-
!
|
|
340
|
+
!_canExecuteUserTransaction(payment.from)
|
|
336
341
|
) {
|
|
337
342
|
results[iteration] = false;
|
|
338
343
|
continue;
|
|
@@ -367,6 +372,14 @@ contract Core is Storage {
|
|
|
367
372
|
}
|
|
368
373
|
}
|
|
369
374
|
|
|
375
|
+
if (
|
|
376
|
+
(listStatus.current == 0x01 && !allowList[payment.token]) ||
|
|
377
|
+
(listStatus.current == 0x02 && denyList[payment.token])
|
|
378
|
+
) {
|
|
379
|
+
results[iteration] = false;
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
|
|
370
383
|
if (
|
|
371
384
|
(payment.senderExecutor != address(0) &&
|
|
372
385
|
msg.sender != payment.senderExecutor) ||
|
|
@@ -450,7 +463,7 @@ contract Core is Storage {
|
|
|
450
463
|
) != from
|
|
451
464
|
) revert Error.InvalidSignature();
|
|
452
465
|
|
|
453
|
-
if (!
|
|
466
|
+
if (!_canExecuteUserTransaction(from))
|
|
454
467
|
revert Error.UserCannotExecuteTransaction();
|
|
455
468
|
|
|
456
469
|
if (isAsyncExec) {
|
|
@@ -480,6 +493,8 @@ contract Core is Storage {
|
|
|
480
493
|
if (balances[from][token] < amount + (isSenderStaker ? priorityFee : 0))
|
|
481
494
|
revert Error.InsufficientBalance();
|
|
482
495
|
|
|
496
|
+
if (listStatus.current != 0x00) _verifyTokenInteractionAllowance(token);
|
|
497
|
+
|
|
483
498
|
uint256 acomulatedAmount = 0;
|
|
484
499
|
balances[from][token] -= (amount + (isSenderStaker ? priorityFee : 0));
|
|
485
500
|
address to_aux;
|
|
@@ -546,6 +561,8 @@ contract Core is Storage {
|
|
|
546
561
|
address token,
|
|
547
562
|
uint256 amount
|
|
548
563
|
) external {
|
|
564
|
+
if (listStatus.current != 0x00) _verifyTokenInteractionAllowance(token);
|
|
565
|
+
|
|
549
566
|
address from = msg.sender;
|
|
550
567
|
|
|
551
568
|
if (!CAUtils.verifyIfCA(from)) revert Error.NotAnCA();
|
|
@@ -608,7 +625,7 @@ contract Core is Storage {
|
|
|
608
625
|
if (originExecutor != address(0) && tx.origin != originExecutor)
|
|
609
626
|
revert Error.OriginIsNotTheOriginExecutor();
|
|
610
627
|
|
|
611
|
-
if (!
|
|
628
|
+
if (!_canExecuteUserTransaction(user))
|
|
612
629
|
revert Error.UserCannotExecuteTransaction();
|
|
613
630
|
|
|
614
631
|
if (isAsyncExec) {
|
|
@@ -688,17 +705,15 @@ contract Core is Storage {
|
|
|
688
705
|
* - Canceling pending service operations
|
|
689
706
|
* - Correcting accidental reservations
|
|
690
707
|
* - Freeing nonces for different services
|
|
691
|
-
*
|
|
692
|
-
* @param user Address that reserved the nonce
|
|
693
708
|
* @param nonce The async nonce to revoke reservation for
|
|
694
709
|
*/
|
|
695
|
-
function revokeAsyncNonce(
|
|
696
|
-
if (asyncNonce[
|
|
710
|
+
function revokeAsyncNonce(uint256 nonce) external {
|
|
711
|
+
if (asyncNonce[msg.sender][nonce]) revert Error.AsyncNonceAlreadyUsed();
|
|
697
712
|
|
|
698
|
-
if (asyncNonceReservedPointers[
|
|
713
|
+
if (asyncNonceReservedPointers[msg.sender][nonce] == address(0))
|
|
699
714
|
revert Error.AsyncNonceNotReserved();
|
|
700
715
|
|
|
701
|
-
asyncNonceReservedPointers[
|
|
716
|
+
asyncNonceReservedPointers[msg.sender][nonce] = address(0);
|
|
702
717
|
}
|
|
703
718
|
|
|
704
719
|
//░▒▓█ UserValidator Management Functions █████████████████████████████████████▓▒░
|
|
@@ -764,7 +779,7 @@ contract Core is Storage {
|
|
|
764
779
|
*/
|
|
765
780
|
function acceptUserValidatorProposal() external onlyAdmin {
|
|
766
781
|
if (block.timestamp < userValidatorAddress.timeToAccept)
|
|
767
|
-
revert Error.
|
|
782
|
+
revert Error.ProposalNotReadyToAccept();
|
|
768
783
|
|
|
769
784
|
userValidatorAddress.current = userValidatorAddress.proposal;
|
|
770
785
|
userValidatorAddress.proposal = address(0);
|
|
@@ -806,6 +821,8 @@ contract Core is Storage {
|
|
|
806
821
|
address token,
|
|
807
822
|
uint256 amount
|
|
808
823
|
) external {
|
|
824
|
+
if (listStatus.current != 0x00) _verifyTokenInteractionAllowance(token);
|
|
825
|
+
|
|
809
826
|
if (msg.sender != treasuryAddress) revert Error.SenderIsNotTreasury();
|
|
810
827
|
|
|
811
828
|
balances[user][token] += amount;
|
|
@@ -830,6 +847,113 @@ contract Core is Storage {
|
|
|
830
847
|
|
|
831
848
|
//░▒▓█ Administrative Functions ████████████████████████████████████████████████████████▓▒░
|
|
832
849
|
|
|
850
|
+
//██ Total Supply Management ████████████████████████████████████████
|
|
851
|
+
|
|
852
|
+
function proposeDeleteTotalSupply() external onlyAdmin {
|
|
853
|
+
if (
|
|
854
|
+
currentSupply < (evvmMetadata.totalSupply * 9999) / 10000 ||
|
|
855
|
+
evvmMetadata.totalSupply == type(uint256).max
|
|
856
|
+
) revert Error.MaxSupplyDeletionNotAllowed();
|
|
857
|
+
|
|
858
|
+
timeToDeleteMaxSupply = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
function rejectDeleteTotalSupply() external onlyAdmin {
|
|
862
|
+
timeToDeleteMaxSupply = 0;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
function acceptDeleteTotalSupply() external onlyAdmin {
|
|
866
|
+
if (block.timestamp < timeToDeleteMaxSupply)
|
|
867
|
+
revert Error.ProposalNotReadyToAccept();
|
|
868
|
+
|
|
869
|
+
evvmMetadata.totalSupply = type(uint256).max;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
//██ Reward distribution ████████████████████████████████████████
|
|
873
|
+
|
|
874
|
+
function proposeChangeBaseRewardAmount(
|
|
875
|
+
uint256 newBaseReward
|
|
876
|
+
) external onlyAdmin {
|
|
877
|
+
if (
|
|
878
|
+
evvmMetadata.totalSupply != type(uint256).max ||
|
|
879
|
+
newBaseReward >= evvmMetadata.reward
|
|
880
|
+
) revert Error.BaseRewardIncreaseNotAllowed();
|
|
881
|
+
proposalChangeReward = newBaseReward;
|
|
882
|
+
timeToAcceptChangeReward = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
function rejectChangeBaseRewardAmount() external onlyAdmin {
|
|
886
|
+
proposalChangeReward = 0;
|
|
887
|
+
timeToAcceptChangeReward = 0;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
function acceptChangeBaseRewardAmount() external onlyAdmin {
|
|
891
|
+
if (block.timestamp < timeToAcceptChangeReward)
|
|
892
|
+
revert Error.ProposalNotReadyToAccept();
|
|
893
|
+
|
|
894
|
+
evvmMetadata.reward = proposalChangeReward;
|
|
895
|
+
proposalChangeReward = 0;
|
|
896
|
+
timeToAcceptChangeReward = 0;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
function proposeChangeRewardFlowDistribution() external onlyAdmin {
|
|
900
|
+
if (currentSupply < (evvmMetadata.totalSupply * 9999) / 10000)
|
|
901
|
+
revert Error.RewardFlowDistributionChangeNotAllowed();
|
|
902
|
+
|
|
903
|
+
rewardFlowDistribution.timeToAccept =
|
|
904
|
+
block.timestamp +
|
|
905
|
+
TIME_TO_ACCEPT_PROPOSAL;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
function rejectChangeRewardFlowDistribution() external onlyAdmin {
|
|
909
|
+
rewardFlowDistribution.timeToAccept = 0;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
function acceptChangeRewardFlowDistribution() external onlyAdmin {
|
|
913
|
+
if (block.timestamp < rewardFlowDistribution.timeToAccept)
|
|
914
|
+
revert Error.ProposalNotReadyToAccept();
|
|
915
|
+
|
|
916
|
+
rewardFlowDistribution.flag = !rewardFlowDistribution.flag;
|
|
917
|
+
rewardFlowDistribution.timeToAccept = 0;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
//██ List state Management ████████████████████████████████████████
|
|
921
|
+
|
|
922
|
+
function proposeListStatus(bytes1 newStatus) external onlyAdmin {
|
|
923
|
+
if (uint8(newStatus) >= uint8(0x03)) revert Error.InvalidListStatus();
|
|
924
|
+
|
|
925
|
+
listStatus.proposal = newStatus;
|
|
926
|
+
listStatus.timeToAccept = block.timestamp + TIME_TO_ACCEPT_PROPOSAL;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
function rejectListStatusProposal() external onlyAdmin {
|
|
930
|
+
listStatus.proposal = 0x00;
|
|
931
|
+
listStatus.timeToAccept = 0;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
function acceptListStatusProposal() external onlyAdmin {
|
|
935
|
+
if (block.timestamp < listStatus.timeToAccept)
|
|
936
|
+
revert Error.ProposalNotReadyToAccept();
|
|
937
|
+
|
|
938
|
+
listStatus.current = listStatus.proposal;
|
|
939
|
+
listStatus.proposal = 0x00;
|
|
940
|
+
listStatus.timeToAccept = 0;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
function setTokenStatusOnAllowList(
|
|
944
|
+
address token,
|
|
945
|
+
bool status
|
|
946
|
+
) external onlyAdmin {
|
|
947
|
+
allowList[token] = status;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
function setTokenStatusOnDenyList(
|
|
951
|
+
address token,
|
|
952
|
+
bool status
|
|
953
|
+
) external onlyAdmin {
|
|
954
|
+
denyList[token] = status;
|
|
955
|
+
}
|
|
956
|
+
|
|
833
957
|
//██ Proxy Management █████████████████████████████████████████████
|
|
834
958
|
|
|
835
959
|
/**
|
|
@@ -857,7 +981,7 @@ contract Core is Storage {
|
|
|
857
981
|
*/
|
|
858
982
|
function acceptImplementation() external onlyAdmin {
|
|
859
983
|
if (block.timestamp < timeToAcceptImplementation)
|
|
860
|
-
revert Error.
|
|
984
|
+
revert Error.ProposalNotReadyToAccept();
|
|
861
985
|
|
|
862
986
|
currentImplementation = proposalImplementation;
|
|
863
987
|
proposalImplementation = address(0);
|
|
@@ -898,7 +1022,7 @@ contract Core is Storage {
|
|
|
898
1022
|
*/
|
|
899
1023
|
function acceptAdmin() external {
|
|
900
1024
|
if (block.timestamp < admin.timeToAccept)
|
|
901
|
-
revert Error.
|
|
1025
|
+
revert Error.ProposalNotReadyToAccept();
|
|
902
1026
|
|
|
903
1027
|
if (msg.sender != admin.proposal)
|
|
904
1028
|
revert Error.SenderIsNotTheProposedAdmin();
|
|
@@ -933,42 +1057,21 @@ contract Core is Storage {
|
|
|
933
1057
|
* - Can be called by anyone when conditions are met
|
|
934
1058
|
*/
|
|
935
1059
|
function recalculateReward() public {
|
|
936
|
-
if (
|
|
1060
|
+
if (
|
|
1061
|
+
evvmMetadata.totalSupply > evvmMetadata.eraTokens &&
|
|
1062
|
+
evvmMetadata.totalSupply != type(uint256).max
|
|
1063
|
+
) {
|
|
937
1064
|
evvmMetadata.eraTokens += ((evvmMetadata.totalSupply -
|
|
938
1065
|
evvmMetadata.eraTokens) / 2);
|
|
939
1066
|
balances[msg.sender][evvmMetadata.principalTokenAddress] +=
|
|
940
1067
|
evvmMetadata.reward *
|
|
941
|
-
|
|
1068
|
+
_getRandom(1, 5083);
|
|
942
1069
|
evvmMetadata.reward = evvmMetadata.reward / 2;
|
|
943
1070
|
} else {
|
|
944
1071
|
revert();
|
|
945
1072
|
}
|
|
946
1073
|
}
|
|
947
1074
|
|
|
948
|
-
/**
|
|
949
|
-
* @notice Generates a pseudo-random number within a specified range
|
|
950
|
-
* @dev Uses block timestamp and prevrandao for randomness (suitable for non-critical randomness)
|
|
951
|
-
*
|
|
952
|
-
* Randomness Source:
|
|
953
|
-
* - Combines block.timestamp and block.prevrandao
|
|
954
|
-
* - Suitable for reward bonuses and non-security-critical randomness
|
|
955
|
-
* - Not suitable for high-stakes randomness requiring true unpredictability
|
|
956
|
-
*
|
|
957
|
-
* @param min Minimum value (inclusive)
|
|
958
|
-
* @param max Maximum value (inclusive)
|
|
959
|
-
* @return Random number between min and max (inclusive)
|
|
960
|
-
*/
|
|
961
|
-
function getRandom(
|
|
962
|
-
uint256 min,
|
|
963
|
-
uint256 max
|
|
964
|
-
) internal view returns (uint256) {
|
|
965
|
-
return
|
|
966
|
-
min +
|
|
967
|
-
(uint256(
|
|
968
|
-
keccak256(abi.encodePacked(block.timestamp, block.prevrandao))
|
|
969
|
-
) % (max - min + 1));
|
|
970
|
-
}
|
|
971
|
-
|
|
972
1075
|
//░▒▓█ Staking Integration Functions █████████████████████████████████████████████████▓▒░
|
|
973
1076
|
|
|
974
1077
|
/**
|
|
@@ -1045,19 +1148,6 @@ contract Core is Storage {
|
|
|
1045
1148
|
return evvmMetadata.EvvmID;
|
|
1046
1149
|
}
|
|
1047
1150
|
|
|
1048
|
-
/**
|
|
1049
|
-
* @notice Gets the acceptance deadline for pending token whitelist proposals
|
|
1050
|
-
* @dev Returns timestamp when prepared tokens can be added to whitelist
|
|
1051
|
-
* @return Timestamp when pending token can be whitelisted (0 if no pending proposal)
|
|
1052
|
-
*/
|
|
1053
|
-
function getWhitelistTokenToBeAddedDateToSet()
|
|
1054
|
-
external
|
|
1055
|
-
view
|
|
1056
|
-
returns (uint256)
|
|
1057
|
-
{
|
|
1058
|
-
return whitelistTokenToBeAdded_dateToSet;
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
1151
|
/**
|
|
1062
1152
|
* @notice Gets the current NameService contract address
|
|
1063
1153
|
* @dev Returns the address used for identity resolution in payments
|
|
@@ -1076,18 +1166,6 @@ contract Core is Storage {
|
|
|
1076
1166
|
return stakingContractAddress;
|
|
1077
1167
|
}
|
|
1078
1168
|
|
|
1079
|
-
/**
|
|
1080
|
-
* @notice Gets the next Fisher Bridge deposit nonce for a user
|
|
1081
|
-
* @dev Returns the expected nonce for the next cross-chain deposit
|
|
1082
|
-
* @param user Address to check deposit nonce for
|
|
1083
|
-
* @return Next Fisher Bridge deposit nonce
|
|
1084
|
-
*/
|
|
1085
|
-
function getNextFisherDepositNonce(
|
|
1086
|
-
address user
|
|
1087
|
-
) external view returns (uint256) {
|
|
1088
|
-
return nextFisherDepositNonce[user];
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
1169
|
/**
|
|
1092
1170
|
* @notice Gets the balance of a specific token for a user
|
|
1093
1171
|
* @dev Returns the current balance stored in the EVVM system
|
|
@@ -1112,15 +1190,6 @@ contract Core is Storage {
|
|
|
1112
1190
|
return stakerList[user] == FLAG_IS_STAKER;
|
|
1113
1191
|
}
|
|
1114
1192
|
|
|
1115
|
-
/**
|
|
1116
|
-
* @notice Gets the current era token threshold for reward transitions
|
|
1117
|
-
* @dev Returns the token supply threshold that triggers the next reward halving
|
|
1118
|
-
* @return Current era tokens threshold
|
|
1119
|
-
*/
|
|
1120
|
-
function getEraPrincipalToken() public view returns (uint256) {
|
|
1121
|
-
return evvmMetadata.eraTokens;
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
1193
|
/**
|
|
1125
1194
|
* @notice Gets the current Principal Token reward amount per transaction
|
|
1126
1195
|
* @dev Returns the base reward distributed to stakers for transaction processing
|
|
@@ -1130,6 +1199,25 @@ contract Core is Storage {
|
|
|
1130
1199
|
return evvmMetadata.reward;
|
|
1131
1200
|
}
|
|
1132
1201
|
|
|
1202
|
+
/**
|
|
1203
|
+
* @notice Gets comprehensive details of the reward change proposal
|
|
1204
|
+
* @dev Returns current reward, proposed reward and time-lock info
|
|
1205
|
+
*
|
|
1206
|
+
* @return Proposal struct with current reward, proposed reward,
|
|
1207
|
+
* and time to accept the proposal
|
|
1208
|
+
*/
|
|
1209
|
+
function getFullDetailReward()
|
|
1210
|
+
public
|
|
1211
|
+
view
|
|
1212
|
+
returns (ProposalStructs.UintTypeProposal memory)
|
|
1213
|
+
{
|
|
1214
|
+
return ProposalStructs.UintTypeProposal({
|
|
1215
|
+
current: evvmMetadata.reward,
|
|
1216
|
+
proposal: proposalChangeReward,
|
|
1217
|
+
timeToAccept: timeToAcceptChangeReward
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1133
1221
|
/**
|
|
1134
1222
|
* @notice Gets the total supply of the Principal Token
|
|
1135
1223
|
* @dev Returns the current total supply used for era transition calculations
|
|
@@ -1139,6 +1227,14 @@ contract Core is Storage {
|
|
|
1139
1227
|
return evvmMetadata.totalSupply;
|
|
1140
1228
|
}
|
|
1141
1229
|
|
|
1230
|
+
/**
|
|
1231
|
+
* @notice Gets the current supply of the Principal Token in circulation
|
|
1232
|
+
* @dev Returns the current circulating supply used for reward recalculations
|
|
1233
|
+
*/
|
|
1234
|
+
function getCurrentSupply() public view returns (uint256) {
|
|
1235
|
+
return currentSupply;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1142
1238
|
/**
|
|
1143
1239
|
* @notice Gets the current active implementation contract address
|
|
1144
1240
|
* @dev Returns the implementation used by the proxy for delegatecalls
|
|
@@ -1149,21 +1245,23 @@ contract Core is Storage {
|
|
|
1149
1245
|
}
|
|
1150
1246
|
|
|
1151
1247
|
/**
|
|
1152
|
-
* @notice Gets the
|
|
1153
|
-
* @dev Returns
|
|
1154
|
-
*
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
return proposalImplementation;
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
/**
|
|
1161
|
-
* @notice Gets the acceptance deadline for the pending implementation upgrade
|
|
1162
|
-
* @dev Returns timestamp when the proposed implementation can be accepted
|
|
1163
|
-
* @return Timestamp when implementation upgrade can be executed (0 if no pending proposal)
|
|
1248
|
+
* @notice Gets comprehensive details of the implementation upgrade proposal
|
|
1249
|
+
* @dev Returns current, proposed implementation addresses and time-lock info
|
|
1250
|
+
*
|
|
1251
|
+
* @return Proposal struct with current implementation, proposed implementation,
|
|
1252
|
+
* and time to accept the proposal
|
|
1164
1253
|
*/
|
|
1165
|
-
function
|
|
1166
|
-
|
|
1254
|
+
function getFullDetailImplementation()
|
|
1255
|
+
public
|
|
1256
|
+
view
|
|
1257
|
+
returns (ProposalStructs.AddressTypeProposal memory)
|
|
1258
|
+
{
|
|
1259
|
+
return
|
|
1260
|
+
ProposalStructs.AddressTypeProposal({
|
|
1261
|
+
current: currentImplementation,
|
|
1262
|
+
proposal: proposalImplementation,
|
|
1263
|
+
timeToAccept: timeToAcceptImplementation
|
|
1264
|
+
});
|
|
1167
1265
|
}
|
|
1168
1266
|
|
|
1169
1267
|
/**
|
|
@@ -1175,31 +1273,12 @@ contract Core is Storage {
|
|
|
1175
1273
|
return admin.current;
|
|
1176
1274
|
}
|
|
1177
1275
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
return admin.proposal;
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
/**
|
|
1188
|
-
* @notice Gets the acceptance deadline for the pending admin change
|
|
1189
|
-
* @dev Returns timestamp when the proposed admin can accept the role
|
|
1190
|
-
* @return Timestamp when admin change can be executed (0 if no pending proposal)
|
|
1191
|
-
*/
|
|
1192
|
-
function getTimeToAcceptAdmin() public view returns (uint256) {
|
|
1193
|
-
return admin.timeToAccept;
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
/**
|
|
1197
|
-
* @notice Gets the address of the token pending whitelist approval
|
|
1198
|
-
* @dev Returns the token address that can be whitelisted after time delay
|
|
1199
|
-
* @return Address of the token prepared for whitelisting (zero if none)
|
|
1200
|
-
*/
|
|
1201
|
-
function getWhitelistTokenToBeAdded() public view returns (address) {
|
|
1202
|
-
return whitelistTokenToBeAdded_address;
|
|
1276
|
+
function getFullDetailAdmin()
|
|
1277
|
+
public
|
|
1278
|
+
view
|
|
1279
|
+
returns (ProposalStructs.AddressTypeProposal memory)
|
|
1280
|
+
{
|
|
1281
|
+
return admin;
|
|
1203
1282
|
}
|
|
1204
1283
|
|
|
1205
1284
|
/**
|
|
@@ -1288,7 +1367,7 @@ contract Core is Storage {
|
|
|
1288
1367
|
* @return Proposal struct with current validator address,
|
|
1289
1368
|
* proposed address, and time to accept
|
|
1290
1369
|
*/
|
|
1291
|
-
function
|
|
1370
|
+
function getFullDetailUserValidator()
|
|
1292
1371
|
public
|
|
1293
1372
|
view
|
|
1294
1373
|
returns (ProposalStructs.AddressTypeProposal memory)
|
|
@@ -1296,8 +1375,113 @@ contract Core is Storage {
|
|
|
1296
1375
|
return userValidatorAddress;
|
|
1297
1376
|
}
|
|
1298
1377
|
|
|
1378
|
+
/**
|
|
1379
|
+
* @notice Gets the current token list status (none, denylist, allowlist)
|
|
1380
|
+
* @dev Returns byte code indicating current token restriction mode
|
|
1381
|
+
* - 0x00: No restrictions
|
|
1382
|
+
* - 0x01: Denylist active
|
|
1383
|
+
* - 0x02: Allowlist active
|
|
1384
|
+
*/
|
|
1385
|
+
function getCurrentListStatus() public view returns (bytes1) {
|
|
1386
|
+
return listStatus.current;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/**
|
|
1390
|
+
* @notice Gets comprehensive token list status details
|
|
1391
|
+
* @dev Returns current list status along with pending proposal info
|
|
1392
|
+
*/
|
|
1393
|
+
function getFullDetailListStatus()
|
|
1394
|
+
public
|
|
1395
|
+
view
|
|
1396
|
+
returns (ProposalStructs.Bytes1TypeProposal memory)
|
|
1397
|
+
{
|
|
1398
|
+
return listStatus;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
/**
|
|
1402
|
+
* @notice Checks if a token is on the allowList or denyList based on current list status
|
|
1403
|
+
* @dev Returns boolean indicating if token is allowed for execution
|
|
1404
|
+
* - true if allowed
|
|
1405
|
+
* - false if denied
|
|
1406
|
+
*/
|
|
1407
|
+
function getAllowListStatus(address token) public view returns (bool) {
|
|
1408
|
+
return allowList[token];
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
/**
|
|
1412
|
+
* @notice Checks if a token is on the denylist or allowlist based on current list status
|
|
1413
|
+
* @dev Returns boolean indicating if token is restricted for execution
|
|
1414
|
+
* - true if denied
|
|
1415
|
+
* - false if allowed
|
|
1416
|
+
*/
|
|
1417
|
+
function getDenyListStatus(address token) public view returns (bool) {
|
|
1418
|
+
return denyList[token];
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
/**
|
|
1422
|
+
* @notice Gets the current status of the reward flow distribution flag
|
|
1423
|
+
* @dev Returns boolean indicating if reward distribution is active
|
|
1424
|
+
* - true if rewards are distributed to stakers
|
|
1425
|
+
* - false if rewards are disabled
|
|
1426
|
+
*/
|
|
1427
|
+
function getRewardFlowDistributionFlag() public view returns (bool) {
|
|
1428
|
+
return rewardFlowDistribution.flag;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
/**
|
|
1432
|
+
* @notice Gets full details of the reward flow distribution proposal
|
|
1433
|
+
* @dev Returns current flag, proposed flag, and time-lock info
|
|
1434
|
+
*
|
|
1435
|
+
* @return Proposal struct with current flag, proposed flag, and time to accept
|
|
1436
|
+
*/
|
|
1437
|
+
function getFullDetailRewardFlowDistribution()
|
|
1438
|
+
public
|
|
1439
|
+
view
|
|
1440
|
+
returns (ProposalStructs.BoolTypeProposal memory)
|
|
1441
|
+
{
|
|
1442
|
+
return rewardFlowDistribution;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
/**
|
|
1446
|
+
* @notice Gets the time remaining to delete the maximum supply
|
|
1447
|
+
* @dev Returns the timestamp when the max supply can be deleted
|
|
1448
|
+
*
|
|
1449
|
+
* @return Timestamp for max supply deletion
|
|
1450
|
+
*/
|
|
1451
|
+
function getTimeToDeleteMaxSupply() public view returns (uint256) {
|
|
1452
|
+
return timeToDeleteMaxSupply;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1299
1455
|
//░▒▓█ Internal Functions █████████████████████████████████████████████████████▓▒░
|
|
1300
1456
|
|
|
1457
|
+
/**
|
|
1458
|
+
* @notice Generates a pseudo-random number within a specified range
|
|
1459
|
+
* @dev Uses block timestamp and prevrandao for randomness (suitable for non-critical randomness)
|
|
1460
|
+
*
|
|
1461
|
+
* @param min Minimum value (inclusive)
|
|
1462
|
+
* @param max Maximum value (inclusive)
|
|
1463
|
+
* @return Random number between min and max (inclusive)
|
|
1464
|
+
*/
|
|
1465
|
+
function _getRandom(
|
|
1466
|
+
uint256 min,
|
|
1467
|
+
uint256 max
|
|
1468
|
+
) internal view returns (uint256) {
|
|
1469
|
+
uint256 randomHash = uint256(
|
|
1470
|
+
keccak256(
|
|
1471
|
+
abi.encodePacked(
|
|
1472
|
+
blockhash(block.number - 1),
|
|
1473
|
+
block.timestamp,
|
|
1474
|
+
block.prevrandao,
|
|
1475
|
+
msg.sender,
|
|
1476
|
+
tx.origin,
|
|
1477
|
+
gasleft()
|
|
1478
|
+
)
|
|
1479
|
+
)
|
|
1480
|
+
);
|
|
1481
|
+
|
|
1482
|
+
return min + (randomHash % (max - min + 1));
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1301
1485
|
//██ Balance Management █████████████████████████████████████████████
|
|
1302
1486
|
|
|
1303
1487
|
/**
|
|
@@ -1325,6 +1509,8 @@ contract Core is Storage {
|
|
|
1325
1509
|
address token,
|
|
1326
1510
|
uint256 value
|
|
1327
1511
|
) internal {
|
|
1512
|
+
if (listStatus.current != 0x00) _verifyTokenInteractionAllowance(token);
|
|
1513
|
+
|
|
1328
1514
|
uint256 fromBalance = balances[from][token];
|
|
1329
1515
|
if (fromBalance < value) revert Error.InsufficientBalance();
|
|
1330
1516
|
|
|
@@ -1350,20 +1536,28 @@ contract Core is Storage {
|
|
|
1350
1536
|
*
|
|
1351
1537
|
* @param user Address of the staker to receive principal token rewards
|
|
1352
1538
|
* @param amount Number of transactions or reward multiplier
|
|
1353
|
-
* @return success True if reward distribution completed successfully
|
|
1354
1539
|
*/
|
|
1355
|
-
function _giveReward(address user, uint256 amount) internal
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
evvmMetadata.
|
|
1359
|
-
|
|
1540
|
+
function _giveReward(address user, uint256 amount) internal {
|
|
1541
|
+
if (
|
|
1542
|
+
!rewardFlowDistribution.flag ||
|
|
1543
|
+
currentSupply >= evvmMetadata.totalSupply
|
|
1544
|
+
) return;
|
|
1360
1545
|
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1546
|
+
uint256 principalReward = evvmMetadata.reward * amount;
|
|
1547
|
+
balances[user][evvmMetadata.principalTokenAddress] += principalReward;
|
|
1548
|
+
currentSupply += principalReward;
|
|
1549
|
+
}
|
|
1364
1550
|
|
|
1365
|
-
|
|
1366
|
-
|
|
1551
|
+
/**
|
|
1552
|
+
* @notice Internal function to check from the token allowlist/denylist
|
|
1553
|
+
* based on current list status and revert if the token is not allowed for execution
|
|
1554
|
+
* @dev Used by functions that execute transactions to enforce token restrictions
|
|
1555
|
+
*/
|
|
1556
|
+
function _verifyTokenInteractionAllowance(address token) internal view {
|
|
1557
|
+
if (
|
|
1558
|
+
(listStatus.current == 0x01 && !allowList[token]) ||
|
|
1559
|
+
(listStatus.current == 0x02 && denyList[token])
|
|
1560
|
+
) revert Error.TokenIsDeniedForExecution();
|
|
1367
1561
|
}
|
|
1368
1562
|
|
|
1369
1563
|
//██ User Validation █████████████████████████████████████████████
|
|
@@ -1385,7 +1579,7 @@ contract Core is Storage {
|
|
|
1385
1579
|
* @param user Address to check execution permission for
|
|
1386
1580
|
* @return True if user can execute, false if blocked
|
|
1387
1581
|
*/
|
|
1388
|
-
function
|
|
1582
|
+
function _canExecuteUserTransaction(
|
|
1389
1583
|
address user
|
|
1390
1584
|
) internal view returns (bool) {
|
|
1391
1585
|
if (userValidatorAddress.current == address(0)) return true;
|