@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.
- package/contracts/evvm/Evvm.sol +13 -9
- package/contracts/evvm/lib/EvvmStorage.sol +2 -0
- package/contracts/evvm/lib/SignatureUtils.sol +13 -13
- package/contracts/nameService/NameService.sol +11 -8
- package/contracts/nameService/lib/ErrorsLib.sol +1 -1
- package/contracts/nameService/lib/SignatureUtils.sol +38 -39
- package/contracts/p2pSwap/P2PSwap.sol +20 -388
- package/contracts/p2pSwap/lib/SignatureUtils.sol +15 -16
- package/contracts/staking/Staking.sol +28 -17
- package/contracts/staking/lib/ErrorsLib.sol +0 -1
- package/contracts/staking/lib/SignatureUtils.sol +6 -34
- package/contracts/treasuryTwoChains/lib/SignatureUtils.sol +7 -7
- package/interfaces/IStaking.sol +1 -1
- package/library/Erc191TestBuilder.sol +57 -57
- package/library/EvvmService.sol +104 -0
- package/library/primitives/Math.sol +415 -0
- package/library/primitives/SignatureRecover.sol +42 -0
- package/library/utils/AdvancedStrings.sol +89 -0
- package/library/utils/SignatureUtil.sol +29 -0
- package/library/utils/service/AsyncNonceService.sol +34 -0
- package/library/utils/service/MakeServicePaymentOnEvvm.sol +49 -0
- package/library/utils/service/StakingServiceUtils.sol +37 -0
- package/library/utils/service/SyncNonceService.sol +18 -0
- package/package.json +1 -1
- package/contracts/evvm/EvvmLegacy.sol +0 -1553
- package/library/AdvancedStrings.sol +0 -77
- package/library/SignatureRecover.sol +0 -140
- package/library/StakingServiceHooks.sol +0 -116
|
@@ -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
|
-
}
|