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.
- package/CHANGELOG.md +31 -3
- package/package.json +1 -1
- package/src/Utils/BytesUtils.sol +26 -0
- package/src/Utils/UnsignedUtils.sol +52 -0
- package/src/Xcm/VersionedXcm/VersionedXcm.sol +4 -1
- package/src/Xcm/VersionedXcm/VersionedXcmCodec.sol +11 -0
- package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCode.sol +8 -7
- package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCodeCodec.sol +18 -19
- package/src/Xcm/v5/AssetFilter/AssetFilter.sol +8 -8
- package/src/Xcm/v5/AssetFilter/AssetFilterCodec.sol +47 -34
- package/src/Xcm/v5/AssetInstance/AssetInstance.sol +13 -12
- package/src/Xcm/v5/AssetInstance/AssetInstanceCodec.sol +53 -56
- package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilter.sol +12 -12
- package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilterCodec.sol +48 -20
- package/src/Xcm/v5/Assets/Assets.sol +16 -0
- package/src/Xcm/v5/Assets/AssetsCodec.sol +3 -3
- package/src/Xcm/v5/BodyId/BodyId.sol +24 -24
- package/src/Xcm/v5/BodyId/BodyIdCodec.sol +41 -48
- package/src/Xcm/v5/BodyPart/BodyPart.sol +44 -28
- package/src/Xcm/v5/BodyPart/BodyPartCodec.sol +70 -37
- package/src/Xcm/v5/Constants.sol +2 -2
- package/src/Xcm/v5/Fungibility/Fungibility.sol +6 -6
- package/src/Xcm/v5/Fungibility/FungibilityCodec.sol +40 -36
- package/src/Xcm/v5/Hint/Hint.sol +5 -5
- package/src/Xcm/v5/Hint/HintCodec.sol +24 -20
- package/src/Xcm/v5/Instruction/Instruction.sol +81 -55
- package/src/Xcm/v5/Instruction/InstructionCodec.sol +1047 -73
- package/src/Xcm/v5/Junction/Junction.sol +55 -69
- package/src/Xcm/v5/Junction/JunctionCodec.sol +72 -135
- package/src/Xcm/v5/Junctions/Junctions.sol +34 -0
- package/src/Xcm/v5/Junctions/JunctionsCodec.sol +0 -18
- package/src/Xcm/v5/Location/Location.sol +8 -0
- package/src/Xcm/v5/NetworkId/NetworkId.sol +15 -16
- package/src/Xcm/v5/NetworkId/NetworkIdCodec.sol +57 -34
- package/src/Xcm/v5/OriginKind/OriginKindCodec.sol +1 -1
- package/src/Xcm/v5/Response/Response.sol +49 -40
- package/src/Xcm/v5/Response/ResponseCodec.sol +64 -54
- package/src/Xcm/v5/Weight/WeightCodec.sol +3 -2
- package/src/Xcm/v5/WeightLimit/WeightLimit.sol +6 -6
- package/src/Xcm/v5/WeightLimit/WeightLimitCodec.sol +32 -23
- package/src/Xcm/v5/WildAsset/WildAsset.sol +17 -25
- package/src/Xcm/v5/WildAsset/WildAssetCodec.sol +35 -38
- package/src/Xcm/v5/WildFungibility/WildFungibilityCodec.sol +6 -6
- package/src/Xcm/v5/Xcm/XcmBuilder.sol +689 -0
- package/src/Xcm/v5/XcmError/XcmError.sol +7 -7
- package/src/Xcm/v5/XcmError/XcmErrorCodec.sol +25 -22
|
@@ -6,7 +6,17 @@ import {Bytes4} from "../../../Scale/Bytes/Bytes4.sol";
|
|
|
6
6
|
import {Bytes8} from "../../../Scale/Bytes/Bytes8.sol";
|
|
7
7
|
import {Bytes16} from "../../../Scale/Bytes/Bytes16.sol";
|
|
8
8
|
import {Bytes32} from "../../../Scale/Bytes/Bytes32.sol";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
AssetInstance,
|
|
11
|
+
AssetInstanceVariant,
|
|
12
|
+
IndexParams,
|
|
13
|
+
Array4Params,
|
|
14
|
+
Array8Params,
|
|
15
|
+
Array16Params,
|
|
16
|
+
Array32Params
|
|
17
|
+
} from "./AssetInstance.sol";
|
|
18
|
+
import {BytesUtils} from "../../../Utils/BytesUtils.sol";
|
|
19
|
+
import {UnsignedUtils} from "../../../Utils/UnsignedUtils.sol";
|
|
10
20
|
|
|
11
21
|
/// @title SCALE Codec for XCM v5 `AssetInstance`
|
|
12
22
|
/// @notice SCALE-compliant encoder/decoder for the `AssetInstance` type.
|
|
@@ -14,8 +24,7 @@ import {AssetInstance, AssetInstanceType} from "./AssetInstance.sol";
|
|
|
14
24
|
/// @dev XCM v5 reference: https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v5/index.html
|
|
15
25
|
library AssetInstanceCodec {
|
|
16
26
|
error InvalidAssetInstanceLength();
|
|
17
|
-
error
|
|
18
|
-
error InvalidAssetInstancePayload();
|
|
27
|
+
error InvalidAssetInstanceVariant(uint8 variant);
|
|
19
28
|
|
|
20
29
|
/// @notice Encodes an `AssetInstance` struct into bytes.
|
|
21
30
|
/// @param assetInstance The `AssetInstance` struct to encode.
|
|
@@ -23,7 +32,7 @@ library AssetInstanceCodec {
|
|
|
23
32
|
function encode(
|
|
24
33
|
AssetInstance memory assetInstance
|
|
25
34
|
) internal pure returns (bytes memory) {
|
|
26
|
-
return abi.encodePacked(assetInstance.
|
|
35
|
+
return abi.encodePacked(assetInstance.variant, assetInstance.payload);
|
|
27
36
|
}
|
|
28
37
|
|
|
29
38
|
/// @notice Returns the total number of bytes that an `AssetInstance` would occupy when encoded, based on the type and payload.
|
|
@@ -37,22 +46,22 @@ library AssetInstanceCodec {
|
|
|
37
46
|
if (data.length < offset + 1) {
|
|
38
47
|
revert InvalidAssetInstanceLength();
|
|
39
48
|
}
|
|
40
|
-
uint8
|
|
49
|
+
uint8 variant = uint8(data[offset]);
|
|
41
50
|
uint256 payloadLength;
|
|
42
|
-
if (
|
|
51
|
+
if (variant == uint8(AssetInstanceVariant.Index)) {
|
|
43
52
|
payloadLength = Compact.encodedSizeAt(data, offset + 1);
|
|
44
|
-
} else if (
|
|
53
|
+
} else if (variant == uint8(AssetInstanceVariant.Array4)) {
|
|
45
54
|
payloadLength = 4;
|
|
46
|
-
} else if (
|
|
55
|
+
} else if (variant == uint8(AssetInstanceVariant.Array8)) {
|
|
47
56
|
payloadLength = 8;
|
|
48
|
-
} else if (
|
|
57
|
+
} else if (variant == uint8(AssetInstanceVariant.Array16)) {
|
|
49
58
|
payloadLength = 16;
|
|
50
|
-
} else if (
|
|
59
|
+
} else if (variant == uint8(AssetInstanceVariant.Array32)) {
|
|
51
60
|
payloadLength = 32;
|
|
52
|
-
} else if (
|
|
61
|
+
} else if (variant == uint8(AssetInstanceVariant.Undefined)) {
|
|
53
62
|
payloadLength = 0;
|
|
54
63
|
} else {
|
|
55
|
-
revert
|
|
64
|
+
revert InvalidAssetInstanceVariant(variant);
|
|
56
65
|
}
|
|
57
66
|
|
|
58
67
|
if (data.length < offset + 1 + payloadLength) {
|
|
@@ -89,18 +98,12 @@ library AssetInstanceCodec {
|
|
|
89
98
|
pure
|
|
90
99
|
returns (AssetInstance memory assetInstance, uint256 bytesRead)
|
|
91
100
|
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
uint8 iType = uint8(data[offset]);
|
|
96
|
-
uint256 payloadLength = encodedSizeAt(data, offset) - 1; // subtract 1 byte for the iType
|
|
97
|
-
bytes memory payload = new bytes(payloadLength);
|
|
98
|
-
for (uint256 i = 0; i < payloadLength; i++) {
|
|
99
|
-
payload[i] = data[offset + 1 + i];
|
|
100
|
-
}
|
|
101
|
+
uint256 payloadLength = encodedSizeAt(data, offset) - 1; // subtract 1 byte for the variant
|
|
102
|
+
uint8 variant = uint8(data[offset]);
|
|
103
|
+
bytes memory payload = BytesUtils.copy(data, offset + 1, payloadLength);
|
|
101
104
|
|
|
102
105
|
assetInstance = AssetInstance({
|
|
103
|
-
|
|
106
|
+
variant: AssetInstanceVariant(variant),
|
|
104
107
|
payload: payload
|
|
105
108
|
});
|
|
106
109
|
bytesRead = 1 + payloadLength;
|
|
@@ -108,67 +111,61 @@ library AssetInstanceCodec {
|
|
|
108
111
|
|
|
109
112
|
/// @notice Extracts the index value from an `Index` asset instance. Reverts if the asset instance is not of type `Index` or if the decoded index exceeds the maximum value for `uint128`.
|
|
110
113
|
/// @param assetInstance The `AssetInstance` struct to decode, which must have type `Index`.
|
|
111
|
-
/// @return
|
|
114
|
+
/// @return params A `IndexParams` struct containing the decoded index value.
|
|
112
115
|
function asIndex(
|
|
113
116
|
AssetInstance memory assetInstance
|
|
114
|
-
) internal pure returns (
|
|
115
|
-
|
|
116
|
-
revert InvalidAssetInstanceType(uint8(assetInstance.iType));
|
|
117
|
-
}
|
|
117
|
+
) internal pure returns (IndexParams memory params) {
|
|
118
|
+
_assertVariant(assetInstance, AssetInstanceVariant.Index);
|
|
118
119
|
(uint256 decodedIndex, ) = Compact.decode(assetInstance.payload);
|
|
119
|
-
|
|
120
|
-
revert InvalidAssetInstancePayload();
|
|
121
|
-
}
|
|
122
|
-
unchecked {
|
|
123
|
-
idx = uint128(decodedIndex);
|
|
124
|
-
}
|
|
120
|
+
params.index = UnsignedUtils.toU128(decodedIndex);
|
|
125
121
|
}
|
|
126
122
|
|
|
127
123
|
/// @notice Extracts the 4-byte data from an `Array4` asset instance. Reverts if the asset instance is not of type `Array4`.
|
|
128
124
|
/// @param assetInstance The `AssetInstance` struct to decode, which must have type `Array4`.
|
|
129
|
-
/// @return
|
|
125
|
+
/// @return params A `Array4Params` struct containing the decoded 4-byte data.
|
|
130
126
|
function asArray4(
|
|
131
127
|
AssetInstance memory assetInstance
|
|
132
|
-
) internal pure returns (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
return Bytes4.decode(assetInstance.payload);
|
|
128
|
+
) internal pure returns (Array4Params memory params) {
|
|
129
|
+
_assertVariant(assetInstance, AssetInstanceVariant.Array4);
|
|
130
|
+
params.data = Bytes4.decode(assetInstance.payload);
|
|
137
131
|
}
|
|
138
132
|
|
|
139
133
|
/// @notice Extracts the 8-byte data from an `Array8` asset instance. Reverts if the asset instance is not of type `Array8`.
|
|
140
134
|
/// @param assetInstance The `AssetInstance` struct to decode, which must have type `Array8`.
|
|
141
|
-
/// @return
|
|
135
|
+
/// @return params A `Array8Params` struct containing the decoded 8-byte data.
|
|
142
136
|
function asArray8(
|
|
143
137
|
AssetInstance memory assetInstance
|
|
144
|
-
) internal pure returns (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
return Bytes8.decode(assetInstance.payload);
|
|
138
|
+
) internal pure returns (Array8Params memory params) {
|
|
139
|
+
_assertVariant(assetInstance, AssetInstanceVariant.Array8);
|
|
140
|
+
params.data = Bytes8.decode(assetInstance.payload);
|
|
149
141
|
}
|
|
150
142
|
|
|
151
143
|
/// @notice Extracts the 16-byte data from an `Array16` asset instance. Reverts if the asset instance is not of type `Array16`.
|
|
152
144
|
/// @param assetInstance The `AssetInstance` struct to decode, which must have type `Array16`.
|
|
153
|
-
/// @return
|
|
145
|
+
/// @return params A `Array16Params` struct containing the decoded 16-byte data.
|
|
154
146
|
function asArray16(
|
|
155
147
|
AssetInstance memory assetInstance
|
|
156
|
-
) internal pure returns (
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
return Bytes16.decode(assetInstance.payload);
|
|
148
|
+
) internal pure returns (Array16Params memory params) {
|
|
149
|
+
_assertVariant(assetInstance, AssetInstanceVariant.Array16);
|
|
150
|
+
params.data = Bytes16.decode(assetInstance.payload);
|
|
161
151
|
}
|
|
162
152
|
|
|
163
153
|
/// @notice Extracts the 32-byte data from an `Array32` asset instance. Reverts if the asset instance is not of type `Array32`.
|
|
164
154
|
/// @param assetInstance The `AssetInstance` struct to decode, which must have type `Array32`.
|
|
165
|
-
/// @return
|
|
155
|
+
/// @return params A `Array32Params` struct containing the decoded 32-byte data.
|
|
166
156
|
function asArray32(
|
|
167
157
|
AssetInstance memory assetInstance
|
|
168
|
-
) internal pure returns (
|
|
169
|
-
|
|
170
|
-
|
|
158
|
+
) internal pure returns (Array32Params memory params) {
|
|
159
|
+
_assertVariant(assetInstance, AssetInstanceVariant.Array32);
|
|
160
|
+
params.data = Bytes32.decode(assetInstance.payload);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function _assertVariant(
|
|
164
|
+
AssetInstance memory assetInstance,
|
|
165
|
+
AssetInstanceVariant expected
|
|
166
|
+
) private pure {
|
|
167
|
+
if (assetInstance.variant != expected) {
|
|
168
|
+
revert InvalidAssetInstanceVariant(uint8(assetInstance.variant));
|
|
171
169
|
}
|
|
172
|
-
return Bytes32.decode(assetInstance.payload);
|
|
173
170
|
}
|
|
174
171
|
}
|
|
@@ -5,7 +5,7 @@ import {AssetFilter} from "../AssetFilter/AssetFilter.sol";
|
|
|
5
5
|
import {AssetFilterCodec} from "../AssetFilter/AssetFilterCodec.sol";
|
|
6
6
|
|
|
7
7
|
/// @notice Discriminant for the `AssetTransferFilter` enum.
|
|
8
|
-
enum
|
|
8
|
+
enum AssetTransferFilterVariant {
|
|
9
9
|
/// @custom:variant Teleport assets matching `AssetFilter` to a specific destination.
|
|
10
10
|
Teleport,
|
|
11
11
|
/// @custom:variant Reserve-transfer assets matching `AssetFilter` to a specific destination, using the local chain as reserve.
|
|
@@ -16,8 +16,8 @@ enum AssetTransferFilterType {
|
|
|
16
16
|
|
|
17
17
|
/// @notice Matches assets based on inner `AssetFilter` and tags them for a specific type of asset transfer.
|
|
18
18
|
struct AssetTransferFilter {
|
|
19
|
-
/// @custom:property The type of asset transfer. See `
|
|
20
|
-
|
|
19
|
+
/// @custom:property The type of asset transfer. See `AssetTransferFilterVariant` enum for possible values.
|
|
20
|
+
AssetTransferFilterVariant variant;
|
|
21
21
|
/// @custom:property The SCALE-encoded `AssetFilter` payload.
|
|
22
22
|
bytes payload;
|
|
23
23
|
}
|
|
@@ -25,19 +25,19 @@ struct AssetTransferFilter {
|
|
|
25
25
|
/// @notice Parameters for the `Teleport` variant.
|
|
26
26
|
struct TeleportParams {
|
|
27
27
|
/// @custom:property Asset filter used for teleport transfer.
|
|
28
|
-
AssetFilter
|
|
28
|
+
AssetFilter assetFilter;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/// @notice Parameters for the `ReserveDeposit` variant.
|
|
32
32
|
struct ReserveDepositParams {
|
|
33
33
|
/// @custom:property Asset filter used for reserve-deposit transfer.
|
|
34
|
-
AssetFilter
|
|
34
|
+
AssetFilter assetFilter;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/// @notice Parameters for the `ReserveWithdraw` variant.
|
|
38
38
|
struct ReserveWithdrawParams {
|
|
39
39
|
/// @custom:property Asset filter used for reserve-withdraw transfer.
|
|
40
|
-
AssetFilter
|
|
40
|
+
AssetFilter assetFilter;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
// ============ Factory Functions ============
|
|
@@ -50,8 +50,8 @@ function teleport(
|
|
|
50
50
|
) pure returns (AssetTransferFilter memory) {
|
|
51
51
|
return
|
|
52
52
|
AssetTransferFilter({
|
|
53
|
-
|
|
54
|
-
payload: AssetFilterCodec.encode(params.
|
|
53
|
+
variant: AssetTransferFilterVariant.Teleport,
|
|
54
|
+
payload: AssetFilterCodec.encode(params.assetFilter)
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -63,8 +63,8 @@ function reserveDeposit(
|
|
|
63
63
|
) pure returns (AssetTransferFilter memory) {
|
|
64
64
|
return
|
|
65
65
|
AssetTransferFilter({
|
|
66
|
-
|
|
67
|
-
payload: AssetFilterCodec.encode(params.
|
|
66
|
+
variant: AssetTransferFilterVariant.ReserveDeposit,
|
|
67
|
+
payload: AssetFilterCodec.encode(params.assetFilter)
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -76,7 +76,7 @@ function reserveWithdraw(
|
|
|
76
76
|
) pure returns (AssetTransferFilter memory) {
|
|
77
77
|
return
|
|
78
78
|
AssetTransferFilter({
|
|
79
|
-
|
|
80
|
-
payload: AssetFilterCodec.encode(params.
|
|
79
|
+
variant: AssetTransferFilterVariant.ReserveWithdraw,
|
|
80
|
+
payload: AssetFilterCodec.encode(params.assetFilter)
|
|
81
81
|
});
|
|
82
82
|
}
|
|
@@ -5,8 +5,12 @@ import {AssetFilter} from "../AssetFilter/AssetFilter.sol";
|
|
|
5
5
|
import {AssetFilterCodec} from "../AssetFilter/AssetFilterCodec.sol";
|
|
6
6
|
import {
|
|
7
7
|
AssetTransferFilter,
|
|
8
|
-
|
|
8
|
+
AssetTransferFilterVariant,
|
|
9
|
+
TeleportParams,
|
|
10
|
+
ReserveDepositParams,
|
|
11
|
+
ReserveWithdrawParams
|
|
9
12
|
} from "./AssetTransferFilter.sol";
|
|
13
|
+
import {BytesUtils} from "../../../Utils/BytesUtils.sol";
|
|
10
14
|
|
|
11
15
|
/// @title SCALE Codec for XCM v5 `AssetTransferFilter`
|
|
12
16
|
/// @notice SCALE-compliant encoder/decoder for the `AssetTransferFilter` type.
|
|
@@ -14,7 +18,7 @@ import {
|
|
|
14
18
|
/// @dev XCM v5 reference: https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v5/enum.AssetTransferFilter.html
|
|
15
19
|
library AssetTransferFilterCodec {
|
|
16
20
|
error InvalidAssetTransferFilterLength();
|
|
17
|
-
error
|
|
21
|
+
error InvalidAssetTransferFilterVariant(uint8 variant);
|
|
18
22
|
|
|
19
23
|
/// @notice Encodes an `AssetTransferFilter` struct into SCALE bytes.
|
|
20
24
|
/// @param atf The `AssetTransferFilter` struct to encode.
|
|
@@ -22,7 +26,7 @@ library AssetTransferFilterCodec {
|
|
|
22
26
|
function encode(
|
|
23
27
|
AssetTransferFilter memory atf
|
|
24
28
|
) internal pure returns (bytes memory) {
|
|
25
|
-
return abi.encodePacked(uint8(atf.
|
|
29
|
+
return abi.encodePacked(uint8(atf.variant), atf.payload);
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
/// @notice Returns the number of bytes that an `AssetTransferFilter` would occupy when SCALE-encoded.
|
|
@@ -34,9 +38,9 @@ library AssetTransferFilterCodec {
|
|
|
34
38
|
uint256 offset
|
|
35
39
|
) internal pure returns (uint256) {
|
|
36
40
|
if (data.length < offset + 1) revert InvalidAssetTransferFilterLength();
|
|
37
|
-
uint8
|
|
38
|
-
if (
|
|
39
|
-
revert
|
|
41
|
+
uint8 variant = uint8(data[offset]);
|
|
42
|
+
if (variant > uint8(AssetTransferFilterVariant.ReserveWithdraw))
|
|
43
|
+
revert InvalidAssetTransferFilterVariant(variant);
|
|
40
44
|
return 1 + AssetFilterCodec.encodedSizeAt(data, offset + 1);
|
|
41
45
|
}
|
|
42
46
|
|
|
@@ -67,29 +71,53 @@ library AssetTransferFilterCodec {
|
|
|
67
71
|
pure
|
|
68
72
|
returns (AssetTransferFilter memory atf, uint256 bytesRead)
|
|
69
73
|
{
|
|
70
|
-
if (data.length < offset + 1) revert InvalidAssetTransferFilterLength();
|
|
71
|
-
uint8 atfType = uint8(data[offset]);
|
|
72
|
-
if (atfType > uint8(AssetTransferFilterType.ReserveWithdraw))
|
|
73
|
-
revert InvalidAssetTransferFilterType(atfType);
|
|
74
74
|
uint256 size = encodedSizeAt(data, offset);
|
|
75
|
+
uint8 variant = uint8(data[offset]);
|
|
75
76
|
uint256 payloadLength = size - 1;
|
|
76
|
-
bytes memory payload =
|
|
77
|
-
for (uint256 i = 0; i < payloadLength; ++i) {
|
|
78
|
-
payload[i] = data[offset + 1 + i];
|
|
79
|
-
}
|
|
77
|
+
bytes memory payload = BytesUtils.copy(data, offset + 1, payloadLength);
|
|
80
78
|
atf = AssetTransferFilter({
|
|
81
|
-
|
|
79
|
+
variant: AssetTransferFilterVariant(variant),
|
|
82
80
|
payload: payload
|
|
83
81
|
});
|
|
84
82
|
bytesRead = size;
|
|
85
83
|
}
|
|
86
84
|
|
|
87
|
-
/// @notice Extracts the inner `AssetFilter` from an `AssetTransferFilter
|
|
85
|
+
/// @notice Extracts the inner `AssetFilter` from an `AssetTransferFilter` with `Teleport` variant
|
|
88
86
|
/// @param atf The `AssetTransferFilter` struct to decode.
|
|
89
|
-
/// @return
|
|
90
|
-
function
|
|
87
|
+
/// @return params A `TeleportParams` struct containing the inner `AssetFilter`.
|
|
88
|
+
function asTeleport(
|
|
91
89
|
AssetTransferFilter memory atf
|
|
92
|
-
) internal pure returns (
|
|
93
|
-
|
|
90
|
+
) internal pure returns (TeleportParams memory params) {
|
|
91
|
+
_assertVariant(atf, AssetTransferFilterVariant.Teleport);
|
|
92
|
+
(params.assetFilter, ) = AssetFilterCodec.decode(atf.payload);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/// @notice Extracts the inner `AssetFilter` from an `AssetTransferFilter` with `ReserveDeposit` variant
|
|
96
|
+
/// @param atf The `AssetTransferFilter` struct to decode.
|
|
97
|
+
/// @return params A `ReserveDepositParams` struct containing the inner `AssetFilter`.
|
|
98
|
+
function asReserveDeposit(
|
|
99
|
+
AssetTransferFilter memory atf
|
|
100
|
+
) internal pure returns (ReserveDepositParams memory params) {
|
|
101
|
+
_assertVariant(atf, AssetTransferFilterVariant.ReserveDeposit);
|
|
102
|
+
(params.assetFilter, ) = AssetFilterCodec.decode(atf.payload);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/// @notice Extracts the inner `AssetFilter` from an `AssetTransferFilter` with `ReserveWithdraw` variant
|
|
106
|
+
/// @param atf The `AssetTransferFilter` struct to decode.
|
|
107
|
+
/// @return params A `ReserveWithdrawParams` struct containing the inner `AssetFilter`.
|
|
108
|
+
function asReserveWithdraw(
|
|
109
|
+
AssetTransferFilter memory atf
|
|
110
|
+
) internal pure returns (ReserveWithdrawParams memory params) {
|
|
111
|
+
_assertVariant(atf, AssetTransferFilterVariant.ReserveWithdraw);
|
|
112
|
+
(params.assetFilter, ) = AssetFilterCodec.decode(atf.payload);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function _assertVariant(
|
|
116
|
+
AssetTransferFilter memory atf,
|
|
117
|
+
AssetTransferFilterVariant expected
|
|
118
|
+
) internal pure {
|
|
119
|
+
if (atf.variant != expected) {
|
|
120
|
+
revert InvalidAssetTransferFilterVariant(uint8(atf.variant));
|
|
121
|
+
}
|
|
94
122
|
}
|
|
95
123
|
}
|
|
@@ -12,3 +12,19 @@ struct Assets {
|
|
|
12
12
|
/// @custom:property The items of the array.
|
|
13
13
|
Asset[] items;
|
|
14
14
|
}
|
|
15
|
+
|
|
16
|
+
/// @notice Creates an `Assets` wrapper from a single `Asset`.
|
|
17
|
+
/// @param asset The asset to include.
|
|
18
|
+
/// @return An `Assets` struct containing one item.
|
|
19
|
+
function fromAsset(Asset memory asset) pure returns (Assets memory) {
|
|
20
|
+
Asset[] memory items = new Asset[](1);
|
|
21
|
+
items[0] = asset;
|
|
22
|
+
return Assets({items: items});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/// @notice Creates an `Assets` wrapper from an asset array.
|
|
26
|
+
/// @param assets The assets to include.
|
|
27
|
+
/// @return An `Assets` struct containing `assets`.
|
|
28
|
+
function fromAssets(Asset[] memory assets) pure returns (Assets memory) {
|
|
29
|
+
return Assets({items: assets});
|
|
30
|
+
}
|
|
@@ -41,6 +41,9 @@ library AssetsCodec {
|
|
|
41
41
|
revert InvalidAssetsLength();
|
|
42
42
|
}
|
|
43
43
|
(uint256 length, uint256 bytesRead) = Compact.decodeAt(data, offset);
|
|
44
|
+
if (length > MAX_ITEMS_IN_ASSETS) {
|
|
45
|
+
revert InvalidAssetsPayload();
|
|
46
|
+
}
|
|
44
47
|
uint256 currentOffset = offset + bytesRead;
|
|
45
48
|
for (uint256 i = 0; i < length; i++) {
|
|
46
49
|
uint256 assetSize = AssetCodec.encodedSizeAt(data, currentOffset);
|
|
@@ -68,9 +71,6 @@ library AssetsCodec {
|
|
|
68
71
|
bytes memory data,
|
|
69
72
|
uint256 offset
|
|
70
73
|
) internal pure returns (Assets memory assets, uint256 bytesRead) {
|
|
71
|
-
if (data.length < offset + 1) {
|
|
72
|
-
revert InvalidAssetsLength();
|
|
73
|
-
}
|
|
74
74
|
(uint256 length, uint256 compactBytesRead) = Compact.decodeAt(
|
|
75
75
|
data,
|
|
76
76
|
offset
|
|
@@ -5,7 +5,7 @@ import {Bytes4} from "../../../Scale/Bytes.sol";
|
|
|
5
5
|
import {Compact} from "../../../Scale/Compact.sol";
|
|
6
6
|
|
|
7
7
|
/// @dev Discriminant for the different types of BodyIds in XCM v5. Each variant corresponds to a specific structure of the payload.
|
|
8
|
-
enum
|
|
8
|
+
enum BodyIdVariant {
|
|
9
9
|
/// @custom:variant The only body in its context.
|
|
10
10
|
Unit,
|
|
11
11
|
/// @custom:variant A named body.
|
|
@@ -31,7 +31,7 @@ enum BodyIdType {
|
|
|
31
31
|
/// @notice An identifier of a pluralistic body.
|
|
32
32
|
struct BodyId {
|
|
33
33
|
/// @custom:property The type of BodyId, which determines how to interpret the payload
|
|
34
|
-
|
|
34
|
+
BodyIdVariant variant;
|
|
35
35
|
/// @custom:property For Moniker and Index types, this will hold the relevant data
|
|
36
36
|
bytes payload;
|
|
37
37
|
}
|
|
@@ -45,77 +45,77 @@ struct MonikerParams {
|
|
|
45
45
|
/// @notice Parameters for the `Index` variant.
|
|
46
46
|
struct IndexParams {
|
|
47
47
|
/// @custom:property The index of the body.
|
|
48
|
-
uint32
|
|
48
|
+
uint32 index;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
// ============ Factory Functions ============
|
|
52
52
|
|
|
53
53
|
/// @notice Creates a `BodyId` representing a `Unit` body.
|
|
54
|
-
/// @return A `BodyId` with `
|
|
54
|
+
/// @return A `BodyId` with `variant` set to `Unit` and an empty payload.
|
|
55
55
|
function unit() pure returns (BodyId memory) {
|
|
56
|
-
return BodyId({
|
|
56
|
+
return BodyId({variant: BodyIdVariant.Unit, payload: ""});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/// @notice Creates a `BodyId` representing a `Moniker` body with the given 4-byte name.
|
|
60
60
|
/// @param params Parameters for the moniker variant.
|
|
61
|
-
/// @return A `BodyId` with `
|
|
61
|
+
/// @return A `BodyId` with `variant` set to `Moniker` and the provided name encoded in the payload.
|
|
62
62
|
function moniker(MonikerParams memory params) pure returns (BodyId memory) {
|
|
63
63
|
return
|
|
64
64
|
BodyId({
|
|
65
|
-
|
|
65
|
+
variant: BodyIdVariant.Moniker,
|
|
66
66
|
payload: Bytes4.encode(params.name)
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/// @notice Creates a `BodyId` representing an `Index` body with the given index.
|
|
71
71
|
/// @param params Parameters for the index variant.
|
|
72
|
-
/// @return A `BodyId` with `
|
|
72
|
+
/// @return A `BodyId` with `variant` set to `Index` and the provided index encoded in the payload.
|
|
73
73
|
function index(IndexParams memory params) pure returns (BodyId memory) {
|
|
74
74
|
return
|
|
75
75
|
BodyId({
|
|
76
|
-
|
|
77
|
-
payload: Compact.encode(params.
|
|
76
|
+
variant: BodyIdVariant.Index,
|
|
77
|
+
payload: Compact.encode(params.index)
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
/// @notice Creates a `BodyId` representing an `Executive` body.
|
|
82
|
-
/// @return A `BodyId` with `
|
|
82
|
+
/// @return A `BodyId` with `variant` set to `Executive` and an empty payload.
|
|
83
83
|
function executive() pure returns (BodyId memory) {
|
|
84
|
-
return BodyId({
|
|
84
|
+
return BodyId({variant: BodyIdVariant.Executive, payload: ""});
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
/// @notice Creates a `BodyId` representing a `Technical` body.
|
|
88
|
-
/// @return A `BodyId` with `
|
|
88
|
+
/// @return A `BodyId` with `variant` set to `Technical` and an empty payload.
|
|
89
89
|
function technical() pure returns (BodyId memory) {
|
|
90
|
-
return BodyId({
|
|
90
|
+
return BodyId({variant: BodyIdVariant.Technical, payload: ""});
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
/// @notice Creates a `BodyId` representing a `Legislative` body.
|
|
94
|
-
/// @return A `BodyId` with `
|
|
94
|
+
/// @return A `BodyId` with `variant` set to `Legislative` and an empty payload.
|
|
95
95
|
function legislative() pure returns (BodyId memory) {
|
|
96
|
-
return BodyId({
|
|
96
|
+
return BodyId({variant: BodyIdVariant.Legislative, payload: ""});
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/// @notice Creates a `BodyId` representing a `Judicial` body.
|
|
100
|
-
/// @return A `BodyId` with `
|
|
100
|
+
/// @return A `BodyId` with `variant` set to `Judicial` and an empty payload.
|
|
101
101
|
function judicial() pure returns (BodyId memory) {
|
|
102
|
-
return BodyId({
|
|
102
|
+
return BodyId({variant: BodyIdVariant.Judicial, payload: ""});
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/// @notice Creates a `BodyId` representing a `Defense` body.
|
|
106
|
-
/// @return A `BodyId` with `
|
|
106
|
+
/// @return A `BodyId` with `variant` set to `Defense` and an empty payload.
|
|
107
107
|
function defense() pure returns (BodyId memory) {
|
|
108
|
-
return BodyId({
|
|
108
|
+
return BodyId({variant: BodyIdVariant.Defense, payload: ""});
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/// @notice Creates a `BodyId` representing an `Administration` body.
|
|
112
|
-
/// @return A `BodyId` with `
|
|
112
|
+
/// @return A `BodyId` with `variant` set to `Administration` and an empty payload.
|
|
113
113
|
function administration() pure returns (BodyId memory) {
|
|
114
|
-
return BodyId({
|
|
114
|
+
return BodyId({variant: BodyIdVariant.Administration, payload: ""});
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
/// @notice Creates a `BodyId` representing a `Treasury` body.
|
|
118
|
-
/// @return A `BodyId` with `
|
|
118
|
+
/// @return A `BodyId` with `variant` set to `Treasury` and an empty payload.
|
|
119
119
|
function treasury() pure returns (BodyId memory) {
|
|
120
|
-
return BodyId({
|
|
120
|
+
return BodyId({variant: BodyIdVariant.Treasury, payload: ""});
|
|
121
121
|
}
|