@evvm/testnet-contracts 2.3.0 → 3.0.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.
Files changed (67) hide show
  1. package/README.md +44 -24
  2. package/contracts/core/Core.sol +1392 -0
  3. package/contracts/core/lib/CoreStorage.sol +171 -0
  4. package/contracts/nameService/NameService.sol +613 -543
  5. package/contracts/nameService/lib/IdentityValidation.sol +15 -21
  6. package/contracts/p2pSwap/P2PSwap.sol +258 -145
  7. package/contracts/staking/Estimator.sol +25 -44
  8. package/contracts/staking/Staking.sol +284 -262
  9. package/contracts/treasury/Treasury.sol +40 -47
  10. package/contracts/treasuryTwoChains/TreasuryExternalChainStation.sol +585 -198
  11. package/contracts/treasuryTwoChains/TreasuryHostChainStation.sol +425 -174
  12. package/contracts/treasuryTwoChains/lib/PayloadUtils.sol +2 -4
  13. package/interfaces/{IEvvm.sol → ICore.sol} +58 -25
  14. package/interfaces/IEstimator.sol +1 -1
  15. package/interfaces/INameService.sol +46 -49
  16. package/interfaces/IP2PSwap.sol +16 -17
  17. package/interfaces/IStaking.sol +21 -17
  18. package/interfaces/ITreasury.sol +2 -1
  19. package/interfaces/ITreasuryExternalChainStation.sol +15 -9
  20. package/interfaces/ITreasuryHostChainStation.sol +14 -11
  21. package/interfaces/IUserValidator.sol +6 -0
  22. package/library/Erc191TestBuilder.sol +336 -471
  23. package/library/EvvmService.sol +27 -71
  24. package/library/errors/CoreError.sol +116 -0
  25. package/library/errors/CrossChainTreasuryError.sol +36 -0
  26. package/library/errors/NameServiceError.sol +79 -0
  27. package/library/errors/StakingError.sol +79 -0
  28. package/{contracts/treasury/lib/ErrorsLib.sol → library/errors/TreasuryError.sol} +9 -17
  29. package/library/structs/CoreStructs.sol +146 -0
  30. package/library/structs/ExternalChainStationStructs.sol +92 -0
  31. package/library/structs/HostChainStationStructs.sol +77 -0
  32. package/library/structs/NameServiceStructs.sol +47 -0
  33. package/library/structs/P2PSwapStructs.sol +127 -0
  34. package/library/structs/StakingStructs.sol +67 -0
  35. package/library/utils/AdvancedStrings.sol +62 -44
  36. package/library/utils/CAUtils.sol +29 -0
  37. package/library/utils/governance/Admin.sol +66 -0
  38. package/library/utils/governance/ProposalStructs.sol +49 -0
  39. package/library/utils/service/CoreExecution.sol +158 -0
  40. package/library/utils/service/StakingServiceUtils.sol +20 -37
  41. package/library/utils/signature/CoreHashUtils.sol +73 -0
  42. package/library/utils/signature/NameServiceHashUtils.sol +156 -0
  43. package/library/utils/signature/P2PSwapHashUtils.sol +65 -0
  44. package/library/utils/signature/StakingHashUtils.sol +41 -0
  45. package/library/utils/signature/TreasuryCrossChainHashUtils.sol +40 -0
  46. package/package.json +1 -1
  47. package/contracts/evvm/Evvm.sol +0 -1300
  48. package/contracts/evvm/lib/ErrorsLib.sol +0 -131
  49. package/contracts/evvm/lib/EvvmStorage.sol +0 -217
  50. package/contracts/evvm/lib/EvvmStructs.sol +0 -208
  51. package/contracts/evvm/lib/SignatureUtils.sol +0 -162
  52. package/contracts/nameService/lib/ErrorsLib.sol +0 -155
  53. package/contracts/nameService/lib/NameServiceStructs.sol +0 -125
  54. package/contracts/nameService/lib/SignatureUtils.sol +0 -420
  55. package/contracts/p2pSwap/lib/P2PSwapStructs.sol +0 -59
  56. package/contracts/p2pSwap/lib/SignatureUtils.sol +0 -98
  57. package/contracts/staking/lib/ErrorsLib.sol +0 -98
  58. package/contracts/staking/lib/SignatureUtils.sol +0 -105
  59. package/contracts/staking/lib/StakingStructs.sol +0 -106
  60. package/contracts/treasuryTwoChains/lib/ErrorsLib.sol +0 -48
  61. package/contracts/treasuryTwoChains/lib/ExternalChainStationStructs.sol +0 -80
  62. package/contracts/treasuryTwoChains/lib/HostChainStationStructs.sol +0 -87
  63. package/contracts/treasuryTwoChains/lib/SignatureUtils.sol +0 -79
  64. package/library/utils/GovernanceUtils.sol +0 -81
  65. package/library/utils/nonces/AsyncNonce.sol +0 -74
  66. package/library/utils/nonces/SyncNonce.sol +0 -71
  67. package/library/utils/service/EvvmPayments.sol +0 -144
@@ -3,52 +3,30 @@
3
3
 
4
4
  pragma solidity ^0.8.0;
5
5
 
