@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
@@ -0,0 +1,92 @@
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
+ /**
7
+ * @title External Chain Station Data Structures
8
+ * @author Mate labs
9
+ * @notice Data structures for external to host chain bridge
10
+ * @dev Structures for TreasuryExternalChainStation: multi-protocol messaging (Hyperlane, LayerZero, Axelar). Independent from Core.sol (Fisher bridge has own nonces).
11
+ */
12
+ library ExternalChainStationStructs {
13
+ /**
14
+ * @notice Time-delayed address proposal for governance
15
+ * @dev 1-day delay for admin/fisherExecutor changes. Only proposal address can accept.
16
+ * @param current Currently active address
17
+ * @param proposal Proposed new address (1 day delay)
18
+ * @param timeToAccept Timestamp when acceptable
19
+ */
20
+ struct AddressTypeProposal {
21
+ address current;
22
+ address proposal;
23
+ uint256 timeToAccept;
24
+ }
25
+
26
+ /**
27
+ * @notice Hyperlane protocol configuration
28
+ * @dev Hyperlane cross-chain messaging: domain ID + mailbox. External → Host via mailbox.dispatch.
29
+ * @param hostChainStationDomainId Hyperlane domain for host
30
+ * @param hostChainStationAddress Host station (bytes32)
31
+ * @param mailboxAddress Hyperlane mailbox on this chain
32
+ */
33
+ struct HyperlaneConfig {
34
+ uint32 hostChainStationDomainId;
35
+ bytes32 hostChainStationAddress;
36
+ address mailboxAddress;
37
+ }
38
+
39
+ /**
40
+ * @notice LayerZero V2 protocol configuration
41
+ * @dev LayerZero V2 omnichain: eid + endpoint. External → Host via endpoint.send. Gas limit 200k.
42
+ * @param hostChainStationEid LayerZero eid for host chain
43
+ * @param hostChainStationAddress Host station (bytes32)
44
+ * @param endpointAddress LayerZero V2 endpoint address
45
+ */
46
+ struct LayerZeroConfig {
47
+ uint32 hostChainStationEid;
48
+ bytes32 hostChainStationAddress;
49
+ address endpointAddress;
50
+ }
51
+
52
+ /**
53
+ * @notice Axelar protocol configuration
54
+ * @dev Axelar cross-chain: chainName + gateway. External → Host via gateway.callContract.
55
+ * @param hostChainStationChainName Axelar chain name
56
+ * @param hostChainStationAddress Host station (string)
57
+ * @param gasServiceAddress Axelar gas service
58
+ * @param gatewayAddress Axelar gateway contract
59
+ */
60
+ struct AxelarConfig {
61
+ string hostChainStationChainName;
62
+ string hostChainStationAddress;
63
+ address gasServiceAddress;
64
+ address gatewayAddress;
65
+ }
66
+
67
+ /**
68
+ * @notice Unified deployment configuration
69
+ * @dev Groups all protocol configs: Hyperlane, LayerZero V2, Axelar.
70
+ */
71
+ struct CrosschainConfig {
72
+ HyperlaneConfig hyperlane;
73
+ LayerZeroConfig layerZero;
74
+ AxelarConfig axelar;
75
+ }
76
+
77
+ /**
78
+ * @notice Coordinated host chain address change proposal
79
+ * @dev 1-day delay to update host station across all protocols. AddressType for Hyperlane/LZ, StringType for Axelar.
80
+ * @param porposeAddress_AddressType Address for Hyperlane/LZ
81
+ * @param porposeAddress_StringType String for Axelar
82
+ * @param currentAddress Current host station address
83
+ * @param timeToAccept Timestamp when acceptable
84
+ */
85
+ struct ChangeHostChainAddressParams {
86
+ address porposeAddress_AddressType;
87
+ string porposeAddress_StringType;
88
+ address currentAddress;
89
+ uint256 timeToAccept;
90
+ }
91
+ }
92
+
@@ -0,0 +1,77 @@
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
+ /**
7
+ * @title Host Chain Station Data Structures
8
+ * @author Mate labs
9
+ * @notice Data structures for host to external chain bridge
10
+ * @dev Structures for TreasuryHostChainStation: multi-protocol messaging (Hyperlane, LayerZero, Axelar). Core.sol balance management on host only. Fisher bridge uses Core.sol nonces.
11
+ */
12
+
13
+ library HostChainStationStructs {
14
+ /**
15
+ * @notice Hyperlane protocol configuration
16
+ * @dev Hyperlane cross-chain messaging: domain ID + mailbox. Host → External via mailbox.dispatch.
17
+ * @param externalChainStationDomainId Hyperlane domain for external
18
+ * @param externalChainStationAddress External station (bytes32)
19
+ * @param mailboxAddress Hyperlane mailbox on host chain
20
+ */
21
+ struct HyperlaneConfig {
22
+ uint32 externalChainStationDomainId;
23
+ bytes32 externalChainStationAddress;
24
+ address mailboxAddress;
25
+ }
26
+
27
+ /**
28
+ * @notice LayerZero V2 protocol configuration
29
+ * @dev LayerZero V2 omnichain: eid + endpoint. Host → External via endpoint.send. Gas limit 200k.
30
+ * @param externalChainStationEid LayerZero eid for external chain
31
+ * @param externalChainStationAddress External station (bytes32)
32
+ * @param endpointAddress LayerZero V2 endpoint address
33
+ */
34
+ struct LayerZeroConfig {
35
+ uint32 externalChainStationEid;
36
+ bytes32 externalChainStationAddress;
37
+ address endpointAddress;
38
+ }
39
+
40
+ /**
41
+ * @notice Axelar protocol configuration
42
+ * @dev Axelar cross-chain: chainName + gateway. Host → External via gateway.callContract.
43
+ * @param externalChainStationChainName Axelar chain name
44
+ * @param externalChainStationAddress External station (string)
45
+ * @param gasServiceAddress Axelar gas service
46
+ * @param gatewayAddress Axelar gateway contract
47
+ */
48
+ struct AxelarConfig {
49
+ string externalChainStationChainName;
50
+ string externalChainStationAddress;
51
+ address gasServiceAddress;
52
+ address gatewayAddress;
53
+ }
54
+
55
+ /**
56
+ * @notice Unified deployment configuration
57
+ * @dev Groups all protocol configs: Hyperlane, LayerZero V2, Axelar.
58
+ */
59
+ struct CrosschainConfig {
60
+ HyperlaneConfig hyperlane;
61
+ LayerZeroConfig layerZero;
62
+ AxelarConfig axelar;
63
+ }
64
+
65
+ /**
66
+ * @notice Coordinated external chain address change proposal
67
+ * @dev 1-day delay to update external station across all protocols. AddressType for Hyperlane/LZ, StringType for Axelar.
68
+ * @param porposeAddress_AddressType Address for Hyperlane/LZ
69
+ * @param porposeAddress_StringType String for Axelar
70
+ * @param timeToAccept Timestamp when acceptable
71
+ */
72
+ struct ChangeExternalChainAddressParams {
73
+ address porposeAddress_AddressType;
74
+ string porposeAddress_StringType;
75
+ uint256 timeToAccept;
76
+ }
77
+ }
@@ -0,0 +1,47 @@
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
+ /**
7
+ * @title NameServiceStructs
8
+ * @author Mate labs
9
+ * @notice Data structures for NameService.sol (identity, marketplace, governance)
10
+ * @dev Identity and marketplace structures. Nonce validation and payment processing via Core.sol.
11
+ */
12
+ library NameServiceStructs {
13
+
14
+ //░▒▓█ Identity Management Structures ███████████████████████████████████████████████▓▒░
15
+
16
+ /**
17
+ * @notice Core metadata for registered identity/username
18
+ * @dev Registration states: flagNotAUsername (0x01=pre-reg, 0x00=active). Renewable up to 100 years. Cost: 100x EVVM reward.
19
+ * @param owner Owner address
20
+ * @param expirationDate Registration expiry timestamp
21
+ * @param customMetadataMaxSlots Metadata entry count
22
+ * @param offerMaxSlots Highest offer ID
23
+ * @param flagNotAUsername Registration state flag
24
+ */
25
+ struct IdentityBaseMetadata {
26
+ address owner;
27
+ uint256 expirationDate;
28
+ uint256 customMetadataMaxSlots;
29
+ uint256 offerMaxSlots;
30
+ bytes1 flagNotAUsername;
31
+ }
32
+
33
+ //░▒▓█ Marketplace Structures ███████████████████████████████████████████████████████▓▒░
34
+
35
+ /**
36
+ * @notice Metadata for marketplace offers on usernames
37
+ * @dev Lifecycle: Created (locked PT with 0.5% fee) → Active (can be accepted/withdrawn) → Completed (offerer = address(0)).
38
+ * @param offerer Offer creator (can withdraw)
39
+ * @param expirationDate Offer expiry timestamp
40
+ * @param amount PT offered (after 0.5% fee)
41
+ */
42
+ struct OfferMetadata {
43
+ address offerer;
44
+ uint256 expirationDate;
45
+ uint256 amount;
46
+ }
47
+ }
@@ -0,0 +1,127 @@
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
+ /**
7
+ * @title P2P Swap Data Structures
8
+ * @author Mate labs
9
+ * @notice Core data structures for P2PSwap.sol order book (markets, orders, fees, operation metadata)
10
+ * @dev All operations validated via Core.sol async nonces. Payments via Core.sol.
11
+ */
12
+
13
+ abstract contract P2PSwapStructs {
14
+ /**
15
+ * @notice Market metadata for token pair trading
16
+ * @dev Tracks order slot allocation and active order count.
17
+ * @param tokenA First token in pair
18
+ * @param tokenB Second token in pair
19
+ * @param maxSlot Highest slot number assigned
20
+ * @param ordersAvailable Active order count
21
+ */
22
+ struct MarketInformation {
23
+ address tokenA;
24
+ address tokenB;
25
+ uint256 maxSlot;
26
+ uint256 ordersAvailable;
27
+ }
28
+
29
+ /**
30
+ * @notice Core order data stored on-chain
31
+ * @dev Minimal storage for gas efficiency. Token addresses inferred from market ID. Deleted orders: seller = address(0).
32
+ * @param seller Order creator
33
+ * @param amountA Amount of tokenA offered
34
+ * @param amountB Amount of tokenB requested
35
+ */
36
+ struct Order {
37
+ address seller;
38
+ uint256 amountA;
39
+ uint256 amountB;
40
+ }
41
+
42
+ /**
43
+ * @notice Extended order data for view functions
44
+ * @dev Includes market and order IDs for UI display.
45
+ * @param marketId Market containing order
46
+ * @param orderId Order slot ID
47
+ * @param seller Order creator
48
+ * @param amountA Amount of tokenA offered
49
+ * @param amountB Amount of tokenB requested
50
+ */
51
+ struct OrderForGetter {
52
+ uint256 marketId;
53
+ uint256 orderId;
54
+ address seller;
55
+ uint256 amountA;
56
+ uint256 amountB;
57
+ }
58
+
59
+ /**
60
+ * @notice Fee distribution percentages for trades (basis points)
61
+ * @dev Total must equal 10,000 (100.00%). Adjustable via time-delayed governance.
62
+ * @param seller Basis points to order seller
63
+ * @param service Basis points to P2PSwap service
64
+ * @param mateStaker Basis points to staker
65
+ */
66
+ struct Percentage {
67
+ uint256 seller;
68
+ uint256 service;
69
+ uint256 mateStaker;
70
+ }
71
+
72
+ /**
73
+ * @notice Metadata for makeOrder operation signature
74
+ * @dev Hashed via P2PSwapHashUtils. Validated via Core.sol with async nonce.
75
+ * @param nonce Async nonce
76
+ * @param tokenA Token offered
77
+ * @param tokenB Token requested
78
+ * @param amountA Amount offered
79
+ * @param amountB Amount requested
80
+ */
81
+ struct MetadataMakeOrder {
82
+ uint256 nonce;
83
+ address originExecutor;
84
+ address tokenA;
85
+ address tokenB;
86
+ uint256 amountA;
87
+ uint256 amountB;
88
+ }
89
+
90
+ /**
91
+ * @notice Metadata for cancelOrder operation signature
92
+ * @dev Hashed via P2PSwapHashUtils. Only order owner can cancel. Async nonce.
93
+ * @param nonce Async nonce
94
+ * @param tokenA Token A in pair
95
+ * @param tokenB Token B in pair
96
+ * @param orderId Order ID to cancel
97
+ * @param signature EIP-191 signature from seller
98
+ */
99
+ struct MetadataCancelOrder {
100
+ uint256 nonce;
101
+ address originExecutor;
102
+ address tokenA;
103
+ address tokenB;
104
+ uint256 orderId;
105
+ bytes signature;
106
+ }
107
+
108
+ /**
109
+ * @notice Metadata for dispatchOrder operation signature
110
+ * @dev Hashed via P2PSwapHashUtils. Used by both proportional and fixed fee variants. Async nonce.
111
+ * @param nonce Async nonce
112
+ * @param tokenA Token A in pair
113
+ * @param tokenB Token B in pair
114
+ * @param orderId Order ID to fill
115
+ * @param amountOfTokenBToFill Total tokenB including fees
116
+ * @param signature EIP-191 signature from buyer
117
+ */
118
+ struct MetadataDispatchOrder {
119
+ uint256 nonce;
120
+ address originExecutor;
121
+ address tokenA;
122
+ address tokenB;
123
+ uint256 orderId;
124
+ uint256 amountOfTokenBToFill;
125
+ bytes signature;
126
+ }
127
+ }
@@ -0,0 +1,67 @@
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
+ * @title Staking Data Structures
7
+ * @author Mate Labs
8
+ * @notice Core data structures for Staking.sol (presale, history, service staking)
9
+ * @dev Operations validated and payments processed via Core.sol. Cost: PRICE_OF_STAKING (5083 PT) per token.
10
+ */
11
+
12
+ library StakingStructs {
13
+ /**
14
+ * @notice Metadata for presale staker whitelist
15
+ * @dev Max 800 presale stakers globally. Each limited to 2 staking tokens.
16
+ * @param isAllow Presale whitelist status
17
+ * @param stakingAmount Current staking tokens staked (max 2)
18
+ */
19
+ struct PresaleStakerMetadata {
20
+ bool isAllow;
21
+ uint256 stakingAmount;
22
+ }
23
+
24
+ /**
25
+ * @notice Historical record of staking transactions
26
+ * @dev Transaction types: 0x01=staking, 0x02=unstaking, others=yield/rewards.
27
+ * @param transactionType Operation type identifier
28
+ * @param amount Staking tokens affected
29
+ * @param timestamp Block timestamp
30
+ * @param totalStaked Total after operation
31
+ */
32
+ struct HistoryMetadata {
33
+ bytes32 transactionType;
34
+ uint256 amount;
35
+ uint256 timestamp;
36
+ uint256 totalStaked;
37
+ }
38
+
39
+ /**
40
+ * @notice Temporary metadata for service staking process
41
+ * @dev Atomic 3-step process: prepareServiceStaking → Evvm.caPay → confirmServiceStaking. All steps MUST occur in same tx.
42
+ * @param service Contract performing staking
43
+ * @param timestamp Block timestamp of prepare
44
+ * @param amountOfStaking Staking tokens to acquire
45
+ * @param amountServiceBeforeStaking Service PT balance before
46
+ * @param amountStakingBeforeStaking Staking PT balance before
47
+ */
48
+ struct ServiceStakingMetadata {
49
+ address service;
50
+ uint256 timestamp;
51
+ uint256 amountOfStaking;
52
+ uint256 amountServiceBeforeStaking;
53
+ uint256 amountStakingBeforeStaking;
54
+ }
55
+
56
+ /**
57
+ * @notice Account metadata with service/EOA indicator
58
+ * @dev IsAService: true if code size > 0 (contract), false if code size == 0 (EOA).
59
+ * @param Address Account address
60
+ * @param IsAService Contract flag
61
+ */
62
+ struct AccountMetadata {
63
+ address Address;
64
+ bool IsAService;
65
+ }
66
+
67
+ }
@@ -5,20 +5,8 @@ pragma solidity ^0.8.0;
5
5
  /**
6
6
  * @title AdvancedStrings
7
7
  * @author Mate Labs
8
- * @notice Library for advanced string manipulation and type conversions
9
- * @dev Provides utility functions for converting various Solidity types to their string
10
- * representations. These functions are essential for building EIP-191 signature messages
11
- * in the EVVM ecosystem.
12
- *
13
- * Key Features:
14
- * - Unsigned integer to string conversion
15
- * - Address to hexadecimal string conversion
16
- * - Bytes and bytes32 to hexadecimal string conversion
17
- * - Boolean to string conversion
18
- * - String equality comparison
19
- *
20
- * All hexadecimal outputs use lowercase letters and include the "0x" prefix where applicable.
21
- * This library can be used by community-developed services for message construction.
8
+ * @notice Type conversion library for EIP-191 signature payload construction
9
+ * @dev Converts uint256, address, bytes, bytes32, bool to strings. Hexadecimal output uses lowercase with "0x" prefix.
22
10
  */
