@evvm/testnet-contracts 2.1.3 → 2.2.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.
@@ -1,77 +0,0 @@
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 {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
7
-
8
- library AdvancedStrings {
9
- function addressToString(
10
- address _address
11
- ) internal pure returns (string memory) {
12
- bytes32 _bytes = bytes32(uint256(uint160(_address)));
13
- bytes memory HEX = "0123456789abcdef";
14
- bytes memory _string = new bytes(42);
15
- _string[0] = "0";
16
- _string[1] = "x";
17
- for (uint256 i = 0; i < 20; i++) {
18
- _string[2 + i * 2] = HEX[uint8(_bytes[i + 12] >> 4)];
19
- _string[3 + i * 2] = HEX[uint8(_bytes[i + 12] & 0x0f)];
20
- }
21
- return string(_string);
22
- }
23
-
24
- function toHex16(bytes16 data) internal pure returns (bytes32 result) {
25
- result =
26
- (bytes32(data) &
27
- 0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000) |
28
- ((bytes32(data) &
29
- 0x0000000000000000FFFFFFFFFFFFFFFF00000000000000000000000000000000) >>
30
- 64);
31
- result =
32
- (result &
33
- 0xFFFFFFFF000000000000000000000000FFFFFFFF000000000000000000000000) |
34
- ((result &
35
- 0x00000000FFFFFFFF000000000000000000000000FFFFFFFF0000000000000000) >>
36
- 32);
37
- result =
38
- (result &
39
- 0xFFFF000000000000FFFF000000000000FFFF000000000000FFFF000000000000) |
40
- ((result &
41
- 0x0000FFFF000000000000FFFF000000000000FFFF000000000000FFFF00000000) >>
42
- 16);
43
- result =
44
- (result &
45
- 0xFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000) |
46
- ((result &
47
- 0x00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000) >>
48
- 8);
49
- result =
50
- ((result &
51
- 0xF000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000) >>
52
- 4) |
53
- ((result &
54
- 0x0F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F00) >>
55
- 8);
56
- result = bytes32(
57
- 0x3030303030303030303030303030303030303030303030303030303030303030 +
58
- uint256(result) +
59
- (((uint256(result) +
60
- 0x0606060606060606060606060606060606060606060606060606060606060606) >>
61
- 4) &
62
- 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F) *
63
- 7
64
- );
65
- }
66
-
67
- function bytes32ToString(bytes32 data) public pure returns (string memory) {
68
- return
69
- string(
70
- abi.encodePacked(
71
- "0x",
72
- toHex16(bytes16(data)),
73
- toHex16(bytes16(data << 128))
74
- )
75
- );
76
- }
77
- }
@@ -1,140 +0,0 @@
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 SignatureRecover
8
- * @author Mate labs
9
- * @notice Library for ECDSA signature verification and signer recovery in the EVVM ecosystem
10
- * @dev Provides utilities for verifying signatures against expected signers and recovering addresses from signatures.
11
- * Uses ERC-191 standard message signing format with proper message hashing and signature validation.
12
- *
13
- * Key Features:
14
- * - EVVM-specific signature verification with structured message format
15
- * - ERC-191 compliant signature format (\x19Ethereum Signed Message)
16
- * - Safe signature splitting and validation
17
- * - Address recovery from message signatures
18
- *
19
- * Security Features:
20
- * - Validates signature length (must be 65 bytes)
21
- * - Ensures proper v value (27 or 28)
22
- * - Uses keccak256 hashing with ERC-191 message prefix
23
- * - Prevents signature malleability attacks
24
- *
25
- * Usage Pattern:
26
- * ```solidity
27
- * bool isValid = SignatureRecover.signatureVerification(
28
- * evvmID,
29
- * "functionName",
30
- * string.concat(param1, ",", param2, ",", param3),
31
- * signature,
32
- * expectedAddress
33
- * );
34
- * ```
35
- */
36
-
37
- import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
38
-
39
- library SignatureRecover {
40
- /**
41
- * @notice Verifies that a signature matches the expected signer for EVVM operations
42
- * @dev Constructs a standardized message format and verifies the signature against the expected signer
43
- *
44
- * Message Format: "{evvmID},{functionName},{inputs}"
45
- * This creates a unique signature for each EVVM operation preventing replay attacks across:
46
- * - Different EVVM instances (via evvmID)
47
- * - Different functions (via functionName)
48
- * - Different parameters (via inputs)
49
- *
50
- * @param evvmID Unique identifier for the EVVM instance (prevents cross-chain replay)
51
- * @param functionName Name of the function being called (prevents cross-function replay)
52
- * @param inputs Comma-separated string of function inputs. Must be constructed using
53
- * string.concat(param1, ",", param2, ",", param3)
54
- * where all parameters are converted to strings
55
- * @param signature The ECDSA signature to verify (65 bytes: r(32) + s(32) + v(1))
56
- * @param expectedSigner Address that should have signed the message
57
- * @return bool True if the signature is valid and matches the expected signer, false otherwise
58
- */
59
- function signatureVerification(
60
- string memory evvmID,
61
- string memory functionName,
62
- string memory inputs,
63
- bytes memory signature,
64
- address expectedSigner
65
- ) internal pure returns (bool) {
66
- return
67
- recoverSigner(
68
- string.concat(evvmID, ",", functionName, ",", inputs),
69
- signature
70
- ) == expectedSigner;
71
- }
72
-
73
- /**
74
- * @notice Recovers the signer address from a message and its signature
75
- * @dev Uses ERC-191 standard message signing format with proper prefix and length encoding
76
- *
77
- * The message is hashed using the ERC-191 standard format:
78
- * keccak256("\x19Ethereum Signed Message:\n" + messageLength + message)
79
- *
80
- * This ensures compatibility with standard Ethereum wallets and signing tools like:
81
- * - MetaMask personal_sign
82
- * - web3.eth.personal.sign
83
- * - ethers.js signMessage
84
- *
85
- * @param message The original message that was signed (plain text)
86
- * @param signature The ECDSA signature (65 bytes: r + s + v)
87
- * @return address The recovered signer address, or zero address if signature is invalid
88
- */
89
- function recoverSigner(
90
- string memory message,
91
- bytes memory signature
92
- ) internal pure returns (address) {
93
- bytes32 messageHash = keccak256(
94
- abi.encodePacked(
95
- "\x19Ethereum Signed Message:\n",
96
- Strings.toString(bytes(message).length),
97
- message
98
- )
99
- );
100
- (bytes32 r, bytes32 s, uint8 v) = splitSignature(signature);
101
- return ecrecover(messageHash, v, r, s);
102
- }
103
-
104
- /**
105
- * @notice Splits a signature into its component parts (r, s, v)
106
- * @dev Extracts r, s, and v values from a 65-byte signature and validates the format
107
- *
108
- * Signature Format (65 bytes total):
109
- * - r: bytes 0-31 (32 bytes) - First part of ECDSA signature
110
- * - s: bytes 32-63 (32 bytes) - Second part of ECDSA signature
111
- * - v: byte 64 (1 byte) - Recovery identifier (27 or 28)
112
- *
113
- * Security validations:
114
- * - Ensures signature is exactly 65 bytes
115
- * - Normalizes v value to 27/28 if needed
116
- * - Validates v is either 27 or 28 (standard Ethereum values)
117
- *
118
- * @param signature The complete signature bytes to split (must be 65 bytes)
119
- * @return r The r component of the signature (bytes32)
120
- * @return s The s component of the signature (bytes32)
121
- * @return v The recovery identifier (uint8, either 27 or 28)
122
- */
123
- function splitSignature(
124
- bytes memory signature
125
- ) internal pure returns (bytes32 r, bytes32 s, uint8 v) {
126
- require(signature.length == 65, "Invalid signature length");
127
-
128
- assembly {
129
- r := mload(add(signature, 32))
130
- s := mload(add(signature, 64))
131
- v := byte(0, mload(add(signature, 96)))
132
- }
133
-
134
- // Ensure signature is valid
135
- if (v < 27) {
136
- v += 27;
137
- }
138
- require(v == 27 || v == 28, "Invalid signature value");
139
- }
140
- }
@@ -1,116 +0,0 @@
1
- // SPDX-License-Identifier: EVVM-NONCOMMERCIAL-1.0
2
- // Full license terms available at: https://www.evvm.info/docs/EVVMNoncommercialLicense
3
- pragma solidity ^0.8.0;
4
-
5
- /**
6
- * @title StakingServiceHooks
7
- * @author Mate labs
8
- * @notice Abstract contract providing simplified staking functionality for service contracts
9
- * @dev This contract provides pre-built hooks for service contracts to easily interact with the EVVM staking system.
10
- * It handles the complex 3-step staking process atomically to prevent token loss.
11
- *
12
- * Key Features:
13
- * - Atomic service staking: Combines prepareServiceStaking, caPay, and confirmServiceStaking in one call
14
- * - Simplified unstaking for services
15
- * - Automatic address management for Staking and EVVM contracts
16
- * - Safe state management to prevent token loss
17
- *
18
- * Usage:
19
- * - Inherit from this contract in your service contract
20
- * - Call makeStakeService(amount) to stake tokens safely
21
- * - Call makeUnstakeService(amount) to unstake tokens
22
- *
23
- * IMPORTANT: The service contract must have sufficient Principal Token balance before calling makeStakeService
24
- */
25
-
26
- import {Staking} from "@evvm/testnet-contracts/contracts/staking/Staking.sol";
27
- import {Evvm} from "@evvm/testnet-contracts/contracts/evvm/Evvm.sol";
28
-
29
- abstract contract StakingServiceHooks {
30
- /// @dev Address of the Staking contract that handles staking operations
31
- address stakingHookAddress;
32
- /// @dev Address of the EVVM core contract that handles token operations
33
- address evvmHookAddress;
34
-
35
- /**
36
- * @notice Initializes the service hooks with the staking contract address
37
- * @dev Automatically retrieves and stores the EVVM contract address from the staking contract
38
- * @param _stakingAddress Address of the deployed Staking contract
39
- */
40
- constructor(address _stakingAddress) {
41
- stakingHookAddress = _stakingAddress;
42
- evvmHookAddress = Staking(stakingHookAddress).getEvvmAddress();
43
- }
44
-
45
- /**
46
- * @notice Performs atomic staking operation for the service contract
47
- * @dev Executes the complete 3-step staking process in a single transaction to prevent token loss:
48
- * 1. Prepares service staking (records pre-staking state)
49
- * 2. Transfers Principal Tokens to staking contract via caPay
50
- * 3. Confirms staking completion
51
- *
52
- * @param amountToStake Number of staking tokens to stake (not Principal Tokens)
53
- *
54
- * Requirements:
55
- * - Service must have sufficient Principal Token balance (amountToStake * PRICE_OF_STAKING)
56
- * - Service must not be in cooldown period from previous unstaking
57
- * - All operations must succeed in the same transaction
58
- *
59
- * @dev CRITICAL: This function ensures atomicity - if any step fails, the entire transaction reverts
60
- * preventing the loss of Principal Tokens that could occur with manual step-by-step execution
61
- */
62
- function _makeStakeService(uint256 amountToStake) internal {
63
- Staking(stakingHookAddress).prepareServiceStaking(amountToStake);
64
- Evvm(evvmHookAddress).caPay(
65
- address(stakingHookAddress),
66
- 0x0000000000000000000000000000000000000001,
67
- Staking(stakingHookAddress).priceOfStaking() * amountToStake
68
- );
69
- Staking(stakingHookAddress).confirmServiceStaking();
70
- }
71
-
72
- /**
73
- * @notice Performs unstaking operation for the service contract
74
- * @dev Allows the service to withdraw staked tokens and receive Principal Tokens back
75
- *
76
- * @param amountToUnstake Number of staking tokens to unstake
77
- *
78
- * The service will receive: amountToUnstake * PRICE_OF_STAKING Principal Tokens
79
- *
80
- * Requirements:
81
- * - Service must have at least amountToUnstake staking tokens staked
82
- * - If unstaking all tokens, must wait 21 days since last zero balance
83
- * - Cannot unstake more than currently staked amount
84
- *
85
- * @dev Unstaking is subject to the same time locks as regular user unstaking
86
- */
87
- function _makeUnstakeService(uint256 amountToUnstake) internal {
88
- Staking(stakingHookAddress).serviceUnstaking(amountToUnstake);
89
- }
90
-
91
- /**
92
- * @notice Internal function to update the staking contract address
93
- * @dev Updates both staking and EVVM addresses. Should be used when staking contract is upgraded
94
- * @param newStakingAddress Address of the new Staking contract
95
- *
96
- * @dev This function should be called by inheriting contracts when they need to migrate
97
- * to a new version of the staking contract. It automatically updates the EVVM address too.
98
- */
99
- function _changeStakingHookAddress(address newStakingAddress) internal {
100
- stakingHookAddress = newStakingAddress;
101
- evvmHookAddress = Staking(stakingHookAddress).getEvvmAddress();
102
- }
103
-
104
- /**
105
- * @notice Internal function to manually update the EVVM contract address
106
- * @dev Updates only the EVVM address. Use when EVVM contract is upgraded independently
107
- * @param newEvvmAddress Address of the new EVVM contract
108
- *
109
- * @dev This function should be used sparingly, typically only when the EVVM contract
110
- * is upgraded but the staking contract remains the same. In most cases, prefer
111
- * using _changeStakingHookAddress which updates both addresses automatically.
112
- */
113
- function _changeEvvmHookAddress(address newEvvmAddress) internal {
114
- evvmHookAddress = newEvvmAddress;
115
- }
116
- }