@evvm/testnet-contracts 3.0.1 → 3.0.3
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 +2 -0
- package/contracts/core/Core.sol +323 -127
- package/contracts/core/lib/CoreStorage.sol +60 -24
- package/contracts/p2pSwap/P2PSwap.sol +183 -141
- package/library/EvvmService.sol +2 -2
- package/library/errors/CoreError.sol +25 -11
- package/library/structs/P2PSwapStructs.sol +1 -57
- package/library/utils/governance/ProposalStructs.sol +6 -0
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -170,9 +170,11 @@ Quick Start (CLI): https://www.evvm.info/docs/QuickStart
|
|
|
170
170
|
- **RPC timeouts**: CLI automatically tries fallback RPCs; set `RPC_URL` in `.env` to a reliable endpoint.
|
|
171
171
|
- **Wallet not found**: import with `cast wallet import <name> --interactive`.
|
|
172
172
|
- **Bun missing**: install Bun (`curl -fsSL https://bun.sh/install | bash`).
|
|
173
|
+
- **Native binary fails (exit 126)**: if you see "cannot execute binary file" the wrapper will now try running the CLI via `bun run cli/index.ts` automatically when Bun is available. This works as a fallback until correct platform-specific binaries are built.
|
|
173
174
|
- **Tests**: run `./evvm developer --runTest` (Linux/Mac) or `evvm.bat developer --runTest` (Windows), or `forge test`.
|
|
174
175
|
- **Script not executable (Linux/Mac)**: run `chmod +x ./evvm` and ensure `.executables/` binaries have execute permissions.
|
|
175
176
|
- **Wrong architecture detected**: The wrapper scripts auto-detect OS/architecture. If issues occur, manually run the correct binary from `.executables/`.
|
|
177
|
+
- **Binaries built on the wrong host**: macOS and Windows executables must be compiled on their respective platforms. Building on Linux will produce a Linux ELF file regardless of the filename, which leads to "cannot execute binary file" errors on macOS. Use `npm run build-macos` on a Mac and `npm run build-windows` on Windows, or rely on the Bun fallback described below.
|
|
176
178
|
|
|
177
179
|
Files & structure (short)
|
|
178
180
|
|
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) {
|
|
@@ -762,7 +779,7 @@ contract Core is Storage {
|
|
|
762
779
|
*/
|
|
763
780
|
function acceptUserValidatorProposal() external onlyAdmin {
|
|
764
781
|
if (block.timestamp < userValidatorAddress.timeToAccept)
|
|
765
|
-
revert Error.
|
|
782
|
+
revert Error.ProposalNotReadyToAccept();
|
|
766
783
|
|
|
767
784
|
userValidatorAddress.current = userValidatorAddress.proposal;
|
|
768
785
|
userValidatorAddress.proposal = address(0);
|
|
@@ -804,6 +821,8 @@ contract Core is Storage {
|
|
|
804
821
|
address token,
|
|
805
822
|
uint256 amount
|
|
806
823
|
) external {
|
|
824
|
+
if (listStatus.current != 0x00) _verifyTokenInteractionAllowance(token);
|
|
825
|
+
|
|
807
826
|
if (msg.sender != treasuryAddress) revert Error.SenderIsNotTreasury();
|
|
808
827
|
|
|
809
828
|
balances[user][token] += amount;
|
|
@@ -828,6 +847,113 @@ contract Core is Storage {
|
|
|
828
847
|
|
|
829
848
|
//░▒▓█ Administrative Functions ████████████████████████████████████████████████████████▓▒░
|
|
830
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
|
+
|
|
831
957
|
//██ Proxy Management █████████████████████████████████████████████
|
|
832
958
|
|
|
833
959
|
/**
|
|
@@ -855,7 +981,7 @@ contract Core is Storage {
|
|
|
855
981
|
*/
|
|
856
982
|
function acceptImplementation() external onlyAdmin {
|
|
857
983
|
if (block.timestamp < timeToAcceptImplementation)
|
|
858
|
-
revert Error.
|
|
984
|
+
revert Error.ProposalNotReadyToAccept();
|
|
859
985
|
|
|
860
986
|
currentImplementation = proposalImplementation;
|
|
861
987
|
proposalImplementation = address(0);
|
|
@@ -896,7 +1022,7 @@ contract Core is Storage {
|
|
|
896
1022
|
*/
|
|
897
1023
|
function acceptAdmin() external {
|
|
898
1024
|
if (block.timestamp < admin.timeToAccept)
|
|
899
|
-
revert Error.
|
|
1025
|
+
revert Error.ProposalNotReadyToAccept();
|
|
900
1026
|
|
|
901
1027
|
if (msg.sender != admin.proposal)
|
|
902
1028
|
revert Error.SenderIsNotTheProposedAdmin();
|
|
@@ -931,42 +1057,21 @@ contract Core is Storage {
|
|
|
931
1057
|
* - Can be called by anyone when conditions are met
|
|
932
1058
|
*/
|
|
933
1059
|
function recalculateReward() public {
|
|
934
|
-
if (
|
|
1060
|
+
if (
|
|
1061
|
+
evvmMetadata.totalSupply > evvmMetadata.eraTokens &&
|
|
1062
|
+
evvmMetadata.totalSupply != type(uint256).max
|
|
1063
|
+
) {
|
|
935
1064
|
evvmMetadata.eraTokens += ((evvmMetadata.totalSupply -
|
|
936
1065
|
evvmMetadata.eraTokens) / 2);
|
|
937
1066
|
balances[msg.sender][evvmMetadata.principalTokenAddress] +=
|
|
938
1067
|
evvmMetadata.reward *
|
|
939
|
-
|
|
1068
|
+
_getRandom(1, 5083);
|
|
940
1069
|
evvmMetadata.reward = evvmMetadata.reward / 2;
|
|
941
1070
|
} else {
|
|
942
1071
|
revert();
|
|
943
1072
|
}
|
|
944
1073
|
}
|
|
945
1074
|
|
|
946
|
-
/**
|
|
947
|
-
* @notice Generates a pseudo-random number within a specified range
|
|
948
|
-
* @dev Uses block timestamp and prevrandao for randomness (suitable for non-critical randomness)
|
|
949
|
-
*
|
|
950
|
-
* Randomness Source:
|
|
951
|
-
* - Combines block.timestamp and block.prevrandao
|
|
952
|
-
* - Suitable for reward bonuses and non-security-critical randomness
|
|
953
|
-
* - Not suitable for high-stakes randomness requiring true unpredictability
|
|
954
|
-
*
|
|
955
|
-
* @param min Minimum value (inclusive)
|
|
956
|
-
* @param max Maximum value (inclusive)
|
|
957
|
-
* @return Random number between min and max (inclusive)
|
|
958
|
-
*/
|
|
959
|
-
function getRandom(
|
|
960
|
-
uint256 min,
|
|
961
|
-
uint256 max
|
|
962
|
-
) internal view returns (uint256) {
|
|
963
|
-
return
|
|
964
|
-
min +
|
|
965
|
-
(uint256(
|
|
966
|
-
keccak256(abi.encodePacked(block.timestamp, block.prevrandao))
|
|
967
|
-
) % (max - min + 1));
|
|
968
|
-
}
|
|
969
|
-
|
|
970
1075
|
//░▒▓█ Staking Integration Functions █████████████████████████████████████████████████▓▒░
|
|
971
1076
|
|
|
972
1077
|
/**
|
|
@@ -1043,19 +1148,6 @@ contract Core is Storage {
|
|
|
1043
1148
|
return evvmMetadata.EvvmID;
|
|
1044
1149
|
}
|
|
1045
1150
|
|
|
1046
|
-
/**
|
|
1047
|
-
* @notice Gets the acceptance deadline for pending token whitelist proposals
|
|
1048
|
-
* @dev Returns timestamp when prepared tokens can be added to whitelist
|
|
1049
|
-
* @return Timestamp when pending token can be whitelisted (0 if no pending proposal)
|
|
1050
|
-
*/
|
|
1051
|
-
function getWhitelistTokenToBeAddedDateToSet()
|
|
1052
|
-
external
|
|
1053
|
-
view
|
|
1054
|
-
returns (uint256)
|
|
1055
|
-
{
|
|
1056
|
-
return whitelistTokenToBeAdded_dateToSet;
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
1151
|
/**
|
|
1060
1152
|
* @notice Gets the current NameService contract address
|
|
1061
1153
|
* @dev Returns the address used for identity resolution in payments
|
|
@@ -1074,18 +1166,6 @@ contract Core is Storage {
|
|
|
1074
1166
|
return stakingContractAddress;
|
|
1075
1167
|
}
|
|
1076
1168
|
|
|
1077
|
-
/**
|
|
1078
|
-
* @notice Gets the next Fisher Bridge deposit nonce for a user
|
|
1079
|
-
* @dev Returns the expected nonce for the next cross-chain deposit
|
|
1080
|
-
* @param user Address to check deposit nonce for
|
|
1081
|
-
* @return Next Fisher Bridge deposit nonce
|
|
1082
|
-
*/
|
|
1083
|
-
function getNextFisherDepositNonce(
|
|
1084
|
-
address user
|
|
1085
|
-
) external view returns (uint256) {
|
|
1086
|
-
return nextFisherDepositNonce[user];
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
1169
|
/**
|
|
1090
1170
|
* @notice Gets the balance of a specific token for a user
|
|
1091
1171
|
* @dev Returns the current balance stored in the EVVM system
|
|
@@ -1110,15 +1190,6 @@ contract Core is Storage {
|
|
|
1110
1190
|
return stakerList[user] == FLAG_IS_STAKER;
|
|
1111
1191
|
}
|
|
1112
1192
|
|
|
1113
|
-
/**
|
|
1114
|
-
* @notice Gets the current era token threshold for reward transitions
|
|
1115
|
-
* @dev Returns the token supply threshold that triggers the next reward halving
|
|
1116
|
-
* @return Current era tokens threshold
|
|
1117
|
-
*/
|
|
1118
|
-
function getEraPrincipalToken() public view returns (uint256) {
|
|
1119
|
-
return evvmMetadata.eraTokens;
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
1193
|
/**
|
|
1123
1194
|
* @notice Gets the current Principal Token reward amount per transaction
|
|
1124
1195
|
* @dev Returns the base reward distributed to stakers for transaction processing
|
|
@@ -1128,6 +1199,25 @@ contract Core is Storage {
|
|
|
1128
1199
|
return evvmMetadata.reward;
|
|
1129
1200
|
}
|
|
1130
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
|
+
|
|
1131
1221
|
/**
|
|
1132
1222
|
* @notice Gets the total supply of the Principal Token
|
|
1133
1223
|
* @dev Returns the current total supply used for era transition calculations
|
|
@@ -1137,6 +1227,14 @@ contract Core is Storage {
|
|
|
1137
1227
|
return evvmMetadata.totalSupply;
|
|
1138
1228
|
}
|
|
1139
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
|
+
|
|
1140
1238
|
/**
|
|
1141
1239
|
* @notice Gets the current active implementation contract address
|
|
1142
1240
|
* @dev Returns the implementation used by the proxy for delegatecalls
|
|
@@ -1147,21 +1245,23 @@ contract Core is Storage {
|
|
|
1147
1245
|
}
|
|
1148
1246
|
|
|
1149
1247
|
/**
|
|
1150
|
-
* @notice Gets the
|
|
1151
|
-
* @dev Returns
|
|
1152
|
-
*
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
return proposalImplementation;
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
/**
|
|
1159
|
-
* @notice Gets the acceptance deadline for the pending implementation upgrade
|
|
1160
|
-
* @dev Returns timestamp when the proposed implementation can be accepted
|
|
1161
|
-
* @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
|
|
1162
1253
|
*/
|
|
1163
|
-
function
|
|
1164
|
-
|
|
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
|
+
});
|
|
1165
1265
|
}
|
|
1166
1266
|
|
|
1167
1267
|
/**
|
|
@@ -1173,31 +1273,12 @@ contract Core is Storage {
|
|
|
1173
1273
|
return admin.current;
|
|
1174
1274
|
}
|
|
1175
1275
|
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
return admin.proposal;
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
/**
|
|
1186
|
-
* @notice Gets the acceptance deadline for the pending admin change
|
|
1187
|
-
* @dev Returns timestamp when the proposed admin can accept the role
|
|
1188
|
-
* @return Timestamp when admin change can be executed (0 if no pending proposal)
|
|
1189
|
-
*/
|
|
1190
|
-
function getTimeToAcceptAdmin() public view returns (uint256) {
|
|
1191
|
-
return admin.timeToAccept;
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
/**
|
|
1195
|
-
* @notice Gets the address of the token pending whitelist approval
|
|
1196
|
-
* @dev Returns the token address that can be whitelisted after time delay
|
|
1197
|
-
* @return Address of the token prepared for whitelisting (zero if none)
|
|
1198
|
-
*/
|
|
1199
|
-
function getWhitelistTokenToBeAdded() public view returns (address) {
|
|
1200
|
-
return whitelistTokenToBeAdded_address;
|
|
1276
|
+
function getFullDetailAdmin()
|
|
1277
|
+
public
|
|
1278
|
+
view
|
|
1279
|
+
returns (ProposalStructs.AddressTypeProposal memory)
|
|
1280
|
+
{
|
|
1281
|
+
return admin;
|
|
1201
1282
|
}
|
|
1202
1283
|
|
|
1203
1284
|
/**
|
|
@@ -1286,7 +1367,7 @@ contract Core is Storage {
|
|
|
1286
1367
|
* @return Proposal struct with current validator address,
|
|
1287
1368
|
* proposed address, and time to accept
|
|
1288
1369
|
*/
|
|
1289
|
-
function
|
|
1370
|
+
function getFullDetailUserValidator()
|
|
1290
1371
|
public
|
|
1291
1372
|
view
|
|
1292
1373
|
returns (ProposalStructs.AddressTypeProposal memory)
|
|
@@ -1294,8 +1375,113 @@ contract Core is Storage {
|
|
|
1294
1375
|
return userValidatorAddress;
|
|
1295
1376
|
}
|
|
1296
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
|
+
|
|
1297
1455
|
//░▒▓█ Internal Functions █████████████████████████████████████████████████████▓▒░
|
|
1298
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
|
+
|
|
1299
1485
|
//██ Balance Management █████████████████████████████████████████████
|
|
1300
1486
|
|
|
1301
1487
|
/**
|
|
@@ -1323,6 +1509,8 @@ contract Core is Storage {
|
|
|
1323
1509
|
address token,
|
|
1324
1510
|
uint256 value
|
|
1325
1511
|
) internal {
|
|
1512
|
+
if (listStatus.current != 0x00) _verifyTokenInteractionAllowance(token);
|
|
1513
|
+
|
|
1326
1514
|
uint256 fromBalance = balances[from][token];
|
|
1327
1515
|
if (fromBalance < value) revert Error.InsufficientBalance();
|
|
1328
1516
|
|
|
@@ -1348,20 +1536,28 @@ contract Core is Storage {
|
|
|
1348
1536
|
*
|
|
1349
1537
|
* @param user Address of the staker to receive principal token rewards
|
|
1350
1538
|
* @param amount Number of transactions or reward multiplier
|
|
1351
|
-
* @return success True if reward distribution completed successfully
|
|
1352
1539
|
*/
|
|
1353
|
-
function _giveReward(address user, uint256 amount) internal
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
evvmMetadata.
|
|
1357
|
-
|
|
1540
|
+
function _giveReward(address user, uint256 amount) internal {
|
|
1541
|
+
if (
|
|
1542
|
+
!rewardFlowDistribution.flag ||
|
|
1543
|
+
currentSupply >= evvmMetadata.totalSupply
|
|
1544
|
+
) return;
|
|
1358
1545
|
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1546
|
+
uint256 principalReward = evvmMetadata.reward * amount;
|
|
1547
|
+
balances[user][evvmMetadata.principalTokenAddress] += principalReward;
|
|
1548
|
+
currentSupply += principalReward;
|
|
1549
|
+
}
|
|
1362
1550
|
|
|
1363
|
-
|
|
1364
|
-
|
|
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();
|
|
1365
1561
|
}
|
|
1366
1562
|
|
|
1367
1563
|
//██ User Validation █████████████████████████████████████████████
|
|
@@ -1383,7 +1579,7 @@ contract Core is Storage {
|
|
|
1383
1579
|
* @param user Address to check execution permission for
|
|
1384
1580
|
* @return True if user can execute, false if blocked
|
|
1385
1581
|
*/
|
|
1386
|
-
function
|
|
1582
|
+
function _canExecuteUserTransaction(
|
|
1387
1583
|
address user
|
|
1388
1584
|
) internal view returns (bool) {
|
|
1389
1585
|
if (userValidatorAddress.current == address(0)) return true;
|