@callcium/sdk 0.12.0 → 0.13.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/README.md +2 -2
- package/dist/index.d.ts +659 -611
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2285 -2071
- package/dist/index.js.map +1 -1
- package/package.json +13 -10
- package/src/bytes.ts +1 -0
- package/src/calldata-reader.ts +3 -3
- package/src/constants.ts +156 -86
- package/src/constraint.ts +34 -24
- package/src/descriptor-coder.ts +126 -103
- package/src/descriptor.ts +79 -288
- package/src/errors.ts +30 -19
- package/src/hint.ts +237 -0
- package/src/index.ts +29 -10
- package/src/operators.ts +168 -267
- package/src/path.ts +7 -31
- package/src/policy-builder.ts +201 -181
- package/src/policy-coder.ts +1156 -523
- package/src/policy-enforcer.ts +499 -486
- package/src/policy-validator.ts +557 -1046
- package/src/signature.ts +7 -11
- package/src/type-desc.ts +6 -6
- package/src/types.ts +230 -129
- package/src/validation-issue.ts +78 -465
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,295 @@
|
|
|
1
|
+
//#region src/constants.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Extract a `{ KEY: code }` map from a table with `key` and `code` fields.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
type CodeMap<T extends readonly {
|
|
7
|
+
readonly key: string;
|
|
8
|
+
readonly code: number;
|
|
9
|
+
}[]> = { readonly [E in T[number] as E["key"]]: E["code"]; };
|
|
10
|
+
/** ABI type code ranges and sentinel values for the descriptor format. */
|
|
11
|
+
export declare const TypeCode: {
|
|
12
|
+
readonly UINT_MIN: 1;
|
|
13
|
+
readonly UINT_MAX: 32;
|
|
14
|
+
readonly INT_MIN: 33;
|
|
15
|
+
readonly INT_MAX: 64;
|
|
16
|
+
readonly ADDRESS: 65;
|
|
17
|
+
readonly BOOL: 66;
|
|
18
|
+
readonly FUNCTION: 67;
|
|
19
|
+
readonly FIXED_BYTES_MIN: 80;
|
|
20
|
+
readonly FIXED_BYTES_MAX: 111;
|
|
21
|
+
readonly BYTES: 112;
|
|
22
|
+
readonly STRING: 113;
|
|
23
|
+
readonly STATIC_ARRAY: 128;
|
|
24
|
+
readonly DYNAMIC_ARRAY: 129;
|
|
25
|
+
readonly TUPLE: 144;
|
|
26
|
+
};
|
|
27
|
+
/** Well-known context property IDs for context-scope rules. */
|
|
28
|
+
export declare const ContextProperty: CodeMap<readonly [{
|
|
29
|
+
readonly key: "MSG_SENDER";
|
|
30
|
+
readonly code: 0;
|
|
31
|
+
readonly label: "msg.sender";
|
|
32
|
+
readonly contextKey: "msgSender";
|
|
33
|
+
readonly typeCode: 65;
|
|
34
|
+
}, {
|
|
35
|
+
readonly key: "MSG_VALUE";
|
|
36
|
+
readonly code: 1;
|
|
37
|
+
readonly label: "msg.value";
|
|
38
|
+
readonly contextKey: "msgValue";
|
|
39
|
+
readonly typeCode: 32;
|
|
40
|
+
}, {
|
|
41
|
+
readonly key: "BLOCK_TIMESTAMP";
|
|
42
|
+
readonly code: 2;
|
|
43
|
+
readonly label: "block.timestamp";
|
|
44
|
+
readonly contextKey: "blockTimestamp";
|
|
45
|
+
readonly typeCode: 32;
|
|
46
|
+
}, {
|
|
47
|
+
readonly key: "BLOCK_NUMBER";
|
|
48
|
+
readonly code: 3;
|
|
49
|
+
readonly label: "block.number";
|
|
50
|
+
readonly contextKey: "blockNumber";
|
|
51
|
+
readonly typeCode: 32;
|
|
52
|
+
}, {
|
|
53
|
+
readonly key: "CHAIN_ID";
|
|
54
|
+
readonly code: 4;
|
|
55
|
+
readonly label: "block.chainid";
|
|
56
|
+
readonly contextKey: "chainId";
|
|
57
|
+
readonly typeCode: 32;
|
|
58
|
+
}, {
|
|
59
|
+
readonly key: "TX_ORIGIN";
|
|
60
|
+
readonly code: 5;
|
|
61
|
+
readonly label: "tx.origin";
|
|
62
|
+
readonly contextKey: "txOrigin";
|
|
63
|
+
readonly typeCode: 65;
|
|
64
|
+
}, {
|
|
65
|
+
readonly key: "BASE_FEE";
|
|
66
|
+
readonly code: 6;
|
|
67
|
+
readonly label: "block.basefee";
|
|
68
|
+
readonly contextKey: "baseFee";
|
|
69
|
+
readonly typeCode: 32;
|
|
70
|
+
}, {
|
|
71
|
+
readonly key: "GAS_PRICE";
|
|
72
|
+
readonly code: 7;
|
|
73
|
+
readonly label: "tx.gasprice";
|
|
74
|
+
readonly contextKey: "gasPrice";
|
|
75
|
+
readonly typeCode: 32;
|
|
76
|
+
}]>;
|
|
77
|
+
/** Display metadata for a context property code. */
|
|
78
|
+
type ContextPropertyInfo = {
|
|
79
|
+
label: string;
|
|
80
|
+
contextKey: keyof Context;
|
|
81
|
+
typeCode: number;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Map a context property code to its display label and ABI type code.
|
|
85
|
+
* @param code - Context property ID.
|
|
86
|
+
* @returns Display metadata including the ABI type code for the property value.
|
|
87
|
+
* @throws {CallciumError} If the code is not a recognised context property.
|
|
88
|
+
*/
|
|
89
|
+
export declare function lookupContextProperty(code: number): ContextPropertyInfo;
|
|
90
|
+
declare const SCOPE_TABLE: readonly [{
|
|
91
|
+
readonly key: "CONTEXT";
|
|
92
|
+
readonly code: 0;
|
|
93
|
+
readonly label: "context";
|
|
94
|
+
}, {
|
|
95
|
+
readonly key: "CALLDATA";
|
|
96
|
+
readonly code: 1;
|
|
97
|
+
readonly label: "calldata";
|
|
98
|
+
}, {
|
|
99
|
+
readonly key: "LOOP";
|
|
100
|
+
readonly code: 2;
|
|
101
|
+
readonly label: "loop";
|
|
102
|
+
}];
|
|
103
|
+
/** Rule scope discriminant: context (EVM environment), calldata (ABI payload) or loop (array elements). */
|
|
104
|
+
export declare const Scope: CodeMap<readonly [{
|
|
105
|
+
readonly key: "CONTEXT";
|
|
106
|
+
readonly code: 0;
|
|
107
|
+
readonly label: "context";
|
|
108
|
+
}, {
|
|
109
|
+
readonly key: "CALLDATA";
|
|
110
|
+
readonly code: 1;
|
|
111
|
+
readonly label: "calldata";
|
|
112
|
+
}, {
|
|
113
|
+
readonly key: "LOOP";
|
|
114
|
+
readonly code: 2;
|
|
115
|
+
readonly label: "loop";
|
|
116
|
+
}]>;
|
|
117
|
+
/** A defined scope code. */
|
|
118
|
+
type ScopeCode = (typeof SCOPE_TABLE)[number]["code"];
|
|
119
|
+
/** Display metadata for a scope code. */
|
|
120
|
+
type ScopeInfo = {
|
|
121
|
+
label: string;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Map a scope code to its display label.
|
|
125
|
+
* @param code - Scope byte value.
|
|
126
|
+
* @returns Display metadata for the scope.
|
|
127
|
+
* @throws {CallciumError} If the code is not a recognised scope.
|
|
128
|
+
*/
|
|
129
|
+
export declare function lookupScope(code: number): ScopeInfo;
|
|
130
|
+
declare const QUANTIFIER_TABLE: readonly [{
|
|
131
|
+
readonly key: "ALL";
|
|
132
|
+
readonly code: 1;
|
|
133
|
+
readonly label: "all";
|
|
134
|
+
}, {
|
|
135
|
+
readonly key: "ANY";
|
|
136
|
+
readonly code: 2;
|
|
137
|
+
readonly label: "any";
|
|
138
|
+
}];
|
|
139
|
+
/** Loop quantifier: the body holds for every element (`ALL`) or for some element (`ANY`). */
|
|
140
|
+
export declare const LoopQuantifier: CodeMap<readonly [{
|
|
141
|
+
readonly key: "ALL";
|
|
142
|
+
readonly code: 1;
|
|
143
|
+
readonly label: "all";
|
|
144
|
+
}, {
|
|
145
|
+
readonly key: "ANY";
|
|
146
|
+
readonly code: 2;
|
|
147
|
+
readonly label: "any";
|
|
148
|
+
}]>;
|
|
149
|
+
/** A defined loop quantifier code. */
|
|
150
|
+
type QuantifierCode = (typeof QUANTIFIER_TABLE)[number]["code"];
|
|
151
|
+
/** Display metadata for a loop quantifier code. */
|
|
152
|
+
type QuantifierInfo = {
|
|
153
|
+
label: string;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Map a loop quantifier code to its display label.
|
|
157
|
+
* @param code - Quantifier byte value.
|
|
158
|
+
* @returns Display metadata for the quantifier.
|
|
159
|
+
* @throws {CallciumError} If the code is not a recognised quantifier.
|
|
160
|
+
*/
|
|
161
|
+
export declare function lookupQuantifier(code: number): QuantifierInfo;
|
|
162
|
+
/** Operand count category of an operator. */
|
|
163
|
+
type Operands = "single" | "range" | "variadic";
|
|
164
|
+
/** @internal */
|
|
165
|
+
declare const OP_TABLE: readonly [{
|
|
166
|
+
readonly key: "EQ";
|
|
167
|
+
readonly code: 1;
|
|
168
|
+
readonly label: "==";
|
|
169
|
+
readonly operands: "single";
|
|
170
|
+
}, {
|
|
171
|
+
readonly key: "GT";
|
|
172
|
+
readonly code: 2;
|
|
173
|
+
readonly label: ">";
|
|
174
|
+
readonly operands: "single";
|
|
175
|
+
}, {
|
|
176
|
+
readonly key: "LT";
|
|
177
|
+
readonly code: 3;
|
|
178
|
+
readonly label: "<";
|
|
179
|
+
readonly operands: "single";
|
|
180
|
+
}, {
|
|
181
|
+
readonly key: "GTE";
|
|
182
|
+
readonly code: 4;
|
|
183
|
+
readonly label: ">=";
|
|
184
|
+
readonly operands: "single";
|
|
185
|
+
}, {
|
|
186
|
+
readonly key: "LTE";
|
|
187
|
+
readonly code: 5;
|
|
188
|
+
readonly label: "<=";
|
|
189
|
+
readonly operands: "single";
|
|
190
|
+
}, {
|
|
191
|
+
readonly key: "BETWEEN";
|
|
192
|
+
readonly code: 6;
|
|
193
|
+
readonly label: "between";
|
|
194
|
+
readonly operands: "range";
|
|
195
|
+
}, {
|
|
196
|
+
readonly key: "IN";
|
|
197
|
+
readonly code: 7;
|
|
198
|
+
readonly label: "in";
|
|
199
|
+
readonly operands: "variadic";
|
|
200
|
+
}, {
|
|
201
|
+
readonly key: "BITMASK_ALL";
|
|
202
|
+
readonly code: 16;
|
|
203
|
+
readonly label: "bitmask all";
|
|
204
|
+
readonly operands: "single";
|
|
205
|
+
}, {
|
|
206
|
+
readonly key: "BITMASK_ANY";
|
|
207
|
+
readonly code: 17;
|
|
208
|
+
readonly label: "bitmask any";
|
|
209
|
+
readonly operands: "single";
|
|
210
|
+
}, {
|
|
211
|
+
readonly key: "BITMASK_NONE";
|
|
212
|
+
readonly code: 18;
|
|
213
|
+
readonly label: "bitmask none";
|
|
214
|
+
readonly operands: "single";
|
|
215
|
+
}, {
|
|
216
|
+
readonly key: "LENGTH_EQ";
|
|
217
|
+
readonly code: 24;
|
|
218
|
+
readonly label: "length ==";
|
|
219
|
+
readonly operands: "single";
|
|
220
|
+
}, {
|
|
221
|
+
readonly key: "LENGTH_GT";
|
|
222
|
+
readonly code: 25;
|
|
223
|
+
readonly label: "length >";
|
|
224
|
+
readonly operands: "single";
|
|
225
|
+
}, {
|
|
226
|
+
readonly key: "LENGTH_LT";
|
|
227
|
+
readonly code: 26;
|
|
228
|
+
readonly label: "length <";
|
|
229
|
+
readonly operands: "single";
|
|
230
|
+
}, {
|
|
231
|
+
readonly key: "LENGTH_GTE";
|
|
232
|
+
readonly code: 27;
|
|
233
|
+
readonly label: "length >=";
|
|
234
|
+
readonly operands: "single";
|
|
235
|
+
}, {
|
|
236
|
+
readonly key: "LENGTH_LTE";
|
|
237
|
+
readonly code: 28;
|
|
238
|
+
readonly label: "length <=";
|
|
239
|
+
readonly operands: "single";
|
|
240
|
+
}, {
|
|
241
|
+
readonly key: "LENGTH_BETWEEN";
|
|
242
|
+
readonly code: 29;
|
|
243
|
+
readonly label: "length between";
|
|
244
|
+
readonly operands: "range";
|
|
245
|
+
}];
|
|
246
|
+
/** Callcium policy operator codes, with the NOT flag and the operand source fields. */
|
|
247
|
+
export declare const Op: {
|
|
248
|
+
readonly NOT: 128;
|
|
249
|
+
readonly SOURCE_SHIFT: 5;
|
|
250
|
+
readonly COMPARISON_MASK: 31;
|
|
251
|
+
readonly BETWEEN: 6;
|
|
252
|
+
readonly BITMASK_ALL: 16;
|
|
253
|
+
readonly BITMASK_ANY: 17;
|
|
254
|
+
readonly BITMASK_NONE: 18;
|
|
255
|
+
readonly EQ: 1;
|
|
256
|
+
readonly GT: 2;
|
|
257
|
+
readonly GTE: 4;
|
|
258
|
+
readonly IN: 7;
|
|
259
|
+
readonly LENGTH_BETWEEN: 29;
|
|
260
|
+
readonly LENGTH_EQ: 24;
|
|
261
|
+
readonly LENGTH_GT: 25;
|
|
262
|
+
readonly LENGTH_GTE: 27;
|
|
263
|
+
readonly LENGTH_LT: 26;
|
|
264
|
+
readonly LENGTH_LTE: 28;
|
|
265
|
+
readonly LT: 3;
|
|
266
|
+
readonly LTE: 5;
|
|
267
|
+
};
|
|
268
|
+
/** A defined comparison code. */
|
|
269
|
+
type ComparisonCode = (typeof OP_TABLE)[number]["code"];
|
|
270
|
+
/** Operand source: constant values, or a context property. */
|
|
271
|
+
export declare const Source: CodeMap<readonly [{
|
|
272
|
+
readonly key: "CONSTANT";
|
|
273
|
+
readonly code: 0;
|
|
274
|
+
readonly labelSuffix: "";
|
|
275
|
+
}, {
|
|
276
|
+
readonly key: "CONTEXT";
|
|
277
|
+
readonly code: 1;
|
|
278
|
+
readonly labelSuffix: " ctx";
|
|
279
|
+
}]>;
|
|
280
|
+
/** Display metadata for an operator code. */
|
|
281
|
+
type OpInfo = {
|
|
282
|
+
label: string;
|
|
283
|
+
operands: Operands;
|
|
284
|
+
};
|
|
285
|
+
/**
|
|
286
|
+
* Map an operator code to its display label. Strips the NOT flag automatically. A context source adds ` ctx`.
|
|
287
|
+
* @param code - Operator byte value (can include the NOT flag).
|
|
288
|
+
* @returns Display metadata for the base operator.
|
|
289
|
+
* @throws {CallciumError} If the base code is not a recognised operator.
|
|
290
|
+
*/
|
|
291
|
+
export declare function lookupOp(code: number): OpInfo;
|
|
292
|
+
//#endregion
|
|
1
293
|
//#region src/types.d.ts
|
|
2
294
|
/** Hex-encoded byte string, 0x-prefixed. */
|
|
3
295
|
type Hex = `0x${string}`;
|
|
@@ -8,6 +300,11 @@ type Span = {
|
|
|
8
300
|
start: number;
|
|
9
301
|
end: number;
|
|
10
302
|
};
|
|
303
|
+
/** A decoded value with its byte position in the source blob. */
|
|
304
|
+
type Field<T> = {
|
|
305
|
+
value: T;
|
|
306
|
+
span: Span;
|
|
307
|
+
};
|
|
11
308
|
/**
|
|
12
309
|
* Execution context for context-scoped rules. Each property maps to a well-known EVM execution environment value. Only
|
|
13
310
|
* the properties referenced by the policy need to be supplied.
|
|
@@ -38,49 +335,60 @@ type MissingSelectorViolation = {
|
|
|
38
335
|
};
|
|
39
336
|
/** Calldata selector does not match the policy's expected selector. */
|
|
40
337
|
type SelectorMismatchViolation = {
|
|
41
|
-
code: "SELECTOR_MISMATCH";
|
|
42
|
-
|
|
338
|
+
code: "SELECTOR_MISMATCH";
|
|
339
|
+
/** Selector declared by the policy. */
|
|
340
|
+
expectedValue: Hex;
|
|
341
|
+
/** Selector observed in the calldata. */
|
|
43
342
|
resolvedValue: Hex;
|
|
44
343
|
};
|
|
45
344
|
/**
|
|
46
|
-
* A
|
|
47
|
-
*
|
|
345
|
+
* A test read a context property not supplied in the execution context — a context test's subject, or a context
|
|
346
|
+
* operand on either kind of test.
|
|
347
|
+
*
|
|
348
|
+
* `group` and `rule` locate the root rule. A test in a loop body adds `bodyRule` and `elementIndex`.
|
|
48
349
|
*/
|
|
49
350
|
type MissingContextViolation = {
|
|
50
351
|
code: "MISSING_CONTEXT";
|
|
51
352
|
group: number;
|
|
52
353
|
rule: number;
|
|
53
|
-
scope:
|
|
54
|
-
path:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
354
|
+
scope: ScopeCode;
|
|
355
|
+
/** The test's path: a context test's property ID, or a calldata test's steps (in a loop body, from the element). */
|
|
356
|
+
path: Hex;
|
|
357
|
+
/** Declared type of the missing context property. */
|
|
358
|
+
typeCode: number;
|
|
359
|
+
/** The test's operator, absent for a context test's subject. */
|
|
360
|
+
operator?: DecodedOperator;
|
|
361
|
+
/** Position of the test in the loop body, absent for a root test. */
|
|
362
|
+
bodyRule?: number;
|
|
363
|
+
/** Position of the element the body test read, absent for a root test. */
|
|
364
|
+
elementIndex?: number;
|
|
58
365
|
};
|
|
59
366
|
/**
|
|
60
|
-
* A
|
|
367
|
+
* A test's operator returned false against the loaded value.
|
|
61
368
|
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* - `resolvedValue` present, `elementIndex` present — universal-quantifier per-element failure.
|
|
65
|
-
* - `resolvedValue` absent, `elementIndex` absent — existential-aggregate failure (no element satisfied).
|
|
66
|
-
*
|
|
67
|
-
* For length operators, `resolvedValue` is the length as a 32-byte word.
|
|
369
|
+
* `resolvedValue` is the value the operator compared: a word, or for length operators the length as a 32-byte word.
|
|
370
|
+
* `group` and `rule` locate the root rule. A test in a loop body adds `bodyRule` and `elementIndex`.
|
|
68
371
|
*/
|
|
69
372
|
type ValueMismatchViolation = {
|
|
70
373
|
code: "VALUE_MISMATCH";
|
|
71
374
|
group: number;
|
|
72
375
|
rule: number;
|
|
73
|
-
scope:
|
|
74
|
-
path:
|
|
75
|
-
|
|
76
|
-
|
|
376
|
+
scope: ScopeCode;
|
|
377
|
+
/** The test's path: a context test's property ID, or a calldata test's steps (in a loop body, from the element). */
|
|
378
|
+
path: Hex;
|
|
379
|
+
/** The test's operator. */
|
|
380
|
+
operator: DecodedOperator;
|
|
381
|
+
/** Type code of the failing value. */
|
|
77
382
|
typeCode: number;
|
|
78
|
-
resolvedValue
|
|
383
|
+
resolvedValue: Hex;
|
|
79
384
|
/**
|
|
80
|
-
* Resolved runtime value of a
|
|
81
|
-
*
|
|
385
|
+
* Resolved runtime value of a context operand as a 32-byte word, present when the operator's operand names a context
|
|
386
|
+
* property, not a constant.
|
|
82
387
|
*/
|
|
83
388
|
resolvedOperand?: Hex;
|
|
389
|
+
/** Position of the test in the loop body, absent for a root test. */
|
|
390
|
+
bodyRule?: number;
|
|
391
|
+
/** Position of the element the body test read, absent for a root test. */
|
|
84
392
|
elementIndex?: number;
|
|
85
393
|
};
|
|
86
394
|
/**
|
|
@@ -91,29 +399,33 @@ type CalldataNavigationVariant<C extends NavigationViolationCode> = {
|
|
|
91
399
|
code: C;
|
|
92
400
|
group: number;
|
|
93
401
|
rule: number;
|
|
94
|
-
scope:
|
|
402
|
+
scope: ScopeCode;
|
|
95
403
|
path: Hex;
|
|
96
|
-
|
|
97
|
-
operandData?: Hex;
|
|
404
|
+
operator?: DecodedOperator;
|
|
98
405
|
typeCode?: number;
|
|
406
|
+
bodyRule?: number;
|
|
99
407
|
elementIndex?: number;
|
|
100
408
|
};
|
|
101
409
|
/**
|
|
102
|
-
* Calldata structure prevented
|
|
410
|
+
* Calldata structure prevented a rule from being evaluated.
|
|
103
411
|
*
|
|
104
|
-
* The operator was never applied
|
|
105
|
-
* describing the failing site, not a constraint claim.
|
|
412
|
+
* The operator was never applied. `operator`, `typeCode`, `bodyRule` and `elementIndex` are diagnostic context
|
|
413
|
+
* describing the failing site, not a constraint claim. A failure resolving a loop's array carries the loop
|
|
414
|
+
* rule's scope and array path and no operator. A failure resolving an element adds `elementIndex`. A failure in a body
|
|
415
|
+
* test adds the test's fields and `bodyRule`.
|
|
106
416
|
*
|
|
107
417
|
* A union of per-code variants, narrowable with `Extract<Violation, { code: "..." }>`.
|
|
108
418
|
*/
|
|
109
419
|
type CalldataNavigationViolation = CalldataNavigationVariant<"CALLDATA_OUT_OF_BOUNDS"> | CalldataNavigationVariant<"ARRAY_INDEX_OUT_OF_BOUNDS">;
|
|
110
|
-
/** A
|
|
420
|
+
/** A loop's array exceeded `MAX_QUANTIFIED_ARRAY_LENGTH`. */
|
|
111
421
|
type QuantifierLimitExceededViolation = {
|
|
112
422
|
code: "QUANTIFIER_LIMIT_EXCEEDED";
|
|
113
423
|
group: number;
|
|
114
424
|
rule: number;
|
|
115
|
-
scope:
|
|
116
|
-
|
|
425
|
+
scope: ScopeCode;
|
|
426
|
+
/** The loop's array path. */
|
|
427
|
+
path: Hex;
|
|
428
|
+
/** Hex-encoded element count of the offending array. */
|
|
117
429
|
resolvedValue: Hex;
|
|
118
430
|
};
|
|
119
431
|
/**
|
|
@@ -125,115 +437,238 @@ type NonCanonicalValueViolation = {
|
|
|
125
437
|
code: "NON_CANONICAL_VALUE";
|
|
126
438
|
group: number;
|
|
127
439
|
rule: number;
|
|
128
|
-
scope:
|
|
129
|
-
path: Hex;
|
|
130
|
-
|
|
440
|
+
scope: ScopeCode;
|
|
441
|
+
path: Hex;
|
|
442
|
+
/** Type code of the target whose encoding was violated. */
|
|
443
|
+
typeCode: number;
|
|
444
|
+
/** Raw 32-byte word as it appeared in calldata, before any masking. */
|
|
131
445
|
resolvedValue: Hex;
|
|
132
|
-
|
|
133
|
-
|
|
446
|
+
/** The test's operator. */
|
|
447
|
+
operator: DecodedOperator;
|
|
448
|
+
/** Position of the test in the loop body, absent for a root test. */
|
|
449
|
+
bodyRule?: number;
|
|
450
|
+
/** Position of the element the body test read, absent for a root test. */
|
|
134
451
|
elementIndex?: number;
|
|
135
452
|
};
|
|
136
|
-
/**
|
|
137
|
-
type
|
|
138
|
-
code: "
|
|
453
|
+
/** No element satisfied an `ANY` loop's body, the empty array included. No element and no test is to blame. */
|
|
454
|
+
type QuantifierNoMatchViolation = {
|
|
455
|
+
code: "QUANTIFIER_NO_MATCH";
|
|
139
456
|
group: number;
|
|
140
457
|
rule: number;
|
|
141
|
-
scope:
|
|
458
|
+
scope: ScopeCode;
|
|
459
|
+
/** The loop's array path. */
|
|
142
460
|
path: Hex;
|
|
143
461
|
};
|
|
144
462
|
/**
|
|
145
463
|
* Structured details of a single rule failure during enforcement.
|
|
146
464
|
*
|
|
147
|
-
* Carries semantic data only
|
|
465
|
+
* Carries semantic data only, with no message strings. Discriminate on `code` to narrow to the matching variant.
|
|
148
466
|
*/
|
|
149
|
-
type Violation = MissingSelectorViolation | SelectorMismatchViolation | MissingContextViolation | ValueMismatchViolation | CalldataNavigationViolation | NonCanonicalValueViolation | QuantifierLimitExceededViolation |
|
|
467
|
+
type Violation = MissingSelectorViolation | SelectorMismatchViolation | MissingContextViolation | ValueMismatchViolation | CalldataNavigationViolation | NonCanonicalValueViolation | QuantifierLimitExceededViolation | QuantifierNoMatchViolation;
|
|
150
468
|
/** Machine-readable reason code for an enforcement violation. Derived from `Violation` to prevent drift. */
|
|
151
469
|
type ViolationCode = Violation["code"];
|
|
152
|
-
/**
|
|
470
|
+
/** A test or a context test of a loop body, or of a group. */
|
|
471
|
+
type BodyRule = {
|
|
472
|
+
scope: typeof Scope.CONTEXT | typeof Scope.CALLDATA;
|
|
473
|
+
/** BE16-encoded path from the starting point. A context test's path is its property ID. */
|
|
474
|
+
path: Hex;
|
|
475
|
+
/** The hint a blob carries for the path, absent for a context test and in data not read from a blob. */
|
|
476
|
+
hint?: Hex;
|
|
477
|
+
/** Encoded operator: opCode(1) || each operand value as a 32-byte word, a context property as its ID. */
|
|
478
|
+
operator: Hex;
|
|
479
|
+
};
|
|
480
|
+
/** A loop: its body over each element of the array at `path`. */
|
|
481
|
+
type LoopRule = {
|
|
482
|
+
scope: typeof Scope.LOOP;
|
|
483
|
+
quantifier: QuantifierCode;
|
|
484
|
+
/** BE16-encoded path from the arguments to the array. */
|
|
485
|
+
path: Hex;
|
|
486
|
+
/** The frame hint a blob carries for the path, absent in data not read from a blob. */
|
|
487
|
+
hint?: Hex;
|
|
488
|
+
body: BodyRule[];
|
|
489
|
+
};
|
|
490
|
+
/** A rule of a group: a test, a context test or a loop. */
|
|
491
|
+
type Rule = BodyRule | LoopRule;
|
|
492
|
+
/** A policy: its selector, its descriptor and its groups of rules. */
|
|
153
493
|
type PolicyData = {
|
|
154
494
|
isSelectorless: boolean;
|
|
155
495
|
selector: Hex;
|
|
156
496
|
descriptor: Hex;
|
|
157
|
-
groups:
|
|
158
|
-
span?: Span;
|
|
497
|
+
groups: Rule[][];
|
|
159
498
|
};
|
|
499
|
+
/**
|
|
500
|
+
* An operator as a policy stores it: its comparison, its polarity and its operands. Constants are loaded to 32-byte
|
|
501
|
+
* words of `operandType`. A context operand names its property.
|
|
502
|
+
*/
|
|
503
|
+
type DecodedOperator = {
|
|
504
|
+
/** Operator code with the `Op.NOT` bit intact. */
|
|
505
|
+
opCode: number;
|
|
506
|
+
/** Comparison bits of `opCode`. */
|
|
507
|
+
comparison: ComparisonCode;
|
|
508
|
+
/** True when `opCode` carries the `Op.NOT` bit. */
|
|
509
|
+
negated: boolean;
|
|
510
|
+
/**
|
|
511
|
+
* Type code of the operands: the target's type, the type a length compares as for a length comparison,
|
|
512
|
+
* or the context property's type.
|
|
513
|
+
*/
|
|
514
|
+
operandType: number;
|
|
515
|
+
} & ({
|
|
516
|
+
source: typeof Source.CONSTANT;
|
|
517
|
+
/** Each constant loaded to its 32-byte word. */
|
|
518
|
+
values: Hex[];
|
|
519
|
+
} | {
|
|
520
|
+
source: typeof Source.CONTEXT;
|
|
521
|
+
/** The context property the operand names. */
|
|
522
|
+
contextPropertyId: number;
|
|
523
|
+
});
|
|
160
524
|
/** A collection of operators targeting a specific value. */
|
|
161
525
|
type Constraint = {
|
|
162
|
-
scope:
|
|
526
|
+
scope: typeof Scope.CONTEXT | typeof Scope.CALLDATA;
|
|
163
527
|
path: Hex;
|
|
164
|
-
operators: Hex[];
|
|
165
|
-
hint?: Hex;
|
|
166
|
-
span?: Span;
|
|
528
|
+
operators: Hex[];
|
|
167
529
|
};
|
|
168
|
-
/** A
|
|
169
|
-
type
|
|
170
|
-
value: T;
|
|
171
|
-
span: Span;
|
|
172
|
-
};
|
|
173
|
-
/** Structural representation of a decoded parameter within the descriptor. */
|
|
174
|
-
type DecodedParam = {
|
|
175
|
-
index: number;
|
|
530
|
+
/** A descriptor node: its type, its head size and the bytes it spans, with its fields or its element. */
|
|
531
|
+
type DecodedNode = {
|
|
176
532
|
typeCode: number;
|
|
177
533
|
isDynamic: boolean;
|
|
534
|
+
/** Head size in bytes, zero for a dynamic type. */
|
|
178
535
|
staticSize: number;
|
|
179
|
-
|
|
536
|
+
span: Span;
|
|
537
|
+
} & ({
|
|
538
|
+
typeClass: "elementary";
|
|
539
|
+
} | {
|
|
540
|
+
typeClass: "tuple";
|
|
541
|
+
fields: DecodedNode[];
|
|
542
|
+
} | {
|
|
543
|
+
typeClass: "staticArray";
|
|
544
|
+
length: number;
|
|
545
|
+
element: DecodedNode;
|
|
546
|
+
} | {
|
|
547
|
+
typeClass: "dynamicArray";
|
|
548
|
+
element: DecodedNode;
|
|
549
|
+
});
|
|
550
|
+
/** A descriptor: its header fields and one node per parameter. */
|
|
551
|
+
type DecodedDescriptor = {
|
|
552
|
+
version: Field<number>;
|
|
553
|
+
paramCount: Field<number>;
|
|
554
|
+
params: DecodedNode[];
|
|
555
|
+
span: Span;
|
|
556
|
+
};
|
|
557
|
+
/** An array's meta word. */
|
|
558
|
+
type ArrayMeta = {
|
|
559
|
+
/** The element type is dynamic. An offset word points to each element. */
|
|
560
|
+
isElementDynamic: boolean;
|
|
561
|
+
/** The array is dynamic. A length word is before the elements. */
|
|
562
|
+
isDynamicArray: boolean;
|
|
563
|
+
/** Element head size in words. */
|
|
564
|
+
strideWords: number;
|
|
565
|
+
};
|
|
566
|
+
/** A hop of a compiled hint: a plain hop enters the node behind an offset word, an element hop selects an element. */
|
|
567
|
+
type DecodedHop = {
|
|
568
|
+
kind: "plain" | "element";
|
|
569
|
+
delta: Field<number>;
|
|
570
|
+
index: Field<number>;
|
|
571
|
+
meta: Field<ArrayMeta>;
|
|
180
572
|
span: Span;
|
|
181
573
|
};
|
|
182
|
-
/**
|
|
183
|
-
type
|
|
574
|
+
/** A test hint: its hops, then the target's position, meta word and type code. */
|
|
575
|
+
type DecodedHint = {
|
|
576
|
+
hopCount: Field<number>;
|
|
577
|
+
hops: DecodedHop[];
|
|
578
|
+
targetDelta: Field<number>;
|
|
579
|
+
/** The target's meta word. Every field is false or zero unless the target is a dynamic array. */
|
|
580
|
+
targetMeta: Field<ArrayMeta>;
|
|
581
|
+
typeCode: Field<number>;
|
|
582
|
+
span: Span;
|
|
583
|
+
};
|
|
584
|
+
/** A frame hint: its hops, then the array's position, declared length and meta word. */
|
|
585
|
+
type DecodedFrameHint = {
|
|
586
|
+
hopCount: Field<number>;
|
|
587
|
+
hops: DecodedHop[];
|
|
588
|
+
arrayDelta: Field<number>;
|
|
589
|
+
/** Declared length of a static array, or zero for a dynamic array. */
|
|
590
|
+
count: Field<number>;
|
|
591
|
+
meta: Field<ArrayMeta>;
|
|
592
|
+
span: Span;
|
|
593
|
+
};
|
|
594
|
+
/** A test or a context test, each field with the bytes that contain it. */
|
|
595
|
+
type DecodedTest = {
|
|
184
596
|
ruleSize: Field<number>;
|
|
185
|
-
scope: Field<
|
|
597
|
+
scope: Field<typeof Scope.CONTEXT | typeof Scope.CALLDATA>;
|
|
186
598
|
pathDepth: Field<number>;
|
|
187
|
-
|
|
188
|
-
|
|
599
|
+
/** The path steps, or a context test's property ID. */
|
|
600
|
+
path: Field<Hex>;
|
|
601
|
+
/** The test hint, absent for a context test. */
|
|
602
|
+
hint?: DecodedHint;
|
|
603
|
+
/** Type code of the target: the hint's, or the context property's. */
|
|
604
|
+
targetType: number;
|
|
189
605
|
opCode: Field<number>;
|
|
190
606
|
dataLength: Field<number>;
|
|
607
|
+
/** The operands as stored. */
|
|
191
608
|
data: Field<Hex>;
|
|
609
|
+
operator: DecodedOperator;
|
|
192
610
|
span: Span;
|
|
193
611
|
};
|
|
194
|
-
/**
|
|
612
|
+
/** A loop rule, each field with the bytes that contain it. */
|
|
613
|
+
type DecodedLoop = {
|
|
614
|
+
ruleSize: Field<number>;
|
|
615
|
+
scope: Field<typeof Scope.LOOP>;
|
|
616
|
+
quantifier: Field<QuantifierCode>;
|
|
617
|
+
pathDepth: Field<number>;
|
|
618
|
+
/** The array's path. */
|
|
619
|
+
path: Field<Hex>;
|
|
620
|
+
hint: DecodedFrameHint;
|
|
621
|
+
ruleCount: Field<number>;
|
|
622
|
+
body: DecodedTest[];
|
|
623
|
+
span: Span;
|
|
624
|
+
};
|
|
625
|
+
/** A rule of a group: a test, a context test or a loop. */
|
|
626
|
+
type DecodedRule = DecodedTest | DecodedLoop;
|
|
627
|
+
/** A group, each field with the bytes that contain it. */
|
|
195
628
|
type DecodedGroup = {
|
|
196
629
|
ruleCount: Field<number>;
|
|
197
630
|
groupSize: Field<number>;
|
|
198
631
|
rules: DecodedRule[];
|
|
199
632
|
span: Span;
|
|
200
633
|
};
|
|
201
|
-
/**
|
|
634
|
+
/** A policy blob, each field with the bytes that contain it. */
|
|
202
635
|
type DecodedPolicy = {
|
|
203
|
-
header: Field<
|
|
636
|
+
header: Field<{
|
|
637
|
+
major: number;
|
|
638
|
+
minor: number;
|
|
639
|
+
isSelectorless: boolean;
|
|
640
|
+
}>;
|
|
641
|
+
/** The selector slot, zero for a selectorless policy. */
|
|
204
642
|
selector: Field<Hex>;
|
|
205
643
|
descLength: Field<number>;
|
|
206
|
-
descriptor:
|
|
207
|
-
raw: Hex;
|
|
208
|
-
header: Field<{
|
|
209
|
-
version: number;
|
|
210
|
-
paramCount: number;
|
|
211
|
-
}>;
|
|
212
|
-
params: DecodedParam[];
|
|
213
|
-
span: Span;
|
|
214
|
-
};
|
|
644
|
+
descriptor: DecodedDescriptor;
|
|
215
645
|
groupCount: Field<number>;
|
|
216
646
|
groups: DecodedGroup[];
|
|
217
647
|
span: Span;
|
|
218
|
-
version: number;
|
|
219
|
-
isSelectorless: boolean;
|
|
220
648
|
};
|
|
221
649
|
/** Severity of a validation issue. */
|
|
222
650
|
type IssueSeverity = "info" | "warning" | "error";
|
|
223
|
-
/**
|
|
651
|
+
/** Kind of defect a validation issue reports. */
|
|
224
652
|
type IssueCategory = "typeMismatch" | "contradiction" | "redundancy" | "vacuity" | "compatibility";
|
|
653
|
+
/** Machine-readable code of a validation issue. */
|
|
654
|
+
type IssueCode = "INVALID_DESCRIPTOR" | "UNNAVIGABLE_PATH" | "QUANTIFIER_ON_NON_ARRAY" | "HINT_MISMATCH" | "NUMERIC_OP_ON_NON_NUMERIC" | "BITMASK_ON_INVALID" | "IN_ON_BOOL" | "CONTEXT_TYPE_MISMATCH" | "OUT_OF_PHYSICAL_BOUNDS" | "CONTRADICTORY_RULE" | "REDUNDANT_RULE" | "DOMINATED_BOUND" | "DOMINATED_LENGTH_BOUND" | "VACUOUS_RULE" | "QUANTIFIER_OVER_STATIC_LIMIT" | "CONTEXT_ONLY_BODY";
|
|
225
655
|
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
656
|
+
* The rule an issue names: its group, its position in the group and, for a test in a loop body, its position in the
|
|
657
|
+
* body. The location also carries the rule's scope, path and operator as decoded.
|
|
658
|
+
* A path in a body starts at the element.
|
|
229
659
|
*/
|
|
230
|
-
type
|
|
231
|
-
|
|
232
|
-
|
|
660
|
+
type RuleLocation = {
|
|
661
|
+
groupIndex: number;
|
|
662
|
+
ruleIndex: number;
|
|
663
|
+
bodyRuleIndex?: number;
|
|
664
|
+
scope: ScopeCode;
|
|
665
|
+
path: Hex;
|
|
666
|
+
operator?: Hex;
|
|
667
|
+
};
|
|
668
|
+
/** A validation issue: the rule it names, absent for one about the descriptor, and the values that show the defect. */
|
|
669
|
+
type Issue = Partial<RuleLocation> & {
|
|
233
670
|
severity: IssueSeverity;
|
|
234
671
|
category: IssueCategory;
|
|
235
|
-
groupIndex: number;
|
|
236
|
-
constraintIndex: number;
|
|
237
672
|
code: IssueCode;
|
|
238
673
|
value1: Hex;
|
|
239
674
|
value2: Hex;
|
|
@@ -241,229 +676,140 @@ type Issue = {
|
|
|
241
676
|
};
|
|
242
677
|
//#endregion
|
|
243
678
|
//#region src/policy-builder.d.ts
|
|
244
|
-
/** Fluent
|
|
245
|
-
declare class PolicyBuilder {
|
|
679
|
+
/** Fluent API for drafting policies from constraints. */
|
|
680
|
+
export declare class PolicyBuilder {
|
|
246
681
|
private draft;
|
|
247
682
|
private constructor();
|
|
248
683
|
/**
|
|
249
684
|
* Create a builder from a function signature.
|
|
250
|
-
* @param signature -
|
|
685
|
+
* @param signature - The function signature (for example "transfer(address,uint256)").
|
|
686
|
+
* @returns A new builder.
|
|
687
|
+
* @throws {CallciumError} If the signature is malformed.
|
|
251
688
|
*/
|
|
252
689
|
static create(signature: string): PolicyBuilder;
|
|
253
690
|
/**
|
|
254
|
-
* Create a selectorless builder from a
|
|
255
|
-
* @param typesCsv -
|
|
691
|
+
* Create a selectorless builder from a comma-separated type list.
|
|
692
|
+
* @param typesCsv - The comma-separated ABI types (for example "uint256,address").
|
|
693
|
+
* @returns A new builder.
|
|
694
|
+
* @throws {CallciumError} If a type is malformed.
|
|
256
695
|
*/
|
|
257
696
|
static createRaw(typesCsv: string): PolicyBuilder;
|
|
258
697
|
/**
|
|
259
|
-
* Add a constraint to the
|
|
260
|
-
*
|
|
261
|
-
* @
|
|
262
|
-
*
|
|
263
|
-
*
|
|
698
|
+
* Add a constraint to the active group. A path through `Quantifier.ALL` or `Quantifier.ANY` adds its operators to the
|
|
699
|
+
* body of the group's loop over that array with that quantifier.
|
|
700
|
+
* @param constraint - The constraint to add.
|
|
701
|
+
* @returns This builder.
|
|
702
|
+
* @throws {CallciumError} If the constraint has no operator, or its path does not reach a target in the signature.
|
|
703
|
+
* If a comparison does not apply to its target, or an operand is a value its target's type cannot represent.
|
|
264
704
|
*/
|
|
265
705
|
add(constraint: Constraint): this;
|
|
266
|
-
/**
|
|
706
|
+
/**
|
|
707
|
+
* Start a new constraint group (OR semantics between groups).
|
|
708
|
+
* @returns This builder.
|
|
709
|
+
* @throws {CallciumError} If the current group is empty.
|
|
710
|
+
*/
|
|
267
711
|
or(): this;
|
|
268
712
|
/**
|
|
269
|
-
* Build the policy
|
|
270
|
-
*
|
|
271
|
-
* @
|
|
272
|
-
* @throws {CallciumError} If
|
|
273
|
-
* @throws {ValidationError} If validation finds any issue.
|
|
274
|
-
* @throws {CallciumError} With code `RULE_SIZE_OVERFLOW` when a rule's encoded bytes exceed the rule size field.
|
|
713
|
+
* Build the policy blob and validate it.
|
|
714
|
+
* @returns The encoded policy.
|
|
715
|
+
* @throws {ValidationError} If validation reports any issue.
|
|
716
|
+
* @throws {CallciumError} If the encoder refuses the policy, or the blob fails storage validation.
|
|
275
717
|
*/
|
|
276
718
|
build(): Hex;
|
|
277
719
|
/**
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
* @
|
|
281
|
-
|
|
720
|
+
* Validate the policy the builder contains.
|
|
721
|
+
* @returns Every issue validation reports on the encoded policy.
|
|
722
|
+
* @throws {CallciumError} If the encoder refuses the policy, or the blob fails storage validation.
|
|
723
|
+
*/
|
|
724
|
+
validate(): Issue[];
|
|
725
|
+
/**
|
|
726
|
+
* Build the policy blob without validation. The resulting policy can be invalid.
|
|
727
|
+
* @returns The encoded policy.
|
|
728
|
+
* @throws {CallciumError} If the encoder refuses the policy.
|
|
282
729
|
*/
|
|
283
730
|
buildUnsafe(): Hex;
|
|
731
|
+
/** Append a context test per operator of `constraint`, whose path names a context property. */
|
|
732
|
+
private addContextTests;
|
|
284
733
|
/**
|
|
285
|
-
*
|
|
286
|
-
*
|
|
734
|
+
* Append a calldata test per operator of `constraint`. If the path of `constraint` passes a quantifier step, append a
|
|
735
|
+
* body test per operator to the group's loop over that array instead.
|
|
287
736
|
*/
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
private
|
|
291
|
-
/**
|
|
737
|
+
private addCalldataTests;
|
|
738
|
+
/** The active group. */
|
|
739
|
+
private currentGroup;
|
|
740
|
+
/** The draft as the encoder takes it. */
|
|
292
741
|
private toPolicyData;
|
|
293
742
|
}
|
|
294
743
|
//#endregion
|
|
295
744
|
//#region src/policy-coder.d.ts
|
|
296
745
|
/**
|
|
297
|
-
* Encode a
|
|
298
|
-
*
|
|
299
|
-
* @
|
|
746
|
+
* Encode the canonical form of a policy: each group normalized, its rules and the groups sorted by their
|
|
747
|
+
* size-free bytes, repeats dropped.
|
|
748
|
+
* @param data - The policy.
|
|
749
|
+
* @returns The policy blob as a 0x-prefixed hex string.
|
|
750
|
+
* @throws {CallciumError} When a field does not have the shape the encoder reads, or a path does not compile.
|
|
751
|
+
* When an operator does not apply to its target, or a constant is not a value of its operand type.
|
|
752
|
+
* When a count or size overflows its field.
|
|
300
753
|
*/
|
|
301
754
|
declare function encode(data: PolicyData): Hex;
|
|
302
755
|
/**
|
|
303
|
-
* Decode a
|
|
304
|
-
* @param blob -
|
|
305
|
-
* @returns The decoded policy
|
|
306
|
-
* @throws {CallciumError}
|
|
756
|
+
* Decode a policy blob into the policy it states.
|
|
757
|
+
* @param blob - The policy blob.
|
|
758
|
+
* @returns The decoded policy, each operand loaded to its 32-byte word.
|
|
759
|
+
* @throws {CallciumError} When the blob fails storage validation or its descriptor fails DV-1 or DV-2.
|
|
307
760
|
*/
|
|
308
761
|
declare function decode(blob: Hex): PolicyData;
|
|
309
762
|
/**
|
|
310
|
-
* Inspect a
|
|
311
|
-
*
|
|
312
|
-
* @
|
|
313
|
-
* @
|
|
763
|
+
* Inspect a policy blob: every field it stores with the bytes that contain it. The descriptor is a node tree, the hints
|
|
764
|
+
* are split into their fields and the operators are parsed.
|
|
765
|
+
* @param blob - The policy blob.
|
|
766
|
+
* @returns The inspected policy, each operand loaded to its 32-byte word.
|
|
767
|
+
* @throws {CallciumError} When the blob fails storage validation or its descriptor fails DV-1 or DV-2.
|
|
314
768
|
*/
|
|
315
769
|
declare function inspect$1(blob: Hex): DecodedPolicy;
|
|
316
|
-
/** Encode, decode
|
|
317
|
-
declare const PolicyCoder: {
|
|
770
|
+
/** Encode policies in canonical form, and decode and inspect policy blobs. */
|
|
771
|
+
export declare const PolicyCoder: {
|
|
318
772
|
encode: typeof encode;
|
|
319
773
|
decode: typeof decode;
|
|
320
774
|
inspect: typeof inspect$1;
|
|
321
775
|
};
|
|
322
776
|
//#endregion
|
|
323
777
|
//#region src/path.d.ts
|
|
324
|
-
/**
|
|
325
|
-
declare const Quantifier: {
|
|
778
|
+
/** Path steps that quantify over the array before them: `ALL` over every element, `ANY` over some element. */
|
|
779
|
+
export declare const Quantifier: {
|
|
326
780
|
readonly ALL: 65535;
|
|
327
781
|
readonly ANY: 65534;
|
|
328
782
|
};
|
|
329
|
-
/** Display metadata for a quantifier step. */
|
|
330
|
-
type QuantifierInfo = {
|
|
331
|
-
label: string;
|
|
332
|
-
};
|
|
333
|
-
/** Check whether a path step is a quantifier (ALL or ANY). */
|
|
334
|
-
declare function isQuantifier(step: number): boolean;
|
|
335
|
-
/**
|
|
336
|
-
* Map a quantifier path step to its display label.
|
|
337
|
-
* @param code - Quantifier step value.
|
|
338
|
-
* @returns Display metadata for the quantifier.
|
|
339
|
-
* @throws {CallciumError} If the code is not a recognised quantifier.
|
|
340
|
-
*/
|
|
341
|
-
declare function lookupQuantifier(code: number): QuantifierInfo;
|
|
342
783
|
/**
|
|
343
784
|
* Parse a BE16-encoded hex path into an array of step values.
|
|
344
785
|
* @param path - 0x-prefixed hex string containing BE16-encoded path steps.
|
|
345
786
|
* @returns Array of numeric step values.
|
|
346
787
|
*/
|
|
347
|
-
declare function parsePathSteps(path: Hex): number[];
|
|
348
|
-
//#endregion
|
|
349
|
-
//#region src/descriptor.d.ts
|
|
350
|
-
/** Structural type information extracted from a descriptor node. */
|
|
351
|
-
type TypeInfo = {
|
|
352
|
-
typeCode: number;
|
|
353
|
-
isDynamic: boolean;
|
|
354
|
-
staticSize: number;
|
|
355
|
-
};
|
|
356
|
-
/**
|
|
357
|
-
* Return the byte length of the node at `offset`.
|
|
358
|
-
* @throws {CallciumError} When the descriptor holds no readable node at `offset`.
|
|
359
|
-
*/
|
|
360
|
-
declare function nodeLength(desc: Uint8Array, offset: number): number;
|
|
361
|
-
/**
|
|
362
|
-
* Return the byte offset of the `fieldIndex`-th field inside a tuple node. Starts at the first field and skips
|
|
363
|
-
* `fieldIndex` nodes using `nodeLength`.
|
|
364
|
-
*/
|
|
365
|
-
declare function tupleFieldOffset(desc: Uint8Array, tupleOffset: number, fieldIndex: number): number;
|
|
366
|
-
/**
|
|
367
|
-
* Return the declared top-level parameter count.
|
|
368
|
-
* @throws {CallciumError} When the descriptor is too short to hold a header.
|
|
369
|
-
*/
|
|
370
|
-
declare function paramCount(desc: Uint8Array): number;
|
|
371
|
-
/** Return byte offset of the N-th top-level param (0-indexed). */
|
|
372
|
-
declare function paramOffset(desc: Uint8Array, index: number): number;
|
|
373
|
-
/**
|
|
374
|
-
* Inspect the type node at a given byte offset.
|
|
375
|
-
* @param desc - Raw descriptor bytes.
|
|
376
|
-
* @param offset - Byte position of the node.
|
|
377
|
-
* @returns typeCode, isDynamic, and staticSize in bytes.
|
|
378
|
-
* @throws {CallciumError} When the descriptor holds no readable node at `offset`.
|
|
379
|
-
*/
|
|
380
|
-
declare function inspect(desc: Uint8Array, offset: number): TypeInfo;
|
|
381
|
-
/**
|
|
382
|
-
* Resolve the type at a calldata path (array of step indices).
|
|
383
|
-
*
|
|
384
|
-
* The first step selects a top-level param. Each subsequent step descends into the current node: for tuples it selects
|
|
385
|
-
* a field, for arrays it advances to the element descriptor.
|
|
386
|
-
*
|
|
387
|
-
* @param desc - Raw descriptor bytes.
|
|
388
|
-
* @param steps - Path steps, length >= 1.
|
|
389
|
-
* @returns TypeInfo for the node at the resolved path.
|
|
390
|
-
* @throws {CallciumError} On empty steps, an out-of-bounds param index, tuple field or static array index, or descent
|
|
391
|
-
* into an elementary type.
|
|
392
|
-
*/
|
|
393
|
-
declare function typeAt(desc: Uint8Array, steps: number[]): TypeInfo;
|
|
394
|
-
/**
|
|
395
|
-
* Resolve the type at the path and the declared length of the static array a quantifier step descends into (zero when
|
|
396
|
-
* the path holds no quantifier step over a static array).
|
|
397
|
-
* @param desc - Raw descriptor bytes.
|
|
398
|
-
* @param steps - Path steps, length >= 1.
|
|
399
|
-
* @returns TypeInfo at the resolved path and the quantified static array length.
|
|
400
|
-
* @throws {CallciumError} On empty steps, an out-of-bounds param index, tuple field or static array index, or descent
|
|
401
|
-
* into an elementary type.
|
|
402
|
-
*/
|
|
403
|
-
declare function walkPath(desc: Uint8Array, steps: number[]): {
|
|
404
|
-
typeInfo: TypeInfo;
|
|
405
|
-
quantifiedStaticLength: number;
|
|
406
|
-
};
|
|
407
|
-
/**
|
|
408
|
-
* Return tuple field count at a tuple node offset.
|
|
409
|
-
* @param desc - Raw descriptor bytes.
|
|
410
|
-
* @param offset - Byte position of the tuple node.
|
|
411
|
-
*/
|
|
412
|
-
declare function tupleFieldCount(desc: Uint8Array, offset: number): number;
|
|
413
|
-
/**
|
|
414
|
-
* Return static array length at a static array node offset.
|
|
415
|
-
* @param desc - Raw descriptor bytes.
|
|
416
|
-
* @param offset - Byte position of the static array node.
|
|
417
|
-
*/
|
|
418
|
-
declare function staticArrayLength(desc: Uint8Array, offset: number): number;
|
|
419
|
-
/**
|
|
420
|
-
* Return the byte offset of the array element descriptor.
|
|
421
|
-
* @param offset - Byte position of the array node (static or dynamic).
|
|
422
|
-
*/
|
|
423
|
-
declare function arrayElementOffset(offset: number): number;
|
|
424
|
-
/**
|
|
425
|
-
* Compile a calldata rule path into its wire hint block.
|
|
426
|
-
*
|
|
427
|
-
* @param desc - Raw descriptor bytes.
|
|
428
|
-
* @param steps - Path steps, length >= 1.
|
|
429
|
-
* @returns The hint block bytes.
|
|
430
|
-
* @throws {CallciumError} When a step leaves the structure the descriptor declares, quantifies over a non-array node,
|
|
431
|
-
* or repeats a quantifier.
|
|
432
|
-
*/
|
|
433
|
-
declare function compileHint(desc: Uint8Array, steps: number[]): Uint8Array;
|
|
434
|
-
/** Inspect and navigate raw descriptor bytes. */
|
|
435
|
-
declare const Descriptor: {
|
|
436
|
-
paramCount: typeof paramCount;
|
|
437
|
-
paramOffset: typeof paramOffset;
|
|
438
|
-
inspect: typeof inspect;
|
|
439
|
-
typeAt: typeof typeAt;
|
|
440
|
-
tupleFieldOffset: typeof tupleFieldOffset;
|
|
441
|
-
tupleFieldCount: typeof tupleFieldCount;
|
|
442
|
-
staticArrayLength: typeof staticArrayLength;
|
|
443
|
-
nodeLength: typeof nodeLength;
|
|
444
|
-
arrayElementOffset: typeof arrayElementOffset;
|
|
445
|
-
walkPath: typeof walkPath;
|
|
446
|
-
compileHint: typeof compileHint;
|
|
447
|
-
};
|
|
788
|
+
export declare function parsePathSteps(path: Hex): number[];
|
|
448
789
|
//#endregion
|
|
449
790
|
//#region src/policy-validator.d.ts
|
|
450
791
|
/**
|
|
451
|
-
*
|
|
452
|
-
*
|
|
792
|
+
* Determine whether the compatibility matrix admits an operator on a target type. A context operand is admitted on a
|
|
793
|
+
* target its comparison can pair with a context property. These targets are `uintN` under `EQ`, `GT`, `LT`, `GTE` and
|
|
794
|
+
* `LTE`, and `address` under `EQ`.
|
|
795
|
+
* @param opCode - The operator code, with or without the NOT flag.
|
|
796
|
+
* @param typeCode - The target's type code.
|
|
797
|
+
* @returns True when the operator applies to the target.
|
|
453
798
|
*/
|
|
454
|
-
declare function isOpAllowed(opCode: number,
|
|
799
|
+
export declare function isOpAllowed(opCode: number, typeCode: number): boolean;
|
|
455
800
|
/**
|
|
456
|
-
* Validate a policy
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
801
|
+
* Validate a policy blob (PV-1 to PV-9). Storage validation runs first, since the descriptor check reads the descriptor
|
|
802
|
+
* before anything is decoded. Issues of PV-1 to PV-7 name a rule where the blob stores it. Issues of PV-8 and PV-9 name
|
|
803
|
+
* the group where the blob stores it and the rule's position in the normal form of that group. Only rules that raise no
|
|
804
|
+
* PV-2, PV-3, PV-5 or PV-6 issue and no PV-4 issue on a test enter the normal form. PV-8 skips a loop that lost a body
|
|
805
|
+
* test to such an issue.
|
|
806
|
+
* @param blob - A policy blob that passes storage validation.
|
|
807
|
+
* @returns Every issue found, or one issue alone when the descriptor is not valid.
|
|
808
|
+
* @throws {CallciumError} When the blob fails storage validation, or a group's normal form exceeds a format limit.
|
|
463
809
|
*/
|
|
464
|
-
declare function validate(
|
|
465
|
-
/**
|
|
466
|
-
declare const PolicyValidator: {
|
|
810
|
+
declare function validate(blob: Hex): Issue[];
|
|
811
|
+
/** Build-time validation of policy blobs. */
|
|
812
|
+
export declare const PolicyValidator: {
|
|
467
813
|
validate: typeof validate;
|
|
468
814
|
};
|
|
469
815
|
//#endregion
|
|
@@ -475,7 +821,9 @@ type ScalarValue = bigint | boolean | string;
|
|
|
475
821
|
* folds a negative operand onto its unsigned alias, so the sign survives nowhere else.
|
|
476
822
|
*/
|
|
477
823
|
type OperandExtremes = {
|
|
478
|
-
/** Most negative operand written, or zero when none was negative. */
|
|
824
|
+
/** Most negative operand written, or zero when none was negative. */
|
|
825
|
+
leastNegative: bigint;
|
|
826
|
+
/** Greatest operand written, or zero when none exceeded it. */
|
|
479
827
|
greatest: bigint;
|
|
480
828
|
};
|
|
481
829
|
/**
|
|
@@ -483,20 +831,18 @@ type OperandExtremes = {
|
|
|
483
831
|
* be passed directly to policy builders.
|
|
484
832
|
*/
|
|
485
833
|
declare class ConstraintBuilder<Operand extends ScalarValue = ScalarValue> implements Constraint {
|
|
486
|
-
readonly scope:
|
|
834
|
+
readonly scope: Constraint["scope"];
|
|
487
835
|
readonly path: Hex;
|
|
488
836
|
readonly operators: Hex[];
|
|
489
837
|
/**
|
|
490
|
-
* Extremes of the numeric operands the value operators received, as written.
|
|
491
|
-
* folds into a target's range from below it or from above it, and whichever reaches furthest arrives first. Read it
|
|
492
|
-
* through {@link readOperandExtremes}.
|
|
838
|
+
* Extremes of the numeric operands the value operators received, as written.
|
|
493
839
|
* @internal
|
|
494
840
|
*/
|
|
495
841
|
readonly operandExtremes: OperandExtremes;
|
|
496
842
|
/** @internal */
|
|
497
|
-
constructor(scope:
|
|
843
|
+
constructor(scope: Constraint["scope"], path: Hex);
|
|
498
844
|
/**
|
|
499
|
-
* Push a pre-encoded operator hex string and return this for chaining. `values` are the operands as written
|
|
845
|
+
* Push a pre-encoded operator hex string and return this for chaining. `values` are the operands as written. The
|
|
500
846
|
* numeric ones join the record.
|
|
501
847
|
*/
|
|
502
848
|
private push;
|
|
@@ -531,14 +877,12 @@ declare class ConstraintBuilder<Operand extends ScalarValue = ScalarValue> imple
|
|
|
531
877
|
between(min: bigint, max: bigint): this;
|
|
532
878
|
/**
|
|
533
879
|
* Assert the value is a member of the set. Values are sorted and deduplicated before encoding.
|
|
534
|
-
* @throws {CallciumError} If the set is empty
|
|
535
|
-
* encodable as an operand word.
|
|
880
|
+
* @throws {CallciumError} If the set is empty or a value is not encodable as an operand word.
|
|
536
881
|
*/
|
|
537
882
|
isIn(values: readonly Operand[]): this;
|
|
538
883
|
/**
|
|
539
884
|
* Assert the value is not a member of the set.
|
|
540
|
-
* @throws {CallciumError} If the set is empty
|
|
541
|
-
* encodable as an operand word.
|
|
885
|
+
* @throws {CallciumError} If the set is empty or a value is not encodable as an operand word.
|
|
542
886
|
*/
|
|
543
887
|
notIn(values: readonly Operand[]): this;
|
|
544
888
|
/** Assert all bits in `mask` are set. */
|
|
@@ -564,64 +908,68 @@ declare class ConstraintBuilder<Operand extends ScalarValue = ScalarValue> imple
|
|
|
564
908
|
lengthBetween(min: bigint, max: bigint): this;
|
|
565
909
|
}
|
|
566
910
|
/**
|
|
567
|
-
* Target a calldata argument by path. Each argument is a big-endian uint16 step
|
|
911
|
+
* Target a calldata argument by path. Each argument is a big-endian uint16 step. Further steps navigate nested types.
|
|
568
912
|
*/
|
|
569
|
-
declare function arg(p0: number, ...rest: number[]): ConstraintBuilder;
|
|
913
|
+
export declare function arg(p0: number, ...rest: number[]): ConstraintBuilder;
|
|
570
914
|
/** Target the `msg.sender` context property. */
|
|
571
|
-
declare function msgSender(): ConstraintBuilder<Address>;
|
|
915
|
+
export declare function msgSender(): ConstraintBuilder<Address>;
|
|
572
916
|
/** Target the `msg.value` context property. */
|
|
573
|
-
declare function msgValue(): ConstraintBuilder<bigint>;
|
|
917
|
+
export declare function msgValue(): ConstraintBuilder<bigint>;
|
|
574
918
|
/** Target the `block.timestamp` context property. */
|
|
575
|
-
declare function blockTimestamp(): ConstraintBuilder<bigint>;
|
|
919
|
+
export declare function blockTimestamp(): ConstraintBuilder<bigint>;
|
|
576
920
|
/** Target the `block.number` context property. */
|
|
577
|
-
declare function blockNumber(): ConstraintBuilder<bigint>;
|
|
921
|
+
export declare function blockNumber(): ConstraintBuilder<bigint>;
|
|
578
922
|
/** Target the `block.chainid` context property. */
|
|
579
|
-
declare function chainId(): ConstraintBuilder<bigint>;
|
|
923
|
+
export declare function chainId(): ConstraintBuilder<bigint>;
|
|
580
924
|
/** Target the `tx.origin` context property. */
|
|
581
|
-
declare function txOrigin(): ConstraintBuilder<Address>;
|
|
925
|
+
export declare function txOrigin(): ConstraintBuilder<Address>;
|
|
582
926
|
/** Target the `block.basefee` context property. */
|
|
583
|
-
declare function baseFee(): ConstraintBuilder<bigint>;
|
|
927
|
+
export declare function baseFee(): ConstraintBuilder<bigint>;
|
|
584
928
|
/** Target the `tx.gasprice` context property. */
|
|
585
|
-
declare function gasPrice(): ConstraintBuilder<bigint>;
|
|
929
|
+
export declare function gasPrice(): ConstraintBuilder<bigint>;
|
|
586
930
|
//#endregion
|
|
587
931
|
//#region src/policy-enforcer.d.ts
|
|
588
932
|
/**
|
|
589
|
-
* Check a policy against ABI-encoded call data without throwing on violations.
|
|
933
|
+
* Check a policy against ABI-encoded call data without throwing on violations. Requires a policy blob that passes
|
|
934
|
+
* storage validation. The outcome on any other blob past its header is undefined.
|
|
590
935
|
* @param policy - Binary policy blob as 0x-prefixed hex string.
|
|
591
936
|
* @param callData - ABI-encoded call data as 0x-prefixed hex string.
|
|
592
937
|
* @param context - Optional execution context for context-scoped rules.
|
|
593
938
|
* @returns Pass with matched group index, or fail with one violation per evaluated failing group.
|
|
594
|
-
* @throws {CallciumError} If the policy blob is
|
|
595
|
-
*
|
|
939
|
+
* @throws {CallciumError} If the policy blob is shorter than its fixed prefix or of an unsupported format version.
|
|
940
|
+
* If the policy or call data is not valid hex.
|
|
941
|
+
* If a context value is not of its property's type or does not fit a 32-byte word.
|
|
596
942
|
*/
|
|
597
943
|
declare function check(policy: Hex, callData: Hex, context?: Context): EnforceResult;
|
|
598
944
|
/**
|
|
599
|
-
* Enforce a policy against ABI-encoded call data, throwing on violation.
|
|
945
|
+
* Enforce a policy against ABI-encoded call data, throwing on violation. Requires a policy blob that passes storage
|
|
946
|
+
* validation. The outcome on any other blob past its header is undefined.
|
|
600
947
|
* @param policy - Binary policy blob as 0x-prefixed hex string.
|
|
601
948
|
* @param callData - ABI-encoded call data as 0x-prefixed hex string.
|
|
602
949
|
* @param context - Optional execution context for context-scoped rules.
|
|
603
950
|
* @throws {PolicyViolationError} If the policy rejects the call data.
|
|
604
|
-
* @throws {CallciumError} If the policy blob is
|
|
605
|
-
*
|
|
951
|
+
* @throws {CallciumError} If the policy blob is shorter than its fixed prefix or of an unsupported format version.
|
|
952
|
+
* If the policy or call data is not valid hex.
|
|
953
|
+
* If a context value is not of its property's type or does not fit a 32-byte word.
|
|
606
954
|
*/
|
|
607
955
|
declare function enforce(policy: Hex, callData: Hex, context?: Context): void;
|
|
608
956
|
/** Check and enforce policies against ABI-encoded call data. */
|
|
609
|
-
declare const PolicyEnforcer: {
|
|
957
|
+
export declare const PolicyEnforcer: {
|
|
610
958
|
check: typeof check;
|
|
611
959
|
enforce: typeof enforce;
|
|
612
960
|
};
|
|
613
961
|
//#endregion
|
|
614
962
|
//#region src/bytes.d.ts
|
|
615
963
|
/** Convert a hex string to a byte array, stripping the 0x prefix if present. */
|
|
616
|
-
declare function hexToBytes(hex: string): Uint8Array;
|
|
964
|
+
export declare function hexToBytes(hex: string): Uint8Array;
|
|
617
965
|
/** Convert a byte array to a 0x-prefixed lowercase hex string. */
|
|
618
|
-
declare function bytesToHex(bytes: Uint8Array): Hex;
|
|
966
|
+
export declare function bytesToHex(bytes: Uint8Array): Hex;
|
|
619
967
|
//#endregion
|
|
620
968
|
//#region src/descriptor-coder.d.ts
|
|
621
969
|
/**
|
|
622
970
|
* Encode a comma-separated list of ABI type strings into a binary descriptor.
|
|
623
971
|
*
|
|
624
|
-
* @param typesCsv - Comma-separated ABI type strings,
|
|
972
|
+
* @param typesCsv - Comma-separated ABI type strings, for example `"address,uint256,(bool,bytes32)[],string"`.
|
|
625
973
|
* @returns Binary descriptor bytes starting with the version+paramCount header.
|
|
626
974
|
* @throws {CallciumError} With code `MALFORMED_TYPE_STRING` for malformed input.
|
|
627
975
|
* @throws {CallciumError} With code `UNKNOWN_TYPE` for unrecognised type names.
|
|
@@ -629,327 +977,28 @@ declare function bytesToHex(bytes: Uint8Array): Hex;
|
|
|
629
977
|
*/
|
|
630
978
|
declare function fromTypes(typesCsv: string): Uint8Array;
|
|
631
979
|
/**
|
|
632
|
-
*
|
|
633
|
-
*
|
|
634
|
-
*
|
|
635
|
-
*
|
|
980
|
+
* Inspect a binary descriptor: its header fields and its parameters as a tree of nodes, each with the bytes it spans.
|
|
981
|
+
* @param desc - Binary descriptor bytes (with version+paramCount header).
|
|
982
|
+
* @returns The decoded descriptor.
|
|
983
|
+
* @throws {CallciumError} If the descriptor is malformed, or a composite node disagrees with its children.
|
|
984
|
+
*/
|
|
985
|
+
declare function inspect(desc: Uint8Array): DecodedDescriptor;
|
|
986
|
+
/**
|
|
987
|
+
* Reconstruct a comma-separated list of ABI type strings from a binary descriptor. `fromTypes(toTypes(desc))` returns
|
|
988
|
+
* `desc` for every descriptor `inspect` accepts.
|
|
636
989
|
* @param desc - Binary descriptor bytes (with version+paramCount header).
|
|
637
|
-
* @returns Comma-separated ABI type strings,
|
|
638
|
-
* @throws {CallciumError} If the descriptor is malformed.
|
|
990
|
+
* @returns Comma-separated ABI type strings, for example `"address,uint256,(bool,bytes32)[]"`.
|
|
991
|
+
* @throws {CallciumError} If the descriptor is malformed, or a composite node disagrees with its children.
|
|
639
992
|
*/
|
|
640
993
|
declare function toTypes(desc: Uint8Array): string;
|
|
641
|
-
/** Encode and
|
|
642
|
-
declare const DescriptorCoder: {
|
|
994
|
+
/** Encode descriptors from type strings, inspect them and read their type strings back. */
|
|
995
|
+
export declare const DescriptorCoder: {
|
|
643
996
|
fromTypes: typeof fromTypes;
|
|
997
|
+
inspect: typeof inspect;
|
|
644
998
|
toTypes: typeof toTypes;
|
|
645
999
|
};
|
|
646
1000
|
//#endregion
|
|
647
|
-
//#region src/constants.d.ts
|
|
648
|
-
/** Binary layout constants and normative limits for the Callcium policy format. */
|
|
649
|
-
declare const PolicyFormat: {
|
|
650
|
-
readonly VERSION: 2;
|
|
651
|
-
readonly VERSION_MASK: 15;
|
|
652
|
-
readonly FLAG_NO_SELECTOR: 16;
|
|
653
|
-
readonly RESERVED_MASK: 224;
|
|
654
|
-
readonly HEADER_SIZE: 1;
|
|
655
|
-
readonly SELECTOR_OFFSET: 1;
|
|
656
|
-
readonly SELECTOR_SIZE: 4;
|
|
657
|
-
readonly DESC_LENGTH_OFFSET: 5;
|
|
658
|
-
readonly DESC_LENGTH_SIZE: 2;
|
|
659
|
-
readonly DESC_OFFSET: 7;
|
|
660
|
-
readonly GROUP_COUNT_SIZE: 1;
|
|
661
|
-
readonly GROUP_RULECOUNT_SIZE: 2;
|
|
662
|
-
readonly GROUP_SIZE_SIZE: 4;
|
|
663
|
-
readonly GROUP_HEADER_SIZE: 6;
|
|
664
|
-
readonly RULE_SIZE_SIZE: 2;
|
|
665
|
-
readonly RULE_SCOPE_OFFSET: 2;
|
|
666
|
-
readonly RULE_DEPTH_OFFSET: 3;
|
|
667
|
-
readonly RULE_PATH_OFFSET: 4;
|
|
668
|
-
readonly PATH_STEP_SIZE: 2;
|
|
669
|
-
readonly PATH_STEP_MAX: number;
|
|
670
|
-
readonly RULE_OPCODE_SIZE: 1;
|
|
671
|
-
readonly RULE_DATALENGTH_SIZE: 2;
|
|
672
|
-
readonly RULE_FIXED_OVERHEAD: 7;
|
|
673
|
-
readonly RULE_MIN_SIZE: number;
|
|
674
|
-
readonly HINT_HEADER_SIZE: 1;
|
|
675
|
-
readonly HINT_HOP_SIZE: 8;
|
|
676
|
-
readonly HINT_HOP_INDEX_OFFSET: 4;
|
|
677
|
-
readonly HINT_HOP_META_OFFSET: 6;
|
|
678
|
-
readonly HINT_FRAME_PREFIX_SIZE: 8;
|
|
679
|
-
readonly HINT_FRAME_COUNT_OFFSET: 4;
|
|
680
|
-
readonly HINT_FRAME_META_OFFSET: 6;
|
|
681
|
-
readonly HINT_TARGET_SIZE: 7;
|
|
682
|
-
readonly HINT_TARGET_META_OFFSET: 4;
|
|
683
|
-
readonly HINT_TARGET_TYPECODE_OFFSET: 6;
|
|
684
|
-
readonly HINT_KIND_NONE: 0;
|
|
685
|
-
readonly HINT_KIND_ALL: 1;
|
|
686
|
-
readonly HINT_KIND_ANY: 2;
|
|
687
|
-
readonly HINT_KIND_MAX: 2;
|
|
688
|
-
readonly HINT_KIND_SHIFT: 6;
|
|
689
|
-
readonly HINT_HOP_COUNT_MASK: 63;
|
|
690
|
-
readonly HINT_SUFFIX_RESERVED_MASK: 192;
|
|
691
|
-
readonly HINT_NO_INDEX: 65535;
|
|
692
|
-
readonly HINT_INDEX_RESERVED: 65534;
|
|
693
|
-
readonly HINT_META_ELEM_DYNAMIC: 32768;
|
|
694
|
-
readonly HINT_META_DYNAMIC_ARRAY: 16384;
|
|
695
|
-
readonly HINT_META_RESERVED_MASK: 12288;
|
|
696
|
-
readonly HINT_META_STRIDE_MASK: 4095;
|
|
697
|
-
readonly MAX_PATH_DEPTH: 32;
|
|
698
|
-
readonly MAX_QUANTIFIED_ARRAY_LENGTH: 256;
|
|
699
|
-
readonly MAX_SET_MEMBERS: number;
|
|
700
|
-
};
|
|
701
|
-
/**
|
|
702
|
-
* Extract a `{ KEY: code }` map from a table with `key` and `code` fields.
|
|
703
|
-
* @internal
|
|
704
|
-
*/
|
|
705
|
-
type CodeMap<T extends readonly {
|
|
706
|
-
readonly key: string;
|
|
707
|
-
readonly code: number;
|
|
708
|
-
}[]> = { readonly [E in T[number] as E["key"]]: E["code"] };
|
|
709
|
-
/**
|
|
710
|
-
* Render a wire code as fixed-width hex.
|
|
711
|
-
* @param code - Code value.
|
|
712
|
-
* @param byteWidth - Byte width of the field the code occupies.
|
|
713
|
-
* @returns The code as `0x`-prefixed hex, or its decimal form when no such field holds it.
|
|
714
|
-
*/
|
|
715
|
-
/** Rule scope discriminant: context (EVM environment) vs. calldata (ABI payload). */
|
|
716
|
-
declare const Scope: CodeMap<readonly [{
|
|
717
|
-
readonly key: "CONTEXT";
|
|
718
|
-
readonly code: 0;
|
|
719
|
-
readonly label: "context";
|
|
720
|
-
}, {
|
|
721
|
-
readonly key: "CALLDATA";
|
|
722
|
-
readonly code: 1;
|
|
723
|
-
readonly label: "calldata";
|
|
724
|
-
}]>;
|
|
725
|
-
/** Display metadata for a scope code. */
|
|
726
|
-
type ScopeInfo = {
|
|
727
|
-
label: string;
|
|
728
|
-
};
|
|
729
|
-
/**
|
|
730
|
-
* Map a scope code to its display label.
|
|
731
|
-
* @param code - Scope byte value.
|
|
732
|
-
* @returns Display metadata for the scope.
|
|
733
|
-
* @throws {CallciumError} If the code is not a recognised scope.
|
|
734
|
-
*/
|
|
735
|
-
declare function lookupScope(code: number): ScopeInfo;
|
|
736
|
-
/** ABI type code ranges and sentinel values for the descriptor format. */
|
|
737
|
-
declare const TypeCode: {
|
|
738
|
-
readonly UINT_MIN: 1;
|
|
739
|
-
readonly UINT_MAX: 32;
|
|
740
|
-
readonly INT_MIN: 33;
|
|
741
|
-
readonly INT_MAX: 64;
|
|
742
|
-
readonly ADDRESS: 65;
|
|
743
|
-
readonly BOOL: 66;
|
|
744
|
-
readonly FUNCTION: 67;
|
|
745
|
-
readonly FIXED_BYTES_MIN: 80;
|
|
746
|
-
readonly FIXED_BYTES_MAX: 111;
|
|
747
|
-
readonly BYTES: 112;
|
|
748
|
-
readonly STRING: 113;
|
|
749
|
-
readonly STATIC_ARRAY: 128;
|
|
750
|
-
readonly DYNAMIC_ARRAY: 129;
|
|
751
|
-
readonly TUPLE: 144;
|
|
752
|
-
};
|
|
753
|
-
/** Well-known context property IDs for context-scope rules. */
|
|
754
|
-
declare const ContextProperty: CodeMap<readonly [{
|
|
755
|
-
readonly key: "MSG_SENDER";
|
|
756
|
-
readonly code: 0;
|
|
757
|
-
readonly label: "msg.sender";
|
|
758
|
-
readonly contextKey: "msgSender";
|
|
759
|
-
readonly typeCode: 65;
|
|
760
|
-
}, {
|
|
761
|
-
readonly key: "MSG_VALUE";
|
|
762
|
-
readonly code: 1;
|
|
763
|
-
readonly label: "msg.value";
|
|
764
|
-
readonly contextKey: "msgValue";
|
|
765
|
-
readonly typeCode: 32;
|
|
766
|
-
}, {
|
|
767
|
-
readonly key: "BLOCK_TIMESTAMP";
|
|
768
|
-
readonly code: 2;
|
|
769
|
-
readonly label: "block.timestamp";
|
|
770
|
-
readonly contextKey: "blockTimestamp";
|
|
771
|
-
readonly typeCode: 32;
|
|
772
|
-
}, {
|
|
773
|
-
readonly key: "BLOCK_NUMBER";
|
|
774
|
-
readonly code: 3;
|
|
775
|
-
readonly label: "block.number";
|
|
776
|
-
readonly contextKey: "blockNumber";
|
|
777
|
-
readonly typeCode: 32;
|
|
778
|
-
}, {
|
|
779
|
-
readonly key: "CHAIN_ID";
|
|
780
|
-
readonly code: 4;
|
|
781
|
-
readonly label: "block.chainid";
|
|
782
|
-
readonly contextKey: "chainId";
|
|
783
|
-
readonly typeCode: 32;
|
|
784
|
-
}, {
|
|
785
|
-
readonly key: "TX_ORIGIN";
|
|
786
|
-
readonly code: 5;
|
|
787
|
-
readonly label: "tx.origin";
|
|
788
|
-
readonly contextKey: "txOrigin";
|
|
789
|
-
readonly typeCode: 65;
|
|
790
|
-
}, {
|
|
791
|
-
readonly key: "BASE_FEE";
|
|
792
|
-
readonly code: 6;
|
|
793
|
-
readonly label: "block.basefee";
|
|
794
|
-
readonly contextKey: "baseFee";
|
|
795
|
-
readonly typeCode: 32;
|
|
796
|
-
}, {
|
|
797
|
-
readonly key: "GAS_PRICE";
|
|
798
|
-
readonly code: 7;
|
|
799
|
-
readonly label: "tx.gasprice";
|
|
800
|
-
readonly contextKey: "gasPrice";
|
|
801
|
-
readonly typeCode: 32;
|
|
802
|
-
}]>;
|
|
803
|
-
/** Display metadata for a context property code. */
|
|
804
|
-
type ContextPropertyInfo = {
|
|
805
|
-
label: string;
|
|
806
|
-
contextKey: keyof Context;
|
|
807
|
-
typeCode: number;
|
|
808
|
-
};
|
|
809
|
-
/**
|
|
810
|
-
* Look up a context property code in the assigned set.
|
|
811
|
-
* @param code - Context property ID.
|
|
812
|
-
* @returns Display metadata, or undefined when the ID names no assigned property.
|
|
813
|
-
*/
|
|
814
|
-
declare function findContextProperty(code: number): ContextPropertyInfo | undefined;
|
|
815
|
-
/**
|
|
816
|
-
* Map a context property code to its display label and ABI type code.
|
|
817
|
-
* @param code - Context property ID.
|
|
818
|
-
* @returns Display metadata including the ABI type code for the property value.
|
|
819
|
-
* @throws {CallciumError} If the code is not a recognised context property.
|
|
820
|
-
*/
|
|
821
|
-
declare function lookupContextProperty(code: number): ContextPropertyInfo;
|
|
822
|
-
/** Operand count category for operator data validation. */
|
|
823
|
-
type Operands = "single" | "range" | "variadic";
|
|
824
|
-
/** @internal */
|
|
825
|
-
declare const OP_TABLE: readonly [{
|
|
826
|
-
readonly key: "EQ";
|
|
827
|
-
readonly code: 1;
|
|
828
|
-
readonly label: "==";
|
|
829
|
-
readonly operands: "single";
|
|
830
|
-
}, {
|
|
831
|
-
readonly key: "GT";
|
|
832
|
-
readonly code: 2;
|
|
833
|
-
readonly label: ">";
|
|
834
|
-
readonly operands: "single";
|
|
835
|
-
}, {
|
|
836
|
-
readonly key: "LT";
|
|
837
|
-
readonly code: 3;
|
|
838
|
-
readonly label: "<";
|
|
839
|
-
readonly operands: "single";
|
|
840
|
-
}, {
|
|
841
|
-
readonly key: "GTE";
|
|
842
|
-
readonly code: 4;
|
|
843
|
-
readonly label: ">=";
|
|
844
|
-
readonly operands: "single";
|
|
845
|
-
}, {
|
|
846
|
-
readonly key: "LTE";
|
|
847
|
-
readonly code: 5;
|
|
848
|
-
readonly label: "<=";
|
|
849
|
-
readonly operands: "single";
|
|
850
|
-
}, {
|
|
851
|
-
readonly key: "BETWEEN";
|
|
852
|
-
readonly code: 6;
|
|
853
|
-
readonly label: "between";
|
|
854
|
-
readonly operands: "range";
|
|
855
|
-
}, {
|
|
856
|
-
readonly key: "IN";
|
|
857
|
-
readonly code: 7;
|
|
858
|
-
readonly label: "in";
|
|
859
|
-
readonly operands: "variadic";
|
|
860
|
-
}, {
|
|
861
|
-
readonly key: "EQ_CTX";
|
|
862
|
-
readonly code: 8;
|
|
863
|
-
readonly label: "== ctx";
|
|
864
|
-
readonly operands: "single";
|
|
865
|
-
}, {
|
|
866
|
-
readonly key: "GT_CTX";
|
|
867
|
-
readonly code: 9;
|
|
868
|
-
readonly label: "> ctx";
|
|
869
|
-
readonly operands: "single";
|
|
870
|
-
}, {
|
|
871
|
-
readonly key: "LT_CTX";
|
|
872
|
-
readonly code: 10;
|
|
873
|
-
readonly label: "< ctx";
|
|
874
|
-
readonly operands: "single";
|
|
875
|
-
}, {
|
|
876
|
-
readonly key: "GTE_CTX";
|
|
877
|
-
readonly code: 11;
|
|
878
|
-
readonly label: ">= ctx";
|
|
879
|
-
readonly operands: "single";
|
|
880
|
-
}, {
|
|
881
|
-
readonly key: "LTE_CTX";
|
|
882
|
-
readonly code: 12;
|
|
883
|
-
readonly label: "<= ctx";
|
|
884
|
-
readonly operands: "single";
|
|
885
|
-
}, {
|
|
886
|
-
readonly key: "BITMASK_ALL";
|
|
887
|
-
readonly code: 16;
|
|
888
|
-
readonly label: "bitmask all";
|
|
889
|
-
readonly operands: "single";
|
|
890
|
-
}, {
|
|
891
|
-
readonly key: "BITMASK_ANY";
|
|
892
|
-
readonly code: 17;
|
|
893
|
-
readonly label: "bitmask any";
|
|
894
|
-
readonly operands: "single";
|
|
895
|
-
}, {
|
|
896
|
-
readonly key: "BITMASK_NONE";
|
|
897
|
-
readonly code: 18;
|
|
898
|
-
readonly label: "bitmask none";
|
|
899
|
-
readonly operands: "single";
|
|
900
|
-
}, {
|
|
901
|
-
readonly key: "LENGTH_EQ";
|
|
902
|
-
readonly code: 32;
|
|
903
|
-
readonly label: "length ==";
|
|
904
|
-
readonly operands: "single";
|
|
905
|
-
}, {
|
|
906
|
-
readonly key: "LENGTH_GT";
|
|
907
|
-
readonly code: 33;
|
|
908
|
-
readonly label: "length >";
|
|
909
|
-
readonly operands: "single";
|
|
910
|
-
}, {
|
|
911
|
-
readonly key: "LENGTH_LT";
|
|
912
|
-
readonly code: 34;
|
|
913
|
-
readonly label: "length <";
|
|
914
|
-
readonly operands: "single";
|
|
915
|
-
}, {
|
|
916
|
-
readonly key: "LENGTH_GTE";
|
|
917
|
-
readonly code: 35;
|
|
918
|
-
readonly label: "length >=";
|
|
919
|
-
readonly operands: "single";
|
|
920
|
-
}, {
|
|
921
|
-
readonly key: "LENGTH_LTE";
|
|
922
|
-
readonly code: 36;
|
|
923
|
-
readonly label: "length <=";
|
|
924
|
-
readonly operands: "single";
|
|
925
|
-
}, {
|
|
926
|
-
readonly key: "LENGTH_BETWEEN";
|
|
927
|
-
readonly code: 37;
|
|
928
|
-
readonly label: "length between";
|
|
929
|
-
readonly operands: "range";
|
|
930
|
-
}];
|
|
931
|
-
/** Callcium policy operator codes. */
|
|
932
|
-
declare const Op: CodeMap<typeof OP_TABLE> & {
|
|
933
|
-
readonly NOT: 0x80;
|
|
934
|
-
};
|
|
935
|
-
/** Display metadata for an operator code. */
|
|
936
|
-
type OpInfo = {
|
|
937
|
-
label: string;
|
|
938
|
-
operands: Operands;
|
|
939
|
-
};
|
|
940
|
-
/**
|
|
941
|
-
* Map an operator code to its display label. Strips the NOT flag automatically.
|
|
942
|
-
* @param code - Operator byte value (may include the NOT flag).
|
|
943
|
-
* @returns Display metadata for the base operator.
|
|
944
|
-
* @throws {CallciumError} If the base code is not a recognised operator.
|
|
945
|
-
*/
|
|
946
|
-
declare function lookupOp(code: number): OpInfo;
|
|
947
|
-
//#endregion
|
|
948
1001
|
//#region src/operators.d.ts
|
|
949
|
-
/** Return true when the operator code (with or without NOT flag) is a LENGTH_* variant. */
|
|
950
|
-
declare function isLengthOp(opCode: number): boolean;
|
|
951
|
-
/** Return true when the operator code (with or without NOT flag) is a *_CTX variant. */
|
|
952
|
-
declare function isContextOp(opCode: number): boolean;
|
|
953
1002
|
/** Structural category for a descriptor type code. */
|
|
954
1003
|
type TypeClass = "elementary" | "tuple" | "staticArray" | "dynamicArray";
|
|
955
1004
|
/** Structural classification without label. */
|
|
@@ -967,7 +1016,7 @@ type TypeCodeInfo = TypeClassInfo & {
|
|
|
967
1016
|
* @returns Label, type class, and whether the code alone implies ABI dynamism (false for tuples and static arrays).
|
|
968
1017
|
* @throws {CallciumError} If the code is not a recognised type code.
|
|
969
1018
|
*/
|
|
970
|
-
declare function lookupTypeCode(code: number): TypeCodeInfo;
|
|
1019
|
+
export declare function lookupTypeCode(code: number): TypeCodeInfo;
|
|
971
1020
|
//#endregion
|
|
972
1021
|
//#region src/errors.d.ts
|
|
973
1022
|
/**
|
|
@@ -975,14 +1024,13 @@ declare function lookupTypeCode(code: number): TypeCodeInfo;
|
|
|
975
1024
|
*
|
|
976
1025
|
* Each code names one invariant. Where Solidity detects the same invariant, the code is its error name transliterated
|
|
977
1026
|
* from `PascalCase` to `SCREAMING_SNAKE_CASE`. The codes under "Inputs and validation" have no counterpart: they name
|
|
978
|
-
* input a Solidity signature cannot express.
|
|
979
|
-
* error `PolicyBuilder.OutOfPhysicalBounds` and as an issue code, so the name is shared with `IssueCode`.
|
|
1027
|
+
* input a Solidity signature cannot express.
|
|
980
1028
|
*/
|
|
981
|
-
type CallciumErrorCode = "UNSUPPORTED_VERSION" | "
|
|
1029
|
+
type CallciumErrorCode = "UNSUPPORTED_VERSION" | "UNSUPPORTED_MINOR" | "MINOR_MISMATCH" | "MALFORMED_HEADER" | "UNEXPECTED_END" | "TRAILING_BYTES" | "EMPTY_POLICY" | "EMPTY_GROUP" | "GROUP_SIZE_MISMATCH" | "GROUP_OVERFLOW" | "RULE_TOO_SMALL" | "RULE_SIZE_MISMATCH" | "RULE_OVERFLOW" | "EMPTY_PATH" | "MALFORMED_PATH" | "PATH_TOO_DEEP" | "PARAM_INDEX_OUT_OF_BOUNDS" | "TUPLE_FIELD_OUT_OF_BOUNDS" | "STATIC_ARRAY_INDEX_OUT_OF_BOUNDS" | "NOT_COMPOSITE" | "QUANTIFIER_ON_NON_ARRAY" | "UNKNOWN_PATH_STEP" | "UNKNOWN_QUANTIFIER" | "INVALID_NESTED_LOOP" | "UNKNOWN_SCOPE" | "INVALID_CONTEXT_PATH" | "UNKNOWN_CONTEXT_PROPERTY" | "UNKNOWN_OPERATOR" | "INVALID_OPERATOR_BYTES" | "OPERATOR_TARGET_MISMATCH" | "INVALID_CONTEXT_OPERAND" | "DATA_LENGTH_MISMATCH" | "UNSORTED_IN_SET" | "MALFORMED_HINT" | "NO_CONSTRAINT_OPERATORS" | "EMPTY_SET" | "SET_TOO_LARGE" | "INVALID_RANGE" | "OUT_OF_PHYSICAL_BOUNDS" | "UNKNOWN_TYPE_CODE" | "NODE_LENGTH_TOO_SMALL" | "NODE_LENGTH_TOO_LARGE" | "NODE_OVERFLOW" | "NESTING_TOO_DEEP" | "INVALID_ARRAY_LENGTH" | "INVALID_TUPLE_FIELD_COUNT" | "STATIC_WORDS_TOO_LARGE" | "PARAM_COUNT_MISMATCH" | "TOO_MANY_PARAMS" | "NODE_LENGTH_MISMATCH" | "STATIC_WORDS_MISMATCH" | "INVALID_UINT_BITS" | "INVALID_INT_BITS" | "INVALID_BYTES_LENGTH" | "MALFORMED_TYPE_STRING" | "UNKNOWN_TYPE" | "MALFORMED_SIGNATURE" | "SIGNATURE_CONTAINS_WHITESPACE" | "INVALID_FUNCTION_NAME" | "GROUP_COUNT_OVERFLOW" | "RULE_COUNT_OVERFLOW" | "RULE_SIZE_OVERFLOW" | "DESC_LENGTH_OVERFLOW" | "VALIDATION_ERROR" | "INVALID_HEX" | "MALFORMED_SELECTOR" | "PATH_STEP_OVERFLOW" | "OPERAND_OVERFLOW" | "CONTEXT_VALUE_OVERFLOW" | "MALFORMED_CONTEXT_VALUE" | "MALFORMED_OPERAND";
|
|
982
1030
|
/**
|
|
983
1031
|
* Thrown on malformed or inadmissible SDK input. `offset`, when set, is the error's byte position in the source blob.
|
|
984
1032
|
*/
|
|
985
|
-
declare class CallciumError extends Error {
|
|
1033
|
+
export declare class CallciumError extends Error {
|
|
986
1034
|
readonly code: CallciumErrorCode;
|
|
987
1035
|
/** Byte position in the source blob where the error was detected, if applicable. */
|
|
988
1036
|
readonly offset?: number;
|
|
@@ -992,9 +1040,9 @@ declare class CallciumError extends Error {
|
|
|
992
1040
|
* Thrown by `PolicyBuilder.build` when validation reports any issue.
|
|
993
1041
|
*
|
|
994
1042
|
* Carries every issue the validator found. The `Error.message` is the first issue's message — a diagnostic summary, not
|
|
995
|
-
* a presentation contract.
|
|
1043
|
+
* a presentation contract. To render issues to users, iterate `issues` directly.
|
|
996
1044
|
*/
|
|
997
|
-
declare class ValidationError extends CallciumError {
|
|
1045
|
+
export declare class ValidationError extends CallciumError {
|
|
998
1046
|
readonly issues: Issue[];
|
|
999
1047
|
constructor(issues: Issue[]);
|
|
1000
1048
|
}
|
|
@@ -1003,13 +1051,13 @@ declare class ValidationError extends CallciumError {
|
|
|
1003
1051
|
* signals static issues in the policy itself.
|
|
1004
1052
|
*
|
|
1005
1053
|
* Carries the full list of structured violations (one per failed group). The `Error.message` is a minimal non-lossy
|
|
1006
|
-
* diagnostic summary built from the first violation's structured fields — not a presentation contract.
|
|
1007
|
-
*
|
|
1054
|
+
* diagnostic summary built from the first violation's structured fields — not a presentation contract. To render
|
|
1055
|
+
* violations to users, iterate `violations` directly.
|
|
1008
1056
|
*/
|
|
1009
|
-
declare class PolicyViolationError extends Error {
|
|
1057
|
+
export declare class PolicyViolationError extends Error {
|
|
1010
1058
|
readonly violations: Violation[];
|
|
1011
1059
|
constructor(violations: Violation[]);
|
|
1012
1060
|
}
|
|
1013
1061
|
//#endregion
|
|
1014
|
-
export {
|
|
1062
|
+
export type { Address, ArrayMeta, BodyRule, CallciumErrorCode, CalldataNavigationViolation, ComparisonCode, Constraint, ConstraintBuilder, Context, ContextPropertyInfo, DecodedDescriptor, DecodedFrameHint, DecodedGroup, DecodedHint, DecodedHop, DecodedLoop, DecodedNode, DecodedOperator, DecodedPolicy, DecodedRule, DecodedTest, EnforceResult, Field, Hex, Issue, IssueCategory, IssueCode, IssueSeverity, LoopRule, MissingContextViolation, MissingSelectorViolation, NavigationViolationCode, NonCanonicalValueViolation, OpInfo, Operands, PolicyData, QuantifierCode, QuantifierInfo, QuantifierLimitExceededViolation, QuantifierNoMatchViolation, Rule, RuleLocation, ScalarValue, ScopeCode, ScopeInfo, SelectorMismatchViolation, Span, TypeClass, TypeClassInfo, TypeCodeInfo, ValueMismatchViolation, Violation, ViolationCode };
|
|
1015
1063
|
//# sourceMappingURL=index.d.ts.map
|