diff --git a/yarn-project/foundation/src/abi/decoder.ts b/yarn-project/foundation/src/abi/decoder.ts index 1f4b0499d28c..2d1ec6a4637d 100644 --- a/yarn-project/foundation/src/abi/decoder.ts +++ b/yarn-project/foundation/src/abi/decoder.ts @@ -45,9 +45,9 @@ class AbiDecoder { } case 'struct': { if (isU128Struct(abiType)) { - const hi = this.decodeNext({ kind: 'field' }) as bigint; const lo = this.decodeNext({ kind: 'field' }) as bigint; - return U128.fromU64sBE(hi, lo).toInteger(); + const hi = this.decodeNext({ kind: 'field' }) as bigint; + return U128.fromU64sLE(lo, hi).toInteger(); } const struct: { [key: string]: AbiDecoded } = {}; diff --git a/yarn-project/foundation/src/abi/encoder.ts b/yarn-project/foundation/src/abi/encoder.ts index b3fdb81c41a0..6173663f6226 100644 --- a/yarn-project/foundation/src/abi/encoder.ts +++ b/yarn-project/foundation/src/abi/encoder.ts @@ -107,12 +107,11 @@ class ArgumentEncoder { break; } if (isU128Struct(abiType)) { - // U128 struct has high and low limbs - so we first convert the value to the 2 limbs and then we encode them - // --> this results in the limbs being added to the final flat array as [..., hi, lo, ...] (we stick to big - // endian!). + // U128 struct has low and high limbs - so we first convert the value to the 2 limbs and then we encode them + // --> this results in the limbs being added to the final flat array as [..., lo, hi, ...]. const value = new U128(arg); - this.encodeArgument({ kind: 'field' }, value.hi, `${name}.hi`); this.encodeArgument({ kind: 'field' }, value.lo, `${name}.lo`); + this.encodeArgument({ kind: 'field' }, value.hi, `${name}.hi`); break; } if (isWrappedFieldStruct(abiType)) { diff --git a/yarn-project/foundation/src/abi/u128.test.ts b/yarn-project/foundation/src/abi/u128.test.ts index fb76bdb97298..0c18baba722e 100644 --- a/yarn-project/foundation/src/abi/u128.test.ts +++ b/yarn-project/foundation/src/abi/u128.test.ts @@ -29,11 +29,11 @@ describe('U128', () => { }); }); - describe('fromU64sBE', () => { + describe('fromU64sLE', () => { it('correctly combines valid limbs', () => { - const hi = 0xcafebaben; const lo = 0xdeadbeefn; - const combined = U128.fromU64sBE(hi, lo); + const hi = 0xcafebaben; + const combined = U128.fromU64sLE(lo, hi); expect(combined.lo).toBe(lo); expect(combined.hi).toBe(hi); @@ -42,41 +42,41 @@ describe('U128', () => { it('accepts maximum valid limb values', () => { const maxLimb = 2n ** 64n - 1n; - const value = U128.fromU64sBE(maxLimb, maxLimb); + const value = U128.fromU64sLE(maxLimb, maxLimb); - expect(value.hi).toBe(maxLimb); expect(value.lo).toBe(maxLimb); + expect(value.hi).toBe(maxLimb); expect(value.toInteger()).toBe(2n ** 128n - 1n); }); it('throws for invalid lower limb', () => { const invalid = 2n ** 64n; - expect(() => U128.fromU64sBE(0n, invalid)).toThrow(`Lower limb ${invalid} is not within valid range`); + expect(() => U128.fromU64sLE(invalid, 0n)).toThrow(`Lower limb ${invalid} is not within valid range`); - expect(() => U128.fromU64sBE(0n, -1n)).toThrow('Lower limb -1 is not within valid range'); + expect(() => U128.fromU64sLE(-1n, 0n)).toThrow('Lower limb -1 is not within valid range'); }); it('throws for invalid higher limb', () => { const invalid = 2n ** 64n; - expect(() => U128.fromU64sBE(invalid, 0n)).toThrow(`Higher limb ${invalid} is not within valid range`); + expect(() => U128.fromU64sLE(0n, invalid)).toThrow(`Higher limb ${invalid} is not within valid range`); - expect(() => U128.fromU64sBE(-1n, 0n)).toThrow('Higher limb -1 is not within valid range'); + expect(() => U128.fromU64sLE(0n, -1n)).toThrow('Higher limb -1 is not within valid range'); }); }); describe('getters', () => { - it('correctly extracts hi and lo components', () => { + it('correctly extracts lo and hi components', () => { const testCases = [ - { hi: 0xcafebaben, lo: 0xdeadbeefn }, - { hi: 1n, lo: 0n }, - { hi: 0n, lo: 1n }, - { hi: 2n ** 64n - 1n, lo: 2n ** 64n - 1n }, + { lo: 0xdeadbeefn, hi: 0xcafebaben }, + { lo: 0n, hi: 1n }, + { lo: 1n, hi: 0n }, + { lo: 2n ** 64n - 1n, hi: 2n ** 64n - 1n }, ]; - for (const { hi, lo } of testCases) { - const value = U128.fromU64sBE(hi, lo); - expect(value.hi).toBe(hi); + for (const { lo, hi } of testCases) { + const value = U128.fromU64sLE(lo, hi); expect(value.lo).toBe(lo); + expect(value.hi).toBe(hi); } }); }); diff --git a/yarn-project/foundation/src/abi/u128.ts b/yarn-project/foundation/src/abi/u128.ts index 25a34079e413..4a0431bac074 100644 --- a/yarn-project/foundation/src/abi/u128.ts +++ b/yarn-project/foundation/src/abi/u128.ts @@ -15,14 +15,14 @@ export class U128 { this.value = value; } - static fromU64sBE(hi: bigint, lo: bigint): U128 { + static fromU64sLE(lo: bigint, hi: bigint): U128 { // Validate limbs are within valid ranges - if (hi < 0n || hi >= 2n ** 64n) { - throw new Error(`Higher limb ${hi} is not within valid range (0 to 2^64-1)`); - } if (lo < 0n || lo >= 2n ** 64n) { throw new Error(`Lower limb ${lo} is not within valid range (0 to 2^64-1)`); } + if (hi < 0n || hi >= 2n ** 64n) { + throw new Error(`Higher limb ${hi} is not within valid range (0 to 2^64-1)`); + } // Combine limbs into full value and create new instance const value = (hi << 64n) | lo;