6
- /**
7
- _____
8
- /__ \_ __ ___ __ _ ___ _ _ _ __ _ _
9
- / /\| '__/ _ \/ _` / __| | | | '__| | | |
10
- / / | | | __| (_| \__ | |_| | | | |_| |
11
- \/ |_| \___|\__,_|___/\__,_|_| \__, |
12
- |___/
13
- ___ _ _ __ _ _ _
14
- / __| |__ __ _(_)_ __ / _| |_ __ _| |_(_) ___ _ __
15
- / / | '_ \ / _` | | '_ \\ \| __/ _` | __| |/ _ \| '_ \
16
- / /___| | | | (_| | | | | _\ | || (_| | |_| | (_) | | | |
17
- \____/|_| |_|\__,_|_|_| |_\__/\__\__,_|\__|_|\___/|_| |_|
18
-
19
-
20
-
21
- _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
22
- |_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
23
-
24
- __ __ __ __ _
25
- / / / ____ _____/ /_ _____/ /_ ____ _(_____
26
- / /_/ / __ \/ ___/ __/ / ___/ __ \/ __ `/ / __ \
27
- / __ / /_/ (__ / /_ / /__/ / / / /_/ / / / / /
28
- /_/ /_/\____/____/\__/ \___/_/ /_/\__,_/_/_/ /_/
29
-
30
- * @title Treasury Cross-Chain Host Station Contract
31
- * @author Mate labs
32
- */
33
-
34
- import {IERC20} from "@evvm/testnet-contracts/library/primitives/IERC20.sol";
35
- import {Evvm} from "@evvm/testnet-contracts/contracts/evvm/Evvm.sol";
36
6
  import {
37
- ErrorsLib
38
- } from "@evvm/testnet-contracts/contracts/treasuryTwoChains/lib/ErrorsLib.sol";
7
+ CrossChainTreasuryError as Error
8
+ } from "@evvm/testnet-contracts/library/errors/CrossChainTreasuryError.sol";
39
9
  import {
40
- HostChainStationStructs
41
- } from "@evvm/testnet-contracts/contracts/treasuryTwoChains/lib/HostChainStationStructs.sol";
42
-
10
+ TreasuryCrossChainHashUtils as Hash
11
+ } from "@evvm/testnet-contracts/library/utils/signature/TreasuryCrossChainHashUtils.sol";
43
12
  import {
44
- SignatureUtils
45
- } from "@evvm/testnet-contracts/contracts/treasuryTwoChains/lib/SignatureUtils.sol";
13
+ HostChainStationStructs as Structs
14
+ } from "@evvm/testnet-contracts/library/structs/HostChainStationStructs.sol";
46
15
  import {
47
16
  PayloadUtils
48
17
  } from "@evvm/testnet-contracts/contracts/treasuryTwoChains/lib/PayloadUtils.sol";
49
18
 
50
- import {IMailbox} from "@hyperlane-xyz/core/contracts/interfaces/IMailbox.sol";
19
+ import {Core} from "@evvm/testnet-contracts/contracts/core/Core.sol";
20
+
21
+ import {
22
+ AdvancedStrings
23
+ } from "@evvm/testnet-contracts/library/utils/AdvancedStrings.sol";
24
+ import {
25
+ ProposalStructs
26
+ } from "@evvm/testnet-contracts/library/utils/governance/ProposalStructs.sol";
51
27
 
