solidity-scale-codec 0.3.4 → 1.0.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +31 -3
  2. package/package.json +1 -1
  3. package/src/Utils/BytesUtils.sol +26 -0
  4. package/src/Utils/UnsignedUtils.sol +52 -0
  5. package/src/Xcm/VersionedXcm/VersionedXcm.sol +4 -1
  6. package/src/Xcm/VersionedXcm/VersionedXcmCodec.sol +11 -0
  7. package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCode.sol +8 -7
  8. package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCodeCodec.sol +18 -19
  9. package/src/Xcm/v5/AssetFilter/AssetFilter.sol +8 -8
  10. package/src/Xcm/v5/AssetFilter/AssetFilterCodec.sol +47 -34
  11. package/src/Xcm/v5/AssetInstance/AssetInstance.sol +13 -12
  12. package/src/Xcm/v5/AssetInstance/AssetInstanceCodec.sol +53 -56
  13. package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilter.sol +12 -12
  14. package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilterCodec.sol +48 -20
  15. package/src/Xcm/v5/Assets/Assets.sol +16 -0
  16. package/src/Xcm/v5/Assets/AssetsCodec.sol +3 -3
  17. package/src/Xcm/v5/BodyId/BodyId.sol +24 -24
  18. package/src/Xcm/v5/BodyId/BodyIdCodec.sol +41 -48
  19. package/src/Xcm/v5/BodyPart/BodyPart.sol +44 -28
  20. package/src/Xcm/v5/BodyPart/BodyPartCodec.sol +70 -37
  21. package/src/Xcm/v5/Constants.sol +2 -2
  22. package/src/Xcm/v5/Fungibility/Fungibility.sol +6 -6
  23. package/src/Xcm/v5/Fungibility/FungibilityCodec.sol +40 -36
  24. package/src/Xcm/v5/Hint/Hint.sol +5 -5
  25. package/src/Xcm/v5/Hint/HintCodec.sol +24 -20
  26. package/src/Xcm/v5/Instruction/Instruction.sol +81 -55
  27. package/src/Xcm/v5/Instruction/InstructionCodec.sol +1047 -73
  28. package/src/Xcm/v5/Junction/Junction.sol +55 -69
  29. package/src/Xcm/v5/Junction/JunctionCodec.sol +72 -135
  30. package/src/Xcm/v5/Junctions/Junctions.sol +34 -0
  31. package/src/Xcm/v5/Junctions/JunctionsCodec.sol +0 -18
  32. package/src/Xcm/v5/Location/Location.sol +8 -0
  33. package/src/Xcm/v5/NetworkId/NetworkId.sol +15 -16
  34. package/src/Xcm/v5/NetworkId/NetworkIdCodec.sol +57 -34
  35. package/src/Xcm/v5/OriginKind/OriginKindCodec.sol +1 -1
  36. package/src/Xcm/v5/Response/Response.sol +49 -40
  37. package/src/Xcm/v5/Response/ResponseCodec.sol +64 -54
  38. package/src/Xcm/v5/Weight/WeightCodec.sol +3 -2
  39. package/src/Xcm/v5/WeightLimit/WeightLimit.sol +6 -6
  40. package/src/Xcm/v5/WeightLimit/WeightLimitCodec.sol +32 -23
  41. package/src/Xcm/v5/WildAsset/WildAsset.sol +17 -25
  42. package/src/Xcm/v5/WildAsset/WildAssetCodec.sol +35 -38
  43. package/src/Xcm/v5/WildFungibility/WildFungibilityCodec.sol +6 -6
  44. package/src/Xcm/v5/Xcm/XcmBuilder.sol +689 -0
  45. package/src/Xcm/v5/XcmError/XcmError.sol +7 -7
  46. package/src/Xcm/v5/XcmError/XcmErrorCodec.sol +25 -22
@@ -3,7 +3,12 @@ pragma solidity ^0.8.28;
3
3
 
4
4
  import {Weight} from "../Weight/Weight.sol";
5
5
  import {WeightCodec} from "../Weight/WeightCodec.sol";