23
11
 
24
12
  import {Math} from "@evvm/testnet-contracts/library/primitives/Math.sol";
@@ -28,10 +16,10 @@ library AdvancedStrings {
28
16
  bytes16 private constant HEX_DIGITS = "0123456789abcdef";
29
17
 
30
18
  /**
31
- * @notice Converts an unsigned integer to its decimal string representation
32
- * @dev Uses assembly for gas-efficient string construction. Works for any uint256 value.
33
- * @param value The unsigned integer to convert
34
- * @return The decimal string representation of the value
19
+ * @notice Converts uint256 to decimal string
20
+ * @dev Uses assembly for gas-efficient construction
21
+ * @param value Unsigned integer to convert
22
+ * @return Decimal string representation
35
23
  */
36
24
  function uintToString(uint256 value) internal pure returns (string memory) {
37
25
  unchecked {
@@ -56,10 +44,9 @@ library AdvancedStrings {
56
44
  }
57
45
 
58
46
  /**
59
- * @notice Converts an address to its hexadecimal string representation
60
- * @dev Returns a 42-character string including the "0x" prefix with lowercase hex digits
61
- * @param _address The address to convert
62
- * @return The hexadecimal string representation (e.g., "0x1234...abcd")
47
+ * @notice Converts address to hex string with "0x" prefix
48
+ * @param _address Address to convert
49
+ * @return 42-character lowercase hex string
63
50
  */
64
51
  function addressToString(
65
52
  address _address
@@ -77,10 +64,10 @@ library AdvancedStrings {
77
64
 
78
65
  /**
79
66
  * @notice Compares two strings for equality
80
- * @dev First compares lengths, then compares keccak256 hashes for efficiency
81
- * @param a First string to compare
82
- * @param b Second string to compare
83
- * @return True if both strings are identical, false otherwise
67
+ * @dev Compares lengths then keccak256 hashes
68
+ * @param a First string
69
+ * @param b Second string
70
+ * @return True if identical
84
71
  */
85
72
  function equal(
86
73
  string memory a,
@@ -92,11 +79,10 @@ library AdvancedStrings {
92
79
  }
93
80
 
94
81
  /**
95
- * @notice Converts a dynamic bytes array to its hexadecimal string representation
96
- * @dev Returns a string with "0x" prefix followed by lowercase hex digits.
97
- * Empty input returns "0x".
98
- * @param data The bytes array to convert
99
- * @return The hexadecimal string representation with "0x" prefix
82
+ * @notice Converts bytes array to hex string
83
+ * @dev Returns "0x" for empty input
84
+ * @param data Bytes array to convert
85
+ * @return Hex string with "0x" prefix
100
86
  */
101
87
  function bytesToString(
102
88
  bytes memory data
@@ -104,24 +90,23 @@ library AdvancedStrings {
104
90
  if (data.length == 0) {
105
91
  return "0x";
106
92
  }
107
-
93
+
108
94
  bytes memory result = new bytes(2 + data.length * 2);
109
95
  result[0] = "0";
110
96
  result[1] = "x";
111
-
97
+
112
98
  for (uint256 i = 0; i < data.length; i++) {
113
99
  result[2 + i * 2] = HEX_DIGITS[uint8(data[i] >> 4)];
114
100
  result[3 + i * 2] = HEX_DIGITS[uint8(data[i] & 0x0f)];
115
101
  }
116
-
102
+
117
103
  return string(result);
118
104
  }
119
105
 
120
106
  /**
121
- * @notice Converts a bytes32 value to its hexadecimal string representation
122
- * @dev Returns a 66-character string ("0x" + 64 hex characters) with lowercase letters
123
- * @param data The bytes32 value to convert
124
- * @return The hexadecimal string representation with "0x" prefix
107
+ * @notice Converts bytes32 to hex string
108
+ * @param data Bytes32 value to convert
109
+ * @return 66-character hex string with "0x" prefix
125
110
  */
126
111
  function bytes32ToString(
127
112
  bytes32 data
@@ -129,22 +114,55 @@ library AdvancedStrings {
129
114
  bytes memory result = new bytes(66);
130
115
  result[0] = "0";
131
116
  result[1] = "x";
132
-
117
+
133
118
  for (uint256 i = 0; i < 32; i++) {
134
119
  result[2 + i * 2] = HEX_DIGITS[uint8(data[i] >> 4)];
135
120
  result[3 + i * 2] = HEX_DIGITS[uint8(data[i] & 0x0f)];
136
121
  }
137
-
122
+
138
123
  return string(result);
139
124
  }
140
125
 
141
126
  /**
142
- * @notice Converts a boolean value to its string representation
143
- * @dev Returns "true" or "false" as lowercase strings
144
- * @param value The boolean value to convert
145
- * @return "true" if value is true, "false" otherwise
127
+ * @notice Converts boolean to string ("true"/"false")
128
+ * @param value Boolean to convert
129
+ * @return Lowercase string representation
146
130
  */
147
131
  function boolToString(bool value) internal pure returns (string memory) {
148
132
  return value ? "true" : "false";
149
133
  }
134
+
135
+ /**
136
+ * @notice Builds EIP-191 signature payload for Core.sol validation
137
+ * @dev Format: "{evvmId},{serviceAddress},{hashPayload},{nonce},{isAsyncExec}"
138
+ * @param evvmId Chain-specific EVVM instance identifier
139
+ * @param serviceAddress Service contract requesting validation
140
+ * @param hashPayload Function-specific parameter hash
141
+ * @param nonce Sequential or async nonce
142
+ * @param isAsyncExec Nonce type (true=async, false=sync)
143
+ * @return Comma-separated payload string for signature
144
+ */
145
+ function buildSignaturePayload(
146
+ uint256 evvmId,
147
+ address serviceAddress,
148
+ bytes32 hashPayload,
149
+ address executor,
150
+ uint256 nonce,
151
+ bool isAsyncExec
152
+ ) internal pure returns (string memory) {
153
+ return
154
+ string.concat(
155
+ uintToString(evvmId),
156
+ ",",
157
+ addressToString(serviceAddress),
158
+ ",",
159
+ bytes32ToString(hashPayload),
160
+ ",",
161
+ addressToString(executor),
162
+ ",",
163
+ uintToString(nonce),
164
+ ",",
165
+ boolToString(isAsyncExec)
166
+ );
167
+ }
150
168
  }
@@ -0,0 +1,29 @@
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
+ /**
7
+ * @title Contract Address Verification Utilities
8
+ * @author Mate labs
9
+ * @notice Utilities for detecting contract addresses vs EOAs
10
+ * @dev Uses extcodesize opcode. Returns false during contract construction and after self-destruct.
11
+ */
12
+ library CAUtils {
13
+ /**
14
+ * @notice Checks if address is a contract using extcodesize
15
+ * @dev Returns false during construction and after self-destruct. Not reliable as sole security check.
16
+ * @param from Address to check
17
+ * @return true if contract (codesize > 0), false if EOA
18
+ */
19
+ function verifyIfCA(address from) internal view returns (bool) {
20
+ uint256 size;
21
+
22
+ assembly {
23
+ /// @dev check the size of the opcode of the address
24
+ size := extcodesize(from)
25
+ }
26
+
27
+ return (size != 0);
28
+ }
29
+ }
@@ -0,0 +1,66 @@
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
+ import {
7
+ ProposalStructs
8
+ } from "@evvm/testnet-contracts/library/utils/governance/ProposalStructs.sol";
9
+
10
+ /**
11
+ * @title Admin Governance Base Contract
12
+ * @author Mate labs
13
+ * @notice Time-delayed admin governance with propose/accept pattern
14
+ * @dev Abstract base using ProposalStructs.AddressTypeProposal. Recommended delay: 1 day (86400s).
15
+ */
16
+ abstract contract Admin {
17
+ /**
18
+ * @notice Admin proposal with time-delayed acceptance
19
+ * @dev Stores current, proposed, and acceptance time
20
+ */
21
+ ProposalStructs.AddressTypeProposal public admin;
22
+
23
+ /// @dev Thrown when caller is not current admin
24
+ error SenderIsNotAdmin();
25
+ /// @dev Thrown when proposal acceptance attempted early
26
+ error ProposalNotReady();
27
+
28
+ /**
29
+ * @notice Restricts function access to current admin
30
+ */
31
+ modifier onlyAdmin() {
32
+ if (msg.sender != admin.current) revert SenderIsNotAdmin();
33
+ _;
34
+ }
35
+
36
+ /**
37
+ * @notice Initializes admin governance with initial admin address
38
+ * @dev Sets admin.current without time delay. Only called during construction.
39
+ * @param initialAdmin Address of first admin
40
+ */
41
+ constructor(address initialAdmin) {
42
+ admin.current = initialAdmin;
43
+ }
44
+
45
+ /**
46
+ * @notice Proposes new admin with custom time delay
47
+ * @dev Sets admin.proposal and admin.timeToAccept (block.timestamp + delay). Only current admin.
48
+ * @param newAdmin Proposed new admin address
49
+ * @param delay Seconds before acceptance allowed
50
+ */
51
+ function proposeAdmin(address newAdmin, uint256 delay) external onlyAdmin {
52
+ admin.proposal = newAdmin;
53
+ admin.timeToAccept = block.timestamp + delay;
54
+ }
55
+
56
+ /**
57
+ * @notice Accepts admin proposal after time delay
58
+ * @dev Transfers admin role to proposed address. Reverts if block.timestamp < timeToAccept. Only current admin.
59
+ */
60
+ function acceptAdminProposal() external onlyAdmin {
61
+ if (block.timestamp < admin.timeToAccept) revert ProposalNotReady();
62
+ admin.current = admin.proposal;
63
+ admin.proposal = address(0);
64
+ admin.timeToAccept = 0;
65
+ }
66
+ }