zk-agent-cli 0.1.0-beta.1 → 0.1.0-beta.2
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/README.md +15 -6
- package/dist/builtin-account-profiles/artifacts/daily-spend-limit/Account.json +693 -0
- package/dist/builtin-account-profiles/artifacts/sed-lite/Account.json +970 -0
- package/dist/builtin-account-profiles/artifacts/sed-lite/EOAValidator.json +50 -0
- package/dist/builtin-account-profiles/artifacts/sed-lite/NativePerTxLimitHook.json +267 -0
- package/dist/builtin-account-profiles/artifacts/sed-lite/TargetAllowlistHook.json +346 -0
- package/dist/builtin-account-profiles/artifacts/sed-lite/TargetSelectorAllowlistHook.json +643 -0
- package/dist/builtin-account-profiles/contracts/daily-spend-limit/AAFactory.sol +28 -0
- package/dist/builtin-account-profiles/contracts/daily-spend-limit/Account.sol +179 -0
- package/dist/builtin-account-profiles/contracts/daily-spend-limit/SpendLimit.sol +85 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/Account.sol +230 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/Auth.sol +16 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/BootloaderAuth.sol +11 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/EOAValidator.sol +23 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/IValidationHook.sol +20 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/IValidator.sol +11 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/ModuleAuth.sol +11 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/ModuleManager.sol +46 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/NativePerTxLimitHook.sol +67 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/OwnerManager.sol +25 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/SelfAuth.sol +9 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/TargetAllowlistHook.sol +110 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/TargetSelectorAllowlistHook.sol +263 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/ValidationHookManager.sol +76 -0
- package/dist/builtin-account-profiles/contracts/sed-lite/ValidatorManager.sol +31 -0
- package/dist/builtin-account-profiles/package.json +5 -0
- package/dist/index.js +4 -3
- package/package.json +1 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.17;
|
|
3
|
+
|
|
4
|
+
import '@matterlabs/zksync-contracts/contracts/system-contracts/libraries/TransactionHelper.sol';
|
|
5
|
+
import '@openzeppelin/contracts/utils/introspection/ERC165.sol';
|
|
6
|
+
import './IValidationHook.sol';
|
|
7
|
+
|
|
8
|
+
contract NativePerTxLimitHook is ERC165, IValidationHook {
|
|
9
|
+
struct LimitState {
|
|
10
|
+
uint256 maxPerTx;
|
|
11
|
+
bool enabled;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
mapping(address => LimitState) public limits;
|
|
15
|
+
|
|
16
|
+
event MaxPerTxSet(address indexed account, uint256 maxPerTx);
|
|
17
|
+
event MaxPerTxRemoved(address indexed account);
|
|
18
|
+
|
|
19
|
+
function init(bytes calldata initData) external override {
|
|
20
|
+
uint256 maxPerTx = abi.decode(initData, (uint256));
|
|
21
|
+
_setLimit(msg.sender, maxPerTx);
|
|
22
|
+
emit Inited(msg.sender);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function disable() external override {
|
|
26
|
+
delete limits[msg.sender];
|
|
27
|
+
emit Disabled(msg.sender);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isInited(address account) external view override returns (bool) {
|
|
31
|
+
return limits[account].enabled;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function setMaxPerTx(uint256 maxPerTx) external {
|
|
35
|
+
_setLimit(msg.sender, maxPerTx);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function removeMaxPerTx() external {
|
|
39
|
+
require(limits[msg.sender].enabled, 'Limit hook is not enabled');
|
|
40
|
+
delete limits[msg.sender];
|
|
41
|
+
emit MaxPerTxRemoved(msg.sender);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function validationHook(bytes32, Transaction calldata transaction) external view override {
|
|
45
|
+
LimitState memory state = limits[msg.sender];
|
|
46
|
+
if (!state.enabled) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
uint256 value = transaction.reserved[1];
|
|
51
|
+
if (value == 0) {
|
|
52
|
+
value = transaction.value;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
require(value <= state.maxPerTx, 'Native transfer exceeds hook per-tx cap');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function supportsInterface(bytes4 interfaceId) public view override(ERC165, IERC165) returns (bool) {
|
|
59
|
+
return interfaceId == type(IValidationHook).interfaceId || super.supportsInterface(interfaceId);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function _setLimit(address account, uint256 maxPerTx) internal {
|
|
63
|
+
require(maxPerTx > 0, 'Spend cap must be greater than zero');
|
|
64
|
+
limits[account] = LimitState({ maxPerTx: maxPerTx, enabled: true });
|
|
65
|
+
emit MaxPerTxSet(account, maxPerTx);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.17;
|
|
3
|
+
|
|
4
|
+
import './Auth.sol';
|
|
5
|
+
|
|
6
|
+
abstract contract OwnerManager is Auth {
|
|
7
|
+
address public owner;
|
|
8
|
+
|
|
9
|
+
event OwnerChanged(address indexed previousOwner, address indexed newOwner);
|
|
10
|
+
|
|
11
|
+
function changeOwner(address newOwner) external onlySelf {
|
|
12
|
+
_changeOwner(newOwner);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function _initializeOwner(address initialOwner) internal {
|
|
16
|
+
require(initialOwner != address(0), 'Owner must not be zero');
|
|
17
|
+
owner = initialOwner;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function _changeOwner(address newOwner) internal {
|
|
21
|
+
require(newOwner != address(0), 'Owner must not be zero');
|
|
22
|
+
emit OwnerChanged(owner, newOwner);
|
|
23
|
+
owner = newOwner;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.17;
|
|
3
|
+
|
|
4
|
+
import '@matterlabs/zksync-contracts/contracts/system-contracts/libraries/TransactionHelper.sol';
|
|
5
|
+
import '@openzeppelin/contracts/utils/introspection/ERC165.sol';
|
|
6
|
+
import './IValidationHook.sol';
|
|
7
|
+
|
|
8
|
+
contract TargetAllowlistHook is ERC165, IValidationHook {
|
|
9
|
+
mapping(address => bool) public enabled;
|
|
10
|
+
mapping(address => mapping(address => bool)) public allowedTargets;
|
|
11
|
+
mapping(address => address[]) private targetLists;
|
|
12
|
+
|
|
13
|
+
event AllowedTargetAdded(address indexed account, address indexed target);
|
|
14
|
+
event AllowedTargetRemoved(address indexed account, address indexed target);
|
|
15
|
+
|
|
16
|
+
function init(bytes calldata initData) external override {
|
|
17
|
+
address[] memory targets = abi.decode(initData, (address[]));
|
|
18
|
+
enabled[msg.sender] = true;
|
|
19
|
+
|
|
20
|
+
uint256 length = targets.length;
|
|
21
|
+
for (uint256 i = 0; i < length; i += 1) {
|
|
22
|
+
_addAllowedTarget(msg.sender, targets[i]);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
emit Inited(msg.sender);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function disable() external override {
|
|
29
|
+
require(enabled[msg.sender], 'Allowlist hook is not enabled');
|
|
30
|
+
_clearAllowedTargets(msg.sender);
|
|
31
|
+
enabled[msg.sender] = false;
|
|
32
|
+
emit Disabled(msg.sender);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function isInited(address account) external view override returns (bool) {
|
|
36
|
+
return enabled[account];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function state(address account) external view returns (bool accountEnabled, address[] memory targets) {
|
|
40
|
+
return (enabled[account], targetLists[account]);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isTargetAllowed(address account, address target) external view returns (bool) {
|
|
44
|
+
return allowedTargets[account][target];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function addAllowedTarget(address target) external {
|
|
48
|
+
require(enabled[msg.sender], 'Allowlist hook is not enabled');
|
|
49
|
+
_addAllowedTarget(msg.sender, target);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function removeAllowedTarget(address target) external {
|
|
53
|
+
require(enabled[msg.sender], 'Allowlist hook is not enabled');
|
|
54
|
+
require(allowedTargets[msg.sender][target], 'Target is not allowlisted');
|
|
55
|
+
|
|
56
|
+
delete allowedTargets[msg.sender][target];
|
|
57
|
+
|
|
58
|
+
address[] storage targets = targetLists[msg.sender];
|
|
59
|
+
uint256 length = targets.length;
|
|
60
|
+
for (uint256 i = 0; i < length; i += 1) {
|
|
61
|
+
if (targets[i] == target) {
|
|
62
|
+
uint256 lastIndex = length - 1;
|
|
63
|
+
if (i != lastIndex) {
|
|
64
|
+
targets[i] = targets[lastIndex];
|
|
65
|
+
}
|
|
66
|
+
targets.pop();
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
emit AllowedTargetRemoved(msg.sender, target);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function validationHook(bytes32, Transaction calldata transaction) external view override {
|
|
75
|
+
if (!enabled[msg.sender]) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
address target = address(uint160(transaction.to));
|
|
80
|
+
if (target == msg.sender) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
require(allowedTargets[msg.sender][target], 'Target is not allowlisted');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function supportsInterface(bytes4 interfaceId) public view override(ERC165, IERC165) returns (bool) {
|
|
88
|
+
return interfaceId == type(IValidationHook).interfaceId || super.supportsInterface(interfaceId);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function _addAllowedTarget(address account, address target) internal {
|
|
92
|
+
require(target != address(0), 'Target must not be zero');
|
|
93
|
+
require(target != account, 'Account self-target is implicit');
|
|
94
|
+
require(!allowedTargets[account][target], 'Target already allowlisted');
|
|
95
|
+
|
|
96
|
+
allowedTargets[account][target] = true;
|
|
97
|
+
targetLists[account].push(target);
|
|
98
|
+
|
|
99
|
+
emit AllowedTargetAdded(account, target);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function _clearAllowedTargets(address account) internal {
|
|
103
|
+
address[] storage targets = targetLists[account];
|
|
104
|
+
uint256 length = targets.length;
|
|
105
|
+
for (uint256 i = 0; i < length; i += 1) {
|
|
106
|
+
delete allowedTargets[account][targets[i]];
|
|
107
|
+
}
|
|
108
|
+
delete targetLists[account];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.17;
|
|
3
|
+
|
|
4
|
+
import '@matterlabs/zksync-contracts/contracts/system-contracts/libraries/TransactionHelper.sol';
|
|
5
|
+
import '@openzeppelin/contracts/utils/introspection/ERC165.sol';
|
|
6
|
+
import './IValidationHook.sol';
|
|
7
|
+
|
|
8
|
+
contract TargetSelectorAllowlistHook is ERC165, IValidationHook {
|
|
9
|
+
struct SelectorRule {
|
|
10
|
+
address target;
|
|
11
|
+
bytes4 selector;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
mapping(address => bool) public enabled;
|
|
15
|
+
mapping(address => mapping(address => bool)) public allowedTargets;
|
|
16
|
+
mapping(address => mapping(address => mapping(bytes4 => bool))) public allowedSelectors;
|
|
17
|
+
mapping(address => address[]) private targetLists;
|
|
18
|
+
mapping(address => SelectorRule[]) private selectorRuleLists;
|
|
19
|
+
|
|
20
|
+
event AllowedTargetAdded(address indexed account, address indexed target);
|
|
21
|
+
event AllowedTargetRemoved(address indexed account, address indexed target);
|
|
22
|
+
event AllowedSelectorAdded(address indexed account, address indexed target, bytes4 indexed selector);
|
|
23
|
+
event AllowedSelectorRemoved(
|
|
24
|
+
address indexed account,
|
|
25
|
+
address indexed target,
|
|
26
|
+
bytes4 indexed selector
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
function init(bytes calldata initData) external override {
|
|
30
|
+
(address[] memory targets, SelectorRule[] memory selectorRules) = abi.decode(
|
|
31
|
+
initData,
|
|
32
|
+
(address[], SelectorRule[])
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
enabled[msg.sender] = true;
|
|
36
|
+
|
|
37
|
+
uint256 targetLength = targets.length;
|
|
38
|
+
for (uint256 i = 0; i < targetLength; i += 1) {
|
|
39
|
+
_addAllowedTarget(msg.sender, targets[i]);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
uint256 selectorRuleLength = selectorRules.length;
|
|
43
|
+
for (uint256 i = 0; i < selectorRuleLength; i += 1) {
|
|
44
|
+
SelectorRule memory rule = selectorRules[i];
|
|
45
|
+
_addAllowedSelector(msg.sender, rule.target, rule.selector);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
emit Inited(msg.sender);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function disable() external override {
|
|
52
|
+
require(enabled[msg.sender], 'Selector allowlist hook is not enabled');
|
|
53
|
+
_clearAllowedTargets(msg.sender);
|
|
54
|
+
_clearAllowedSelectors(msg.sender);
|
|
55
|
+
enabled[msg.sender] = false;
|
|
56
|
+
emit Disabled(msg.sender);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function isInited(address account) external view override returns (bool) {
|
|
60
|
+
return enabled[account];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function state(address account)
|
|
64
|
+
external
|
|
65
|
+
view
|
|
66
|
+
returns (
|
|
67
|
+
bool accountEnabled,
|
|
68
|
+
address[] memory targets,
|
|
69
|
+
SelectorRule[] memory selectorRules
|
|
70
|
+
)
|
|
71
|
+
{
|
|
72
|
+
return (enabled[account], targetLists[account], selectorRuleLists[account]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function isTargetAllowed(address account, address target) external view returns (bool) {
|
|
76
|
+
return allowedTargets[account][target];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function isSelectorAllowed(address account, address target, bytes4 selector)
|
|
80
|
+
external
|
|
81
|
+
view
|
|
82
|
+
returns (bool)
|
|
83
|
+
{
|
|
84
|
+
return allowedSelectors[account][target][selector];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function addAllowedTarget(address target) external {
|
|
88
|
+
require(enabled[msg.sender], 'Selector allowlist hook is not enabled');
|
|
89
|
+
_addAllowedTarget(msg.sender, target);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function removeAllowedTarget(address target) external {
|
|
93
|
+
require(enabled[msg.sender], 'Selector allowlist hook is not enabled');
|
|
94
|
+
require(allowedTargets[msg.sender][target], 'Target is not allowlisted');
|
|
95
|
+
|
|
96
|
+
delete allowedTargets[msg.sender][target];
|
|
97
|
+
|
|
98
|
+
address[] storage targets = targetLists[msg.sender];
|
|
99
|
+
uint256 length = targets.length;
|
|
100
|
+
for (uint256 i = 0; i < length; i += 1) {
|
|
101
|
+
if (targets[i] == target) {
|
|
102
|
+
uint256 lastIndex = length - 1;
|
|
103
|
+
if (i != lastIndex) {
|
|
104
|
+
targets[i] = targets[lastIndex];
|
|
105
|
+
}
|
|
106
|
+
targets.pop();
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
emit AllowedTargetRemoved(msg.sender, target);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function addAllowedSelector(address target, bytes4 selector) external {
|
|
115
|
+
require(enabled[msg.sender], 'Selector allowlist hook is not enabled');
|
|
116
|
+
_addAllowedSelector(msg.sender, target, selector);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function removeAllowedSelector(address target, bytes4 selector) external {
|
|
120
|
+
require(enabled[msg.sender], 'Selector allowlist hook is not enabled');
|
|
121
|
+
require(
|
|
122
|
+
allowedSelectors[msg.sender][target][selector],
|
|
123
|
+
'Target selector is not allowlisted'
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
delete allowedSelectors[msg.sender][target][selector];
|
|
127
|
+
|
|
128
|
+
SelectorRule[] storage selectorRules = selectorRuleLists[msg.sender];
|
|
129
|
+
uint256 length = selectorRules.length;
|
|
130
|
+
for (uint256 i = 0; i < length; i += 1) {
|
|
131
|
+
SelectorRule storage rule = selectorRules[i];
|
|
132
|
+
if (rule.target == target && rule.selector == selector) {
|
|
133
|
+
uint256 lastIndex = length - 1;
|
|
134
|
+
if (i != lastIndex) {
|
|
135
|
+
selectorRules[i] = selectorRules[lastIndex];
|
|
136
|
+
}
|
|
137
|
+
selectorRules.pop();
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
emit AllowedSelectorRemoved(msg.sender, target, selector);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function validationHook(bytes32, Transaction calldata transaction) external view override {
|
|
146
|
+
if (!enabled[msg.sender]) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
address target = address(uint160(transaction.to));
|
|
151
|
+
if (target == msg.sender) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (transaction.data.length < 4) {
|
|
156
|
+
require(allowedTargets[msg.sender][target], 'Target is not allowlisted');
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
bytes4 selector = _selector(transaction.data);
|
|
161
|
+
require(
|
|
162
|
+
allowedSelectors[msg.sender][target][selector],
|
|
163
|
+
'Target selector is not allowlisted'
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function debugValidation(address account, Transaction calldata transaction)
|
|
168
|
+
external
|
|
169
|
+
view
|
|
170
|
+
returns (
|
|
171
|
+
bool accountEnabled,
|
|
172
|
+
address target,
|
|
173
|
+
uint256 dataLength,
|
|
174
|
+
bytes4 selector,
|
|
175
|
+
bool targetAllowed,
|
|
176
|
+
bool selectorAllowed,
|
|
177
|
+
bool wouldAllow
|
|
178
|
+
)
|
|
179
|
+
{
|
|
180
|
+
accountEnabled = enabled[account];
|
|
181
|
+
target = address(uint160(transaction.to));
|
|
182
|
+
dataLength = transaction.data.length;
|
|
183
|
+
targetAllowed = allowedTargets[account][target];
|
|
184
|
+
wouldAllow = !accountEnabled;
|
|
185
|
+
|
|
186
|
+
if (target == account) {
|
|
187
|
+
return (accountEnabled, target, dataLength, bytes4(0), targetAllowed, false, true);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (dataLength < 4) {
|
|
191
|
+
return (
|
|
192
|
+
accountEnabled,
|
|
193
|
+
target,
|
|
194
|
+
dataLength,
|
|
195
|
+
bytes4(0),
|
|
196
|
+
targetAllowed,
|
|
197
|
+
false,
|
|
198
|
+
targetAllowed
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
selector = _selector(transaction.data);
|
|
203
|
+
selectorAllowed = allowedSelectors[account][target][selector];
|
|
204
|
+
wouldAllow = !accountEnabled || selectorAllowed;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function supportsInterface(bytes4 interfaceId) public view override(ERC165, IERC165) returns (bool) {
|
|
208
|
+
return interfaceId == type(IValidationHook).interfaceId || super.supportsInterface(interfaceId);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function _selector(bytes calldata data) internal pure returns (bytes4 selector) {
|
|
212
|
+
selector = bytes4(
|
|
213
|
+
(uint32(uint8(data[0])) << 24)
|
|
214
|
+
| (uint32(uint8(data[1])) << 16)
|
|
215
|
+
| (uint32(uint8(data[2])) << 8)
|
|
216
|
+
| uint32(uint8(data[3]))
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function _addAllowedTarget(address account, address target) internal {
|
|
221
|
+
require(target != address(0), 'Target must not be zero');
|
|
222
|
+
require(target != account, 'Account self-target is implicit');
|
|
223
|
+
require(!allowedTargets[account][target], 'Target already allowlisted');
|
|
224
|
+
|
|
225
|
+
allowedTargets[account][target] = true;
|
|
226
|
+
targetLists[account].push(target);
|
|
227
|
+
|
|
228
|
+
emit AllowedTargetAdded(account, target);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function _addAllowedSelector(address account, address target, bytes4 selector) internal {
|
|
232
|
+
require(target != address(0), 'Target must not be zero');
|
|
233
|
+
require(target != account, 'Account self-target is implicit');
|
|
234
|
+
require(
|
|
235
|
+
!allowedSelectors[account][target][selector],
|
|
236
|
+
'Target selector already allowlisted'
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
allowedSelectors[account][target][selector] = true;
|
|
240
|
+
selectorRuleLists[account].push(SelectorRule({ target: target, selector: selector }));
|
|
241
|
+
|
|
242
|
+
emit AllowedSelectorAdded(account, target, selector);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function _clearAllowedTargets(address account) internal {
|
|
246
|
+
address[] storage targets = targetLists[account];
|
|
247
|
+
uint256 length = targets.length;
|
|
248
|
+
for (uint256 i = 0; i < length; i += 1) {
|
|
249
|
+
delete allowedTargets[account][targets[i]];
|
|
250
|
+
}
|
|
251
|
+
delete targetLists[account];
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function _clearAllowedSelectors(address account) internal {
|
|
255
|
+
SelectorRule[] storage selectorRules = selectorRuleLists[account];
|
|
256
|
+
uint256 length = selectorRules.length;
|
|
257
|
+
for (uint256 i = 0; i < length; i += 1) {
|
|
258
|
+
SelectorRule storage rule = selectorRules[i];
|
|
259
|
+
delete allowedSelectors[account][rule.target][rule.selector];
|
|
260
|
+
}
|
|
261
|
+
delete selectorRuleLists[account];
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.17;
|
|
3
|
+
|
|
4
|
+
import '@matterlabs/zksync-contracts/contracts/system-contracts/libraries/TransactionHelper.sol';
|
|
5
|
+
import '@openzeppelin/contracts/utils/introspection/ERC165Checker.sol';
|
|
6
|
+
import './Auth.sol';
|
|
7
|
+
import './IValidationHook.sol';
|
|
8
|
+
|
|
9
|
+
abstract contract ValidationHookManager is Auth {
|
|
10
|
+
using ERC165Checker for address;
|
|
11
|
+
|
|
12
|
+
mapping(address => bool) public validationHooks;
|
|
13
|
+
address[] internal validationHookList;
|
|
14
|
+
|
|
15
|
+
event ValidationHookAdded(address indexed hook);
|
|
16
|
+
event ValidationHookRemoved(address indexed hook);
|
|
17
|
+
|
|
18
|
+
function addValidationHook(address hook, bytes calldata initData) external onlySelf {
|
|
19
|
+
_addValidationHook(hook, initData);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function removeValidationHook(address hook) external onlySelf {
|
|
23
|
+
_removeValidationHook(hook);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function listValidationHooks() external view returns (address[] memory hooks) {
|
|
27
|
+
hooks = validationHookList;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function _addValidationHook(address hook, bytes calldata initData) internal {
|
|
31
|
+
require(hook != address(0), 'Hook must not be zero');
|
|
32
|
+
require(hook != address(this), 'Account can not be a hook');
|
|
33
|
+
require(hook.code.length > 0, 'Hook must be a deployed contract');
|
|
34
|
+
require(!validationHooks[hook], 'Hook already enabled');
|
|
35
|
+
require(
|
|
36
|
+
hook.supportsInterface(type(IValidationHook).interfaceId),
|
|
37
|
+
'Hook does not support validation interface'
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
validationHooks[hook] = true;
|
|
41
|
+
validationHookList.push(hook);
|
|
42
|
+
IValidationHook(hook).init(initData);
|
|
43
|
+
emit ValidationHookAdded(hook);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function _removeValidationHook(address hook) internal {
|
|
47
|
+
require(validationHooks[hook], 'Hook is not enabled');
|
|
48
|
+
delete validationHooks[hook];
|
|
49
|
+
|
|
50
|
+
uint256 length = validationHookList.length;
|
|
51
|
+
for (uint256 i = 0; i < length; i += 1) {
|
|
52
|
+
if (validationHookList[i] == hook) {
|
|
53
|
+
uint256 lastIndex = length - 1;
|
|
54
|
+
if (i != lastIndex) {
|
|
55
|
+
validationHookList[i] = validationHookList[lastIndex];
|
|
56
|
+
}
|
|
57
|
+
validationHookList.pop();
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try IValidationHook(hook).disable() {} catch {}
|
|
63
|
+
|
|
64
|
+
emit ValidationHookRemoved(hook);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function _runValidationHooks(
|
|
68
|
+
bytes32 signedHash,
|
|
69
|
+
Transaction calldata transaction
|
|
70
|
+
) internal {
|
|
71
|
+
uint256 length = validationHookList.length;
|
|
72
|
+
for (uint256 i = 0; i < length; i += 1) {
|
|
73
|
+
IValidationHook(validationHookList[i]).validationHook(signedHash, transaction);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.17;
|
|
3
|
+
|
|
4
|
+
import '@openzeppelin/contracts/utils/introspection/ERC165Checker.sol';
|
|
5
|
+
import './Auth.sol';
|
|
6
|
+
import './IValidator.sol';
|
|
7
|
+
|
|
8
|
+
abstract contract ValidatorManager is Auth {
|
|
9
|
+
using ERC165Checker for address;
|
|
10
|
+
|
|
11
|
+
address public validator;
|
|
12
|
+
|
|
13
|
+
event ValidatorChanged(address indexed previousValidator, address indexed newValidator);
|
|
14
|
+
|
|
15
|
+
function setValidator(address newValidator) external onlySelf {
|
|
16
|
+
_setValidator(newValidator);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function _setValidator(address newValidator) internal {
|
|
20
|
+
require(newValidator != address(0), 'Validator must not be zero');
|
|
21
|
+
require(newValidator != address(this), 'Account can not be a validator');
|
|
22
|
+
require(newValidator.code.length > 0, 'Validator must be a deployed contract');
|
|
23
|
+
require(
|
|
24
|
+
newValidator.supportsInterface(type(IK1Validator).interfaceId),
|
|
25
|
+
'Validator does not support K1 interface'
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
emit ValidatorChanged(validator, newValidator);
|
|
29
|
+
validator = newValidator;
|
|
30
|
+
}
|
|
31
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -12127,6 +12127,7 @@ function resolvePackageRoot() {
|
|
|
12127
12127
|
const cwd = process.cwd();
|
|
12128
12128
|
const candidates = [
|
|
12129
12129
|
process.env.ZK_AGENT_ACCOUNT_PROFILES_ROOT,
|
|
12130
|
+
path7.join(moduleRoot, "dist", "builtin-account-profiles"),
|
|
12130
12131
|
moduleRoot,
|
|
12131
12132
|
path7.join(cwd, "packages", "account-profiles"),
|
|
12132
12133
|
path7.join(cwd, "account-profiles"),
|
|
@@ -12201,7 +12202,7 @@ function parseArtifactFile(artifactPath2) {
|
|
|
12201
12202
|
}
|
|
12202
12203
|
function missingArtifactError(profileId, artifactPath2) {
|
|
12203
12204
|
return new Error(
|
|
12204
|
-
`Built-in smart-account profile "${profileId}" is
|
|
12205
|
+
`Built-in smart-account profile "${profileId}" is not available in this runtime. Expected a compiled artifact at ${artifactPath2}. If you are running from source, compile the profile with a zkSync EraVM toolchain or point ZK_AGENT_ACCOUNT_PROFILES_ROOT at a checked-out ${PACKAGE_NAME} package directory.`
|
|
12205
12206
|
);
|
|
12206
12207
|
}
|
|
12207
12208
|
function contractPath(...segments) {
|
|
@@ -12236,7 +12237,7 @@ function createDailySpendLimitProfile() {
|
|
|
12236
12237
|
"The checked-in Solidity source uses 24 hours instead of the tutorial 1 minute reset window.",
|
|
12237
12238
|
"AAFactory is kept as a reference helper, but the CLI deploy path targets the account artifact directly.",
|
|
12238
12239
|
...packageRootResolved ? [] : [
|
|
12239
|
-
`Built-in profile assets are not available in this runtime. Set ZK_AGENT_ACCOUNT_PROFILES_ROOT to a checked-out ${PACKAGE_NAME} package directory to enable artifact-backed built-in profile deploys.`
|
|
12240
|
+
`Built-in profile assets are not available in this runtime. Set ZK_AGENT_ACCOUNT_PROFILES_ROOT to a checked-out ${PACKAGE_NAME} package directory to enable artifact-backed built-in profile deploys when source checkout is required.`
|
|
12240
12241
|
]
|
|
12241
12242
|
],
|
|
12242
12243
|
buildConstructorArgs(context) {
|
|
@@ -12283,7 +12284,7 @@ function createSedLiteProfile() {
|
|
|
12283
12284
|
"The first standalone policy hook, NativePerTxLimitHook, is now deployed and live-validated on zkSync Sepolia.",
|
|
12284
12285
|
"The second standalone policy hook, TargetAllowlistHook, is now deployed and live-validated on zkSync Sepolia.",
|
|
12285
12286
|
...packageRootResolved ? [] : [
|
|
12286
|
-
`Built-in profile assets are not available in this runtime. Set ZK_AGENT_ACCOUNT_PROFILES_ROOT to a checked-out ${PACKAGE_NAME} package directory to enable artifact-backed built-in profile deploys.`
|
|
12287
|
+
`Built-in profile assets are not available in this runtime. Set ZK_AGENT_ACCOUNT_PROFILES_ROOT to a checked-out ${PACKAGE_NAME} package directory to enable artifact-backed built-in profile deploys when source checkout is required.`
|
|
12287
12288
|
]
|
|
12288
12289
|
],
|
|
12289
12290
|
buildConstructorArgs(context) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zk-agent-cli",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.2",
|
|
4
4
|
"description": "Local-first zkSync Era and ZK Stack agent CLI with wallet session recovery, workflow orchestration, relay-backed approval, and SED smart-account support.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|