@evvm/testnet-contracts 1.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 (34) hide show
  1. package/LICENSE +166 -0
  2. package/README.md +216 -0
  3. package/package.json +51 -0
  4. package/src/contracts/evvm/Evvm.sol +1327 -0
  5. package/src/contracts/evvm/EvvmLegacy.sol +1553 -0
  6. package/src/contracts/evvm/lib/ErrorsLib.sol +17 -0
  7. package/src/contracts/evvm/lib/EvvmStorage.sol +60 -0
  8. package/src/contracts/evvm/lib/EvvmStructs.sol +64 -0
  9. package/src/contracts/evvm/lib/SignatureUtils.sol +124 -0
  10. package/src/contracts/nameService/NameService.sol +1751 -0
  11. package/src/contracts/nameService/lib/ErrorsLib.sol +27 -0
  12. package/src/contracts/nameService/lib/SignatureUtils.sol +239 -0
  13. package/src/contracts/staking/Estimator.sol +358 -0
  14. package/src/contracts/staking/Staking.sol +1148 -0
  15. package/src/contracts/staking/lib/ErrorsLib.sol +19 -0
  16. package/src/contracts/staking/lib/SignatureUtils.sol +68 -0
  17. package/src/contracts/treasury/Treasury.sol +104 -0
  18. package/src/contracts/treasury/lib/ErrorsLib.sol +11 -0
  19. package/src/contracts/treasuryTwoChains/TreasuryExternalChainStation.sol +551 -0
  20. package/src/contracts/treasuryTwoChains/TreasuryHostChainStation.sol +512 -0
  21. package/src/contracts/treasuryTwoChains/lib/ErrorsLib.sol +15 -0
  22. package/src/contracts/treasuryTwoChains/lib/ExternalChainStationStructs.sol +41 -0
  23. package/src/contracts/treasuryTwoChains/lib/HostChainStationStructs.sol +52 -0
  24. package/src/contracts/treasuryTwoChains/lib/SignatureUtils.sol +47 -0
  25. package/src/interfaces/IEstimator.sol +102 -0
  26. package/src/interfaces/IEvvm.sol +195 -0
  27. package/src/interfaces/INameService.sol +283 -0
  28. package/src/interfaces/IStaking.sol +202 -0
  29. package/src/interfaces/ITreasury.sol +17 -0
  30. package/src/interfaces/ITreasuryExternalChainStation.sol +262 -0
  31. package/src/interfaces/ITreasuryHostChainStation.sol +251 -0
  32. package/src/lib/AdvancedStrings.sol +77 -0
  33. package/src/lib/Erc191TestBuilder.sol +402 -0
  34. package/src/lib/SignatureRecover.sol +56 -0