28
+ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
29
+ import {IMailbox} from "@hyperlane-xyz/core/contracts/interfaces/IMailbox.sol";
52
30
  import {
53
31
  MessagingParams,
54
32
  MessagingReceipt
@@ -64,8 +42,6 @@ import {
64
42
  import {
65
43
  OptionsBuilder
66
44
  } from "@layerzerolabs/oapp-evm/contracts/oapp/libs/OptionsBuilder.sol";
67
- import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
68
-
69
45
  import {
70
46
  AxelarExecutable
71
47
  } from "@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol";
@@ -75,47 +51,67 @@ import {
75
51
  import {
76
52
  IInterchainGasEstimation
77
53
  } from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IInterchainGasEstimation.sol";
78
- import {
79
- AdvancedStrings
80
- } from "@evvm/testnet-contracts/library/utils/AdvancedStrings.sol";
81
54
 
82
- contract TreasuryHostChainStation is
83
- HostChainStationStructs,
84
- OApp,
85
- OAppOptionsType3,
86
- AxelarExecutable
87
- {
55
+
56
+ /**
57
+ _____
58
+ /__ \_ __ ___ __ _ ___ _ _ _ __ _ _
59
+ / /\| '__/ _ \/ _` / __| | | | '__| | | |
60
+ / / | | | __| (_| \__ | |_| | | | |_| |
61
+ \/ |_| \___|\__,_|___/\__,_|_| \__, |
62
+ |___/
63
+ ___ _ _ __ _ _ _
64
+ / __| |__ __ _(_)_ __ / _| |_ __ _| |_(_) ___ _ __
65
+ / / | '_ \ / _` | | '_ \\ \| __/ _` | __| |/ _ \| '_ \
66
+ / /___| | | | (_| | | | | _\ | || (_| | |_| | (_) | | | |
67
+ \____/|_| |_|\__,_|_|_| |_\__/\__\__,_|\__|_|\___/|_| |_|
68
+
69
+
70
+
71
+ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
72
+ |_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
73
+
74
+ __ __ __ __ _
75
+ / / / ____ _____/ /_ _____/ /_ ____ _(_____
76
+ / /_/ / __ \/ ___/ __/ / ___/ __ \/ __ `/ / __ \
77
+ / __ / /_/ (__ / /_ / /__/ / / / /_/ / / / / /
78
+ /_/ /_/\____/____/\__/ \___/_/ /_/\__,_/_/_/ /_/
79
+
80
+ * @title EVVM Host Chain Station
81
+ * @author Mate labs
82
+ * @notice Manages cross-chain withdrawals from the EVVM host chain to an external chain.
83
+ * @dev Multi-protocol bridge supporting Hyperlane, LayerZero V2, and Axelar.
84
+ * Integrates with Core.sol for balance updates and uses Fisher-specific nonces.
85
+ */
86
+
87
+ contract TreasuryHostChainStation is OApp, OAppOptionsType3, AxelarExecutable {
88
88
  /// @notice EVVM core contract for balance operations
89
89
  /// @dev Used to integrate with EVVM's balance management and token operations
90
- Evvm evvm;
90
+ Core core;
91
91
 
92
92
  /// @notice Admin address management with time-delayed proposals
93
93
  /// @dev Stores current admin, proposed admin, and acceptance timestamp
94
- AddressTypeProposal admin;
94
+ ProposalStructs.AddressTypeProposal admin;
95
95
 
96
96
  /// @notice Fisher executor address management with time-delayed proposals
97
97
  /// @dev Fisher executor can process cross-chain bridge transactions
98
- AddressTypeProposal fisherExecutor;
98
+ ProposalStructs.AddressTypeProposal fisherExecutor;
99
99
 
100
100
  /// @notice Hyperlane protocol configuration for cross-chain messaging
101
101
  /// @dev Contains domain ID, external chain address, and mailbox contract address
102
- HyperlaneConfig hyperlane;
102
+ Structs.HyperlaneConfig hyperlane;
103
103
 
104
104
  /// @notice LayerZero protocol configuration for omnichain messaging
105
105
  /// @dev Contains endpoint ID, external chain address, and endpoint contract address
106
- LayerZeroConfig layerZero;
106
+ Structs.LayerZeroConfig layerZero;
107
107
 
108
108
  /// @notice Axelar protocol configuration for cross-chain communication
109
109
  /// @dev Contains chain name, external chain address, gas service, and gateway addresses
110
- AxelarConfig axelar;
110
+ Structs.AxelarConfig axelar;
111
111
 
112
112
  /// @notice Pending proposal for changing external chain addresses across all protocols
113
113
  /// @dev Used for coordinated updates to external chain addresses with time delay
114
- ChangeExternalChainAddressParams externalChainAddressChangeProposal;
115
-
116
- /// @notice Tracks the next nonce for Fisher bridge operations per user address
117
- /// @dev Prevents replay attacks in Fisher bridge transactions
118
- mapping(address => uint256) nextFisherExecutionNonce;
114
+ Structs.ChangeExternalChainAddressParams externalChainAddressChangeProposal;
119
115
 
120
116
  /// @notice LayerZero execution options with gas limit configuration
121
117
  /// @dev Pre-built options for LayerZero message execution (200k gas limit)
@@ -166,40 +162,40 @@ contract TreasuryHostChainStation is
166
162
 
167
163
  /// @notice Initializes the Host Chain Station with EVVM integration and cross-chain protocols
168
164
  /// @dev Sets up Hyperlane, LayerZero, and Axelar configurations for multi-protocol support
169
- /// @param _evvmAddress Address of the EVVM core contract for balance operations
165
+ /// @param _coreAddress Address of the EVVM core contract for balance operations
170
166
  /// @param _admin Initial admin address with full administrative privileges
171
167
  /// @param _crosschainConfig Configuration struct containing all cross-chain protocol settings
172
168
  constructor(
173
- address _evvmAddress,
169
+ address _coreAddress,
174
170
  address _admin,
175
- CrosschainConfig memory _crosschainConfig
171
+ Structs.CrosschainConfig memory _crosschainConfig
176
172
  )
177
173
  OApp(_crosschainConfig.layerZero.endpointAddress, _admin)
178
174
  Ownable(_admin)
179
175
  AxelarExecutable(_crosschainConfig.axelar.gatewayAddress)
180
176
  {
181
- evvm = Evvm(_evvmAddress);
177
+ core = Core(_coreAddress);
182
178
 
183
- admin = AddressTypeProposal({
179
+ admin = ProposalStructs.AddressTypeProposal({
184
180
  current: _admin,
185
181
  proposal: address(0),
186
182
  timeToAccept: 0
187
183
  });
188
- hyperlane = HyperlaneConfig({
184
+ hyperlane = Structs.HyperlaneConfig({
189
185
  externalChainStationDomainId: _crosschainConfig
190
186
  .hyperlane
191
187
  .externalChainStationDomainId,
192
188
  externalChainStationAddress: "",
193
189
  mailboxAddress: _crosschainConfig.hyperlane.mailboxAddress
194
190
  });
195
- layerZero = LayerZeroConfig({
191
+ layerZero = Structs.LayerZeroConfig({
196
192
  externalChainStationEid: _crosschainConfig
197
193
  .layerZero
198
194
  .externalChainStationEid,
199
195
  externalChainStationAddress: "",
200
196
  endpointAddress: _crosschainConfig.layerZero.endpointAddress
201
197
  });
202
- axelar = AxelarConfig({
198
+ axelar = Structs.AxelarConfig({
203
199
  externalChainStationChainName: _crosschainConfig
204
200
  .axelar
205
201
  .externalChainStationChainName,
@@ -234,25 +230,63 @@ contract TreasuryHostChainStation is
234
230
  fuseSetExternalChainAddress = 0x00;
235
231
  }
236
232
 
237
- /// @notice Withdraws tokens from EVVM balance and sends to external chain via selected protocol
238
- /// @dev Validates balance, deducts from EVVM, and bridges via Hyperlane/LayerZero/Axelar
239
- /// @param toAddress Recipient address on the external chain
240
- /// @param token Token contract address (cannot be Principal Token)
241
- /// @param amount Amount to withdraw and send to external chain
242
- /// @param protocolToExecute Protocol selector: 0x01=Hyperlane, 0x02=LayerZero, 0x03=Axelar
233
+ /**
234
+ * @notice Withdraws tokens via selected protocol
235
+ * @dev Deducts Evvm balance then bridges to external chain
236
+ *
237
+ * Process:
238
+ * - Validate: Check Evvm.getBalance >= amount
239
+ * - Deduct: executerEVVM(false) removes balance
240
+ * - Encode: PayloadUtils.encodePayload
241
+ * - Route: Protocol-specific message dispatch
242
+ * - Receive: External chain receives tokens
243
+ *
244
+ * Protocol Routing:
245
+ * - 0x01: Hyperlane (mailbox.dispatch + quote fee)
246
+ * - 0x02: LayerZero (_lzSend + msg.value fee)
247
+ * - 0x03: Axelar (payNativeGas + callContract)
248
+ *
249
+ * Evvm Integration:
250
+ * - Balance Check: core.getBalance(sender, token)
251
+ * - Deduction: evvm.removeAmountFromUser
252
+ * - Principal Token: Cannot withdraw (MATE locked)
253
+ * - Other Tokens: Full withdrawal support
254
+ *
255
+ * Fee Payment:
256
+ * - Hyperlane: msg.value = quote
257
+ * - LayerZero: msg.value = fee (refund excess)
258
+ * - Axelar: msg.value for gas service
259
+ *
260
+ * External Chain Integration:
261
+ * - Receives: handle/_lzReceive/_execute
262
+ * - Transfers: Tokens sent from contract balance
263
+ * - Native ETH: address(0) representation
264
+ *
265
+ * Security:
266
+ * - MATE Block: Principal token cannot withdraw
267
+ * - Balance Check: Revert if insufficient Evvm
268
+ * - Sender Only: msg.sender balance deducted
269
+ * - Protocol Validation: External checks sender
270
+ *
271
+ * @param toAddress Recipient on external chain
272
+ * @param token Token address (NOT principal token)
273
+ * @param amount Token amount to withdraw
274
+ * @param protocolToExecute 0x01=Hyperlane,
275
+ * 0x02=LZ, 0x03=Axelar
276
+ */
243
277
  function withdraw(
244
278
  address toAddress,
245
279
  address token,
246
280
  uint256 amount,
247
281
  bytes1 protocolToExecute
248
282
  ) external payable {
249
- if (token == evvm.getEvvmMetadata().principalTokenAddress)
250
- revert ErrorsLib.PrincipalTokenIsNotWithdrawable();
283
+ if (token == core.getEvvmMetadata().principalTokenAddress)
284
+ revert Error.PrincipalTokenIsNotWithdrawable();
251
285
 
252
- if (evvm.getBalance(msg.sender, token) < amount)
253
- revert ErrorsLib.InsufficientBalance();
286
+ if (core.getBalance(msg.sender, token) < amount)
287
+ revert Error.InsufficientBalance();
254
288
 
255
- executerEVVM(false, msg.sender, token, amount);
289
+ executerCore(false, msg.sender, token, amount);
256
290
 
257
291
  bytes memory payload = PayloadUtils.encodePayload(
258
292
  token,
@@ -299,84 +333,174 @@ contract TreasuryHostChainStation is
299
333
  }
300
334
  }
301
335
 
302
- /// @notice Receives Fisher bridge transactions from external chain and credits EVVM balances
303
- /// @dev Verifies signature, increments nonce, and adds balance to recipient and executor
304
- /// @param from Original sender address from external chain
305
- /// @param addressToReceive Recipient address on this host chain
306
- /// @param tokenAddress Token contract address (address(0) for ETH)
307
- /// @param priorityFee Fee amount paid to Fisher executor
308
- /// @param amount Amount of tokens being received
309
- /// @param signature ECDSA signature proving transaction authorization
336
+ /**
337
+ * @notice Receives Fisher bridge deposits from external
338
+ * @dev Validates signature via Core.sol, credits balances
339
+ *
340
+ * Purpose:
341
+ * - Receive: Deposits from external chain
342
+ * - Validate: ECDSA signature via Core.sol
343
+ * - Credit: Add tokens to Core balances
344
+ * - Fee: Pay Fisher executor priority fee
345
+ *
346
+ * Fisher Bridge Flow:
347
+ * - External: TreasuryExternalChainStation emits
348
+ * - Monitor: Fisher executor watches events
349
+ * - Call: Executor calls this function
350
+ * - Validate: core.validateAndConsumeNonce
351
+ * - Credit: Core balances updated
352
+ *
353
+ * Core Integration:
354
+ * - Nonce: core.validateAndConsumeNonce
355
+ * - Hash: TreasuryCrossChainHashUtils.hashData...
356
+ * - Async: true (independent nonce system)
357
+ * - Signature: ECDSA via SignatureRecover
358
+ *
359
+ * Core Balance Operations:
360
+ * - Recipient: core.addAmountToUser(to, token,
361
+ * amount)
362
+ * - Fee: core.addAmountToUser(executor, token,
363
+ * priorityFee)
364
+ * - Total: amount + priorityFee credited
365
+ * - No Transfer: Core tracks virtual balances
366
+ *
367
+ * Nonce System:
368
+ * - Core.sol: validateAndConsumeNonce(from, hash,
369
+ * nonce...)
370
+ * - Sequential: User manages own nonces
371
+ * - Replay Prevention: Core.sol marks used
372
+ * - Async: true (Fisher bridge nonces)
373
+ *
374
+ * Security:
375
+ * - Executor Only: onlyFisherExecutor modifier
376
+ * - Signature: Core.sol validates ECDSA
377
+ * - Nonce: Core.sol prevents replays
378
+ * - Fee Payment: Executor compensated for gas
379
+ *
380
+ * @param from Original sender on external chain
381
+ * @param addressToReceive Recipient on host chain
382
+ * @param tokenAddress Token (address(0) for ETH)
383
+ * @param priorityFee Fee for Fisher executor
384
+ * @param amount Token amount received
385
+ * @param nonce Sequential nonce from user
386
+ * @param signature ECDSA signature from 'from'
387
+ */
310
388
  function fisherBridgeReceive(
311
389
  address from,
312
390
  address addressToReceive,
313
391
  address tokenAddress,
314
392
  uint256 priorityFee,
315
393
  uint256 amount,
394
+ uint256 nonce,
316
395
  bytes memory signature
317
396
  ) external onlyFisherExecutor {
318
- if (
319
- !SignatureUtils.verifyMessageSignedForFisherBridge(
320
- evvm.getEvvmID(),
321
- from,
397
+ core.validateAndConsumeNonce(
398
+ from,
399
+ Hash.hashDataForFisherBridge(
322
400
  addressToReceive,
323
- nextFisherExecutionNonce[from],
324
401
  tokenAddress,
325
402
  priorityFee,
326
- amount,
327
- signature
328
- )
329
- ) revert ErrorsLib.InvalidSignature();
330
-
331
- nextFisherExecutionNonce[from]++;
403
+ amount
404
+ ),
405
+ fisherExecutor.current,
406
+ nonce,
407
+ true,
408
+ signature
409
+ );
332
410
 
333
- executerEVVM(true, addressToReceive, tokenAddress, amount);
411
+ executerCore(true, addressToReceive, tokenAddress, amount);
334
412
 
335
413
  if (priorityFee > 0)
336
- executerEVVM(true, msg.sender, tokenAddress, priorityFee);
337
- }
338
-
339
- /// @notice Processes Fisher bridge token transfers from host to external chain
340
- /// @dev Validates balance and signature, deducts from sender, pays executor fee
341
- /// @param from Sender address initiating the bridge transaction
342
- /// @param addressToReceive Recipient address on the external chain
343
- /// @param tokenAddress Token contract address (cannot be Principal Token)
344
- /// @param priorityFee Fee amount paid to Fisher executor
345
- /// @param amount Amount of tokens to bridge to external chain
346
- /// @param signature ECDSA signature proving transaction authorization
414
+ executerCore(true, msg.sender, tokenAddress, priorityFee);
415
+ }
416
+
417
+ /**
418
+ * @notice Executes Fisher bridge withdrawal to external
419
+ * @dev Validates signature, deducts Evvm balance, emits
420
+ *
421
+ * Purpose:
422
+ * - Withdraw: Deduct Evvm balance for bridging
423
+ * - Validate: ECDSA signature via Core.sol
424
+ * - Fee: Pay Fisher executor from sender balance
425
+ * - Emit: Log for Fisher to process on external
426
+ *
427
+ * Fisher Bridge Flow:
428
+ * - Host: User signs intent + executor calls this
429
+ * - Validate: State.validateAndConsumeNonce
430
+ * - Deduct: Evvm removes amount + priorityFee
431
+ * - Fee: Executor compensated from user balance
432
+ * - Emit: FisherBridgeSend event
433
+ * - External: Fisher processes + sends tokens
434
+ *
435
+ * Core.sol Integration:
436
+ * - Nonce: state.validateAndConsumeNonce
437
+ * - Hash: TreasuryCrossChainHashUtils.hashData...
438
+ * - Async: true (Fisher bridge nonces)
439
+ * - Signature: ECDSA validation via Core.sol
440
+ *
441
+ * Evvm Balance Operations:
442
+ * - Validate: core.getBalance(from, token) >=
443
+ * amount
444
+ * - Deduct: evvm.removeAmountFromUser(from, token,
445
+ * amount+fee)
446
+ * - Credit Fee: evvm.addAmountToUser(executor,
447
+ * token, fee)
448
+ * - Principal: MATE cannot be withdrawn
449
+ *
450
+ * External Chain Processing:
451
+ * - Monitor: Fisher watches FisherBridgeSend event
452
+ * - Action: Fisher calls external station functions
453
+ * - Transfer: Tokens sent from external contract
454
+ * - Recipient: addressToReceive gets tokens
455
+ *
456
+ * Security:
457
+ * - MATE Block: Principal token cannot withdraw
458
+ * - Balance Check: Revert if insufficient Evvm
459
+ * - Signature: Core.sol validates ECDSA
460
+ * - Nonce: Core.sol prevents replays
461
+ * - Executor Only: onlyFisherExecutor modifier
462
+ *
463
+ * @param from Sender (signer) on host chain
464
+ * @param addressToReceive Recipient on external chain
465
+ * @param tokenAddress Token (NOT principal token)
466
+ * @param priorityFee Fee for Fisher executor
467
+ * @param amount Token amount to bridge
468
+ * @param nonce Sequential nonce from user
469
+ * @param signature ECDSA signature from 'from'
470
+ */
347
471
  function fisherBridgeSend(
348
472
  address from,
349
473
  address addressToReceive,
350
474
  address tokenAddress,
351
475
  uint256 priorityFee,
352
476
  uint256 amount,
477
+ uint256 nonce,
353
478
  bytes memory signature
354
479
  ) external onlyFisherExecutor {
355
- if (tokenAddress == evvm.getEvvmMetadata().principalTokenAddress)
356
- revert ErrorsLib.PrincipalTokenIsNotWithdrawable();
480
+ if (tokenAddress == core.getEvvmMetadata().principalTokenAddress)
481
+ revert Error.PrincipalTokenIsNotWithdrawable();
357
482
 
358
- if (evvm.getBalance(from, tokenAddress) < amount)
359
- revert ErrorsLib.InsufficientBalance();
483
+ if (core.getBalance(from, tokenAddress) < amount)
484
+ revert Error.InsufficientBalance();
360
485
 
361
- if (
362
- !SignatureUtils.verifyMessageSignedForFisherBridge(
363
- evvm.getEvvmID(),
364
- from,
486
+ core.validateAndConsumeNonce(
487
+ from,
488
+ Hash.hashDataForFisherBridge(
365
489
  addressToReceive,
366
- nextFisherExecutionNonce[from],
367
490
  tokenAddress,
368
491
  priorityFee,
369
- amount,
370
- signature
371
- )
372
- ) revert ErrorsLib.InvalidSignature();
373
-
374
- nextFisherExecutionNonce[from]++;
492
+ amount
493
+ ),
494
+ fisherExecutor.current,
495
+ nonce,
496
+ true,
497
+ signature
498
+ );
375
499
 
376
- executerEVVM(false, from, tokenAddress, amount + priorityFee);
500
+ executerCore(false, from, tokenAddress, amount + priorityFee);
377
501
 
378
502
  if (priorityFee > 0)
379
- executerEVVM(true, msg.sender, tokenAddress, priorityFee);
503
+ executerCore(true, msg.sender, tokenAddress, priorityFee);
380
504
 
381
505
  emit FisherBridgeSend(
382
506
  from,
@@ -384,7 +508,7 @@ contract TreasuryHostChainStation is
384
508
  tokenAddress,
385
509
  priorityFee,
386
510
  amount,
387
- nextFisherExecutionNonce[from] - 1
511
+ nonce
388
512
  );
389
513
  }
390
514
 
@@ -409,24 +533,60 @@ contract TreasuryHostChainStation is
409
533
  );
410
534
  }
411
535
 
412
- /// @notice Handles incoming Hyperlane messages from the external chain
413
- /// @dev Validates origin, sender authorization, and processes deposit to EVVM
414
- /// @param _origin Source chain domain ID where the message originated
415
- /// @param _sender Address of the message sender (must be external chain station)
416
- /// @param _data Encoded payload containing deposit instructions
536
+ /**
537
+ * @notice Handles incoming Hyperlane messages
538
+ * @dev Validates origin, sender, credits Evvm balance
539
+ *
540
+ * Purpose:
541
+ * - Receive: Messages from external via Hyperlane
542
+ * - Validate: Origin domain + sender address
543
+ * - Process: Decode payload + credit Evvm balance
544
+ * - Security: Multi-layer validation checks
545
+ *
546
+ * Hyperlane Message Flow:
547
+ * - External: TreasuryExternalChainStation.dispatch
548
+ * - Relayer: Submits message to host chain
549
+ * - Mailbox: Calls this handle() function
550
+ * - Process: decodeAndDeposit credits Evvm
551
+ *
552
+ * Validation Layers:
553
+ * - Caller: Must be hyperlane.mailboxAddress
554
+ * - Sender: Must be hyperlane.externalChain
555
+ * StationAddress
556
+ * - Origin: Must be hyperlane.externalChain
557
+ * StationDomainId
558
+ * - All checks prevent unauthorized deposits
559
+ *
560
+ * Evvm Integration:
561
+ * - Decode: PayloadUtils.decodePayload(_data)
562
+ * - Extract: token address, recipient, amount
563
+ * - Credit: evvm.addAmountToUser(recipient, token,
564
+ * amt)
565
+ * - Balance: Virtual balance in Core.sol
566
+ *
567
+ * Security:
568
+ * - Mailbox Only: Reverts if caller not mailbox
569
+ * - Sender Check: Reverts if not external station
570
+ * - Domain Check: Reverts if wrong origin
571
+ * - Three-layer validation prevents attacks
572
+ *
573
+ * @param _origin Source chain domain ID
574
+ * @param _sender Sender address (external station)
575
+ * @param _data Encoded payload (token, to, amount)
576
+ */
417
577
  function handle(
418
578
  uint32 _origin,
419
579
  bytes32 _sender,
420
580
  bytes calldata _data
421
581
  ) external payable virtual {
422
582
  if (msg.sender != hyperlane.mailboxAddress)
423
- revert ErrorsLib.MailboxNotAuthorized();
583
+ revert Error.MailboxNotAuthorized();
424
584
 
425
585
  if (_sender != hyperlane.externalChainStationAddress)
426
- revert ErrorsLib.SenderNotAuthorized();
586
+ revert Error.SenderNotAuthorized();
427
587
 
428
588
  if (_origin != hyperlane.externalChainStationDomainId)
429
- revert ErrorsLib.ChainIdNotAuthorized();
589
+ revert Error.ChainIdNotAuthorized();
430
590
 
431
591
  decodeAndDeposit(_data);
432
592
  }
@@ -453,10 +613,47 @@ contract TreasuryHostChainStation is
453
613
  return fee.nativeFee;
454
614
  }
455
615
 
456
- /// @notice Handles incoming LayerZero messages from the external chain
457
- /// @dev Validates origin chain and sender, then processes deposit to EVVM
458
- /// @param _origin Origin information containing source endpoint ID and sender
459
- /// @param message Encoded payload containing deposit instructions
616
+ /**
617
+ * @notice Handles incoming LayerZero messages
618
+ * @dev Validates origin + sender, credits Evvm balance
619
+ *
620
+ * Purpose:
621
+ * - Receive: Messages from external via LayerZero V2
622
+ * - Validate: Origin eid + sender address
623
+ * - Process: Decode payload + credit Evvm balance
624
+ * - Security: Multi-layer validation checks
625
+ *
626
+ * LayerZero Message Flow:
627
+ * - External: TreasuryExternalChainStation._lzSend
628
+ * - DVNs: Verify message across networks
629
+ * - Executor: Submits message to host chain
630
+ * - Endpoint: Calls this _lzReceive function
631
+ *
632
+ * Validation Layers:
633
+ * - Origin EID: Must be layerZero.externalChain
634
+ * StationEid
635
+ * - Sender: Must be layerZero.externalChain
636
+ * StationAddress
637
+ * - Peer: OApp validates via _getPeerOrRevert
638
+ * - All checks prevent unauthorized deposits
639
+ *
640
+ * Evvm Integration:
641
+ * - Decode: PayloadUtils.decodePayload(message)
642
+ * - Extract: token address, recipient, amount
643
+ * - Credit: evvm.addAmountToUser(recipient, token,
644
+ * amt)
645
+ * - Balance: Virtual balance in Core.sol
646
+ *
647
+ * Security:
648
+ * - EID Check: Reverts if wrong source endpoint
649
+ * - Sender Check: Reverts if not external station
650
+ * - OApp Pattern: Peer validation built-in
651
+ * - Two-layer validation prevents attacks
652
+ *
653
+ * @param _origin Origin info (srcEid, sender,
654
+ * nonce)
655
+ * @param message Encoded payload (token, to, amount)
656
+ */
460
657
  function _lzReceive(
461
658
  Origin calldata _origin,
462
659
  bytes32 /*_guid*/,
@@ -466,10 +663,10 @@ contract TreasuryHostChainStation is
466
663
  ) internal override {
467
664
  // Decode the payload to get the message
468
665
  if (_origin.srcEid != layerZero.externalChainStationEid)
469
- revert ErrorsLib.ChainIdNotAuthorized();
666
+ revert Error.ChainIdNotAuthorized();
470
667
 
471
668
  if (_origin.sender != layerZero.externalChainStationAddress)
472
- revert ErrorsLib.SenderNotAuthorized();
669
+ revert Error.SenderNotAuthorized();
473
670
 
474
671
  decodeAndDeposit(message);
475
672
  }
@@ -509,11 +706,54 @@ contract TreasuryHostChainStation is
509
706
 
510
707
  // Axelar Specific Functions //
511
708
 
512
- /// @notice Handles incoming Axelar messages from the external chain
513
- /// @dev Validates source chain and address, then processes deposit to EVVM
514
- /// @param _sourceChain Source blockchain name (must match configured external chain)
515
- /// @param _sourceAddress Source contract address (must match external chain station)
516
- /// @param _payload Encoded payload containing deposit instructions
709
+ /**
710
+ * @notice Handles incoming Axelar messages
711
+ * @dev Validates source chain/address, credits Evvm
712
+ *
713
+ * Purpose:
714
+ * - Receive: Messages from external via Axelar
715
+ * - Validate: Source chain name + sender address
716
+ * - Process: Decode payload + credit Evvm balance
717
+ * - Security: Multi-layer validation checks
718
+ *
719
+ * Axelar Message Flow:
720
+ * - External: TreasuryExternalChainStation.
721
+ * callContract
722
+ * - Axelar: Validates via validator network
723
+ * - Gateway: Calls this _execute function
724
+ * - Process: decodeAndDeposit credits Evvm
725
+ *
726
+ * Validation Layers:
727
+ * - Source Chain: Must be axelar.externalChain
728
+ * StationChainName
729
+ * - Source Address: Must be axelar.externalChain
730
+ * StationAddress
731
+ * - Gateway: AxelarExecutable validates caller
732
+ * - All checks prevent unauthorized deposits
733
+ *
734
+ * String Comparison:
735
+ * - AdvancedStrings.equal: Chain name validation
736
+ * - Case-Sensitive: Exact match required
737
+ * - Address Format: String type for Axelar
738
+ * - Security: Double validation of source
739
+ *
740
+ * Evvm Integration:
741
+ * - Decode: PayloadUtils.decodePayload(_payload)
742
+ * - Extract: token address, recipient, amount
743
+ * - Credit: evvm.addAmountToUser(recipient, token,
744
+ * amt)
745
+ * - Balance: Virtual balance in Core.sol
746
+ *
747
+ * Security:
748
+ * - Chain Check: Reverts if wrong source chain
749
+ * - Address Check: Reverts if not external station
750
+ * - Gateway Pattern: AxelarExecutable validation
751
+ * - Two-layer validation prevents attacks
752
+ *
753
+ * @param _sourceChain Source blockchain name
754
+ * @param _sourceAddress Source contract address
755
+ * @param _payload Encoded payload (token, to, amount)
756
+ */
517
757
  function _execute(
518
758
  bytes32 /*commandId*/,
519
759
  string calldata _sourceChain,
@@ -525,14 +765,14 @@ contract TreasuryHostChainStation is
525
765
  _sourceChain,
526
766
  axelar.externalChainStationChainName
527
767
  )
528
- ) revert ErrorsLib.ChainIdNotAuthorized();
768
+ ) revert Error.ChainIdNotAuthorized();
529
769
 
530
770
  if (
531
771
  !AdvancedStrings.equal(
532
772
  _sourceAddress,
533
773
  axelar.externalChainStationAddress
534
774
  )
535
- ) revert ErrorsLib.SenderNotAuthorized();
775
+ ) revert Error.SenderNotAuthorized();
536
776
 
537
777
  decodeAndDeposit(_payload);
538
778
  }
@@ -614,21 +854,23 @@ contract TreasuryHostChainStation is
614
854
  ) external onlyAdmin {
615
855
  if (fuseSetExternalChainAddress == 0x01) revert();
616
856
 
617
- externalChainAddressChangeProposal = ChangeExternalChainAddressParams({
618
- porposeAddress_AddressType: externalChainStationAddress,
619
- porposeAddress_StringType: externalChainStationAddressString,
620
- timeToAccept: block.timestamp + 1 minutes
621
- });
857
+ externalChainAddressChangeProposal = Structs
858
+ .ChangeExternalChainAddressParams({
859
+ porposeAddress_AddressType: externalChainStationAddress,
860
+ porposeAddress_StringType: externalChainStationAddressString,
861
+ timeToAccept: block.timestamp + 1 minutes
862
+ });
622
863
  }
623
864
 
624
865
  /// @notice Cancels a pending external chain address change proposal
625
866
  /// @dev Resets the external chain address proposal to default state
626
867
  function rejectProposalExternalChainAddress() external onlyAdmin {
627
- externalChainAddressChangeProposal = ChangeExternalChainAddressParams({
628
- porposeAddress_AddressType: address(0),
629
- porposeAddress_StringType: "",
630
- timeToAccept: 0
631
- });
868
+ externalChainAddressChangeProposal = Structs
869
+ .ChangeExternalChainAddressParams({
870
+ porposeAddress_AddressType: address(0),
871
+ porposeAddress_StringType: "",
872
+ timeToAccept: 0
873
+ });
632
874
  }
633
875
 
634
876
  /// @notice Accepts pending external chain address changes across all protocols
@@ -665,7 +907,11 @@ contract TreasuryHostChainStation is
665
907
 
666
908
  /// @notice Returns the complete admin configuration including proposals and timelock
667
909
  /// @return Current admin address, proposed admin, and acceptance timestamp
668
- function getAdmin() external view returns (AddressTypeProposal memory) {
910
+ function getAdmin()
911
+ external
912
+ view
913
+ returns (ProposalStructs.AddressTypeProposal memory)
914
+ {
669
915
  return admin;
670
916
  }
671
917
 
@@ -674,7 +920,7 @@ contract TreasuryHostChainStation is
674
920
  function getFisherExecutor()
675
921
  external
676
922
  view
677
- returns (AddressTypeProposal memory)
923
+ returns (ProposalStructs.AddressTypeProposal memory)
678
924
  {
679
925
  return fisherExecutor;
680
926
  }
@@ -683,16 +929,17 @@ contract TreasuryHostChainStation is
683
929
  /// @dev Used to prevent replay attacks in cross-chain bridge transactions
684
930
  /// @param user Address to query the next Fisher execution nonce for
685
931
  /// @return Next sequential nonce value for the user's Fisher bridge operations
686
- function getNextFisherExecutionNonce(
687
- address user
688
- ) external view returns (uint256) {
689
- return nextFisherExecutionNonce[user];
932
+ function getIfUsedAsyncNonce(
933
+ address user,
934
+ uint256 nonce
935
+ ) external view returns (bool) {
936
+ return core.getIfUsedAsyncNonce(user, nonce);
690
937
  }
691
938
 
692
939
  /// @notice Returns the EVVM core contract address
693
940
  /// @return Address of the EVVM contract used for balance operations
694
- function getEvvmAddress() external view returns (address) {
695
- return address(evvm);
941
+ function getCoreAddress() external view returns (address) {
942
+ return address(core);
696
943
  }
697
944
 
698
945
  /// @notice Returns the complete Hyperlane protocol configuration
@@ -700,7 +947,7 @@ contract TreasuryHostChainStation is
700
947
  function getHyperlaneConfig()
701
948
  external
702
949
  view
703
- returns (HyperlaneConfig memory)
950
+ returns (Structs.HyperlaneConfig memory)
704
951
  {
705
952
  return hyperlane;
706
953
  }
@@ -710,14 +957,18 @@ contract TreasuryHostChainStation is
710
957
  function getLayerZeroConfig()
711
958
  external
712
959
  view
713
- returns (LayerZeroConfig memory)
960
+ returns (Structs.LayerZeroConfig memory)
714
961
  {
715
962
  return layerZero;
716
963
  }
717
964
 
718
965
  /// @notice Returns the complete Axelar protocol configuration
719
966
  /// @return Axelar configuration including chain name, addresses, gas service, and gateway
720
- function getAxelarConfig() external view returns (AxelarConfig memory) {
967
+ function getAxelarConfig()
968
+ external
969
+ view
970
+ returns (Structs.AxelarConfig memory)
971
+ {
721
972
  return axelar;
722
973
  }
723
974
 
@@ -735,7 +986,7 @@ contract TreasuryHostChainStation is
735
986
  function decodeAndDeposit(bytes memory payload) internal {
736
987
  (address token, address from, uint256 amount) = PayloadUtils
737
988
  .decodePayload(payload);
738
- executerEVVM(true, from, token, amount);
989
+ executerCore(true, from, token, amount);
739
990
  }
740
991
 
741
992
  /// @notice Executes EVVM balance operations (add or remove)
@@ -744,7 +995,7 @@ contract TreasuryHostChainStation is
744
995
  /// @param userToExecute Address whose balance will be modified
745
996
  /// @param token Token contract address for the balance operation
746
997
  /// @param amount Amount to add or remove from the user's balance
747
- function executerEVVM(
998
+ function executerCore(
748
999
  bool typeOfExecution,
749
1000
  address userToExecute,
750
1001
  address token,
@@ -752,10 +1003,10 @@ contract TreasuryHostChainStation is
752
1003
  ) internal {
753
1004
  if (typeOfExecution) {
754
1005
  // true = add
755
- evvm.addAmountToUser(userToExecute, token, amount);
1006
+ core.addAmountToUser(userToExecute, token, amount);
756
1007
  } else {
757
1008
  // false = remove
758
- evvm.removeAmountFromUser(userToExecute, token, amount);
1009
+ core.removeAmountFromUser(userToExecute, token, amount);
759
1010
  }
760
1011
  }
761
1012