@layerzerolabs/onesig-evm 0.0.8 → 0.0.10
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/artifacts/contracts/ExecutorStore.sol/ExecutorStore.json +164 -0
- package/artifacts/contracts/MultiSig.sol/MultiSig.json +2 -2
- package/artifacts/contracts/OneSig.sol/OneSig.json +198 -11
- package/artifacts/contracts/lib/SelfCallable.sol/SelfCallable.json +16 -0
- package/artifacts-tron/contracts/ExecutorStore.sol/ExecutorStore.json +164 -0
- package/artifacts-tron/contracts/MultiSig.sol/MultiSig.json +2 -2
- package/artifacts-tron/contracts/OneSig.sol/OneSig.json +198 -11
- package/artifacts-tron/contracts/lib/SelfCallable.sol/SelfCallable.json +16 -0
- package/artifacts-zk/contracts/ExecutorStore.sol/ExecutorStore.json +165 -0
- package/artifacts-zk/contracts/MultiSig.sol/MultiSig.json +2 -2
- package/artifacts-zk/contracts/OneSig.sol/OneSig.json +198 -11
- package/artifacts-zk/contracts/lib/SelfCallable.sol/SelfCallable.json +17 -0
- package/contracts/ExecutorStore.sol +137 -0
- package/contracts/MultiSig.sol +15 -20
- package/contracts/OneSig.sol +53 -26
- package/contracts/lib/SelfCallable.sol +16 -0
- package/dist/index.js +1 -0
- package/package.json +5 -4
- package/typechain-types/@openzeppelin/contracts/utils/ReentrancyGuard.ts +55 -0
- package/typechain-types/@openzeppelin/contracts/utils/index.ts +1 -0
- package/typechain-types/contracts/ExecutorStore.ts +286 -0
- package/typechain-types/contracts/MultiSig.ts +5 -2
- package/typechain-types/contracts/OneSig.ts +248 -3
- package/typechain-types/contracts/index.ts +3 -0
- package/typechain-types/contracts/lib/SelfCallable.ts +55 -0
- package/typechain-types/contracts/lib/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/ReentrancyGuard__factory.ts +31 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/cryptography/ECDSA__factory.ts +1 -1
- package/typechain-types/factories/@openzeppelin/contracts/utils/cryptography/MerkleProof__factory.ts +1 -1
- package/typechain-types/factories/@openzeppelin/contracts/utils/index.ts +1 -0
- package/typechain-types/factories/contracts/ExecutorStore__factory.ts +179 -0
- package/typechain-types/factories/contracts/MultiSig__factory.ts +2 -2
- package/typechain-types/factories/contracts/OneSig__factory.ts +209 -14
- package/typechain-types/factories/contracts/index.ts +2 -0
- package/typechain-types/factories/contracts/lib/SelfCallable__factory.ts +31 -0
- package/typechain-types/factories/contracts/lib/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/MockOApp__factory.ts +1 -1
- package/typechain-types/hardhat.d.ts +27 -0
- package/typechain-types/index.ts +6 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_format": "hh-zksolc-artifact-1",
|
|
3
|
+
"contractName": "SelfCallable",
|
|
4
|
+
"sourceName": "contracts/lib/SelfCallable.sol",
|
|
5
|
+
"abi": [
|
|
6
|
+
{
|
|
7
|
+
"inputs": [],
|
|
8
|
+
"name": "OnlySelfCall",
|
|
9
|
+
"type": "error"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"bytecode": "0x",
|
|
13
|
+
"deployedBytecode": "0x",
|
|
14
|
+
"linkReferences": {},
|
|
15
|
+
"deployedLinkReferences": {},
|
|
16
|
+
"factoryDeps": {}
|
|
17
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.22;
|
|
4
|
+
|
|
5
|
+
import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
|
6
|
+
import { SelfCallable } from "./lib/SelfCallable.sol";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @title ExecutorStore
|
|
10
|
+
* @notice Abstract contract that manages a set of executors and a whether they are required.
|
|
11
|
+
* @dev Uses EnumerableSet to store executor addresses
|
|
12
|
+
*/
|
|
13
|
+
abstract contract ExecutorStore is SelfCallable {
|
|
14
|
+
using EnumerableSet for EnumerableSet.AddressSet;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @dev Set of available executors for the MultiSig.
|
|
18
|
+
*/
|
|
19
|
+
EnumerableSet.AddressSet internal executorSet;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @notice Whether the executor permission is required to execute a transaction.
|
|
23
|
+
*/
|
|
24
|
+
bool public executorRequired;
|
|
25
|
+
|
|
26
|
+
/// @notice Error thrown when an executor address is invalid.
|
|
27
|
+
/// @dev This error is thrown when the address is zero.
|
|
28
|
+
error InvalidExecutor();
|
|
29
|
+
|
|
30
|
+
/// @notice Error thrown when attempting to add an execute who is already active.
|
|
31
|
+
/// @param executor The address of the executor.
|
|
32
|
+
error ExecutorAlreadyActive(address executor);
|
|
33
|
+
|
|
34
|
+
/// @notice Error thrown when attempting to remove an execute who is not found.
|
|
35
|
+
/// @param executor The address of the executor.
|
|
36
|
+
error ExecutorNotFound(address executor);
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @notice Emitted when an executor's active status is updated.
|
|
40
|
+
* @param executor The address of the executor.
|
|
41
|
+
* @param active True if added, false if removed.
|
|
42
|
+
*/
|
|
43
|
+
event ExecutorSet(address indexed executor, bool active);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @notice Emitted when the executor required state is updated.
|
|
47
|
+
* @param required The new state
|
|
48
|
+
*/
|
|
49
|
+
event ExecutorRequiredSet(bool required);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @dev Initializes the ExecutorStore with a list of executors and sets whether executors are required.
|
|
53
|
+
* @param _executors Array of executor addresses, can be empty.
|
|
54
|
+
* @dev If the array is empty, executorsRequired will be set to false.
|
|
55
|
+
*/
|
|
56
|
+
constructor(address[] memory _executors, bool _executorRequired) {
|
|
57
|
+
for (uint256 i = 0; i < _executors.length; i++) {
|
|
58
|
+
_addExecutor(_executors[i]);
|
|
59
|
+
}
|
|
60
|
+
_setExecutorRequired(_executorRequired);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @dev Sets whether executors are required.
|
|
65
|
+
* @param _executorRequired The new threshold value.
|
|
66
|
+
*/
|
|
67
|
+
function setExecutorRequired(bool _executorRequired) external onlySelfCall {
|
|
68
|
+
_setExecutorRequired(_executorRequired);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @dev Internal function to set whether executors are required for this MultiSig.
|
|
73
|
+
* @param _executorRequired The new value.
|
|
74
|
+
*/
|
|
75
|
+
function _setExecutorRequired(bool _executorRequired) internal {
|
|
76
|
+
executorRequired = _executorRequired;
|
|
77
|
+
emit ExecutorRequiredSet(_executorRequired);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @notice Adds or removes an executor from this MultiSig.
|
|
82
|
+
* @dev Only callable via the MultiSig contract itself.
|
|
83
|
+
* @param _executor The address of the executor to add/remove.
|
|
84
|
+
* @param _active True to add executor, false to remove executor.
|
|
85
|
+
*/
|
|
86
|
+
function setExecutor(address _executor, bool _active) external onlySelfCall {
|
|
87
|
+
if (_active) {
|
|
88
|
+
_addExecutor(_executor);
|
|
89
|
+
} else {
|
|
90
|
+
_removeExecutor(_executor);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @dev Internal function to add an executor.
|
|
96
|
+
* @param _executor The address of the executor to add.
|
|
97
|
+
*/
|
|
98
|
+
function _addExecutor(address _executor) internal {
|
|
99
|
+
if (_executor == address(0)) revert InvalidExecutor();
|
|
100
|
+
if (!executorSet.add(_executor)) revert ExecutorAlreadyActive(_executor);
|
|
101
|
+
emit ExecutorSet(_executor, true);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @dev Internal function to remove an executor.
|
|
106
|
+
* @param _executor The address of the executor to remove.
|
|
107
|
+
*/
|
|
108
|
+
function _removeExecutor(address _executor) internal {
|
|
109
|
+
if (!executorSet.remove(_executor)) revert ExecutorNotFound(_executor);
|
|
110
|
+
emit ExecutorSet(_executor, false);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @notice Returns the list of all active executors.
|
|
115
|
+
* @return An array of addresses representing the current set of executors.
|
|
116
|
+
*/
|
|
117
|
+
function getExecutors() public view returns (address[] memory) {
|
|
118
|
+
return executorSet.values();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @notice Checks if a given address is in the set of executors.
|
|
123
|
+
* @param _executor The address to check.
|
|
124
|
+
* @return True if the address is a executor, otherwise false.
|
|
125
|
+
*/
|
|
126
|
+
function isExecutor(address _executor) public view returns (bool) {
|
|
127
|
+
return executorSet.contains(_executor);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @notice Returns the total number of active executors.
|
|
132
|
+
* @return The number of executors currently active.
|
|
133
|
+
*/
|
|
134
|
+
function totalExecutors() public view returns (uint256) {
|
|
135
|
+
return executorSet.length();
|
|
136
|
+
}
|
|
137
|
+
}
|
package/contracts/MultiSig.sol
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
// SPDX-License-Identifier:
|
|
2
|
-
// TODO confirm the license
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
3
2
|
|
|
4
3
|
pragma solidity ^0.8.22;
|
|
5
4
|
|
|
6
5
|
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
|
|
7
6
|
import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
|
7
|
+
import { SelfCallable } from "./lib/SelfCallable.sol";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @title MultiSig
|
|
@@ -12,7 +12,7 @@ import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableS
|
|
|
12
12
|
* Designed to be inherited by contracts requiring multi-signature verification.
|
|
13
13
|
* @dev Uses EnumerableSet to store signer addresses and ECDSA for signature recovery.
|
|
14
14
|
*/
|
|
15
|
-
abstract contract MultiSig {
|
|
15
|
+
abstract contract MultiSig is SelfCallable {
|
|
16
16
|
using EnumerableSet for EnumerableSet.AddressSet;
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -28,9 +28,6 @@ abstract contract MultiSig {
|
|
|
28
28
|
/// @notice Error thrown when a signer address is invalid.
|
|
29
29
|
error InvalidSigner();
|
|
30
30
|
|
|
31
|
-
/// @notice Error thrown when a function is not called from this contract itself.
|
|
32
|
-
error OnlyMultiSig();
|
|
33
|
-
|
|
34
31
|
/// @notice Error thrown when the threshold is set to zero.
|
|
35
32
|
error ZeroThreshold();
|
|
36
33
|
|
|
@@ -58,7 +55,7 @@ abstract contract MultiSig {
|
|
|
58
55
|
* @param signer The address of the signer.
|
|
59
56
|
* @param active True if added, false if removed.
|
|
60
57
|
*/
|
|
61
|
-
event SignerSet(address signer, bool active);
|
|
58
|
+
event SignerSet(address indexed signer, bool active);
|
|
62
59
|
|
|
63
60
|
/**
|
|
64
61
|
* @notice Emitted when the threshold for signatures is set.
|
|
@@ -67,12 +64,9 @@ abstract contract MultiSig {
|
|
|
67
64
|
event ThresholdSet(uint256 threshold);
|
|
68
65
|
|
|
69
66
|
/**
|
|
70
|
-
* @dev
|
|
67
|
+
* @dev The length of a single signature in bytes (r=32, s=32, v=1).
|
|
71
68
|
*/
|
|
72
|
-
|
|
73
|
-
if (msg.sender != address(this)) revert OnlyMultiSig();
|
|
74
|
-
_;
|
|
75
|
-
}
|
|
69
|
+
uint8 constant SIGNATURE_LENGTH = 65;
|
|
76
70
|
|
|
77
71
|
/**
|
|
78
72
|
* @dev Initializes the MultiSig with a list of signers and sets the signature threshold.
|
|
@@ -91,7 +85,7 @@ abstract contract MultiSig {
|
|
|
91
85
|
* @dev This function can only be called by the MultiSig contract itself.
|
|
92
86
|
* @param _threshold The new threshold value.
|
|
93
87
|
*/
|
|
94
|
-
function setThreshold(uint256 _threshold) external
|
|
88
|
+
function setThreshold(uint256 _threshold) external onlySelfCall {
|
|
95
89
|
_setThreshold(_threshold);
|
|
96
90
|
}
|
|
97
91
|
|
|
@@ -115,7 +109,7 @@ abstract contract MultiSig {
|
|
|
115
109
|
* @param _signer The address of the signer to add/remove.
|
|
116
110
|
* @param _active True to add signer, false to remove signer.
|
|
117
111
|
*/
|
|
118
|
-
function setSigner(address _signer, bool _active) external
|
|
112
|
+
function setSigner(address _signer, bool _active) external onlySelfCall {
|
|
119
113
|
if (_active) {
|
|
120
114
|
_addSigner(_signer);
|
|
121
115
|
} else {
|
|
@@ -172,22 +166,23 @@ abstract contract MultiSig {
|
|
|
172
166
|
*/
|
|
173
167
|
function verifyNSignatures(bytes32 _digest, bytes calldata _signatures, uint256 _threshold) public view {
|
|
174
168
|
if (_threshold == 0) revert ZeroThreshold();
|
|
175
|
-
// Each signature is 65 bytes (r=32, s=32, v=1).
|
|
176
|
-
if (_signatures.length
|
|
169
|
+
// Each signature is SIGNATURE_LENGTH (65) bytes (r=32, s=32, v=1).
|
|
170
|
+
if ((_signatures.length % SIGNATURE_LENGTH) != 0) revert SignatureError();
|
|
171
|
+
uint256 signaturesCount = _signatures.length / SIGNATURE_LENGTH;
|
|
172
|
+
if (signaturesCount < _threshold) revert SignatureError();
|
|
177
173
|
|
|
178
174
|
// There cannot be a signer with address 0, so we start with address(0) to ensure ascending order.
|
|
179
175
|
address lastSigner = address(0);
|
|
180
176
|
|
|
181
|
-
for (uint256 i = 0; i <
|
|
182
|
-
// Extract a single signature (65 bytes) at a time.
|
|
183
|
-
bytes calldata signature = _signatures[i *
|
|
177
|
+
for (uint256 i = 0; i < signaturesCount; i++) {
|
|
178
|
+
// Extract a single signature (SIGNATURE_LENGTH (65) bytes) at a time.
|
|
179
|
+
bytes calldata signature = _signatures[i * SIGNATURE_LENGTH:(i + 1) * SIGNATURE_LENGTH];
|
|
184
180
|
address currentSigner = ECDSA.recover(_digest, signature);
|
|
185
181
|
|
|
186
182
|
// Check ordering to avoid duplicates and ensure strictly increasing addresses.
|
|
187
183
|
if (currentSigner <= lastSigner) revert UnsortedSigners();
|
|
188
184
|
// Check if the signer is in our set.
|
|
189
185
|
if (!isSigner(currentSigner)) revert SignerNotFound(currentSigner);
|
|
190
|
-
|
|
191
186
|
lastSigner = currentSigner;
|
|
192
187
|
}
|
|
193
188
|
}
|
package/contracts/OneSig.sol
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
// SPDX-License-Identifier:
|
|
2
|
-
// TODO confirm the license
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
3
2
|
|
|
4
3
|
pragma solidity ^0.8.22;
|
|
5
4
|
|
|
6
5
|
import { MerkleProof } from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
|
|
6
|
+
import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
|
|
7
7
|
import { MultiSig } from "./MultiSig.sol";
|
|
8
|
+
import { ExecutorStore } from "./ExecutorStore.sol";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* @title OneSig
|
|
@@ -14,7 +15,7 @@ import { MultiSig } from "./MultiSig.sol";
|
|
|
14
15
|
* provided the Merkle proof is valid and the threshold of signers is met.
|
|
15
16
|
* @dev Inherits from MultiSig for signature threshold logic.
|
|
16
17
|
*/
|
|
17
|
-
contract OneSig is MultiSig {
|
|
18
|
+
contract OneSig is MultiSig, ReentrancyGuard, ExecutorStore {
|
|
18
19
|
/// @notice The version string of the OneSig contract.
|
|
19
20
|
string public constant VERSION = "0.0.1";
|
|
20
21
|
|
|
@@ -47,7 +48,7 @@ contract OneSig is MultiSig {
|
|
|
47
48
|
abi.encode(
|
|
48
49
|
EIP712DOMAIN_TYPE_HASH,
|
|
49
50
|
keccak256(bytes("OneSig")), // this contract name
|
|
50
|
-
keccak256(bytes(
|
|
51
|
+
keccak256(bytes(VERSION)), // version
|
|
51
52
|
1, // Ethereum mainnet chainId
|
|
52
53
|
address(0xdEaD) // verifyingContract
|
|
53
54
|
)
|
|
@@ -75,7 +76,7 @@ contract OneSig is MultiSig {
|
|
|
75
76
|
/**
|
|
76
77
|
* @notice A sequential nonce to prevent replay attacks and enforce transaction ordering.
|
|
77
78
|
*/
|
|
78
|
-
|
|
79
|
+
uint64 public nonce;
|
|
79
80
|
|
|
80
81
|
/// @notice Emitted when the seed is updated.
|
|
81
82
|
event SeedSet(bytes32 seed);
|
|
@@ -95,6 +96,9 @@ contract OneSig is MultiSig {
|
|
|
95
96
|
/// @param index The index of the failing call within the transaction.
|
|
96
97
|
error ExecutionFailed(uint256 index);
|
|
97
98
|
|
|
99
|
+
/// @notice Error thrown when a function is not called from an executor or signer.
|
|
100
|
+
error OnlyExecutorOrSigner();
|
|
101
|
+
|
|
98
102
|
/**
|
|
99
103
|
* @notice Call to be executed as part of a Transaction.calls.
|
|
100
104
|
* - OneSig -> [Arbitrary contract].
|
|
@@ -123,22 +127,40 @@ contract OneSig is MultiSig {
|
|
|
123
127
|
bytes32[] proof;
|
|
124
128
|
}
|
|
125
129
|
|
|
130
|
+
/**
|
|
131
|
+
* @dev Restricts access to functions so they can only be called via an executor, OR a multisig signer.
|
|
132
|
+
*/
|
|
133
|
+
modifier onlyExecutorOrSigner() {
|
|
134
|
+
if (!canExecuteTransaction(msg.sender)) revert OnlyExecutorOrSigner();
|
|
135
|
+
_;
|
|
136
|
+
}
|
|
137
|
+
|
|
126
138
|
/**
|
|
127
139
|
* @notice Constructor to initialize the OneSig contract.
|
|
128
140
|
* @dev Inherits MultiSig(_signers, _threshold).
|
|
141
|
+
* @param _executors The list of executors authorized to execute transactions.
|
|
129
142
|
* @param _signers The list of signers authorized to sign transactions.
|
|
130
143
|
* @param _threshold The initial threshold of signers required to execute a transaction.
|
|
131
144
|
* @param _oneSigId A unique identifier per deployment, (typically block.chainid).
|
|
132
145
|
* @param _seed The random seed to encode into the signatures/root.
|
|
133
146
|
*/
|
|
134
147
|
constructor(
|
|
148
|
+
uint64 _oneSigId,
|
|
135
149
|
address[] memory _signers,
|
|
136
150
|
uint256 _threshold,
|
|
137
|
-
|
|
151
|
+
address[] memory _executors,
|
|
152
|
+
bool _executorRequired,
|
|
138
153
|
bytes32 _seed
|
|
139
|
-
) MultiSig(_signers, _threshold) {
|
|
154
|
+
) MultiSig(_signers, _threshold) ExecutorStore(_executors, _executorRequired) {
|
|
140
155
|
ONE_SIG_ID = _oneSigId;
|
|
156
|
+
_setSeed(_seed);
|
|
157
|
+
}
|
|
141
158
|
|
|
159
|
+
/**
|
|
160
|
+
* @notice Internal method to set the contract's seed.
|
|
161
|
+
* @param _seed The new seed value.
|
|
162
|
+
*/
|
|
163
|
+
function _setSeed(bytes32 _seed) internal virtual {
|
|
142
164
|
seed = _seed;
|
|
143
165
|
emit SeedSet(_seed);
|
|
144
166
|
}
|
|
@@ -148,9 +170,8 @@ contract OneSig is MultiSig {
|
|
|
148
170
|
* @dev Only callable via MultiSig functionality (i.e., requires threshold signatures from signers).
|
|
149
171
|
* @param _seed The new seed value.
|
|
150
172
|
*/
|
|
151
|
-
function setSeed(bytes32 _seed)
|
|
152
|
-
|
|
153
|
-
emit SeedSet(_seed);
|
|
173
|
+
function setSeed(bytes32 _seed) public virtual onlySelfCall {
|
|
174
|
+
_setSeed(_seed);
|
|
154
175
|
}
|
|
155
176
|
|
|
156
177
|
/**
|
|
@@ -167,7 +188,7 @@ contract OneSig is MultiSig {
|
|
|
167
188
|
bytes32 _merkleRoot,
|
|
168
189
|
uint256 _expiry,
|
|
169
190
|
bytes calldata _signatures
|
|
170
|
-
)
|
|
191
|
+
) public payable virtual nonReentrant onlyExecutorOrSigner {
|
|
171
192
|
// Verify the merkle root and signatures
|
|
172
193
|
verifyMerkleRoot(_merkleRoot, _expiry, _signatures);
|
|
173
194
|
|
|
@@ -227,32 +248,38 @@ contract OneSig is MultiSig {
|
|
|
227
248
|
}
|
|
228
249
|
|
|
229
250
|
/**
|
|
230
|
-
* @notice
|
|
251
|
+
* @notice Double encodes the transaction leaf for inclusion in the merkle tree.
|
|
231
252
|
* @param _nonce The nonce of the transaction.
|
|
232
253
|
* @param _calls The calls to be made in this transaction.
|
|
233
254
|
* @return The keccak256 hash of the encoded leaf.
|
|
234
255
|
*/
|
|
235
|
-
function encodeLeaf(
|
|
236
|
-
/**
|
|
237
|
-
* The leaves here are NOT 64 bytes long, so they do not need to be double-encoded.
|
|
238
|
-
*
|
|
239
|
-
* The attack relies on being able to pass the preimage of the intermediate node
|
|
240
|
-
* (e.g., `a = h(l₁) + h(l₂)`, which is 64 bytes) as the leaf. Since this contract
|
|
241
|
-
* does not accept 64-byte leaves, it is impossible to supply a malicious leaf
|
|
242
|
-
* that matches the required format (`h(l₁) + h(l₂)`), thereby preventing the attack.
|
|
243
|
-
*/
|
|
256
|
+
function encodeLeaf(uint64 _nonce, Call[] calldata _calls) public view returns (bytes32) {
|
|
244
257
|
return
|
|
245
258
|
keccak256(
|
|
246
259
|
abi.encodePacked(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
260
|
+
keccak256(
|
|
261
|
+
abi.encodePacked(
|
|
262
|
+
LEAF_ENCODING_VERSION,
|
|
263
|
+
ONE_SIG_ID,
|
|
264
|
+
bytes32(uint256(uint160(address(this)))), // convert address(this) into bytes32
|
|
265
|
+
_nonce,
|
|
266
|
+
abi.encode(_calls)
|
|
267
|
+
)
|
|
268
|
+
)
|
|
252
269
|
)
|
|
253
270
|
);
|
|
254
271
|
}
|
|
255
272
|
|
|
273
|
+
/**
|
|
274
|
+
* @notice Checks if the a given address can execute a transaction.
|
|
275
|
+
* @param _sender The address of the message sender.
|
|
276
|
+
* @return True if executeTransaction can be called by the executor, otherwise false.
|
|
277
|
+
*/
|
|
278
|
+
function canExecuteTransaction(address _sender) public view returns (bool) {
|
|
279
|
+
// If the flag is set to false, then ANYONE can execute permissionlessly, otherwise the msg.sender must be a executor, or a signer
|
|
280
|
+
return (!executorRequired || isExecutor(_sender) || isSigner(_sender));
|
|
281
|
+
}
|
|
282
|
+
|
|
256
283
|
/**
|
|
257
284
|
* @notice Fallback function to receive ether.
|
|
258
285
|
* @dev Allows the contract to accept ETH.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.22;
|
|
4
|
+
|
|
5
|
+
abstract contract SelfCallable {
|
|
6
|
+
/// @notice Error thrown when attempting to call a function from an invalid address.
|
|
7
|
+
error OnlySelfCall();
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @dev Restricts access to functions so they can only be called via this contract itself.
|
|
11
|
+
*/
|
|
12
|
+
modifier onlySelfCall() {
|
|
13
|
+
if (msg.sender != address(this)) revert OnlySelfCall();
|
|
14
|
+
_;
|
|
15
|
+
}
|
|
16
|
+
}
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@layerzerolabs/onesig-evm",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"license": "
|
|
3
|
+
"version": "0.0.10",
|
|
4
|
+
"license": "GPL-3.0-only",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"./package.json": "./package.json"
|
|
12
12
|
},
|
|
13
13
|
"main": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
14
15
|
"files": [
|
|
15
16
|
"contracts/**/*.sol",
|
|
16
17
|
"artifacts/contracts/**/!(*.dbg).json",
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
37
|
"ethers": "^5.7.2",
|
|
37
|
-
"@layerzerolabs/onesig-core": "0.0.
|
|
38
|
+
"@layerzerolabs/onesig-core": "0.0.8"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"@babel/core": "^7.23.9",
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"@typechain/hardhat": "^6.1.6",
|
|
57
58
|
"@types/chai": "^4.3.11",
|
|
58
59
|
"@types/mocha": "^10.0.6",
|
|
59
|
-
"@types/node": "
|
|
60
|
+
"@types/node": "20.10.0",
|
|
60
61
|
"chai": "~4.3.10",
|
|
61
62
|
"chai-ethers": "^0.0.1",
|
|
62
63
|
"dotenv": "^16.4.1",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* Autogenerated file. Do not edit manually. */
|
|
2
|
+
/* tslint:disable */
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
import type { BaseContract, Signer, utils } from "ethers";
|
|
5
|
+
|
|
6
|
+
import type { Listener, Provider } from "@ethersproject/providers";
|
|
7
|
+
import type {
|
|
8
|
+
TypedEventFilter,
|
|
9
|
+
TypedEvent,
|
|
10
|
+
TypedListener,
|
|
11
|
+
OnEvent,
|
|
12
|
+
} from "../../../common";
|
|
13
|
+
|
|
14
|
+
export interface ReentrancyGuardInterface extends utils.Interface {
|
|
15
|
+
functions: {};
|
|
16
|
+
|
|
17
|
+
events: {};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ReentrancyGuard extends BaseContract {
|
|
21
|
+
connect(signerOrProvider: Signer | Provider | string): this;
|
|
22
|
+
attach(addressOrName: string): this;
|
|
23
|
+
deployed(): Promise<this>;
|
|
24
|
+
|
|
25
|
+
interface: ReentrancyGuardInterface;
|
|
26
|
+
|
|
27
|
+
queryFilter<TEvent extends TypedEvent>(
|
|
28
|
+
event: TypedEventFilter<TEvent>,
|
|
29
|
+
fromBlockOrBlockhash?: string | number | undefined,
|
|
30
|
+
toBlock?: string | number | undefined
|
|
31
|
+
): Promise<Array<TEvent>>;
|
|
32
|
+
|
|
33
|
+
listeners<TEvent extends TypedEvent>(
|
|
34
|
+
eventFilter?: TypedEventFilter<TEvent>
|
|
35
|
+
): Array<TypedListener<TEvent>>;
|
|
36
|
+
listeners(eventName?: string): Array<Listener>;
|
|
37
|
+
removeAllListeners<TEvent extends TypedEvent>(
|
|
38
|
+
eventFilter: TypedEventFilter<TEvent>
|
|
39
|
+
): this;
|
|
40
|
+
removeAllListeners(eventName?: string): this;
|
|
41
|
+
off: OnEvent<this>;
|
|
42
|
+
on: OnEvent<this>;
|
|
43
|
+
once: OnEvent<this>;
|
|
44
|
+
removeListener: OnEvent<this>;
|
|
45
|
+
|
|
46
|
+
functions: {};
|
|
47
|
+
|
|
48
|
+
callStatic: {};
|
|
49
|
+
|
|
50
|
+
filters: {};
|
|
51
|
+
|
|
52
|
+
estimateGas: {};
|
|
53
|
+
|
|
54
|
+
populateTransaction: {};
|
|
55
|
+
}
|