-
Notifications
You must be signed in to change notification settings - Fork 591
/
Assertions.sol
176 lines (160 loc) · 6.67 KB
/
Assertions.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import { OrderParameters } from "./ConsiderationStructs.sol";
import { GettersAndDerivers } from "./GettersAndDerivers.sol";
import {
TokenTransferrerErrors
} from "../interfaces/TokenTransferrerErrors.sol";
import { CounterManager } from "./CounterManager.sol";
import "./ConsiderationErrors.sol";
/**
* @title Assertions
* @author 0age
* @notice Assertions contains logic for making various assertions that do not
* fit neatly within a dedicated semantic scope.
*/
contract Assertions is
GettersAndDerivers,
CounterManager,
TokenTransferrerErrors
{
/**
* @dev Derive and set hashes, reference chainId, and associated domain
* separator during deployment.
*
* @param conduitController A contract that deploys conduits, or proxies
* that may optionally be used to transfer approved
* ERC20/721/1155 tokens.
*/
constructor(
address conduitController
) GettersAndDerivers(conduitController) {}
/**
* @dev Internal view function to ensure that the supplied consideration
* array length on a given set of order parameters is not less than the
* original consideration array length for that order and to retrieve
* the current counter for a given order's offerer and zone and use it
* to derive the order hash.
*
* @param orderParameters The parameters of the order to hash.
*
* @return The hash.
*/
function _assertConsiderationLengthAndGetOrderHash(
OrderParameters memory orderParameters
) internal view returns (bytes32) {
// Ensure supplied consideration array length is not less than original.
_assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(
orderParameters.consideration.length,
orderParameters.totalOriginalConsiderationItems
);
// Derive and return order hash using current counter for the offerer.
return
_deriveOrderHash(
orderParameters,
_getCounter(orderParameters.offerer)
);
}
/**
* @dev Internal pure function to ensure that the supplied consideration
* array length for an order to be fulfilled is not less than the
* original consideration array length for that order.
*
* @param suppliedConsiderationItemTotal The number of consideration items
* supplied when fulfilling the order.
* @param originalConsiderationItemTotal The number of consideration items
* supplied on initial order creation.
*/
function _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(
uint256 suppliedConsiderationItemTotal,
uint256 originalConsiderationItemTotal
) internal pure {
// Ensure supplied consideration array length is not less than original.
if (suppliedConsiderationItemTotal < originalConsiderationItemTotal) {
_revertMissingOriginalConsiderationItems();
}
}
/**
* @dev Internal pure function to ensure that a given item amount is not
* zero.
*
* @param amount The amount to check.
*/
function _assertNonZeroAmount(uint256 amount) internal pure {
assembly {
if iszero(amount) {
// Store left-padded selector with push4, mem[28:32] = selector
mstore(0, MissingItemAmount_error_selector)
// revert(abi.encodeWithSignature("MissingItemAmount()"))
revert(Error_selector_offset, MissingItemAmount_error_length)
}
}
}
/**
* @dev Internal pure function to validate calldata offsets for dynamic
* types in BasicOrderParameters and other parameters. This ensures
* that functions using the calldata object normally will be using the
* same data as the assembly functions and that values that are bound
* to a given range are within that range. Note that no parameters are
* supplied as all basic order functions use the same calldata
* encoding.
*/
function _assertValidBasicOrderParameters() internal pure {
// Declare a boolean designating basic order parameter offset validity.
bool validOffsets;
// Utilize assembly in order to read offset data directly from calldata.
assembly {
/*
* Checks:
* 1. Order parameters struct offset == 0x20
* 2. Additional recipients arr offset == 0x240
* 3. Signature offset == 0x260 + (recipients.length * 0x40)
* 4. BasicOrderType between 0 and 23 (i.e. < 24)
*/
validOffsets := and(
// Order parameters at calldata 0x04 must have offset of 0x20.
eq(
calldataload(BasicOrder_parameters_cdPtr),
BasicOrder_parameters_ptr
),
// Additional recipients at cd 0x224 must have offset of 0x240.
eq(
calldataload(BasicOrder_additionalRecipients_head_cdPtr),
BasicOrder_additionalRecipients_head_ptr
)
)
validOffsets := and(
validOffsets,
eq(
// Load signature offset from calldata 0x244.
calldataload(BasicOrder_signature_cdPtr),
// Derive expected offset as start of recipients + len * 64.
add(
BasicOrder_signature_ptr,
shl(
// Each additional recipient has a length of 0x40.
AdditionalRecipient_size_shift,
// Additional recipients length at calldata 0x264.
calldataload(
BasicOrder_additionalRecipients_length_cdPtr
)
)
)
)
)
validOffsets := and(
validOffsets,
lt(
// BasicOrderType parameter at calldata offset 0x124.
calldataload(BasicOrder_basicOrderType_cdPtr),
// Value should be less than 24.
BasicOrder_basicOrderType_range
)
)
}
// Revert with an error if basic order parameter offsets are invalid.
if (!validOffsets) {
_revertInvalidBasicOrderParameterEncoding();
}
}
}