@aztec/simulator 5.0.0-nightly.20260422 → 5.0.0-nightly.20260424

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.
@@ -9,4 +9,6 @@ export declare function invalidByteTest(tester: PublicTxSimulationTester): Promi
9
9
  export declare function instructionTruncatedTest(tester: PublicTxSimulationTester): Promise<import("@aztec/stdlib/avm").PublicTxResult>;
10
10
  export declare function invalidTagValueTest(tester: PublicTxSimulationTester): Promise<import("@aztec/stdlib/avm").PublicTxResult>;
11
11
  export declare function invalidTagValueAndInstructionTruncatedTest(tester: PublicTxSimulationTester): Promise<import("@aztec/stdlib/avm").PublicTxResult>;
12
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tX2J5dGVjb2RlX3Rlc3RzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcHVibGljL2ZpeHR1cmVzL2N1c3RvbV9ieXRlY29kZV90ZXN0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFhQSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUk1RSx3QkFBc0IsOEJBQThCLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsd0JBQXdCLHVEQWN6RztBQUtELHdCQUFzQixrQ0FBa0MsQ0FBQyxNQUFNLEVBQUUsd0JBQXdCLHVEQXNCeEY7QUFPRCx3QkFBc0IsOENBQThDLENBQUMsTUFBTSxFQUFFLHdCQUF3Qix1REF3QnBHO0FBT0Qsd0JBQXNCLHFEQUFxRCxDQUFDLE1BQU0sRUFBRSx3QkFBd0IsdURBeUIzRztBQUVELHdCQUFzQixnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsd0JBQXdCLHVEQVF0RTtBQUVELHdCQUFzQixpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsd0JBQXdCLHVEQWlCdkU7QUFHRCx3QkFBc0IsZUFBZSxDQUFDLE1BQU0sRUFBRSx3QkFBd0IsdURBT3JFO0FBR0Qsd0JBQXNCLHdCQUF3QixDQUFDLE1BQU0sRUFBRSx3QkFBd0IsdURBVTlFO0FBR0Qsd0JBQXNCLG1CQUFtQixDQUFDLE1BQU0sRUFBRSx3QkFBd0IsdURBWXpFO0FBR0Qsd0JBQXNCLDBDQUEwQyxDQUFDLE1BQU0sRUFBRSx3QkFBd0IsdURBaUJoRyJ9
12
+ export declare function setTruncationTest(tester: PublicTxSimulationTester): Promise<import("@aztec/stdlib/avm").PublicTxResult>;
13
+ export declare function castTruncationTest(tester: PublicTxSimulationTester): Promise<import("@aztec/stdlib/avm").PublicTxResult>;
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tX2J5dGVjb2RlX3Rlc3RzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcHVibGljL2ZpeHR1cmVzL2N1c3RvbV9ieXRlY29kZV90ZXN0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFhQSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUk1RSx3QkFBc0IsOEJBQThCLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsd0JBQXdCLHVEQWN6RztBQUtELHdCQUFzQixrQ0FBa0MsQ0FBQyxNQUFNLEVBQUUsd0JBQXdCLHVEQXNCeEY7QUFPRCx3QkFBc0IsOENBQThDLENBQUMsTUFBTSxFQUFFLHdCQUF3Qix1REF3QnBHO0FBT0Qsd0JBQXNCLHFEQUFxRCxDQUFDLE1BQU0sRUFBRSx3QkFBd0IsdURBeUIzRztBQUVELHdCQUFzQixnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsd0JBQXdCLHVEQVF0RTtBQUVELHdCQUFzQixpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsd0JBQXdCLHVEQWlCdkU7QUFHRCx3QkFBc0IsZUFBZSxDQUFDLE1BQU0sRUFBRSx3QkFBd0IsdURBT3JFO0FBR0Qsd0JBQXNCLHdCQUF3QixDQUFDLE1BQU0sRUFBRSx3QkFBd0IsdURBVTlFO0FBR0Qsd0JBQXNCLG1CQUFtQixDQUFDLE1BQU0sRUFBRSx3QkFBd0IsdURBWXpFO0FBR0Qsd0JBQXNCLDBDQUEwQyxDQUFDLE1BQU0sRUFBRSx3QkFBd0IsdURBaUJoRztBQU1ELHdCQUFzQixpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsd0JBQXdCLHVEQTJEdkU7QUFNRCx3QkFBc0Isa0JBQWtCLENBQUMsTUFBTSxFQUFFLHdCQUF3Qix1REFtRXhFIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"custom_bytecode_tests.d.ts","sourceRoot":"","sources":["../../../src/public/fixtures/custom_bytecode_tests.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAI5E,wBAAsB,8BAA8B,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,wBAAwB,uDAczG;AAKD,wBAAsB,kCAAkC,CAAC,MAAM,EAAE,wBAAwB,uDAsBxF;AAOD,wBAAsB,8CAA8C,CAAC,MAAM,EAAE,wBAAwB,uDAwBpG;AAOD,wBAAsB,qDAAqD,CAAC,MAAM,EAAE,wBAAwB,uDAyB3G;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,wBAAwB,uDAQtE;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,wBAAwB,uDAiBvE;AAGD,wBAAsB,eAAe,CAAC,MAAM,EAAE,wBAAwB,uDAOrE;AAGD,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,wBAAwB,uDAU9E;AAGD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,wBAAwB,uDAYzE;AAGD,wBAAsB,0CAA0C,CAAC,MAAM,EAAE,wBAAwB,uDAiBhG"}
1
+ {"version":3,"file":"custom_bytecode_tests.d.ts","sourceRoot":"","sources":["../../../src/public/fixtures/custom_bytecode_tests.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAI5E,wBAAsB,8BAA8B,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,wBAAwB,uDAczG;AAKD,wBAAsB,kCAAkC,CAAC,MAAM,EAAE,wBAAwB,uDAsBxF;AAOD,wBAAsB,8CAA8C,CAAC,MAAM,EAAE,wBAAwB,uDAwBpG;AAOD,wBAAsB,qDAAqD,CAAC,MAAM,EAAE,wBAAwB,uDAyB3G;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,wBAAwB,uDAQtE;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,wBAAwB,uDAiBvE;AAGD,wBAAsB,eAAe,CAAC,MAAM,EAAE,wBAAwB,uDAOrE;AAGD,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,wBAAwB,uDAU9E;AAGD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,wBAAwB,uDAYzE;AAGD,wBAAsB,0CAA0C,CAAC,MAAM,EAAE,wBAAwB,uDAiBhG;AAMD,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,wBAAwB,uDA2DvE;AAMD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,wBAAwB,uDAmExE"}
@@ -1,7 +1,7 @@
1
1
  import { strict as assert } from 'assert';
2
2
  import { TypeTag } from '../avm/avm_memory_types.js';
3
3
  import { Addressing, AddressingMode } from '../avm/opcodes/addressing_mode.js';
4
- import { Add, CalldataCopy, Jump, Return, Set } from '../avm/opcodes/index.js';
4
+ import { Add, CalldataCopy, Cast, Jump, Return, Set } from '../avm/opcodes/index.js';
5
5
  import { encodeToBytecode } from '../avm/serialization/bytecode_serialization.js';
6
6
  import { MAX_OPCODE_VALUE, Opcode, OperandType, getOperandSize } from '../avm/serialization/instruction_serialization.js';
7
7
  import { deployAndExecuteCustomBytecode } from './custom_bytecode_tester.js';
@@ -155,6 +155,66 @@ export async function invalidTagValueAndInstructionTruncatedTest(tester) {
155
155
  const txLabel = 'InvalidTagValueAndInstructionTruncated';
156
156
  return await deployAndExecuteCustomBytecode(bytecode, tester, txLabel);
157
157
  }
158
+ // Exercise SET truncation: set values whose widths exceed the target tag and
159
+ // rely on `buildFromTagTruncating` to truncate to the low bits of the tag.
160
+ // Covers sources larger than 128 bits (via SET_FF) and sources in (32, 128]
161
+ // bits (via SET_64) against destination tags U1/U8/U16/U32/U64/U128.
162
+ export async function setTruncationTest(tester) {
163
+ // 200-bit value: forces truncation for every target tag up to U128.
164
+ const LARGE_FIELD_VALUE = (1n << 200n) + 0x1234567890abcdef1234567890abcdefn;
165
+ // 40-bit value: forces truncation for target tags up to U32.
166
+ const LARGE_U64_VALUE = (1n << 40n) + 0xdeadbeefn;
167
+ const bytecode = encodeToBytecode([
168
+ // Zero U32 at offset 0 — used as the Return copy-size slot.
169
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 0, TypeTag.UINT32, /*value=*/ 0).as(Opcode.SET_8, Set.wireFormat8),
170
+ // Source >128 bits (via SET_FF) truncated to smaller target tags.
171
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 1, TypeTag.UINT128, LARGE_FIELD_VALUE).as(Opcode.SET_FF, Set.wireFormatFF),
172
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 2, TypeTag.UINT64, LARGE_FIELD_VALUE).as(Opcode.SET_FF, Set.wireFormatFF),
173
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 3, TypeTag.UINT32, LARGE_FIELD_VALUE).as(Opcode.SET_FF, Set.wireFormatFF),
174
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 4, TypeTag.UINT16, LARGE_FIELD_VALUE).as(Opcode.SET_FF, Set.wireFormatFF),
175
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 5, TypeTag.UINT8, LARGE_FIELD_VALUE).as(Opcode.SET_FF, Set.wireFormatFF),
176
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 6, TypeTag.UINT1, LARGE_FIELD_VALUE).as(Opcode.SET_FF, Set.wireFormatFF),
177
+ // Source in (32, 128] bits (via SET_64) truncated to smaller target tags.
178
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 7, TypeTag.UINT32, LARGE_U64_VALUE).as(Opcode.SET_64, Set.wireFormat64),
179
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 8, TypeTag.UINT16, LARGE_U64_VALUE).as(Opcode.SET_64, Set.wireFormat64),
180
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 9, TypeTag.UINT8, LARGE_U64_VALUE).as(Opcode.SET_64, Set.wireFormat64),
181
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 10, TypeTag.UINT1, LARGE_U64_VALUE).as(Opcode.SET_64, Set.wireFormat64),
182
+ new Return(/*addressing_mode=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 0)
183
+ ]);
184
+ const txLabel = 'SetTruncation';
185
+ return await deployAndExecuteCustomBytecode(bytecode, tester, txLabel);
186
+ }
187
+ // Exercise CAST truncation: store a wide source value in memory then CAST it
188
+ // to smaller destination tags. Covers sources larger than 128 bits (FIELD
189
+ // source) and sources in (32, 128] bits (UINT64 source) against destination
190
+ // tags U1/U8/U16/U32/U64/U128.
191
+ export async function castTruncationTest(tester) {
192
+ // 200-bit source: stored as FIELD so that CASTs to any integer tag truncate.
193
+ const LARGE_FIELD_VALUE = (1n << 200n) + 0x1234567890abcdef1234567890abcdefn;
194
+ // 40-bit source: stored as UINT64 so CASTs to U1/U8/U16/U32 truncate.
195
+ const LARGE_U64_VALUE = (1n << 40n) + 0xdeadbeefn;
196
+ const bytecode = encodeToBytecode([
197
+ // Zero U32 at offset 0 — used as the Return copy-size slot.
198
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 0, TypeTag.UINT32, /*value=*/ 0).as(Opcode.SET_8, Set.wireFormat8),
199
+ // Store wide FIELD source at offset 10, then CAST to smaller tags.
200
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 10, TypeTag.FIELD, LARGE_FIELD_VALUE).as(Opcode.SET_FF, Set.wireFormatFF),
201
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 11, TypeTag.UINT128).as(Opcode.CAST_8, Cast.wireFormat8),
202
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 12, TypeTag.UINT64).as(Opcode.CAST_8, Cast.wireFormat8),
203
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 13, TypeTag.UINT32).as(Opcode.CAST_8, Cast.wireFormat8),
204
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 14, TypeTag.UINT16).as(Opcode.CAST_8, Cast.wireFormat8),
205
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 15, TypeTag.UINT8).as(Opcode.CAST_8, Cast.wireFormat8),
206
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 16, TypeTag.UINT1).as(Opcode.CAST_8, Cast.wireFormat8),
207
+ // Store UINT64 source at offset 20, then CAST to smaller integer tags.
208
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 20, TypeTag.UINT64, LARGE_U64_VALUE).as(Opcode.SET_64, Set.wireFormat64),
209
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 20, /*dstOffset=*/ 21, TypeTag.UINT32).as(Opcode.CAST_8, Cast.wireFormat8),
210
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 20, /*dstOffset=*/ 22, TypeTag.UINT16).as(Opcode.CAST_8, Cast.wireFormat8),
211
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 20, /*dstOffset=*/ 23, TypeTag.UINT8).as(Opcode.CAST_8, Cast.wireFormat8),
212
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 20, /*dstOffset=*/ 24, TypeTag.UINT1).as(Opcode.CAST_8, Cast.wireFormat8),
213
+ new Return(/*addressing_mode=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 0)
214
+ ]);
215
+ const txLabel = 'CastTruncation';
216
+ return await deployAndExecuteCustomBytecode(bytecode, tester, txLabel);
217
+ }
158
218
  /**
159
219
  * Returns the offset of the tag in an instruction.
160
220
  * @details Loops over the wire format operand type entries until it finds the tag.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/simulator",
3
- "version": "5.0.0-nightly.20260422",
3
+ "version": "5.0.0-nightly.20260424",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./server": "./dest/server.js",
@@ -64,25 +64,25 @@
64
64
  ]
65
65
  },
66
66
  "dependencies": {
67
- "@aztec/constants": "5.0.0-nightly.20260422",
68
- "@aztec/foundation": "5.0.0-nightly.20260422",
69
- "@aztec/native": "5.0.0-nightly.20260422",
70
- "@aztec/noir-acvm_js": "5.0.0-nightly.20260422",
71
- "@aztec/noir-noirc_abi": "5.0.0-nightly.20260422",
72
- "@aztec/noir-protocol-circuits-types": "5.0.0-nightly.20260422",
73
- "@aztec/noir-types": "5.0.0-nightly.20260422",
74
- "@aztec/protocol-contracts": "5.0.0-nightly.20260422",
75
- "@aztec/stdlib": "5.0.0-nightly.20260422",
76
- "@aztec/telemetry-client": "5.0.0-nightly.20260422",
77
- "@aztec/world-state": "5.0.0-nightly.20260422",
67
+ "@aztec/constants": "5.0.0-nightly.20260424",
68
+ "@aztec/foundation": "5.0.0-nightly.20260424",
69
+ "@aztec/native": "5.0.0-nightly.20260424",
70
+ "@aztec/noir-acvm_js": "5.0.0-nightly.20260424",
71
+ "@aztec/noir-noirc_abi": "5.0.0-nightly.20260424",
72
+ "@aztec/noir-protocol-circuits-types": "5.0.0-nightly.20260424",
73
+ "@aztec/noir-types": "5.0.0-nightly.20260424",
74
+ "@aztec/protocol-contracts": "5.0.0-nightly.20260424",
75
+ "@aztec/stdlib": "5.0.0-nightly.20260424",
76
+ "@aztec/telemetry-client": "5.0.0-nightly.20260424",
77
+ "@aztec/world-state": "5.0.0-nightly.20260424",
78
78
  "lodash.clonedeep": "^4.5.0",
79
79
  "lodash.merge": "^4.6.2",
80
80
  "tslib": "^2.4.0"
81
81
  },
82
82
  "devDependencies": {
83
- "@aztec/kv-store": "5.0.0-nightly.20260422",
84
- "@aztec/noir-contracts.js": "5.0.0-nightly.20260422",
85
- "@aztec/noir-test-contracts.js": "5.0.0-nightly.20260422",
83
+ "@aztec/kv-store": "5.0.0-nightly.20260424",
84
+ "@aztec/noir-contracts.js": "5.0.0-nightly.20260424",
85
+ "@aztec/noir-test-contracts.js": "5.0.0-nightly.20260424",
86
86
  "@jest/globals": "^30.0.0",
87
87
  "@types/jest": "^30.0.0",
88
88
  "@types/lodash.clonedeep": "^4.5.7",
@@ -2,7 +2,7 @@ import { strict as assert } from 'assert';
2
2
 
3
3
  import { TypeTag } from '../avm/avm_memory_types.js';
4
4
  import { Addressing, AddressingMode } from '../avm/opcodes/addressing_mode.js';
5
- import { Add, CalldataCopy, Jump, Return, Set } from '../avm/opcodes/index.js';
5
+ import { Add, CalldataCopy, Cast, Jump, Return, Set } from '../avm/opcodes/index.js';
6
6
  import { encodeToBytecode } from '../avm/serialization/bytecode_serialization.js';
7
7
  import {
8
8
  MAX_OPCODE_VALUE,
@@ -208,6 +208,144 @@ export async function invalidTagValueAndInstructionTruncatedTest(tester: PublicT
208
208
  return await deployAndExecuteCustomBytecode(bytecode, tester, txLabel);
209
209
  }
210
210
 
211
+ // Exercise SET truncation: set values whose widths exceed the target tag and
212
+ // rely on `buildFromTagTruncating` to truncate to the low bits of the tag.
213
+ // Covers sources larger than 128 bits (via SET_FF) and sources in (32, 128]
214
+ // bits (via SET_64) against destination tags U1/U8/U16/U32/U64/U128.
215
+ export async function setTruncationTest(tester: PublicTxSimulationTester) {
216
+ // 200-bit value: forces truncation for every target tag up to U128.
217
+ const LARGE_FIELD_VALUE = (1n << 200n) + 0x1234567890abcdef1234567890abcdefn;
218
+ // 40-bit value: forces truncation for target tags up to U32.
219
+ const LARGE_U64_VALUE = (1n << 40n) + 0xdeadbeefn;
220
+
221
+ const bytecode = encodeToBytecode([
222
+ // Zero U32 at offset 0 — used as the Return copy-size slot.
223
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 0, TypeTag.UINT32, /*value=*/ 0).as(Opcode.SET_8, Set.wireFormat8),
224
+
225
+ // Source >128 bits (via SET_FF) truncated to smaller target tags.
226
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 1, TypeTag.UINT128, LARGE_FIELD_VALUE).as(
227
+ Opcode.SET_FF,
228
+ Set.wireFormatFF,
229
+ ),
230
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 2, TypeTag.UINT64, LARGE_FIELD_VALUE).as(
231
+ Opcode.SET_FF,
232
+ Set.wireFormatFF,
233
+ ),
234
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 3, TypeTag.UINT32, LARGE_FIELD_VALUE).as(
235
+ Opcode.SET_FF,
236
+ Set.wireFormatFF,
237
+ ),
238
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 4, TypeTag.UINT16, LARGE_FIELD_VALUE).as(
239
+ Opcode.SET_FF,
240
+ Set.wireFormatFF,
241
+ ),
242
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 5, TypeTag.UINT8, LARGE_FIELD_VALUE).as(
243
+ Opcode.SET_FF,
244
+ Set.wireFormatFF,
245
+ ),
246
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 6, TypeTag.UINT1, LARGE_FIELD_VALUE).as(
247
+ Opcode.SET_FF,
248
+ Set.wireFormatFF,
249
+ ),
250
+
251
+ // Source in (32, 128] bits (via SET_64) truncated to smaller target tags.
252
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 7, TypeTag.UINT32, LARGE_U64_VALUE).as(
253
+ Opcode.SET_64,
254
+ Set.wireFormat64,
255
+ ),
256
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 8, TypeTag.UINT16, LARGE_U64_VALUE).as(
257
+ Opcode.SET_64,
258
+ Set.wireFormat64,
259
+ ),
260
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 9, TypeTag.UINT8, LARGE_U64_VALUE).as(
261
+ Opcode.SET_64,
262
+ Set.wireFormat64,
263
+ ),
264
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 10, TypeTag.UINT1, LARGE_U64_VALUE).as(
265
+ Opcode.SET_64,
266
+ Set.wireFormat64,
267
+ ),
268
+
269
+ new Return(/*addressing_mode=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 0),
270
+ ]);
271
+
272
+ const txLabel = 'SetTruncation';
273
+ return await deployAndExecuteCustomBytecode(bytecode, tester, txLabel);
274
+ }
275
+
276
+ // Exercise CAST truncation: store a wide source value in memory then CAST it
277
+ // to smaller destination tags. Covers sources larger than 128 bits (FIELD
278
+ // source) and sources in (32, 128] bits (UINT64 source) against destination
279
+ // tags U1/U8/U16/U32/U64/U128.
280
+ export async function castTruncationTest(tester: PublicTxSimulationTester) {
281
+ // 200-bit source: stored as FIELD so that CASTs to any integer tag truncate.
282
+ const LARGE_FIELD_VALUE = (1n << 200n) + 0x1234567890abcdef1234567890abcdefn;
283
+ // 40-bit source: stored as UINT64 so CASTs to U1/U8/U16/U32 truncate.
284
+ const LARGE_U64_VALUE = (1n << 40n) + 0xdeadbeefn;
285
+
286
+ const bytecode = encodeToBytecode([
287
+ // Zero U32 at offset 0 — used as the Return copy-size slot.
288
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 0, TypeTag.UINT32, /*value=*/ 0).as(Opcode.SET_8, Set.wireFormat8),
289
+
290
+ // Store wide FIELD source at offset 10, then CAST to smaller tags.
291
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 10, TypeTag.FIELD, LARGE_FIELD_VALUE).as(
292
+ Opcode.SET_FF,
293
+ Set.wireFormatFF,
294
+ ),
295
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 11, TypeTag.UINT128).as(
296
+ Opcode.CAST_8,
297
+ Cast.wireFormat8,
298
+ ),
299
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 12, TypeTag.UINT64).as(
300
+ Opcode.CAST_8,
301
+ Cast.wireFormat8,
302
+ ),
303
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 13, TypeTag.UINT32).as(
304
+ Opcode.CAST_8,
305
+ Cast.wireFormat8,
306
+ ),
307
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 14, TypeTag.UINT16).as(
308
+ Opcode.CAST_8,
309
+ Cast.wireFormat8,
310
+ ),
311
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 15, TypeTag.UINT8).as(
312
+ Opcode.CAST_8,
313
+ Cast.wireFormat8,
314
+ ),
315
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 10, /*dstOffset=*/ 16, TypeTag.UINT1).as(
316
+ Opcode.CAST_8,
317
+ Cast.wireFormat8,
318
+ ),
319
+
320
+ // Store UINT64 source at offset 20, then CAST to smaller integer tags.
321
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 20, TypeTag.UINT64, LARGE_U64_VALUE).as(
322
+ Opcode.SET_64,
323
+ Set.wireFormat64,
324
+ ),
325
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 20, /*dstOffset=*/ 21, TypeTag.UINT32).as(
326
+ Opcode.CAST_8,
327
+ Cast.wireFormat8,
328
+ ),
329
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 20, /*dstOffset=*/ 22, TypeTag.UINT16).as(
330
+ Opcode.CAST_8,
331
+ Cast.wireFormat8,
332
+ ),
333
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 20, /*dstOffset=*/ 23, TypeTag.UINT8).as(
334
+ Opcode.CAST_8,
335
+ Cast.wireFormat8,
336
+ ),
337
+ new Cast(/*addressing_mode=*/ 0, /*srcOffset=*/ 20, /*dstOffset=*/ 24, TypeTag.UINT1).as(
338
+ Opcode.CAST_8,
339
+ Cast.wireFormat8,
340
+ ),
341
+
342
+ new Return(/*addressing_mode=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 0),
343
+ ]);
344
+
345
+ const txLabel = 'CastTruncation';
346
+ return await deployAndExecuteCustomBytecode(bytecode, tester, txLabel);
347
+ }
348
+
211
349
  /**
212
350
  * Returns the offset of the tag in an instruction.
213
351
  * @details Loops over the wire format operand type entries until it finds the tag.