6
- import {WeightLimit, WeightLimitType} from "./WeightLimit.sol";
6
+ import {
7
+ WeightLimit,
8
+ WeightLimitVariant,
9
+ LimitedParams
10
+ } from "./WeightLimit.sol";
11
+ import {BytesUtils} from "../../../Utils/BytesUtils.sol";
7
12
 
8
13
  /// @title SCALE Codec for XCM v5 `WeightLimit`
9
14
  /// @notice SCALE-compliant encoder/decoder for the `WeightLimit` type.
@@ -11,7 +16,7 @@ import {WeightLimit, WeightLimitType} from "./WeightLimit.sol";
11
16
  /// @dev XCM v5 reference: https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v5/enum.WeightLimit.html
12
17
  library WeightLimitCodec {
13
18
  error InvalidWeightLimitLength();
14
- error InvalidWeightLimitType(uint8 wlType);
19
+ error InvalidWeightLimitVariant(uint8 variant);
15
20
 
16
21
  /// @notice Encodes a `WeightLimit` struct into SCALE bytes.
17
22
  /// @param wl The `WeightLimit` struct to encode.
@@ -19,7 +24,7 @@ library WeightLimitCodec {
19
24
  function encode(
20
25
  WeightLimit memory wl
21
26
  ) internal pure returns (bytes memory) {
22
- return abi.encodePacked(uint8(wl.wlType), wl.payload);
27
+ return abi.encodePacked(uint8(wl.variant), wl.payload);
23
28
  }
24
29
 
25
30
  /// @notice Returns the number of bytes that a `WeightLimit` would occupy when SCALE-encoded.
@@ -31,13 +36,13 @@ library WeightLimitCodec {
31
36
  uint256 offset
32
37
  ) internal pure returns (uint256) {
33
38
  if (data.length < offset + 1) revert InvalidWeightLimitLength();
34
- uint8 wlType = uint8(data[offset]);
35
- if (wlType == uint8(WeightLimitType.Unlimited)) {
39
+ uint8 variant = uint8(data[offset]);
40
+ if (variant == uint8(WeightLimitVariant.Unlimited)) {
36
41
  return 1;
37
- } else if (wlType == uint8(WeightLimitType.Limited)) {
42
+ } else if (variant == uint8(WeightLimitVariant.Limited)) {
38
43
  return 1 + WeightCodec.encodedSizeAt(data, offset + 1);
39
44
  } else {
40
- revert InvalidWeightLimitType(wlType);
45
+ revert InvalidWeightLimitVariant(variant);
41
46
  }
42
47
  }
43
48
 
@@ -60,29 +65,33 @@ library WeightLimitCodec {
60
65
  bytes memory data,
61
66
  uint256 offset
62
67
  ) internal pure returns (WeightLimit memory wl, uint256 bytesRead) {
63
- if (data.length < offset + 1) revert InvalidWeightLimitLength();
64
- uint8 wlType = uint8(data[offset]);
65
- if (wlType > uint8(WeightLimitType.Limited))
66
- revert InvalidWeightLimitType(wlType);
67
68
  uint256 size = encodedSizeAt(data, offset);
69
+ uint8 variant = uint8(data[offset]);
68
70
  uint256 payloadLength = size - 1;
69
- bytes memory payload = new bytes(payloadLength);
70
- for (uint256 i = 0; i < payloadLength; ++i) {
71
- payload[i] = data[offset + 1 + i];
72
- }
73
- wl = WeightLimit({wlType: WeightLimitType(wlType), payload: payload});
71
+ bytes memory payload = BytesUtils.copy(data, offset + 1, payloadLength);
72
+ wl = WeightLimit({
73
+ variant: WeightLimitVariant(variant),
74
+ payload: payload
75
+ });
74
76
  bytesRead = size;
75
77
  }
76
78
 
77
79
  /// @notice Decodes the `Weight` from a `Limited` weight limit.
78
80
  /// @param wl The `WeightLimit` struct. Must be of type `Limited`.
79
- /// @return The decoded `Weight`.
80
- function asWeight(
81
+ /// @return params A `LimitedParams` struct containing the decoded weight.
82
+ function asLimited(
81
83
  WeightLimit memory wl
82
- ) internal pure returns (Weight memory) {
83
- if (wl.wlType != WeightLimitType.Limited)
84
- revert InvalidWeightLimitType(uint8(wl.wlType));
85
- (Weight memory w, ) = WeightCodec.decode(wl.payload);
86
- return w;
84
+ ) internal pure returns (LimitedParams memory params) {
85
+ _assertVariant(wl, WeightLimitVariant.Limited);
86
+ (params.weight, ) = WeightCodec.decode(wl.payload);
87
+ }
88
+
89
+ function _assertVariant(
90
+ WeightLimit memory wl,
91
+ WeightLimitVariant expected
92
+ ) internal pure {
93
+ if (wl.variant != expected) {
94
+ revert InvalidWeightLimitVariant(uint8(wl.variant));
95
+ }
87
96
  }
88
97
  }
@@ -8,7 +8,7 @@ import {WildFungibility} from "../WildFungibility/WildFungibility.sol";
8
8
  import {WildFungibilityCodec} from "../WildFungibility/WildFungibilityCodec.sol";
9
9
 
10
10
  /// @notice Discriminant for the type of asset being specified in a `WildAsset`.
11
- enum WildAssetType {
11
+ enum WildAssetVariant {
12
12
  /// @custom:variant All assets in Holding.
13
13
  All,
14
14
  /// @custom:variant All assets in Holding of a given fungibility and ID.
@@ -45,9 +45,9 @@ struct AllCountedParams {
45
45
 
46
46
  /// @notice A wildcard representing a set of assets.
47
47
  struct WildAsset {
48
- /// @custom:property The type of wild asset, determining how to interpret the payload. See `WildAssetType` enum for possible values.
49
- WildAssetType waType;
50
- /// @custom:property The encoded payload containing the wild asset data, whose structure depends on the `waType`.
48
+ /// @custom:property The type of wild asset, determining how to interpret the payload. See `WildAssetVariant` enum for possible values.
49
+ WildAssetVariant variant;
50
+ /// @custom:property The encoded payload containing the wild asset data, whose structure depends on the `variant`.
51
51
  bytes payload;
52
52
  }
53
53
 
@@ -56,23 +56,19 @@ struct WildAsset {
56
56
  /// @notice Creates a `WildAsset` struct representing the `All` variant, which matches all assets in Holding.
57
57
  /// @return A `WildAsset` with the `All` variant.
58
58
  function all() pure returns (WildAsset memory) {
59
- return WildAsset({waType: WildAssetType.All, payload: ""});
59
+ return WildAsset({variant: WildAssetVariant.All, payload: ""});
60
60
  }
61
61
 
62
62
  /// @notice Creates a `WildAsset` struct representing the `AllOf` variant, which matches all assets in Holding of a given fungibility and ID.
63
- /// @param id The `AssetId` struct specifying the asset class to match against.
64
- /// @param fun The `WildFungibility` struct specifying the fungibility to match against.
63
+ /// @param params Parameters for the all-of variant.
65
64
  /// @return A `WildAsset` with the `AllOf` variant and the encoded parameters in the payload.
66
- function allOf(
67
- AssetId memory id,
68
- WildFungibility fun
69
- ) pure returns (WildAsset memory) {
65
+ function allOf(AllOfParams memory params) pure returns (WildAsset memory) {
70
66
  return
71
67
  WildAsset({
72
- waType: WildAssetType.AllOf,
68
+ variant: WildAssetVariant.AllOf,
73
69
  payload: abi.encodePacked(
74
- AssetIdCodec.encode(id),
75
- WildFungibilityCodec.encode(fun)
70
+ AssetIdCodec.encode(params.id),
71
+ WildFungibilityCodec.encode(params.fun)
76
72
  )
77
73
  });
78
74
  }
@@ -85,28 +81,24 @@ function allCounted(
85
81
  ) pure returns (WildAsset memory) {
86
82
  return
87
83
  WildAsset({
88
- waType: WildAssetType.AllCounted,
84
+ variant: WildAssetVariant.AllCounted,
89
85
  payload: abi.encodePacked(Compact.encode(params.count))
90
86
  });
91
87
  }
92
88
 
93
89
  /// @notice Creates a `WildAsset` struct representing the `AllOfCounted` variant, which matches all assets in Holding of a given fungibility and ID up to `count` individual assets (different instances of non-fungibles are separate assets).
94
- /// @param id The `AssetId` struct specifying the asset class to match against.
95
- /// @param fun The `WildFungibility` struct specifying the fungibility to match against.
96
- /// @param count The limit of assets against.
90
+ /// @param params Parameters for the all-of-counted variant.
97
91
  /// @return A `WildAsset` with the `AllOfCounted` variant and the encoded parameters in the payload.
98
92
  function allOfCounted(
99
- AssetId memory id,
100
- WildFungibility fun,
101
- uint32 count
93
+ AllOfCountedParams memory params
102
94
  ) pure returns (WildAsset memory) {
103
95
  return
104
96
  WildAsset({
105
- waType: WildAssetType.AllOfCounted,
97
+ variant: WildAssetVariant.AllOfCounted,
106
98
  payload: abi.encodePacked(
107
- AssetIdCodec.encode(id),
108
- WildFungibilityCodec.encode(fun),
109
- Compact.encode(count)
99
+ AssetIdCodec.encode(params.id),
100
+ WildFungibilityCodec.encode(params.fun),
101
+ Compact.encode(params.count)
110
102
  )
111
103
  });
112
104
  }
@@ -8,10 +8,13 @@ import {AssetId} from "../AssetId/AssetId.sol";
8
8
  import {WildFungibility} from "../WildFungibility/WildFungibility.sol";
9
9
  import {
10
10
  WildAsset,
11
- WildAssetType,
11
+ WildAssetVariant,
12
12
  AllOfParams,
13
+ AllCountedParams,
13
14
  AllOfCountedParams
14
15
  } from "./WildAsset.sol";
16
+ import {BytesUtils} from "../../../Utils/BytesUtils.sol";
17
+ import {UnsignedUtils} from "../../../Utils/UnsignedUtils.sol";
15
18
 
16
19
  /// @title SCALE Codec for XCM v5 `WildAsset`
17
20
  /// @notice SCALE-compliant encoder/decoder for the `WildAsset` type.
@@ -19,7 +22,7 @@ import {
19
22
  /// @dev XCM v5 reference: https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v5/index.html
20
23
  library WildAssetCodec {
21
24
  error InvalidWildAssetLength();
22
- error InvalidWildAssetType(uint8 waType);
25
+ error InvalidWildAssetVariant(uint8 variant);
23
26
  error InvalidWildAssetPayload();
24
27
 
25
28
  /// @notice Encodes a `WildAsset` struct into bytes.
@@ -28,7 +31,7 @@ library WildAssetCodec {
28
31
  function encode(
29
32
  WildAsset memory wildAsset
30
33
  ) internal pure returns (bytes memory) {
31
- return abi.encodePacked(uint8(wildAsset.waType), wildAsset.payload);
34
+ return abi.encodePacked(uint8(wildAsset.variant), wildAsset.payload);
32
35
  }
33
36
 
34
37
  /// @notice Returns the number of bytes that a `WildAsset` struct would occupy when SCALE-encoded.
@@ -42,21 +45,21 @@ library WildAssetCodec {
42
45
  if (offset >= data.length) {
43
46
  revert InvalidWildAssetLength();
44
47
  }
45
- uint8 waType = uint8(data[offset]);
46
- if (waType > uint8(WildAssetType.AllOfCounted)) {
47
- revert InvalidWildAssetType(waType);
48
+ uint8 variant = uint8(data[offset]);
49
+ if (variant > uint8(WildAssetVariant.AllOfCounted)) {
50
+ revert InvalidWildAssetVariant(variant);
48
51
  }
49
52
  uint256 payloadLength;
50
- if (waType == uint8(WildAssetType.All)) {
53
+ if (variant == uint8(WildAssetVariant.All)) {
51
54
  payloadLength = 0;
52
- } else if (waType == uint8(WildAssetType.AllOf)) {
55
+ } else if (variant == uint8(WildAssetVariant.AllOf)) {
53
56
  uint256 idSize = AssetIdCodec.encodedSizeAt(data, offset + 1);
54
57
  payloadLength =
55
58
  idSize +
56
59
  WildFungibilityCodec.encodedSizeAt(data, offset + 1 + idSize);
57
- } else if (waType == uint8(WildAssetType.AllCounted)) {
60
+ } else if (variant == uint8(WildAssetVariant.AllCounted)) {
58
61
  payloadLength = Compact.encodedSizeAt(data, offset + 1);
59
- } else if (waType == uint8(WildAssetType.AllOfCounted)) {
62
+ } else if (variant == uint8(WildAssetVariant.AllOfCounted)) {
60
63
  uint256 idSize = AssetIdCodec.encodedSizeAt(data, offset + 1);
61
64
  uint256 funSize = WildFungibilityCodec.encodedSizeAt(
62
65
  data,
@@ -67,9 +70,9 @@ library WildAssetCodec {
67
70
  funSize +
68
71
  Compact.encodedSizeAt(data, offset + 1 + idSize + funSize);
69
72
  } else {
70
- revert InvalidWildAssetType(waType);
73
+ revert InvalidWildAssetVariant(variant);
71
74
  }
72
- return 1 + payloadLength; // 1 byte for the waType
75
+ return 1 + payloadLength; // 1 byte for the variant
73
76
  }
74
77
 
75
78
  /// @notice Decodes a `WildAsset` instance from bytes starting at the beginning of the data.
@@ -91,19 +94,10 @@ library WildAssetCodec {
91
94
  bytes memory data,
92
95
  uint256 offset
93
96
  ) internal pure returns (WildAsset memory wildAsset, uint256 bytesRead) {
94
- if (offset >= data.length) {
95
- revert InvalidWildAssetLength();
96
- }
97
- uint8 waType = uint8(data[offset]);
98
- if (waType > uint8(WildAssetType.AllOfCounted)) {
99
- revert InvalidWildAssetType(waType);
100
- }
101
- wildAsset.waType = WildAssetType(waType);
102
- uint256 payloadLength = encodedSizeAt(data, offset) - 1; // subtract 1 byte for the waType
103
- wildAsset.payload = new bytes(payloadLength);
104
- for (uint256 i = 0; i < payloadLength; i++) {
105
- wildAsset.payload[i] = data[offset + 1 + i];
106
- }
97
+ uint256 payloadLength = encodedSizeAt(data, offset) - 1; // subtract 1 byte for the variant
98
+ uint8 variant = uint8(data[offset]);
99
+ wildAsset.variant = WildAssetVariant(variant);
100
+ wildAsset.payload = BytesUtils.copy(data, offset + 1, payloadLength);
107
101
  bytesRead = 1 + payloadLength;
108
102
  }
109
103
 
@@ -113,9 +107,7 @@ library WildAssetCodec {
113
107
  function asAllOf(
114
108
  WildAsset memory wildAsset
115
109
  ) internal pure returns (AllOfParams memory params) {
116
- if (wildAsset.waType != WildAssetType.AllOf) {
117
- revert InvalidWildAssetType(uint8(wildAsset.waType));
118
- }
110
+ _assertVariant(wildAsset, WildAssetVariant.AllOf);
119
111
  uint256 bytesRead;
120
112
  (params.id, bytesRead) = AssetIdCodec.decode(wildAsset.payload);
121
113
  (params.fun, ) = WildFungibilityCodec.decodeAt(
@@ -126,16 +118,14 @@ library WildAssetCodec {
126
118
 
127
119
  /// @notice Decodes the parameters of a `WildAsset` with the `AllCounted` variant from its payload.
128
120
  /// @param wildAsset The `WildAsset` struct. Must have the `AllCounted` variant.
129
- /// @return count The `count` parameter decoded from the payload, representing the limit of assets to match against.
121
+ /// @return params An `AllCountedParams` struct containing the decoded parameters from the payload, including the count limit.
130
122
  function asAllCounted(
131
123
  WildAsset memory wildAsset
132
- ) internal pure returns (uint32 count) {
133
- if (wildAsset.waType != WildAssetType.AllCounted) {
134
- revert InvalidWildAssetType(uint8(wildAsset.waType));
135
- }
124
+ ) internal pure returns (AllCountedParams memory params) {
125
+ _assertVariant(wildAsset, WildAssetVariant.AllCounted);
136
126
  uint256 decodedCount;
137
127
  (decodedCount, ) = Compact.decode(wildAsset.payload);
138
- count = uint32(decodedCount);
128
+ params.count = UnsignedUtils.toU32(decodedCount);
139
129
  }
140
130
 
141
131
  /// @notice Decodes the parameters of a `WildAsset` with the `AllOfCounted` variant from its payload.
@@ -144,9 +134,7 @@ library WildAssetCodec {
144
134
  function asAllOfCounted(
145
135
  WildAsset memory wildAsset
146
136
  ) internal pure returns (AllOfCountedParams memory params) {
147
- if (wildAsset.waType != WildAssetType.AllOfCounted) {
148
- revert InvalidWildAssetType(uint8(wildAsset.waType));
149
- }
137
+ _assertVariant(wildAsset, WildAssetVariant.AllOfCounted);
150
138
  uint256 offset = 0;
151
139
  uint256 bytesRead;
152
140
  (params.id, bytesRead) = AssetIdCodec.decodeAt(
@@ -161,6 +149,15 @@ library WildAssetCodec {
161
149
  offset += bytesRead;
162
150
  uint256 decodedCount;
163
151
  (decodedCount, ) = Compact.decodeAt(wildAsset.payload, offset);
164
- params.count = uint32(decodedCount);
152
+ params.count = UnsignedUtils.toU32(decodedCount);
153
+ }
154
+
155
+ function _assertVariant(
156
+ WildAsset memory wildAsset,
157
+ WildAssetVariant expected
158
+ ) internal pure {
159
+ if (wildAsset.variant != expected) {
160
+ revert InvalidWildAssetVariant(uint8(wildAsset.variant));
161
+ }
165
162
  }
166
163
  }
@@ -8,8 +8,8 @@ import {WildFungibility} from "./WildFungibility.sol";
8
8
  /// @dev SCALE reference: https://docs.polkadot.com/polkadot-protocol/basics/data-encoding
9
9
  /// @dev XCM v5 reference: https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v5/index.html
10
10
  library WildFungibilityCodec {
11
- error InvalidWildFungibilityLength(uint256 length);
12
- error InvalidWildFungibilityType(uint8 fType);
11
+ error InvalidWildFungibilityLength();
12
+ error InvalidWildFungibility(uint8 fType);
13
13
 
14
14
  /// @notice Encodes a `WildFungibility` value into bytes.
15
15
  /// @param wildFungibility The `WildFungibility` value to encode.
@@ -29,7 +29,7 @@ library WildFungibilityCodec {
29
29
  uint256 offset
30
30
  ) internal pure returns (uint256) {
31
31
  if (offset >= data.length) {
32
- revert InvalidWildFungibilityLength(data.length - offset);
32
+ revert InvalidWildFungibilityLength();
33
33
  }
34
34
  return 1;
35
35
  }
@@ -62,11 +62,11 @@ library WildFungibilityCodec {
62
62
  returns (WildFungibility wildFungibility, uint256 bytesRead)
63
63
  {
64
64
  if (offset >= data.length) {
65
- revert InvalidWildFungibilityLength(data.length - offset);
65
+ revert InvalidWildFungibilityLength();
66
66
  }
67
67
  uint8 fType = uint8(data[offset]);
68
- if (fType > uint8(WildFungibility.NonFungible)) {
69
- revert InvalidWildFungibilityType(fType);
68
+ if (fType > uint8(type(WildFungibility).max)) {
69
+ revert InvalidWildFungibility(fType);
70
70
  }
71
71
  wildFungibility = WildFungibility(fType);
72
72
  bytesRead = 1;