solidity-scale-codec 0.1.2 → 0.2.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 +15 -0
- package/DEFINITIONS.md +132 -0
- package/README.md +95 -1
- package/package.json +8 -3
- package/src/LittleEndian/LittleEndianU128.sol +4 -2
- package/src/LittleEndian/LittleEndianU16.sol +2 -2
- package/src/LittleEndian/LittleEndianU256.sol +4 -2
- package/src/LittleEndian/LittleEndianU32.sol +4 -2
- package/src/LittleEndian/LittleEndianU64.sol +4 -2
- package/src/LittleEndian/LittleEndianU8.sol +2 -2
- package/src/Scale/Address/Address.sol +55 -0
- package/src/Scale/Address.sol +4 -0
- package/src/Scale/Array/BoolArr.sol +16 -2
- package/src/Scale/Array/I128Arr.sol +16 -2
- package/src/Scale/Array/I16Arr.sol +16 -2
- package/src/Scale/Array/I256Arr.sol +16 -2
- package/src/Scale/Array/I32Arr.sol +16 -2
- package/src/Scale/Array/I64Arr.sol +16 -2
- package/src/Scale/Array/I8Arr.sol +16 -2
- package/src/Scale/Array/U128Arr.sol +16 -2
- package/src/Scale/Array/U16Arr.sol +16 -2
- package/src/Scale/Array/U256Arr.sol +16 -2
- package/src/Scale/Array/U32Arr.sol +16 -2
- package/src/Scale/Array/U64Arr.sol +16 -2
- package/src/Scale/Array/U8Arr.sol +16 -2
- package/src/Scale/Bool/Bool.sol +12 -0
- package/src/Scale/Bytes/Bytes.sol +63 -0
- package/src/Scale/Bytes/Bytes16.sol +53 -0
- package/src/Scale/Bytes/Bytes2.sol +53 -0
- package/src/Scale/Bytes/Bytes32.sol +53 -0
- package/src/Scale/Bytes/Bytes4.sol +53 -0
- package/src/Scale/Bytes/Bytes8.sol +53 -0
- package/src/Scale/Bytes.sol +8 -0
- package/src/Scale/Compact/Compact.sol +37 -3
- package/src/Scale/Signed/I128.sol +11 -0
- package/src/Scale/Signed/I16.sol +11 -0
- package/src/Scale/Signed/I256.sol +11 -0
- package/src/Scale/Signed/I32.sol +11 -0
- package/src/Scale/Signed/I64.sol +11 -0
- package/src/Scale/Signed/I8.sol +11 -0
- package/src/Scale/Unsigned/U128.sol +16 -2
- package/src/Scale/Unsigned/U16.sol +16 -2
- package/src/Scale/Unsigned/U256.sol +16 -2
- package/src/Scale/Unsigned/U32.sol +16 -2
- package/src/Scale/Unsigned/U64.sol +16 -2
- package/src/Scale/Unsigned/U8.sol +16 -2
- package/src/Xcm/Types/Version.sol +5 -0
- package/src/Xcm/VersionedXcm/VersionedXcm.sol +27 -0
- package/src/Xcm/VersionedXcm/VersionedXcmCodec.sol +70 -0
- package/src/Xcm/v3/Constants.sol +5 -0
- package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCode.sol +73 -0
- package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCodeCodec.sol +94 -0
- package/src/Xcm/v5/Asset/Asset.sol +13 -0
- package/src/Xcm/v5/Asset/AssetCodec.sol +72 -0
- package/src/Xcm/v5/AssetFilter/AssetFilter.sol +61 -0
- package/src/Xcm/v5/AssetFilter/AssetFilterCodec.sol +105 -0
- package/src/Xcm/v5/AssetId/AssetId.sol +10 -0
- package/src/Xcm/v5/AssetId/AssetIdCodec.sol +57 -0
- package/src/Xcm/v5/AssetInstance/AssetInstance.sol +139 -0
- package/src/Xcm/v5/AssetInstance/AssetInstanceCodec.sol +174 -0
- package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilter.sol +82 -0
- package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilterCodec.sol +95 -0
- package/src/Xcm/v5/Assets/Assets.sol +14 -0
- package/src/Xcm/v5/Assets/AssetsCodec.sol +94 -0
- package/src/Xcm/v5/BodyId/BodyId.sol +121 -0
- package/src/Xcm/v5/BodyId/BodyIdCodec.sol +128 -0
- package/src/Xcm/v5/BodyPart/BodyPart.sol +105 -0
- package/src/Xcm/v5/BodyPart/BodyPartCodec.sol +134 -0
- package/src/Xcm/v5/Constants.sol +15 -0
- package/src/Xcm/v5/Fungibility/Fungibility.sol +60 -0
- package/src/Xcm/v5/Fungibility/FungibilityCodec.sol +128 -0
- package/src/Xcm/v5/Hint/Hint.sol +40 -0
- package/src/Xcm/v5/Hint/HintCodec.sol +82 -0
- package/src/Xcm/v5/Instruction/Instruction.sol +1217 -0
- package/src/Xcm/v5/Instruction/InstructionCodec.sol +321 -0
- package/src/Xcm/v5/Junction/Junction.sol +258 -0
- package/src/Xcm/v5/Junction/JunctionCodec.sol +329 -0
- package/src/Xcm/v5/Junctions/Junctions.sol +12 -0
- package/src/Xcm/v5/Junctions/JunctionsCodec.sol +120 -0
- package/src/Xcm/v5/Location/Location.sol +12 -0
- package/src/Xcm/v5/Location/LocationCodec.sol +68 -0
- package/src/Xcm/v5/NetworkId/NetworkId.sol +115 -0
- package/src/Xcm/v5/NetworkId/NetworkIdCodec.sol +114 -0
- package/src/Xcm/v5/OriginKind/OriginKind.sol +14 -0
- package/src/Xcm/v5/OriginKind/OriginKindCodec.sol +66 -0
- package/src/Xcm/v5/PalletInfo/PalletInfo.sol +18 -0
- package/src/Xcm/v5/PalletInfo/PalletInfoCodec.sol +119 -0
- package/src/Xcm/v5/QueryResponseInfo/QueryResponseInfo.sol +16 -0
- package/src/Xcm/v5/QueryResponseInfo/QueryResponseInfoCodec.sol +91 -0
- package/src/Xcm/v5/Response/Response.sol +145 -0
- package/src/Xcm/v5/Response/ResponseCodec.sol +174 -0
- package/src/Xcm/v5/Types/QueryId.sol +5 -0
- package/src/Xcm/v5/Weight/Weight.sol +10 -0
- package/src/Xcm/v5/Weight/WeightCodec.sol +87 -0
- package/src/Xcm/v5/WeightLimit/WeightLimit.sol +48 -0
- package/src/Xcm/v5/WeightLimit/WeightLimitCodec.sol +88 -0
- package/src/Xcm/v5/WildAsset/WildAsset.sol +112 -0
- package/src/Xcm/v5/WildAsset/WildAssetCodec.sol +166 -0
- package/src/Xcm/v5/WildFungibility/WildFungibility.sol +10 -0
- package/src/Xcm/v5/WildFungibility/WildFungibilityCodec.sol +74 -0
- package/src/Xcm/v5/Xcm/Xcm.sol +27 -0
- package/src/Xcm/v5/Xcm/XcmCodec.sol +83 -0
- package/src/Xcm/v5/XcmError/XcmError.sol +122 -0
- package/src/Xcm/v5/XcmError/XcmErrorCodec.sol +85 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
pragma solidity ^0.8.28;
|
|
3
|
+
|
|
4
|
+
import {Assets} from "../Assets/Assets.sol";
|
|
5
|
+
import {AssetsCodec} from "../Assets/AssetsCodec.sol";
|
|
6
|
+
import {XcmError} from "../XcmError/XcmError.sol";
|
|
7
|
+
import {XcmErrorCodec} from "../XcmError/XcmErrorCodec.sol";
|
|
8
|
+
import {PalletInfo} from "../PalletInfo/PalletInfo.sol";
|
|
9
|
+
import {PalletInfoCodec} from "../PalletInfo/PalletInfoCodec.sol";
|
|
10
|
+
import {MaybeErrorCode} from "../../v3/MaybeErrorCode/MaybeErrorCode.sol";
|
|
11
|
+
import {MaybeErrorCodeCodec} from "../../v3/MaybeErrorCode/MaybeErrorCodeCodec.sol";
|
|
12
|
+
import {Compact} from "../../../Scale/Compact.sol";
|
|
13
|
+
import {LittleEndianU32} from "../../../LittleEndian/LittleEndianU32.sol";
|
|
14
|
+
import {Response, ResponseType} from "./Response.sol";
|
|
15
|
+
|
|
16
|
+
/// @title SCALE Codec for XCM v5 `Response`
|
|
17
|
+
/// @notice SCALE-compliant encoder/decoder for the `Response` type.
|
|
18
|
+
/// @dev SCALE reference: https://docs.polkadot.com/polkadot-protocol/basics/data-encoding
|
|
19
|
+
/// @dev XCM v5 reference: https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v5/index.html
|
|
20
|
+
library ResponseCodec {
|
|
21
|
+
error InvalidResponseLength();
|
|
22
|
+
error InvalidResponseType(uint8 rType);
|
|
23
|
+
|
|
24
|
+
/// @notice Encodes a `Response` struct into SCALE bytes.
|
|
25
|
+
/// @param r The `Response` struct to encode.
|
|
26
|
+
/// @return SCALE-encoded bytes representing the `Response`.
|
|
27
|
+
function encode(Response memory r) internal pure returns (bytes memory) {
|
|
28
|
+
return abi.encodePacked(uint8(r.rType), r.payload);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// @notice Returns the number of bytes that a `Response` would occupy when SCALE-encoded.
|
|
32
|
+
/// @param data The byte sequence containing the encoded `Response`.
|
|
33
|
+
/// @param offset The starting index in `data` from which to calculate the encoded size.
|
|
34
|
+
/// @return The number of bytes occupied by the encoded `Response`.
|
|
35
|
+
function encodedSizeAt(
|
|
36
|
+
bytes memory data,
|
|
37
|
+
uint256 offset
|
|
38
|
+
) internal pure returns (uint256) {
|
|
39
|
+
if (data.length < offset + 1) revert InvalidResponseLength();
|
|
40
|
+
uint8 rType = uint8(data[offset]);
|
|
41
|
+
uint256 pos = offset + 1;
|
|
42
|
+
|
|
43
|
+
if (rType == uint8(ResponseType.Null)) {
|
|
44
|
+
return 1;
|
|
45
|
+
} else if (rType == uint8(ResponseType.Assets)) {
|
|
46
|
+
return 1 + AssetsCodec.encodedSizeAt(data, pos);
|
|
47
|
+
} else if (rType == uint8(ResponseType.ExecutionResult)) {
|
|
48
|
+
if (data.length < pos + 1) revert InvalidResponseLength();
|
|
49
|
+
uint8 isSome = uint8(data[pos]);
|
|
50
|
+
if (isSome == 0) return 2; // 1 type + 1 None byte
|
|
51
|
+
return 2 + 4 + XcmErrorCodec.encodedSizeAt(data, pos + 1 + 4);
|
|
52
|
+
} else if (rType == uint8(ResponseType.Version)) {
|
|
53
|
+
if (data.length < pos + 4) revert InvalidResponseLength();
|
|
54
|
+
return 1 + 4; // 1 type + 4 bytes for version
|
|
55
|
+
} else if (rType == uint8(ResponseType.PalletsInfo)) {
|
|
56
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(data, pos);
|
|
57
|
+
uint256 size = prefixSize;
|
|
58
|
+
uint256 innerPos = pos + prefixSize;
|
|
59
|
+
for (uint256 i = 0; i < count; ++i) {
|
|
60
|
+
uint256 palletSize = PalletInfoCodec.encodedSizeAt(
|
|
61
|
+
data,
|
|
62
|
+
innerPos
|
|
63
|
+
);
|
|
64
|
+
size += palletSize;
|
|
65
|
+
innerPos += palletSize;
|
|
66
|
+
}
|
|
67
|
+
return 1 + size;
|
|
68
|
+
} else if (rType == uint8(ResponseType.DispatchResult)) {
|
|
69
|
+
return 1 + MaybeErrorCodeCodec.encodedSizeAt(data, pos);
|
|
70
|
+
} else {
|
|
71
|
+
revert InvalidResponseType(rType);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/// @notice Decodes a `Response` from SCALE bytes starting at the beginning.
|
|
76
|
+
/// @param data The byte sequence containing the encoded `Response`.
|
|
77
|
+
/// @return r The decoded `Response` struct.
|
|
78
|
+
/// @return bytesRead The number of bytes read.
|
|
79
|
+
function decode(
|
|
80
|
+
bytes memory data
|
|
81
|
+
) internal pure returns (Response memory r, uint256 bytesRead) {
|
|
82
|
+
return decodeAt(data, 0);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/// @notice Decodes a `Response` from SCALE bytes starting at a given offset.
|
|
86
|
+
/// @param data The byte sequence containing the encoded `Response`.
|
|
87
|
+
/// @param offset The starting index in `data` from which to decode.
|
|
88
|
+
/// @return r The decoded `Response` struct.
|
|
89
|
+
/// @return bytesRead The number of bytes read.
|
|
90
|
+
function decodeAt(
|
|
91
|
+
bytes memory data,
|
|
92
|
+
uint256 offset
|
|
93
|
+
) internal pure returns (Response memory r, uint256 bytesRead) {
|
|
94
|
+
if (data.length < offset + 1) revert InvalidResponseLength();
|
|
95
|
+
uint8 rType = uint8(data[offset]);
|
|
96
|
+
uint256 size = encodedSizeAt(data, offset);
|
|
97
|
+
uint256 payloadLength = size - 1;
|
|
98
|
+
bytes memory payload = new bytes(payloadLength);
|
|
99
|
+
for (uint256 i = 0; i < payloadLength; ++i) {
|
|
100
|
+
payload[i] = data[offset + 1 + i];
|
|
101
|
+
}
|
|
102
|
+
r = Response({rType: ResponseType(rType), payload: payload});
|
|
103
|
+
bytesRead = size;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/// @notice Decodes the `Assets` from an `Assets` response.
|
|
107
|
+
/// @param r The `Response` struct. Must be of type `Assets`.
|
|
108
|
+
/// @return The decoded `Assets`.
|
|
109
|
+
function asAssets(Response memory r) internal pure returns (Assets memory) {
|
|
110
|
+
if (r.rType != ResponseType.Assets)
|
|
111
|
+
revert InvalidResponseType(uint8(r.rType));
|
|
112
|
+
(Assets memory a, ) = AssetsCodec.decode(r.payload);
|
|
113
|
+
return a;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/// @notice Decodes the execution result from an `ExecutionResult` response.
|
|
117
|
+
/// @param r The `Response` struct. Must be of type `ExecutionResult`.
|
|
118
|
+
/// @return hasError Whether the execution result contains an error.
|
|
119
|
+
/// @return index The instruction index that caused the error. Only meaningful if `hasError` is true.
|
|
120
|
+
/// @return err The XCM error. Only meaningful if `hasError` is true.
|
|
121
|
+
function asExecutionResult(
|
|
122
|
+
Response memory r
|
|
123
|
+
) internal pure returns (bool hasError, uint32 index, XcmError memory err) {
|
|
124
|
+
if (r.rType != ResponseType.ExecutionResult)
|
|
125
|
+
revert InvalidResponseType(uint8(r.rType));
|
|
126
|
+
if (r.payload.length < 1) revert InvalidResponseLength();
|
|
127
|
+
hasError = r.payload[0] != 0;
|
|
128
|
+
if (hasError) {
|
|
129
|
+
if (r.payload.length < 4) revert InvalidResponseLength();
|
|
130
|
+
index = LittleEndianU32.fromLittleEndian(r.payload, 1);
|
|
131
|
+
(err, ) = XcmErrorCodec.decodeAt(r.payload, 1 + 4);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/// @notice Decodes the version from a `Version` response.
|
|
136
|
+
/// @param r The `Response` struct. Must be of type `Version`.
|
|
137
|
+
/// @return The decoded version.
|
|
138
|
+
function asVersion(Response memory r) internal pure returns (uint32) {
|
|
139
|
+
if (r.rType != ResponseType.Version)
|
|
140
|
+
revert InvalidResponseType(uint8(r.rType));
|
|
141
|
+
if (r.payload.length != 4) revert InvalidResponseLength();
|
|
142
|
+
return LittleEndianU32.fromLittleEndian(r.payload, 0);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/// @notice Decodes the pallets info from a `PalletsInfo` response.
|
|
146
|
+
/// @param r The `Response` struct. Must be of type `PalletsInfo`.
|
|
147
|
+
/// @return pallets The decoded array of `PalletInfo`.
|
|
148
|
+
function asPalletsInfo(
|
|
149
|
+
Response memory r
|
|
150
|
+
) internal pure returns (PalletInfo[] memory pallets) {
|
|
151
|
+
if (r.rType != ResponseType.PalletsInfo)
|
|
152
|
+
revert InvalidResponseType(uint8(r.rType));
|
|
153
|
+
(uint256 count, uint256 prefixSize) = Compact.decodeAt(r.payload, 0);
|
|
154
|
+
pallets = new PalletInfo[](count);
|
|
155
|
+
uint256 pos = prefixSize;
|
|
156
|
+
for (uint256 i = 0; i < count; ++i) {
|
|
157
|
+
uint256 read;
|
|
158
|
+
(pallets[i], read) = PalletInfoCodec.decodeAt(r.payload, pos);
|
|
159
|
+
pos += read;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/// @notice Decodes the dispatch result from a `DispatchResult` response.
|
|
164
|
+
/// @param r The `Response` struct. Must be of type `DispatchResult`.
|
|
165
|
+
/// @return The decoded `MaybeErrorCode`.
|
|
166
|
+
function asDispatchResult(
|
|
167
|
+
Response memory r
|
|
168
|
+
) internal pure returns (MaybeErrorCode memory) {
|
|
169
|
+
if (r.rType != ResponseType.DispatchResult)
|
|
170
|
+
revert InvalidResponseType(uint8(r.rType));
|
|
171
|
+
(MaybeErrorCode memory me, ) = MaybeErrorCodeCodec.decode(r.payload);
|
|
172
|
+
return me;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
pragma solidity ^0.8.28;
|
|
3
|
+
|
|
4
|
+
/// @notice Weight v2 used for measurement for an XCM execution
|
|
5
|
+
struct Weight {
|
|
6
|
+
/// @custom:property The computational time used to execute some logic based on reference hardware.
|
|
7
|
+
uint64 refTime;
|
|
8
|
+
/// @custom:property The size of the proof needed to execute some logic.
|
|
9
|
+
uint64 proofSize;
|
|
10
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
pragma solidity ^0.8.28;
|
|
3
|
+
|
|
4
|
+
import {Compact} from "../../../Scale/Compact.sol";
|
|
5
|
+
import {Weight} from "./Weight.sol";
|
|
6
|
+
|
|
7
|
+
/// @title SCALE Codec for XCM v5 `Weight`
|
|
8
|
+
/// @notice SCALE-compliant encoder/decoder for the `Weight` type.
|
|
9
|
+
/// @dev SCALE reference: https://docs.polkadot.com/polkadot-protocol/basics/data-encoding
|
|
10
|
+
/// @dev XCM v5 reference: https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v5/index.html
|
|
11
|
+
library WeightCodec {
|
|
12
|
+
error InvalidWeightLength();
|
|
13
|
+
|
|
14
|
+
/// @notice Encodes a `Weight` struct into bytes.
|
|
15
|
+
/// @param weight The `Weight` struct to encode.
|
|
16
|
+
/// @return SCALE-encoded byte sequence representing the `Weight`.
|
|
17
|
+
function encode(Weight memory weight) internal pure returns (bytes memory) {
|
|
18
|
+
return
|
|
19
|
+
abi.encodePacked(
|
|
20
|
+
Compact.encode(weight.refTime),
|
|
21
|
+
Compact.encode(weight.proofSize)
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/// @notice Returns the number of bytes that a `Weight` struct would occupy when SCALE-encoded.
|
|
26
|
+
/// @param data The byte sequence containing the encoded `Weight`.
|
|
27
|
+
/// @param offset The starting index in `data` from which to calculate the encoded size of the `Weight`.
|
|
28
|
+
/// @return The number of bytes that the `Weight` struct would occupy when SCALE-encoded.
|
|
29
|
+
function encodedSizeAt(
|
|
30
|
+
bytes memory data,
|
|
31
|
+
uint256 offset
|
|
32
|
+
) internal pure returns (uint256) {
|
|
33
|
+
if (offset >= data.length) {
|
|
34
|
+
revert InvalidWeightLength();
|
|
35
|
+
}
|
|
36
|
+
uint256 refTimeBytes = Compact.encodedSizeAt(data, offset);
|
|
37
|
+
offset += refTimeBytes;
|
|
38
|
+
if (offset >= data.length) {
|
|
39
|
+
revert InvalidWeightLength();
|
|
40
|
+
}
|
|
41
|
+
uint256 proofSizeBytes = Compact.encodedSizeAt(data, offset);
|
|
42
|
+
return refTimeBytes + proofSizeBytes;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// @notice Decodes a byte sequence into a `Weight` struct.
|
|
46
|
+
/// @param data The byte sequence to decode, expected to be the SCALE encoding of a `Weight`.
|
|
47
|
+
/// @return weight The decoded `Weight` struct.
|
|
48
|
+
/// @return bytesRead The total number of bytes read from the input data to decode the `Weight`.
|
|
49
|
+
function decode(
|
|
50
|
+
bytes memory data
|
|
51
|
+
) internal pure returns (Weight memory weight, uint256 bytesRead) {
|
|
52
|
+
return decodeAt(data, 0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// @notice Decodes a byte sequence into a `Weight` struct starting at a specific offset.
|
|
56
|
+
/// @param data The byte sequence to decode, expected to be the SCALE encoding of a `Weight`.
|
|
57
|
+
/// @param offset The byte offset in the data array to start decoding from.
|
|
58
|
+
/// @return weight The decoded `Weight` struct.
|
|
59
|
+
/// @return bytesRead The total number of bytes read from the input data to decode the `Weight`.
|
|
60
|
+
function decodeAt(
|
|
61
|
+
bytes memory data,
|
|
62
|
+
uint256 offset
|
|
63
|
+
) internal pure returns (Weight memory weight, uint256 bytesRead) {
|
|
64
|
+
if (offset >= data.length) {
|
|
65
|
+
revert InvalidWeightLength();
|
|
66
|
+
}
|
|
67
|
+
(uint256 refTime, uint256 refTimeBytes) = Compact.decodeAt(
|
|
68
|
+
data,
|
|
69
|
+
offset
|
|
70
|
+
);
|
|
71
|
+
offset += refTimeBytes;
|
|
72
|
+
(uint256 proofSize, uint256 proofSizeBytes) = Compact.decodeAt(
|
|
73
|
+
data,
|
|
74
|
+
offset
|
|
75
|
+
);
|
|
76
|
+
if (offset + proofSizeBytes > data.length) {
|
|
77
|
+
revert InvalidWeightLength();
|
|
78
|
+
}
|
|
79
|
+
offset += proofSizeBytes;
|
|
80
|
+
|
|
81
|
+
weight = Weight({
|
|
82
|
+
refTime: uint64(refTime),
|
|
83
|
+
proofSize: uint64(proofSize)
|
|
84
|
+
});
|
|
85
|
+
bytesRead = refTimeBytes + proofSizeBytes;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
pragma solidity ^0.8.28;
|
|
3
|
+
|
|
4
|
+
import {Weight} from "../Weight/Weight.sol";
|
|
5
|
+
import {WeightCodec} from "../Weight/WeightCodec.sol";
|
|
6
|
+
|
|
7
|
+
/// @notice Discriminant for the `WeightLimit` enum.
|
|
8
|
+
enum WeightLimitType {
|
|
9
|
+
/// @custom:variant No limit on weight.
|
|
10
|
+
Unlimited,
|
|
11
|
+
/// @custom:variant A specific weight limit.
|
|
12
|
+
Limited
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/// @notice An optional weight limit.
|
|
16
|
+
struct WeightLimit {
|
|
17
|
+
/// @custom:property The type of the weight limit. See `WeightLimitType` enum for possible values.
|
|
18
|
+
WeightLimitType wlType;
|
|
19
|
+
/// @custom:property The SCALE-encoded `Weight`. Only meaningful when `wlType` is `Limited`.
|
|
20
|
+
bytes payload;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/// @notice Parameters for the `Limited` variant.
|
|
24
|
+
struct LimitedParams {
|
|
25
|
+
/// @custom:property Weight limit value.
|
|
26
|
+
Weight weight;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ============ Factory Functions ============
|
|
30
|
+
|
|
31
|
+
/// @notice Creates an `Unlimited` weight limit.
|
|
32
|
+
/// @return A `WeightLimit` struct representing no limit.
|
|
33
|
+
function unlimited() pure returns (WeightLimit memory) {
|
|
34
|
+
return WeightLimit({wlType: WeightLimitType.Unlimited, payload: ""});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// @notice Creates a `Limited` weight limit with the given `Weight`.
|
|
38
|
+
/// @param params Parameters for the limited variant.
|
|
39
|
+
/// @return A `WeightLimit` struct representing the given limit.
|
|
40
|
+
function limited(
|
|
41
|
+
LimitedParams memory params
|
|
42
|
+
) pure returns (WeightLimit memory) {
|
|
43
|
+
return
|
|
44
|
+
WeightLimit({
|
|
45
|
+
wlType: WeightLimitType.Limited,
|
|
46
|
+
payload: WeightCodec.encode(params.weight)
|
|
47
|
+
});
|
|
48
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
pragma solidity ^0.8.28;
|
|
3
|
+
|
|
4
|
+
import {Weight} from "../Weight/Weight.sol";
|
|
5
|
+
import {WeightCodec} from "../Weight/WeightCodec.sol";
|
|
6
|
+
import {WeightLimit, WeightLimitType} from "./WeightLimit.sol";
|
|
7
|
+
|
|
8
|
+
/// @title SCALE Codec for XCM v5 `WeightLimit`
|
|
9
|
+
/// @notice SCALE-compliant encoder/decoder for the `WeightLimit` type.
|
|
10
|
+
/// @dev SCALE reference: https://docs.polkadot.com/polkadot-protocol/basics/data-encoding
|
|
11
|
+
/// @dev XCM v5 reference: https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v5/enum.WeightLimit.html
|
|
12
|
+
library WeightLimitCodec {
|
|
13
|
+
error InvalidWeightLimitLength();
|
|
14
|
+
error InvalidWeightLimitType(uint8 wlType);
|
|
15
|
+
|
|
16
|
+
/// @notice Encodes a `WeightLimit` struct into SCALE bytes.
|
|
17
|
+
/// @param wl The `WeightLimit` struct to encode.
|
|
18
|
+
/// @return SCALE-encoded bytes representing the `WeightLimit`.
|
|
19
|
+
function encode(
|
|
20
|
+
WeightLimit memory wl
|
|
21
|
+
) internal pure returns (bytes memory) {
|
|
22
|
+
return abi.encodePacked(uint8(wl.wlType), wl.payload);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/// @notice Returns the number of bytes that a `WeightLimit` would occupy when SCALE-encoded.
|
|
26
|
+
/// @param data The byte sequence containing the encoded `WeightLimit`.
|
|
27
|
+
/// @param offset The starting index in `data` from which to calculate the encoded size.
|
|
28
|
+
/// @return The number of bytes occupied by the encoded `WeightLimit`.
|
|
29
|
+
function encodedSizeAt(
|
|
30
|
+
bytes memory data,
|
|
31
|
+
uint256 offset
|
|
32
|
+
) internal pure returns (uint256) {
|
|
33
|
+
if (data.length < offset + 1) revert InvalidWeightLimitLength();
|
|
34
|
+
uint8 wlType = uint8(data[offset]);
|
|
35
|
+
if (wlType == uint8(WeightLimitType.Unlimited)) {
|
|
36
|
+
return 1;
|
|
37
|
+
} else if (wlType == uint8(WeightLimitType.Limited)) {
|
|
38
|
+
return 1 + WeightCodec.encodedSizeAt(data, offset + 1);
|
|
39
|
+
} else {
|
|
40
|
+
revert InvalidWeightLimitType(wlType);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// @notice Decodes a `WeightLimit` from SCALE bytes starting at the beginning.
|
|
45
|
+
/// @param data The byte sequence containing the encoded `WeightLimit`.
|
|
46
|
+
/// @return wl The decoded `WeightLimit` struct.
|
|
47
|
+
/// @return bytesRead The number of bytes read.
|
|
48
|
+
function decode(
|
|
49
|
+
bytes memory data
|
|
50
|
+
) internal pure returns (WeightLimit memory wl, uint256 bytesRead) {
|
|
51
|
+
return decodeAt(data, 0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// @notice Decodes a `WeightLimit` from SCALE bytes starting at a given offset.
|
|
55
|
+
/// @param data The byte sequence containing the encoded `WeightLimit`.
|
|
56
|
+
/// @param offset The starting index in `data` from which to decode.
|
|
57
|
+
/// @return wl The decoded `WeightLimit` struct.
|
|
58
|
+
/// @return bytesRead The number of bytes read.
|
|
59
|
+
function decodeAt(
|
|
60
|
+
bytes memory data,
|
|
61
|
+
uint256 offset
|
|
62
|
+
) 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
|
+
uint256 size = encodedSizeAt(data, offset);
|
|
68
|
+
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});
|
|
74
|
+
bytesRead = size;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/// @notice Decodes the `Weight` from a `Limited` weight limit.
|
|
78
|
+
/// @param wl The `WeightLimit` struct. Must be of type `Limited`.
|
|
79
|
+
/// @return The decoded `Weight`.
|
|
80
|
+
function asWeight(
|
|
81
|
+
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;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
pragma solidity ^0.8.28;
|
|
3
|
+
|
|
4
|
+
import {Compact} from "../../../Scale/Compact.sol";
|
|
5
|
+
import {AssetId} from "../AssetId/AssetId.sol";
|
|
6
|
+
import {AssetIdCodec} from "../AssetId/AssetIdCodec.sol";
|
|
7
|
+
import {WildFungibility} from "../WildFungibility/WildFungibility.sol";
|
|
8
|
+
import {WildFungibilityCodec} from "../WildFungibility/WildFungibilityCodec.sol";
|
|
9
|
+
|
|
10
|
+
/// @notice Discriminant for the type of asset being specified in a `WildAsset`.
|
|
11
|
+
enum WildAssetType {
|
|
12
|
+
/// @custom:variant All assets in Holding.
|
|
13
|
+
All,
|
|
14
|
+
/// @custom:variant All assets in Holding of a given fungibility and ID.
|
|
15
|
+
AllOf,
|
|
16
|
+
/// @custom:variant All assets in Holding, up to `uint32` individual assets (different instances of non-fungibles are separate assets).
|
|
17
|
+
AllCounted,
|
|
18
|
+
/// @custom:variant All assets in Holding of a given fungibility and ID up to `count` individual assets (different instances of non-fungibles are separate assets).
|
|
19
|
+
AllOfCounted
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// @notice Parameters for the `AllOf` variant of `WildAsset`, specifying a particular asset class and fungibility to match against.
|
|
23
|
+
struct AllOfParams {
|
|
24
|
+
/// @custom:property The asset class to match against.
|
|
25
|
+
AssetId id;
|
|
26
|
+
/// @custom:property The fungibility to match against.
|
|
27
|
+
WildFungibility fun;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/// @notice Parameters for the `AllOfCounted` variant of `WildAsset`, specifying a limit of assets to match against.
|
|
31
|
+
struct AllOfCountedParams {
|
|
32
|
+
/// @custom:property The asset class to match against.
|
|
33
|
+
AssetId id;
|
|
34
|
+
/// @custom:property The fungibility to match against.
|
|
35
|
+
WildFungibility fun;
|
|
36
|
+
/// @custom:property The limit of assets to match against.
|
|
37
|
+
uint32 count;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// @notice Parameters for the `AllCounted` variant of `WildAsset`.
|
|
41
|
+
struct AllCountedParams {
|
|
42
|
+
/// @custom:property The upper bound of matched assets.
|
|
43
|
+
uint32 count;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/// @notice A wildcard representing a set of assets.
|
|
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`.
|
|
51
|
+
bytes payload;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ============ Factory Functions ============
|
|
55
|
+
|
|
56
|
+
/// @notice Creates a `WildAsset` struct representing the `All` variant, which matches all assets in Holding.
|
|
57
|
+
/// @return A `WildAsset` with the `All` variant.
|
|
58
|
+
function all() pure returns (WildAsset memory) {
|
|
59
|
+
return WildAsset({waType: WildAssetType.All, payload: ""});
|
|
60
|
+
}
|
|
61
|
+
|
|
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.
|
|
65
|
+
/// @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) {
|
|
70
|
+
return
|
|
71
|
+
WildAsset({
|
|
72
|
+
waType: WildAssetType.AllOf,
|
|
73
|
+
payload: abi.encodePacked(
|
|
74
|
+
AssetIdCodec.encode(id),
|
|
75
|
+
WildFungibilityCodec.encode(fun)
|
|
76
|
+
)
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// @notice Creates a `WildAsset` struct representing the `AllCounted` variant, which matches all assets in Holding, up to `uint32` individual assets (different instances of non-fungibles are separate assets).
|
|
81
|
+
/// @param params Parameters for the all-counted variant.
|
|
82
|
+
/// @return A `WildAsset` with the `AllOfCounted` variant and the encoded parameters in the payload.
|
|
83
|
+
function allCounted(
|
|
84
|
+
AllCountedParams memory params
|
|
85
|
+
) pure returns (WildAsset memory) {
|
|
86
|
+
return
|
|
87
|
+
WildAsset({
|
|
88
|
+
waType: WildAssetType.AllCounted,
|
|
89
|
+
payload: abi.encodePacked(Compact.encode(params.count))
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/// @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.
|
|
97
|
+
/// @return A `WildAsset` with the `AllOfCounted` variant and the encoded parameters in the payload.
|
|
98
|
+
function allOfCounted(
|
|
99
|
+
AssetId memory id,
|
|
100
|
+
WildFungibility fun,
|
|
101
|
+
uint32 count
|
|
102
|
+
) pure returns (WildAsset memory) {
|
|
103
|
+
return
|
|
104
|
+
WildAsset({
|
|
105
|
+
waType: WildAssetType.AllOfCounted,
|
|
106
|
+
payload: abi.encodePacked(
|
|
107
|
+
AssetIdCodec.encode(id),
|
|
108
|
+
WildFungibilityCodec.encode(fun),
|
|
109
|
+
Compact.encode(count)
|
|
110
|
+
)
|
|
111
|
+
});
|
|
112
|
+
}
|