solidity-scale-codec 0.1.0 → 0.1.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Solidity Scale Codec
2
2
 
3
- <a href="https://www.npmjs.com/~lucasgrasso" target="_blank"><img alt="NPM Version" src="https://img.shields.io/npm/v/solidity-scale-codec">
3
+ <a href="https://www.npmjs.com/package/solidity-scale-codec" target="_blank"><img alt="NPM Version" src="https://img.shields.io/npm/v/solidity-scale-codec">
4
4
  </a>
5
5
  <a href="https://github.com/LucasGrasso/solidity-scale-codec/blob/main/LICENSE" target="_blank"><img alt="GitHub License" src="https://img.shields.io/github/license/LucasGrasso/solidity-scale-codec"></a>
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solidity-scale-codec",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Solidity implementation of scale-codec.",
5
5
  "keywords": [
6
6
  "solidity",
@@ -16,7 +16,8 @@
16
16
  "url": "git+https://github.com/LucasGrasso/solidity-scale-codec.git"
17
17
  },
18
18
  "files": [
19
- "src/**/*.sol"
19
+ "src/**/*.sol",
20
+ "!src/**/*.t.sol"
20
21
  ],
21
22
  "license": "Apache-2.0",
22
23
  "author": "LucasGrasso",
@@ -1,326 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- pragma solidity ^0.8.20;
3
-
4
- import {Compact} from "./Compact.sol";
5
- import {Test} from "forge-std/Test.sol";
6
-
7
- /// @dev Wrapper contract to test reverts (vm.expectRevert needs external calls)
8
- contract CompactWrapper {
9
- function decode(
10
- bytes memory data
11
- ) external pure returns (uint256, uint256) {
12
- return Compact.decode(data);
13
- }
14
-
15
- function decodeAt(
16
- bytes memory data,
17
- uint256 offset
18
- ) external pure returns (uint256, uint256) {
19
- return Compact.decodeAt(data, offset);
20
- }
21
- }
22
-
23
- contract CompactTest is Test {
24
- CompactWrapper wrapper;
25
-
26
- function setUp() public {
27
- wrapper = new CompactWrapper();
28
- }
29
-
30
- // ============ Single-byte mode (0-63) ============
31
-
32
- function test_Encode_0() public pure {
33
- assertEq(Compact.encode(0), hex"00");
34
- }
35
-
36
- function test_Encode_1() public pure {
37
- assertEq(Compact.encode(1), hex"04");
38
- }
39
-
40
- function test_Encode_2() public pure {
41
- assertEq(Compact.encode(2), hex"08");
42
- }
43
-
44
- function test_Encode_3() public pure {
45
- assertEq(Compact.encode(3), hex"0c");
46
- }
47
-
48
- function test_Encode_63() public pure {
49
- assertEq(Compact.encode(63), hex"fc");
50
- }
51
-
52
- // ============ Two-byte mode (64-16383) ============
53
-
54
- function test_Encode_64() public pure {
55
- assertEq(Compact.encode(64), hex"0101");
56
- }
57
-
58
- function test_Encode_65() public pure {
59
- assertEq(Compact.encode(65), hex"0501");
60
- }
61
-
62
- function test_Encode_16383() public pure {
63
- assertEq(Compact.encode(16383), hex"fdff");
64
- }
65
-
66
- // ============ Four-byte mode (16384-1073741823) ============
67
-
68
- function test_Encode_16384() public pure {
69
- assertEq(Compact.encode(16384), hex"02000100");
70
- }
71
-
72
- function test_Encode_1073741823() public pure {
73
- assertEq(Compact.encode(1073741823), hex"feffffff");
74
- }
75
-
76
- // ============ Big-integer mode (>1073741823) ============
77
-
78
- function test_Encode_1073741824() public pure {
79
- assertEq(Compact.encode(1073741824), hex"0300000040");
80
- }
81
-
82
- function test_Encode_MaxUint32() public pure {
83
- assertEq(Compact.encode(type(uint32).max), hex"03ffffffff");
84
- }
85
-
86
- function test_Encode_MaxUint64() public pure {
87
- bytes memory encoded = Compact.encode(type(uint64).max);
88
- assertEq(encoded[0], bytes1(0x13));
89
- assertEq(encoded.length, 9);
90
- }
91
-
92
- function test_Encode_BigInt_100000000000000() public pure {
93
- assertEq(Compact.encode(100000000000000), hex"0b00407a10f35a");
94
- }
95
-
96
- // ============ Decode single-byte ============
97
-
98
- function test_Decode_0() public pure {
99
- (uint256 value, uint256 bytesRead) = Compact.decode(hex"00");
100
- assertEq(value, 0);
101
- assertEq(bytesRead, 1);
102
- }
103
-
104
- function test_Decode_1() public pure {
105
- (uint256 value, uint256 bytesRead) = Compact.decode(hex"04");
106
- assertEq(value, 1);
107
- assertEq(bytesRead, 1);
108
- }
109
-
110
- function test_Decode_63() public pure {
111
- (uint256 value, uint256 bytesRead) = Compact.decode(hex"fc");
112
- assertEq(value, 63);
113
- assertEq(bytesRead, 1);
114
- }
115
-
116
- // ============ Decode two-byte ============
117
-
118
- function test_Decode_64() public pure {
119
- (uint256 value, uint256 bytesRead) = Compact.decode(hex"0101");
120
- assertEq(value, 64);
121
- assertEq(bytesRead, 2);
122
- }
123
-
124
- function test_Decode_65() public pure {
125
- (uint256 value, uint256 bytesRead) = Compact.decode(hex"0501");
126
- assertEq(value, 65);
127
- assertEq(bytesRead, 2);
128
- }
129
-
130
- function test_Decode_16383() public pure {
131
- (uint256 value, uint256 bytesRead) = Compact.decode(hex"fdff");
132
- assertEq(value, 16383);
133
- assertEq(bytesRead, 2);
134
- }
135
-
136
- // ============ Decode four-byte ============
137
-
138
- function test_Decode_16384() public pure {
139
- (uint256 value, uint256 bytesRead) = Compact.decode(hex"02000100");
140
- assertEq(value, 16384);
141
- assertEq(bytesRead, 4);
142
- }
143
-
144
- function test_Decode_1073741823() public pure {
145
- (uint256 value, uint256 bytesRead) = Compact.decode(hex"feffffff");
146
- assertEq(value, 1073741823);
147
- assertEq(bytesRead, 4);
148
- }
149
-
150
- // ============ Decode big-integer ============
151
-
152
- function test_Decode_1073741824() public pure {
153
- (uint256 value, uint256 bytesRead) = Compact.decode(hex"0300000040");
154
- assertEq(value, 1073741824);
155
- assertEq(bytesRead, 5);
156
- }
157
-
158
- function test_Decode_MaxUint32() public pure {
159
- (uint256 value, uint256 bytesRead) = Compact.decode(hex"03ffffffff");
160
- assertEq(value, type(uint32).max);
161
- assertEq(bytesRead, 5);
162
- }
163
-
164
- function test_Decode_BigInt_100000000000000() public pure {
165
- (uint256 value, uint256 bytesRead) = Compact.decode(
166
- hex"0b00407a10f35a"
167
- );
168
- assertEq(value, 100000000000000);
169
- assertEq(bytesRead, 7);
170
- }
171
-
172
- // ============ DecodeAt with offset ============
173
-
174
- function test_DecodeAt() public pure {
175
- bytes memory data = hex"04010102000100";
176
-
177
- (uint256 v1, uint256 r1) = Compact.decodeAt(data, 0);
178
- assertEq(v1, 1);
179
- assertEq(r1, 1);
180
-
181
- (uint256 v2, uint256 r2) = Compact.decodeAt(data, 1);
182
- assertEq(v2, 64);
183
- assertEq(r2, 2);
184
-
185
- (uint256 v3, uint256 r3) = Compact.decodeAt(data, 3);
186
- assertEq(v3, 16384);
187
- assertEq(r3, 4);
188
- }
189
-
190
- // ============ Typed encoding ============
191
-
192
- function test_EncodeU8() public pure {
193
- assertEq(Compact.encodeU8(42), hex"a8");
194
- assertEq(Compact.encodeU8(255), hex"fd03");
195
- }
196
-
197
- function test_EncodeU16() public pure {
198
- assertEq(Compact.encodeU16(1000), hex"a10f");
199
- assertEq(Compact.encodeU16(65535), hex"feff0300");
200
- }
201
-
202
- function test_EncodeU32() public pure {
203
- assertEq(Compact.encodeU32(1000000), hex"02093d00");
204
- }
205
-
206
- // ============ Typed decoding ============
207
-
208
- function test_DecodeU8() public pure {
209
- (uint8 value, uint256 bytesRead) = Compact.decodeU8(hex"a8");
210
- assertEq(value, 42);
211
- assertEq(bytesRead, 1);
212
- }
213
-
214
- function test_DecodeU16() public pure {
215
- (uint16 value, uint256 bytesRead) = Compact.decodeU16(hex"a10f");
216
- assertEq(value, 1000);
217
- assertEq(bytesRead, 2);
218
- }
219
-
220
- function test_DecodeU32() public pure {
221
- (uint32 value, uint256 bytesRead) = Compact.decodeU32(hex"02093d00");
222
- assertEq(value, 1000000);
223
- assertEq(bytesRead, 4);
224
- }
225
-
226
- // ============ encodedLength ============
227
-
228
- function test_EncodedLength() public pure {
229
- assertEq(Compact.encodedLength(0), 1);
230
- assertEq(Compact.encodedLength(63), 1);
231
- assertEq(Compact.encodedLength(64), 2);
232
- assertEq(Compact.encodedLength(16383), 2);
233
- assertEq(Compact.encodedLength(16384), 4);
234
- assertEq(Compact.encodedLength(1073741823), 4);
235
- assertEq(Compact.encodedLength(1073741824), 5);
236
- assertEq(Compact.encodedLength(type(uint64).max), 9);
237
- }
238
-
239
- // ============ Mode checks ============
240
-
241
- function test_IsSingleByte() public pure {
242
- assertTrue(Compact.isSingleByte(0));
243
- assertTrue(Compact.isSingleByte(63));
244
- assertFalse(Compact.isSingleByte(64));
245
- }
246
-
247
- function test_IsTwoByte() public pure {
248
- assertFalse(Compact.isTwoByte(63));
249
- assertTrue(Compact.isTwoByte(64));
250
- assertTrue(Compact.isTwoByte(16383));
251
- assertFalse(Compact.isTwoByte(16384));
252
- }
253
-
254
- function test_IsFourByte() public pure {
255
- assertFalse(Compact.isFourByte(16383));
256
- assertTrue(Compact.isFourByte(16384));
257
- assertTrue(Compact.isFourByte(1073741823));
258
- assertFalse(Compact.isFourByte(1073741824));
259
- }
260
-
261
- function test_IsBigInt() public pure {
262
- assertFalse(Compact.isBigInt(1073741823));
263
- assertTrue(Compact.isBigInt(1073741824));
264
- assertTrue(Compact.isBigInt(type(uint256).max));
265
- }
266
-
267
- // ============ Fuzz roundtrip ============
268
-
269
- function testFuzz_Roundtrip(uint256 value) public pure {
270
- bytes memory encoded = Compact.encode(value);
271
- (uint256 decoded, ) = Compact.decode(encoded);
272
- assertEq(decoded, value);
273
- }
274
-
275
- function testFuzz_RoundtripU8(uint8 value) public pure {
276
- bytes memory encoded = Compact.encodeU8(value);
277
- (uint8 decoded, ) = Compact.decodeU8(encoded);
278
- assertEq(decoded, value);
279
- }
280
-
281
- function testFuzz_RoundtripU16(uint16 value) public pure {
282
- bytes memory encoded = Compact.encodeU16(value);
283
- (uint16 decoded, ) = Compact.decodeU16(encoded);
284
- assertEq(decoded, value);
285
- }
286
-
287
- function testFuzz_RoundtripU32(uint32 value) public pure {
288
- bytes memory encoded = Compact.encodeU32(value);
289
- (uint32 decoded, ) = Compact.decodeU32(encoded);
290
- assertEq(decoded, value);
291
- }
292
-
293
- function testFuzz_RoundtripU64(uint64 value) public pure {
294
- bytes memory encoded = Compact.encodeU64(value);
295
- (uint64 decoded, ) = Compact.decodeU64(encoded);
296
- assertEq(decoded, value);
297
- }
298
-
299
- function testFuzz_RoundtripU128(uint128 value) public pure {
300
- bytes memory encoded = Compact.encodeU128(value);
301
- (uint128 decoded, ) = Compact.decodeU128(encoded);
302
- assertEq(decoded, value);
303
- }
304
-
305
- // ============ Error cases (using wrapper for external calls) ============
306
-
307
- function test_RevertOnEmptyData() public {
308
- vm.expectRevert(Compact.InvalidCompactEncoding.selector);
309
- wrapper.decode(hex"");
310
- }
311
-
312
- function test_RevertOnTruncatedTwoByte() public {
313
- vm.expectRevert(Compact.InvalidCompactEncoding.selector);
314
- wrapper.decode(hex"01"); // Mode 0b01 but only 1 byte
315
- }
316
-
317
- function test_RevertOnTruncatedFourByte() public {
318
- vm.expectRevert(Compact.InvalidCompactEncoding.selector);
319
- wrapper.decode(hex"020001"); // Mode 0b10 but only 3 bytes
320
- }
321
-
322
- function test_RevertOnTruncatedBigInt() public {
323
- vm.expectRevert(Compact.InvalidCompactEncoding.selector);
324
- wrapper.decode(hex"030000"); // Header says 4 bytes but only 2 provided
325
- }
326
- }
@@ -1,542 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- pragma solidity ^0.8.20;
3
-
4
- import {LittleEndian} from "./LittleEndian.sol";
5
- import {Test} from "forge-std/Test.sol";
6
-
7
- contract LittleEndianTest is Test {
8
- // ============ uint8 / bytes1 ============
9
-
10
- function test_Convert8_Basic() public pure {
11
- assertEq(LittleEndian.toLittleEndianU8(0xAB), bytes1(0xAB));
12
- }
13
-
14
- function test_Convert8_Zero() public pure {
15
- assertEq(LittleEndian.toLittleEndianU8(0), bytes1(0));
16
- }
17
-
18
- function test_Convert8_Max() public pure {
19
- assertEq(LittleEndian.toLittleEndianU8(0xFF), bytes1(0xFF));
20
- }
21
-
22
- function testFuzz_Convert8(uint8 value) public pure {
23
- assertEq(uint8(LittleEndian.toLittleEndianU8(value)), value);
24
- }
25
-
26
- // ============ uint16 / bytes2 ============
27
-
28
- function test_Convert16_Basic() public pure {
29
- assertEq(LittleEndian.toLittleEndianU16(0xABCD), bytes2(0xCDAB));
30
- }
31
-
32
- function test_Convert16_Zero() public pure {
33
- assertEq(LittleEndian.toLittleEndianU16(0), bytes2(0));
34
- }
35
-
36
- function test_Convert16_Max() public pure {
37
- assertEq(LittleEndian.toLittleEndianU16(0xFFFF), bytes2(0xFFFF));
38
- }
39
-
40
- function testFuzz_Roundtrip16(uint16 value) public pure {
41
- bytes2 le = LittleEndian.toLittleEndianU16(value);
42
- uint16 reconstructed = uint16(uint8(le[0])) |
43
- (uint16(uint8(le[1])) << 8);
44
- assertEq(reconstructed, value);
45
- }
46
-
47
- // ============ uint32 / bytes4 ============
48
-
49
- function test_Convert32_Basic() public pure {
50
- assertEq(
51
- LittleEndian.toLittleEndianU32(0x12345678),
52
- bytes4(0x78563412)
53
- );
54
- }
55
-
56
- function test_Convert32_Zero() public pure {
57
- assertEq(LittleEndian.toLittleEndianU32(0), bytes4(0));
58
- }
59
-
60
- function test_Convert32_Max() public pure {
61
- assertEq(
62
- LittleEndian.toLittleEndianU32(0xFFFFFFFF),
63
- bytes4(0xFFFFFFFF)
64
- );
65
- }
66
-
67
- function testFuzz_Roundtrip32(uint32 value) public pure {
68
- bytes4 le = LittleEndian.toLittleEndianU32(value);
69
- uint32 reconstructed = uint32(uint8(le[0])) |
70
- (uint32(uint8(le[1])) << 8) |
71
- (uint32(uint8(le[2])) << 16) |
72
- (uint32(uint8(le[3])) << 24);
73
- assertEq(reconstructed, value);
74
- }
75
-
76
- // ============ uint64 / bytes8 ============
77
-
78
- function test_Convert64_Basic() public pure {
79
- assertEq(
80
- LittleEndian.toLittleEndianU64(0x0102030405060708),
81
- bytes8(0x0807060504030201)
82
- );
83
- }
84
-
85
- function test_Convert64_Zero() public pure {
86
- assertEq(LittleEndian.toLittleEndianU64(0), bytes8(0));
87
- }
88
-
89
- function test_Convert64_Max() public pure {
90
- assertEq(
91
- LittleEndian.toLittleEndianU64(type(uint64).max),
92
- bytes8(0xFFFFFFFFFFFFFFFF)
93
- );
94
- }
95
-
96
- function testFuzz_Roundtrip64(uint64 value) public pure {
97
- bytes8 le = LittleEndian.toLittleEndianU64(value);
98
- uint64 reconstructed;
99
- for (uint256 i = 0; i < 8; i++) {
100
- reconstructed |= uint64(uint8(le[i])) << (i * 8);
101
- }
102
- assertEq(reconstructed, value);
103
- }
104
-
105
- // ============ uint128 / bytes16 ============
106
-
107
- function test_Convert128_Basic() public pure {
108
- assertEq(
109
- LittleEndian.toLittleEndianU128(0x0102030405060708090a0b0c0d0e0f10),
110
- bytes16(0x100f0e0d0c0b0a090807060504030201)
111
- );
112
- }
113
-
114
- function test_Convert128_Zero() public pure {
115
- assertEq(LittleEndian.toLittleEndianU128(0), bytes16(0));
116
- }
117
-
118
- function test_Convert128_Max() public pure {
119
- assertEq(
120
- LittleEndian.toLittleEndianU128(type(uint128).max),
121
- bytes16(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
122
- );
123
- }
124
-
125
- function testFuzz_Roundtrip128(uint128 value) public pure {
126
- bytes16 le = LittleEndian.toLittleEndianU128(value);
127
- uint128 reconstructed;
128
- for (uint256 i = 0; i < 16; i++) {
129
- reconstructed |= uint128(uint8(le[i])) << (i * 8);
130
- }
131
- assertEq(reconstructed, value);
132
- }
133
-
134
- // ============ uint256 / bytes32 ============
135
-
136
- function test_Convert256_Basic() public pure {
137
- uint256 value = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20;
138
- assertEq(
139
- LittleEndian.toLittleEndianU256(value),
140
- bytes32(
141
- 0x201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201
142
- )
143
- );
144
- }
145
-
146
- function test_Convert256_Zero() public pure {
147
- assertEq(LittleEndian.toLittleEndianU256(0), bytes32(0));
148
- }
149
-
150
- function test_Convert256_Max() public pure {
151
- assertEq(
152
- LittleEndian.toLittleEndianU256(type(uint256).max),
153
- bytes32(type(uint256).max)
154
- );
155
- }
156
-
157
- function testFuzz_Roundtrip256(uint256 value) public pure {
158
- bytes32 le = LittleEndian.toLittleEndianU256(value);
159
- uint256 reconstructed;
160
- for (uint256 i = 0; i < 32; i++) {
161
- reconstructed |= uint256(uint8(le[i])) << (i * 8);
162
- }
163
- assertEq(reconstructed, value);
164
- }
165
-
166
- // ============ Idempotency: f(f(x)) == x ============
167
-
168
- function testFuzz_Idempotent16(uint16 value) public pure {
169
- bytes2 le = LittleEndian.toLittleEndianU16(value);
170
- bytes2 back = LittleEndian.toLittleEndianU16(uint16(le));
171
- assertEq(uint16(back), value);
172
- }
173
-
174
- function testFuzz_Idempotent32(uint32 value) public pure {
175
- bytes4 le = LittleEndian.toLittleEndianU32(value);
176
- bytes4 back = LittleEndian.toLittleEndianU32(uint32(le));
177
- assertEq(uint32(back), value);
178
- }
179
-
180
- function testFuzz_Idempotent64(uint64 value) public pure {
181
- bytes8 le = LittleEndian.toLittleEndianU64(value);
182
- bytes8 back = LittleEndian.toLittleEndianU64(uint64(le));
183
- assertEq(uint64(back), value);
184
- }
185
-
186
- function testFuzz_Idempotent128(uint128 value) public pure {
187
- bytes16 le = LittleEndian.toLittleEndianU128(value);
188
- bytes16 back = LittleEndian.toLittleEndianU128(uint128(le));
189
- assertEq(uint128(back), value);
190
- }
191
-
192
- function testFuzz_Idempotent256(uint256 value) public pure {
193
- bytes32 le = LittleEndian.toLittleEndianU256(value);
194
- bytes32 back = LittleEndian.toLittleEndianU256(uint256(le));
195
- assertEq(uint256(back), value);
196
- }
197
-
198
- // ============ Signed int8 ============
199
-
200
- function test_ConvertSigned8_Positive() public pure {
201
- assertEq(LittleEndian.toLittleEndianI8(int8(1)), bytes1(0x01));
202
- }
203
-
204
- function test_ConvertSigned8_Negative() public pure {
205
- assertEq(LittleEndian.toLittleEndianI8(int8(-1)), bytes1(0xff));
206
- }
207
-
208
- function test_ConvertSigned8_Min() public pure {
209
- assertEq(LittleEndian.toLittleEndianI8(type(int8).min), bytes1(0x80));
210
- }
211
-
212
- function test_ConvertSigned8_Max() public pure {
213
- assertEq(LittleEndian.toLittleEndianI8(type(int8).max), bytes1(0x7f));
214
- }
215
-
216
- // ============ Signed int16 ============
217
-
218
- function test_ConvertSigned16_Positive() public pure {
219
- assertEq(LittleEndian.toLittleEndianI16(int16(1)), bytes2(0x0100));
220
- }
221
-
222
- function test_ConvertSigned16_Negative() public pure {
223
- assertEq(LittleEndian.toLittleEndianI16(int16(-1)), bytes2(0xffff));
224
- }
225
-
226
- function test_ConvertSigned16_Neg256() public pure {
227
- assertEq(LittleEndian.toLittleEndianI16(int16(-256)), bytes2(0x00ff));
228
- }
229
-
230
- function test_ConvertSigned16_Min() public pure {
231
- assertEq(
232
- LittleEndian.toLittleEndianI16(type(int16).min),
233
- bytes2(0x0080)
234
- );
235
- }
236
-
237
- function test_ConvertSigned16_Max() public pure {
238
- assertEq(
239
- LittleEndian.toLittleEndianI16(type(int16).max),
240
- bytes2(0xff7f)
241
- );
242
- }
243
-
244
- // ============ Signed int32 ============
245
-
246
- function test_ConvertSigned32_Negative() public pure {
247
- assertEq(LittleEndian.toLittleEndianI32(int32(-1)), bytes4(0xffffffff));
248
- }
249
-
250
- function test_ConvertSigned32_Min() public pure {
251
- assertEq(
252
- LittleEndian.toLittleEndianI32(type(int32).min),
253
- bytes4(0x00000080)
254
- );
255
- }
256
-
257
- function test_ConvertSigned32_Max() public pure {
258
- assertEq(
259
- LittleEndian.toLittleEndianI32(type(int32).max),
260
- bytes4(0xffffff7f)
261
- );
262
- }
263
-
264
- // ============ Signed int64 ============
265
-
266
- function test_ConvertSigned64_Negative() public pure {
267
- assertEq(
268
- LittleEndian.toLittleEndianI64(int64(-1)),
269
- bytes8(0xffffffffffffffff)
270
- );
271
- }
272
-
273
- function test_ConvertSigned64_Min() public pure {
274
- assertEq(
275
- LittleEndian.toLittleEndianI64(type(int64).min),
276
- bytes8(0x0000000000000080)
277
- );
278
- }
279
-
280
- function test_ConvertSigned64_Max() public pure {
281
- assertEq(
282
- LittleEndian.toLittleEndianI64(type(int64).max),
283
- bytes8(0xffffffffffffff7f)
284
- );
285
- }
286
-
287
- // ============ Signed int128 ============
288
-
289
- function test_ConvertSigned128_Negative() public pure {
290
- assertEq(
291
- LittleEndian.toLittleEndianI128(int128(-1)),
292
- bytes16(0xffffffffffffffffffffffffffffffff)
293
- );
294
- }
295
-
296
- function test_ConvertSigned128_Min() public pure {
297
- assertEq(
298
- LittleEndian.toLittleEndianI128(type(int128).min),
299
- bytes16(0x00000000000000000000000000000080)
300
- );
301
- }
302
-
303
- // ============ Signed int256 ============
304
-
305
- function test_ConvertSigned256_Negative() public pure {
306
- assertEq(
307
- LittleEndian.toLittleEndianI256(int256(-1)),
308
- bytes32(type(uint256).max)
309
- );
310
- }
311
-
312
- function test_ConvertSigned256_Min() public pure {
313
- assertEq(
314
- LittleEndian.toLittleEndianI256(type(int256).min),
315
- bytes32(
316
- 0x0000000000000000000000000000000000000000000000000000000000000080
317
- )
318
- );
319
- }
320
-
321
- // ============ Fuzz signed ============
322
-
323
- function testFuzz_RoundtripSigned16(int16 value) public pure {
324
- bytes2 le = LittleEndian.toLittleEndianI16(value);
325
- int16 reconstructed = int16(
326
- uint16(uint8(le[0])) | (uint16(uint8(le[1])) << 8)
327
- );
328
- assertEq(reconstructed, value);
329
- }
330
-
331
- function testFuzz_RoundtripSigned32(int32 value) public pure {
332
- bytes4 le = LittleEndian.toLittleEndianI32(value);
333
- int32 reconstructed = int32(
334
- uint32(uint8(le[0])) |
335
- (uint32(uint8(le[1])) << 8) |
336
- (uint32(uint8(le[2])) << 16) |
337
- (uint32(uint8(le[3])) << 24)
338
- );
339
- assertEq(reconstructed, value);
340
- }
341
-
342
- // ============ fromLittleEndian unsigned ============
343
-
344
- function test_FromLE8_Basic() public pure {
345
- assertEq(LittleEndian.fromLittleEndianU8(bytes1(0xAB)), 0xAB);
346
- }
347
-
348
- function test_FromLE16_Basic() public pure {
349
- // 0xCDAB (LE) → 0xABCD
350
- assertEq(LittleEndian.fromLittleEndianU16(bytes2(0xCDAB)), 0xABCD);
351
- }
352
-
353
- function test_FromLE32_Basic() public pure {
354
- // 0x78563412 (LE) → 0x12345678
355
- assertEq(
356
- LittleEndian.fromLittleEndianU32(bytes4(0x78563412)),
357
- 0x12345678
358
- );
359
- }
360
-
361
- function test_FromLE64_Basic() public pure {
362
- // 0x0807060504030201 (LE) → 0x0102030405060708
363
- assertEq(
364
- LittleEndian.fromLittleEndianU64(bytes8(0x0807060504030201)),
365
- 0x0102030405060708
366
- );
367
- }
368
-
369
- function test_FromLE128_Basic() public pure {
370
- assertEq(
371
- LittleEndian.fromLittleEndianU128(
372
- bytes16(0x100f0e0d0c0b0a090807060504030201)
373
- ),
374
- 0x0102030405060708090a0b0c0d0e0f10
375
- );
376
- }
377
-
378
- function test_FromLE256_Basic() public pure {
379
- assertEq(
380
- LittleEndian.fromLittleEndianU256(
381
- bytes32(
382
- 0x201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201
383
- )
384
- ),
385
- 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20
386
- );
387
- }
388
-
389
- // ============ fromLittleEndian signed ============
390
-
391
- function test_FromLEi8_Negative() public pure {
392
- assertEq(LittleEndian.fromLittleEndianI8(bytes1(0xff)), int8(-1));
393
- }
394
-
395
- function test_FromLEi16_Negative() public pure {
396
- assertEq(LittleEndian.fromLittleEndianI16(bytes2(0xffff)), int16(-1));
397
- }
398
-
399
- function test_FromLEi16_Neg256() public pure {
400
- // 0x00ff (LE) → 0xff00 (BE) → -256
401
- assertEq(LittleEndian.fromLittleEndianI16(bytes2(0x00ff)), int16(-256));
402
- }
403
-
404
- function test_FromLEi32_Negative() public pure {
405
- assertEq(
406
- LittleEndian.fromLittleEndianI32(bytes4(0xffffffff)),
407
- int32(-1)
408
- );
409
- }
410
-
411
- function test_FromLEi32_Min() public pure {
412
- // 0x00000080 (LE) → 0x80000000 (BE) → int32.min
413
- assertEq(
414
- LittleEndian.fromLittleEndianI32(bytes4(0x00000080)),
415
- type(int32).min
416
- );
417
- }
418
-
419
- function test_FromLEi64_Negative() public pure {
420
- assertEq(
421
- LittleEndian.fromLittleEndianI64(bytes8(0xffffffffffffffff)),
422
- int64(-1)
423
- );
424
- }
425
-
426
- function test_FromLEi128_Negative() public pure {
427
- assertEq(
428
- LittleEndian.fromLittleEndianI128(
429
- bytes16(0xffffffffffffffffffffffffffffffff)
430
- ),
431
- int128(-1)
432
- );
433
- }
434
-
435
- function test_FromLEi256_Negative() public pure {
436
- assertEq(
437
- LittleEndian.fromLittleEndianI256(bytes32(type(uint256).max)),
438
- int256(-1)
439
- );
440
- }
441
-
442
- // ============ Fuzz roundtrip: toLE → fromLE ============
443
-
444
- function testFuzz_RoundtripFromLE8(uint8 value) public pure {
445
- assertEq(
446
- LittleEndian.fromLittleEndianU8(
447
- LittleEndian.toLittleEndianU8(value)
448
- ),
449
- value
450
- );
451
- }
452
-
453
- function testFuzz_RoundtripFromLE16(uint16 value) public pure {
454
- assertEq(
455
- LittleEndian.fromLittleEndianU16(
456
- LittleEndian.toLittleEndianU16(value)
457
- ),
458
- value
459
- );
460
- }
461
-
462
- function testFuzz_RoundtripFromLE32(uint32 value) public pure {
463
- assertEq(
464
- LittleEndian.fromLittleEndianU32(
465
- LittleEndian.toLittleEndianU32(value)
466
- ),
467
- value
468
- );
469
- }
470
-
471
- function testFuzz_RoundtripFromLE64(uint64 value) public pure {
472
- assertEq(
473
- LittleEndian.fromLittleEndianU64(
474
- LittleEndian.toLittleEndianU64(value)
475
- ),
476
- value
477
- );
478
- }
479
-
480
- function testFuzz_RoundtripFromLE128(uint128 value) public pure {
481
- assertEq(
482
- LittleEndian.fromLittleEndianU128(
483
- LittleEndian.toLittleEndianU128(value)
484
- ),
485
- value
486
- );
487
- }
488
-
489
- function testFuzz_RoundtripFromLE256(uint256 value) public pure {
490
- assertEq(
491
- LittleEndian.fromLittleEndianU256(
492
- LittleEndian.toLittleEndianU256(value)
493
- ),
494
- value
495
- );
496
- }
497
-
498
- function testFuzz_RoundtripFromLEi16(int16 value) public pure {
499
- assertEq(
500
- LittleEndian.fromLittleEndianI16(
501
- LittleEndian.toLittleEndianI16(value)
502
- ),
503
- value
504
- );
505
- }
506
-
507
- function testFuzz_RoundtripFromLEi32(int32 value) public pure {
508
- assertEq(
509
- LittleEndian.fromLittleEndianI32(
510
- LittleEndian.toLittleEndianI32(value)
511
- ),
512
- value
513
- );
514
- }
515
-
516
- function testFuzz_RoundtripFromLEi64(int64 value) public pure {
517
- assertEq(
518
- LittleEndian.fromLittleEndianI64(
519
- LittleEndian.toLittleEndianI64(value)
520
- ),
521
- value
522
- );
523
- }
524
-
525
- function testFuzz_RoundtripFromLEi128(int128 value) public pure {
526
- assertEq(
527
- LittleEndian.fromLittleEndianI128(
528
- LittleEndian.toLittleEndianI128(value)
529
- ),
530
- value
531
- );
532
- }
533
-
534
- function testFuzz_RoundtripFromLEi256(int256 value) public pure {
535
- assertEq(
536
- LittleEndian.fromLittleEndianI256(
537
- LittleEndian.toLittleEndianI256(value)
538
- ),
539
- value
540
- );
541
- }
542
- }