@@ -0,0 +1,27 @@
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
+ library ErrorsLib {
7
+ error SenderIsNotAdmin();
8
+ error UserIsNotOwnerOfIdentity();
9
+ error NonceAlreadyUsed();
10
+ error InvalidSignatureOnNameService();
11
+ /**
12
+ * @dev Error thrown when a username is not valid.
13
+ * 0x01 - Username is too short.
14
+ * 0x02 - Username does not start with a letter.
15
+ * 0x03 - Username contains invalid characters.
16
+ */
17
+ error InvalidUsername(bytes1);
18
+ error UsernameAlreadyRegistered();
19
+ error PreRegistrationNotValid();
20
+ error MakeOfferVerificationFailed();
21
+ error UserIsNotOwnerOfOffer();
22
+ error AcceptOfferVerificationFailed();
23
+ error RenewUsernameVerificationFailed();
24
+ error EmptyCustomMetadata();
25
+ error InvalidKey();
26
+ error FlushUsernameVerificationFailed();
27
+ }
@@ -0,0 +1,239 @@
1
+ // SPDX-License-Identifier: EVVM-NONCOMMERCIAL-1.0
2
+ // Full license terms available at: https://www.evvm.info/docs/EVVMNoncommercialLicense
3
+
4
+ import {SignatureRecover} from "@evvm/testnet-contracts/lib/SignatureRecover.sol";
5
+ import {AdvancedStrings} from "@evvm/testnet-contracts/lib/AdvancedStrings.sol";
6
+ import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
7
+
8
+ pragma solidity ^0.8.0;
9
+
10
+ library SignatureUtils {
11
+ /**
12
+ * @dev using EIP-191 (https://eips.ethereum.org/EIPS/eip-191) can be used to sign and
13
+ * verify messages, the next functions are used to verify the messages signed
14
+ * by the users
15
+ */
16
+
17
+ function verifyMessageSignedForPreRegistrationUsername(
18
+ uint256 evvmID,
19
+ address signer,
20
+ bytes32 _hashUsername,
21
+ uint256 _nameServiceNonce,
22
+ bytes memory signature
23
+ ) internal pure returns (bool) {
24
+ return
25
+ SignatureRecover.signatureVerification(
26
+ Strings.toString(evvmID),
27
+ "preRegistrationUsername",
28
+ string.concat(
29
+ AdvancedStrings.bytes32ToString(_hashUsername),
30
+ ",",
31
+ Strings.toString(_nameServiceNonce)
32
+ ),
33
+ signature,
34
+ signer
35
+ );
36
+ }
37
+
38
+ function verifyMessageSignedForRegistrationUsername(
39
+ uint256 evvmID,
40
+ address signer,
41
+ string memory _username,
42
+ uint256 _clowNumber,
43
+ uint256 _nameServiceNonce,
44
+ bytes memory signature
45
+ ) internal pure returns (bool) {
46
+ return
47
+ SignatureRecover.signatureVerification(
48
+ Strings.toString(evvmID),
49
+ "registrationUsername",
50
+ string.concat(
51
+ _username,
52
+ ",",
53
+ Strings.toString(_clowNumber),
54
+ ",",
55
+ Strings.toString(_nameServiceNonce)
56
+ ),
57
+ signature,
58
+ signer
59
+ );
60
+ }
61
+
62
+ function verifyMessageSignedForMakeOffer(
63
+ uint256 evvmID,
64
+ address signer,
65
+ string memory _username,
66
+ uint256 _dateExpire,
67
+ uint256 _amount,
68
+ uint256 _nameServiceNonce,
69
+ bytes memory signature
70
+ ) internal pure returns (bool) {
71
+ return
72
+ SignatureRecover.signatureVerification(
73
+ Strings.toString(evvmID),
74
+ "makeOffer",
75
+ string.concat(
76
+ _username,
77
+ ",",
78
+ Strings.toString(_dateExpire),
79
+ ",",
80
+ Strings.toString(_amount),
81
+ ",",
82
+ Strings.toString(_nameServiceNonce)
83
+ ),
84
+ signature,
85
+ signer
86
+ );
87
+ }
88
+
89
+ function verifyMessageSignedForWithdrawOffer(
90
+ uint256 evvmID,
91
+ address signer,
92
+ string memory _username,
93
+ uint256 _offerId,
94
+ uint256 _nameServiceNonce,
95
+ bytes memory signature
96
+ ) internal pure returns (bool) {
97
+ return
98
+ SignatureRecover.signatureVerification(
99
+ Strings.toString(evvmID),
100
+ "withdrawOffer",
101
+ string.concat(
102
+ _username,
103
+ ",",
104
+ Strings.toString(_offerId),
105
+ ",",
106
+ Strings.toString(_nameServiceNonce)
107
+ ),
108
+ signature,
109
+ signer
110
+ );
111
+ }
112
+
113
+ function verifyMessageSignedForAcceptOffer(
114
+ uint256 evvmID,
115
+ address signer,
116
+ string memory _username,
117
+ uint256 _offerId,
118
+ uint256 _nameServiceNonce,
119
+ bytes memory signature
120
+ ) internal pure returns (bool) {
121
+ return
122
+ SignatureRecover.signatureVerification(
123
+ Strings.toString(evvmID),
124
+ "acceptOffer",
125
+ string.concat(
126
+ _username,
127
+ ",",
128
+ Strings.toString(_offerId),
129
+ ",",
130
+ Strings.toString(_nameServiceNonce)
131
+ ),
132
+ signature,
133
+ signer
134
+ );
135
+ }
136
+
137
+ function verifyMessageSignedForRenewUsername(
138
+ uint256 evvmID,
139
+ address signer,
140
+ string memory _username,
141
+ uint256 _nameServiceNonce,
142
+ bytes memory signature
143
+ ) internal pure returns (bool) {
144
+ return
145
+ SignatureRecover.signatureVerification(
146
+ Strings.toString(evvmID),
147
+ "renewUsername",
148
+ string.concat(
149
+ _username,
150
+ ",",
151
+ Strings.toString(_nameServiceNonce)
152
+ ),
153
+ signature,
154
+ signer
155
+ );
156
+ }
157
+
158
+ function verifyMessageSignedForAddCustomMetadata(
159
+ uint256 evvmID,
160
+ address signer,
161
+ string memory _identity,
162
+ string memory _value,
163
+ uint256 _nameServiceNonce,
164
+ bytes memory signature
165
+ ) internal pure returns (bool) {
166
+ return
167
+ SignatureRecover.signatureVerification(
168
+ Strings.toString(evvmID),
169
+ "addCustomMetadata",
170
+ string.concat(
171
+ _identity,
172
+ ",",
173
+ _value,
174
+ ",",
175
+ Strings.toString(_nameServiceNonce)
176
+ ),
177
+ signature,
178
+ signer
179
+ );
180
+ }
181
+
182
+ function verifyMessageSignedForRemoveCustomMetadata(
183
+ uint256 evvmID,
184
+ address signer,
185
+ string memory _username,
186
+ uint256 _key,
187
+ uint256 _nonce,
188
+ bytes memory signature
189
+ ) internal pure returns (bool) {
190
+ return
191
+ SignatureRecover.signatureVerification(
192
+ Strings.toString(evvmID),
193
+ "removeCustomMetadata",
194
+ string.concat(
195
+ _username,
196
+ ",",
197
+ Strings.toString(_key),
198
+ ",",
199
+ Strings.toString(_nonce)
200
+ ),
201
+ signature,
202
+ signer
203
+ );
204
+ }
205
+
206
+ function verifyMessageSignedForFlushCustomMetadata(
207
+ uint256 evvmID,
208
+ address signer,
209
+ string memory _identity,
210
+ uint256 _nonce,
211
+ bytes memory signature
212
+ ) internal pure returns (bool) {
213
+ return
214
+ SignatureRecover.signatureVerification(
215
+ Strings.toString(evvmID),
216
+ "flushCustomMetadata",
217
+ string.concat(_identity, ",", Strings.toString(_nonce)),
218
+ signature,
219
+ signer
220
+ );
221
+ }
222
+
223
+ function verifyMessageSignedForFlushUsername(
224
+ uint256 evvmID,
225
+ address signer,
226
+ string memory _username,
227
+ uint256 _nonce,
228
+ bytes memory signature
229
+ ) internal pure returns (bool) {
230
+ return
231
+ SignatureRecover.signatureVerification(
232
+ Strings.toString(evvmID),
233
+ "flushUsername",
234
+ string.concat(_username, ",", Strings.toString(_nonce)),
235
+ signature,
236
+ signer
237
+ );
238
+ }
239
+ }
@@ -0,0 +1,358 @@
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
+ MM""""""""`M dP oo dP
7
+ MM mmmmmmmM 88 88
8
+ M` MMMM .d8888b. d8888P dP 88d8b.d8b. .d8888b. d8888P .d8888b. 88d888b.
9
+ MM MMMMMMMM Y8ooooo. 88 88 88'`88'`88 88' `88 88 88' `88 88' `88
10
+ MM MMMMMMMM 88 88 88 88 88 88 88. .88 88 88. .88 88
11
+ MM .M `88888P' dP dP dP dP dP `88888P8 dP `88888P' dP
12
+ MMMMMMMMMMMM
13
+
14
+ * @title Staking Mate contract for Roll A Mate Protocol
15
+ * @author jistro.eth ariutokintumi.eth
16
+ */
17
+
18
+ import {Staking} from "@evvm/testnet-contracts/contracts/staking/Staking.sol";
19
+ import {Evvm} from "@evvm/testnet-contracts/contracts/evvm/Evvm.sol";
20
+
21
+ contract Estimator {
22
+ struct AddressTypeProposal {
23
+ address actual;
24
+ address proposal;
25
+ uint256 timeToAccept;
26
+ }
27
+
28
+ struct UintTypeProposal {
29
+ uint256 actual;
30
+ uint256 proposal;
31
+ uint256 timeToAccept;
32
+ }
33
+
34
+ struct EpochMetadata {
35
+ address tokenPool;
36
+ uint256 totalPool;
37
+ uint256 totalStaked;
38
+ uint256 tFinal;
39
+ uint256 tStart;
40
+ }
41
+
42
+ EpochMetadata private epoch;
43
+ AddressTypeProposal private activator;
44
+ AddressTypeProposal private evvmAddress;
45
+ AddressTypeProposal private addressStaking;
46
+ AddressTypeProposal private admin;
47
+
48
+ bytes32 constant DEPOSIT_IDENTIFIER = bytes32(uint256(1));
49
+ bytes32 constant WITHDRAW_IDENTIFIER = bytes32(uint256(2));
50
+ bytes32 constant BEGUIN_IDENTIFIER = WITHDRAW_IDENTIFIER;
51
+
52
+ bytes32 epochId = bytes32(uint256(3));
53
+
54
+ modifier onlyStaking() {
55
+ if (msg.sender != addressStaking.actual) revert();
56
+ _;
57
+ }
58
+
59
+ modifier onlyActivator() {
60
+ if (msg.sender != activator.actual) revert();
61
+ _;
62
+ }
63
+
64
+ modifier onlyAdmin() {
65
+ if (msg.sender != admin.actual) revert();
66
+ _;
67
+ }
68
+
69
+ constructor(
70
+ address _activator,
71
+ address _evvmAddress,
72
+ address _addressStaking,
73
+ address _admin
74
+ ) {
75
+ activator.actual = _activator;
76
+ evvmAddress.actual = _evvmAddress;
77
+ addressStaking.actual = _addressStaking;
78
+ admin.actual = _admin;
79
+ }
80
+
81
+ function notifyNewEpoch(
82
+ address tokenPool,
83
+ uint256 totalPool,
84
+ uint256 totalStaked,
85
+ uint256 tStart
86
+ ) public onlyActivator {
87
+ epoch = EpochMetadata({
88
+ tokenPool: tokenPool,
89
+ totalPool: totalPool,
90
+ totalStaked: totalStaked,
91
+ tFinal: block.timestamp,
92
+ tStart: tStart
93
+ });
94
+ }
95
+
96
+ function makeEstimation(
97
+ address _user
98
+ )
99
+ external
100
+ onlyStaking
101
+ returns (
102
+ bytes32 epochAnswer,
103
+ address tokenAddress,
104
+ uint256 amountTotalToBeRewarded,
105
+ uint256 idToOverwrite,
106
+ uint256 timestampToOverwrite
107
+ )
108
+ {
109
+
110
+ uint256 totSmLast;
111
+ uint256 sumSmT;
112
+
113
+ uint256 tLast = epoch.tStart;
114
+ Staking.HistoryMetadata memory h;
115
+ uint256 size = Staking(addressStaking.actual).getSizeOfAddressHistory(
116
+ _user
117
+ );
118
+
119
+ for (uint256 i = 0; i < size; i++) {
120
+ h = Staking(addressStaking.actual).getAddressHistoryByIndex(
121
+ _user,
122
+ i
123
+ );
124
+
125
+ if (size == 1) totSmLast = h.totalStaked;
126
+
127
+
128
+ if (h.timestamp > epoch.tFinal) {
129
+ if (totSmLast > 0) sumSmT += (epoch.tFinal - tLast) * totSmLast;
130
+
131
+ idToOverwrite = i;
132
+
133
+ break;
134
+ }
135
+
136
+ if (h.transactionType == epochId) return (0, address(0), 0, 0, 0); // alv!!!!
137
+
138
+ if (totSmLast > 0) sumSmT += (h.timestamp - tLast) * totSmLast;
139
+
140
+
141
+ tLast = h.timestamp;
142
+ totSmLast = h.totalStaked;
143
+ idToOverwrite = i;
144
+ }
145
+
146
+ /**
147
+ * @notice to get averageSm the formula is
148
+ * __ n
149
+ * \
150
+ * / [(ti -ti-1) * Si-1] x 10**18
151
+ * --i=1
152
+ * averageSm = --------------------------------------
153
+ * tFinal - tStart
154
+ *
155
+ * where
156
+ * ti ----- timestamp of current iteration
157
+ * ti-1 ----- timestamp of previus iteration
158
+ * t final -- epoch end
159
+ * t zero -- start of epoch
160
+ */
161
+
162
+ uint256 averageSm = (sumSmT * 1e18) / (epoch.tFinal - epoch.tStart);
163
+
164
+ amountTotalToBeRewarded =
165
+ (averageSm * (epoch.totalPool / epoch.totalStaked)) /
166
+ 1e18;
167
+
168
+ timestampToOverwrite = epoch.tFinal;
169
+
170
+
171
+ epoch.totalPool -= amountTotalToBeRewarded;
172
+ epoch.totalStaked -= h.totalStaked;
173
+ }
174
+
175
+ //⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻
176
+ // Admin functions
177
+ //⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻
178
+
179
+ function setActivatorProposal(
180
+ address _proposal
181
+ ) external onlyActivator {
182
+ activator.proposal = _proposal;
183
+ activator.timeToAccept = block.timestamp + 1 days;
184
+ }
185
+
186
+ function cancelActivatorProposal() external onlyActivator {
187
+ activator.proposal = address(0);
188
+ activator.timeToAccept = 0;
189
+ }
190
+
191
+ function acceptActivatorProposal() external {
192
+ if (block.timestamp < activator.timeToAccept) revert();
193
+
194
+ activator.actual = activator.proposal;
195
+ activator.proposal = address(0);
196
+ activator.timeToAccept = 0;
197
+ }
198
+
199
+ function setEvvmAddressProposal(
200
+ address _proposal
201
+ ) external onlyAdmin {
202
+ evvmAddress.proposal = _proposal;
203
+ evvmAddress.timeToAccept = block.timestamp + 1 days;
204
+ }
205
+
206
+ function cancelEvvmAddressProposal() external onlyAdmin {
207
+ evvmAddress.proposal = address(0);
208
+ evvmAddress.timeToAccept = 0;
209
+ }
210
+
211
+ function acceptEvvmAddressProposal() external onlyAdmin {
212
+ if (block.timestamp < evvmAddress.timeToAccept) revert();
213
+
214
+ evvmAddress.actual = evvmAddress.proposal;
215
+ evvmAddress.proposal = address(0);
216
+ evvmAddress.timeToAccept = 0;
217
+ }
218
+
219
+ function setAddressStakingProposal(
220
+ address _proposal
221
+ ) external onlyAdmin {
222
+ addressStaking.proposal = _proposal;
223
+ addressStaking.timeToAccept = block.timestamp + 1 days;
224
+ }
225
+
226
+ function cancelAddressStakingProposal() external onlyAdmin {
227
+ addressStaking.proposal = address(0);
228
+ addressStaking.timeToAccept = 0;
229
+ }
230
+
231
+ function acceptAddressStakingProposal() external onlyAdmin {
232
+ if (block.timestamp < addressStaking.timeToAccept) revert();
233
+
234
+ addressStaking.actual = addressStaking.proposal;
235
+ addressStaking.proposal = address(0);
236
+ addressStaking.timeToAccept = 0;
237
+ }
238
+
239
+ function setAdminProposal(
240
+ address _proposal
241
+ ) external onlyAdmin {
242
+ admin.proposal = _proposal;
243
+ admin.timeToAccept = block.timestamp + 1 days;
244
+ }
245
+
246
+ function cancelAdminProposal() external onlyAdmin {
247
+ admin.proposal = address(0);
248
+ admin.timeToAccept = 0;
249
+ }
250
+
251
+ function acceptAdminProposal() external {
252
+ if (block.timestamp < admin.timeToAccept) revert();
253
+
254
+ admin.actual = admin.proposal;
255
+ admin.proposal = address(0);
256
+ admin.timeToAccept = 0;
257
+ }
258
+
259
+ //⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻
260
+ // Getters
261
+ //⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎽⎼⎻⎺⎺⎻⎼⎽⎼⎻⎺⎺⎻
262
+
263
+ function getEpochMetadata() external view returns (EpochMetadata memory) {
264
+ return epoch;
265
+ }
266
+
267
+ function getActualEpochInUint() external view returns (uint256) {
268
+ return uint256(epochId) - 2;
269
+ }
270
+
271
+ function getActualEpochInFormat() external view returns (bytes32) {
272
+ return epochId;
273
+ }
274
+
275
+ function getActivatorMetadata() external view returns (AddressTypeProposal memory) {
276
+ return activator;
277
+ }
278
+
279
+ function getEvvmAddressMetadata()
280
+ external
281
+ view
282
+ returns (AddressTypeProposal memory)
283
+ {
284
+ return evvmAddress;
285
+ }
286
+
287
+ function getAddressStakingMetadata()
288
+ external
289
+ view
290
+ returns (AddressTypeProposal memory)
291
+ {
292
+ return addressStaking;
293
+ }
294
+
295
+ function getAdminMetadata() external view returns (AddressTypeProposal memory) {
296
+ return admin;
297
+ }
298
+
299
+
300
+
301
+ function simulteEstimation(
302
+ address _user
303
+ )
304
+ external
305
+ view
306
+ returns (
307
+ bytes32 epochAnswer,
308
+ address tokenAddress,
309
+ uint256 amountTotalToBeRewarded,
310
+ uint256 idToOverwrite,
311
+ uint256 timestampToOverwrite
312
+ )
313
+ {
314
+ uint256 totSmLast;
315
+ uint256 sumSmT;
316
+
317
+ uint256 tLast = epoch.tStart;
318
+ Staking.HistoryMetadata memory h;
319
+ uint256 size = Staking(addressStaking.actual).getSizeOfAddressHistory(
320
+ _user
321
+ );
322
+
323
+ for (uint256 i = 0; i < size; i++) {
324
+ h = Staking(addressStaking.actual).getAddressHistoryByIndex(
325
+ _user,
326
+ i
327
+ );
328
+
329
+ if (h.timestamp > epoch.tFinal) {
330
+ if (size == 1) totSmLast = h.totalStaked;
331
+
332
+ if (totSmLast > 0) sumSmT += (epoch.tFinal - tLast) * totSmLast;
333
+
334
+ idToOverwrite = i;
335
+
336
+ break;
337
+ }
338
+
339
+ if (h.transactionType == epochId) return (0, address(0), 0, 0, 0); // alv!!!!
340
+
341
+ if (totSmLast > 0) sumSmT += (h.timestamp - tLast) * totSmLast;
342
+
343
+ tLast = h.timestamp;
344
+ totSmLast = h.totalStaked;
345
+ idToOverwrite = i;
346
+ }
347
+
348
+ uint256 averageSm = (sumSmT * 1e18) / (epoch.tFinal - epoch.tStart);
349
+
350
+ amountTotalToBeRewarded =
351
+ (averageSm * (epoch.totalPool / epoch.totalStaked)) /
352
+ 1e18;
353
+
354
+ timestampToOverwrite = epoch.tFinal;
355
+ }
356
+
357
+
358
+ }