@sablier/bob 1.0.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE-BUSL.md +82 -0
  3. package/LICENSE-GPL.md +470 -0
  4. package/LICENSE.md +9 -0
  5. package/README.md +81 -0
  6. package/artifacts/BobVaultShare.json +936 -0
  7. package/artifacts/SablierBob.json +1683 -0
  8. package/artifacts/SablierEscrow.json +1316 -0
  9. package/artifacts/SablierLidoAdapter.json +1649 -0
  10. package/artifacts/erc20/IERC20.json +226 -0
  11. package/artifacts/interfaces/IBobVaultShare.json +393 -0
  12. package/artifacts/interfaces/ISablierBob.json +1171 -0
  13. package/artifacts/interfaces/ISablierEscrow.json +999 -0
  14. package/artifacts/interfaces/ISablierLidoAdapter.json +1141 -0
  15. package/artifacts/interfaces/external/ICurveStETHPool.json +128 -0
  16. package/artifacts/interfaces/external/ILidoWithdrawalQueue.json +209 -0
  17. package/artifacts/interfaces/external/IStETH.json +262 -0
  18. package/artifacts/interfaces/external/IWETH9.json +259 -0
  19. package/artifacts/interfaces/external/IWstETH.json +311 -0
  20. package/artifacts/libraries/Errors.json +868 -0
  21. package/package.json +68 -0
  22. package/src/BobVaultShare.sol +119 -0
  23. package/src/SablierBob.sol +543 -0
  24. package/src/SablierEscrow.sol +288 -0
  25. package/src/SablierLidoAdapter.sol +549 -0
  26. package/src/abstracts/SablierBobState.sol +156 -0
  27. package/src/abstracts/SablierEscrowState.sol +159 -0
  28. package/src/interfaces/IBobVaultShare.sol +51 -0
  29. package/src/interfaces/ISablierBob.sol +261 -0
  30. package/src/interfaces/ISablierBobAdapter.sol +157 -0
  31. package/src/interfaces/ISablierBobState.sol +74 -0
  32. package/src/interfaces/ISablierEscrow.sol +148 -0
  33. package/src/interfaces/ISablierEscrowState.sol +77 -0
  34. package/src/interfaces/ISablierLidoAdapter.sol +110 -0
  35. package/src/interfaces/external/ICurveStETHPool.sol +31 -0
  36. package/src/interfaces/external/ILidoWithdrawalQueue.sol +67 -0
  37. package/src/interfaces/external/IStETH.sol +18 -0
  38. package/src/interfaces/external/IWETH9.sol +19 -0
  39. package/src/interfaces/external/IWstETH.sol +32 -0
  40. package/src/libraries/Errors.sol +189 -0
  41. package/src/types/Bob.sol +49 -0
  42. package/src/types/Escrow.sol +49 -0
@@ -0,0 +1,67 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity >=0.8.22;
3
+
4
+ /// @title ILidoWithdrawalQueue
5
+ /// @notice Minimal interface for Lido's WithdrawalQueueERC721 contract.
6
+ /// @dev Used as a fallback unstaking path when the Curve pool is unavailable.
7
+ interface ILidoWithdrawalQueue {
8
+ /*//////////////////////////////////////////////////////////////////////////
9
+ READ-ONLY FUNCTIONS
10
+ //////////////////////////////////////////////////////////////////////////*/
11
+
12
+ /// @notice Maximum amount of stETH that can be withdrawn in a single request.
13
+ function MAX_STETH_WITHDRAWAL_AMOUNT() external view returns (uint256);
14
+
15
+ /// @notice Minimum amount of stETH that can be withdrawn in a single request.
16
+ function MIN_STETH_WITHDRAWAL_AMOUNT() external view returns (uint256);
17
+
18
+ /// @notice Finds the list of hints for the given `_requestIds` searching among the checkpoints with indices in the
19
+ /// range `[_firstIndex, _lastIndex]`.
20
+ /// @dev
21
+ /// - Array of request IDs should be sorted.
22
+ /// - `_firstIndex` should be greater than 0, because checkpoint list is 1-based array.
23
+ /// - `_lastIndex` should be less than or equal to `getLastCheckpointIndex()`.
24
+ /// @param _requestIds IDs of the requests sorted in the ascending order to get hints for.
25
+ /// @param _firstIndex Left boundary of the search range. Should be greater than 0.
26
+ /// @param _lastIndex Right boundary of the search range. Should be less than or equal to
27
+ /// `getLastCheckpointIndex()`.
28
+ /// @return hintIds Array of hints used to find required checkpoint for the request.
29
+ function findCheckpointHints(
30
+ uint256[] calldata _requestIds,
31
+ uint256 _firstIndex,
32
+ uint256 _lastIndex
33
+ )
34
+ external
35
+ view
36
+ returns (uint256[] memory hintIds);
37
+
38
+ /// @notice Length of the checkpoint array. Last possible value for the hint.
39
+ function getLastCheckpointIndex() external view returns (uint256);
40
+
41
+ /*//////////////////////////////////////////////////////////////////////////
42
+ STATE-CHANGING FUNCTIONS
43
+ //////////////////////////////////////////////////////////////////////////*/
44
+
45
+ /// @notice Claim a batch of withdrawal requests if they are finalized sending locked ETH to the owner.
46
+ /// @param _requestIds Array of request IDs to claim.
47
+ /// @param _hints Checkpoint hint for each ID. Can be obtained with `findCheckpointHints()`
48
+ /// @dev Reverts if any of the following conditions are met:
49
+ /// - `requestIds` and `hints` arrays length differs.
50
+ /// - Any `requestId` or `hint` in arguments are not valid.
51
+ /// - Any request is not finalized or already claimed.
52
+ /// - `msg.sender` is not an owner of the requests.
53
+ function claimWithdrawals(uint256[] calldata _requestIds, uint256[] calldata _hints) external;
54
+
55
+ /// @notice Request the batch of stETH for withdrawal. Approvals for the passed amounts should be done before.
56
+ /// @param _amounts Array of stETH amount values. The standalone withdrawal request will be created for each item
57
+ /// in the passed list.
58
+ /// @param _owner Address that will be able to manage the created requests. If `address(0)` is passed, `msg.sender`
59
+ /// will be used as owner.
60
+ /// @return requestIds Array of the created withdrawal request IDs.
61
+ function requestWithdrawals(
62
+ uint256[] calldata _amounts,
63
+ address _owner
64
+ )
65
+ external
66
+ returns (uint256[] memory requestIds);
67
+ }
@@ -0,0 +1,18 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity >=0.8.22;
3
+
4
+ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
5
+
6
+ /// @title IStETH
7
+ /// @notice Minimal interface for Lido's stETH.
8
+ interface IStETH is IERC20 {
9
+ /*//////////////////////////////////////////////////////////////////////////
10
+ STATE-CHANGING FUNCTIONS
11
+ //////////////////////////////////////////////////////////////////////////*/
12
+
13
+ /// @notice Send funds to the Lido pool with the optional referral parameter and mints stETH.
14
+ /// @dev The amount of stETH minted equals the amount of ETH sent.
15
+ /// @param referral The referral address can be zero.
16
+ /// @return amount The amount of stETH minted.
17
+ function submit(address referral) external payable returns (uint256 amount);
18
+ }
@@ -0,0 +1,19 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity >=0.8.22;
3
+
4
+ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
5
+
6
+ /// @title IWETH9
7
+ /// @notice Minimal interface for Wrapped Ether.
8
+ interface IWETH9 is IERC20 {
9
+ /*//////////////////////////////////////////////////////////////////////////
10
+ STATE-CHANGING FUNCTIONS
11
+ //////////////////////////////////////////////////////////////////////////*/
12
+
13
+ /// @notice Deposits ETH and mints WETH.
14
+ function deposit() external payable;
15
+
16
+ /// @notice Burns WETH and withdraws ETH.
17
+ /// @param amount The amount of WETH to burn.
18
+ function withdraw(uint256 amount) external;
19
+ }
@@ -0,0 +1,32 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity >=0.8.22;
3
+
4
+ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
5
+
6
+ /// @title IWstETH
7
+ /// @notice Minimal interface for Lido's wstETH.
8
+ interface IWstETH is IERC20 {
9
+ /*//////////////////////////////////////////////////////////////////////////
10
+ READ-ONLY FUNCTIONS
11
+ //////////////////////////////////////////////////////////////////////////*/
12
+
13
+ /// @notice Returns the amount of stETH for a given amount of wstETH.
14
+ /// @param wstETHAmount The amount of wstETH.
15
+ /// @return The equivalent amount of stETH.
16
+ function getStETHByWstETH(uint256 wstETHAmount) external view returns (uint256);
17
+
18
+ /// @notice Returns the amount of wstETH for a given amount of stETH.
19
+ /// @param stETHAmount The amount of stETH.
20
+ /// @return The equivalent amount of wstETH.
21
+ function getWstETHByStETH(uint256 stETHAmount) external view returns (uint256);
22
+
23
+ /*//////////////////////////////////////////////////////////////////////////
24
+ STATE-CHANGING FUNCTIONS
25
+ //////////////////////////////////////////////////////////////////////////*/
26
+
27
+ /// @notice Wraps stETH to wstETH.
28
+ function wrap(uint256 stETHAmount) external returns (uint256 wstETHAmount);
29
+
30
+ /// @notice Unwraps wstETH to stETH.
31
+ function unwrap(uint256 wstETHAmount) external returns (uint256 stETHAmount);
32
+ }
@@ -0,0 +1,189 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity >=0.8.22;
3
+
4
+ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
5
+ import { UD60x18 } from "@prb/math/src/UD60x18.sol";
6
+ import { Escrow } from "../types/Escrow.sol";
7
+
8
+ /// @title Errors
9
+ /// @notice Library containing all custom errors emitted by the Sablier Bob protocol.
10
+ library Errors {
11
+ /*//////////////////////////////////////////////////////////////////////////
12
+ BOB VAULT SHARE
13
+ //////////////////////////////////////////////////////////////////////////*/
14
+
15
+ /// @notice Thrown when a function is called by an address other than SablierBob.
16
+ error BobVaultShare_OnlySablierBob(address caller, address expectedCaller);
17
+
18
+ /// @notice Thrown when the provided vault ID does not match the share token's vault ID.
19
+ error BobVaultShare_VaultIdMismatch(uint256 providedVaultId, uint256 expectedVaultId);
20
+
21
+ /*//////////////////////////////////////////////////////////////////////////
22
+ SABLIER BOB
23
+ //////////////////////////////////////////////////////////////////////////*/
24
+
25
+ /// @notice Thrown when `onShareTransfer` is called by an address other than the share token.
26
+ error SablierBob_CallerNotShareToken(uint256 vaultId, address caller);
27
+
28
+ /// @notice Thrown when depositing zero amount in a vault.
29
+ error SablierBob_DepositAmountZero(uint256 vaultId, address user);
30
+
31
+ /// @notice Thrown when trying to create a vault with an expiry timestamp not in the future.
32
+ error SablierBob_ExpiryNotInFuture(uint40 expiry, uint40 currentTime);
33
+
34
+ /// @notice Thrown when trying to create a vault with the native token.
35
+ error SablierBob_ForbidNativeToken(address nativeToken);
36
+
37
+ /// @notice Thrown when trying to redeem with `msg.value` less than the minimum fee required.
38
+ error SablierBob_InsufficientFeePayment(uint256 feePaid, uint256 feeRequired);
39
+
40
+ /// @notice Thrown when trying to pay a fee in the native token from a vault that uses the adapter.
41
+ error SablierBob_MsgValueNotZero(uint256 vaultId);
42
+
43
+ /// @notice Thrown when the native token fee transfer to the comptroller fails.
44
+ error SablierBob_NativeFeeTransferFailed();
45
+
46
+ /// @notice Thrown when trying to set the native token address when it is already set.
47
+ error SablierBob_NativeTokenAlreadySet(address nativeToken);
48
+
49
+ /// @notice Thrown when trying to set zero address as native token.
50
+ error SablierBob_NativeTokenZeroAddress();
51
+
52
+ /// @notice Thrown when the new adapter does not implement the required interface.
53
+ error SablierBob_NewAdapterMissesInterface(address adapter);
54
+
55
+ /// @notice Thrown when trying to exit or redeem with zero share balance.
56
+ error SablierBob_NoSharesToRedeem(uint256 vaultId, address user);
57
+
58
+ /// @notice Thrown when trying to create a vault with a zero target price.
59
+ error SablierBob_TargetPriceZero();
60
+
61
+ /// @notice Thrown when trying to create a vault with a target price that is not greater than the latest price
62
+ /// returned by the oracle.
63
+ error SablierBob_TargetPriceTooLow(uint128 targetPrice, uint128 currentPrice);
64
+
65
+ /// @notice Thrown when trying to create a vault with a zero token address.
66
+ error SablierBob_TokenAddressZero();
67
+
68
+ /// @notice Thrown when trying to unstake vault tokens using the adapter but the amount staked is zero.
69
+ error SablierBob_UnstakeAmountZero(uint256 vaultId);
70
+
71
+ /// @notice Thrown when trying to unstake vault tokens using the adapter but the vault has already been unstaked.
72
+ error SablierBob_VaultAlreadyUnstaked(uint256 vaultId);
73
+
74
+ /// @notice Thrown when trying to unstake from a vault that has no adapter configured.
75
+ error SablierBob_VaultHasNoAdapter(uint256 vaultId);
76
+
77
+ /// @notice Thrown when trying to perform an unauthorized action on a non-active vault.
78
+ error SablierBob_VaultNotActive(uint256 vaultId);
79
+
80
+ /// @notice Thrown when trying to perform an unauthorized action on an active vault.
81
+ error SablierBob_VaultStillActive(uint256 vaultId);
82
+
83
+ /*//////////////////////////////////////////////////////////////////////////
84
+ SABLIER BOB STATE
85
+ //////////////////////////////////////////////////////////////////////////*/
86
+
87
+ /// @notice Thrown when trying to interact with a non-existent vault.
88
+ error SablierBobState_Null(uint256 vaultId);
89
+
90
+ /*//////////////////////////////////////////////////////////////////////////
91
+ SABLIER ESCROW
92
+ //////////////////////////////////////////////////////////////////////////*/
93
+
94
+ /// @notice Thrown when trying to create an order with a zero address for the buy token.
95
+ error SablierEscrow_BuyTokenZero();
96
+
97
+ /// @notice Thrown when the caller is not authorized to perform an action on an order.
98
+ error SablierEscrow_CallerNotAuthorized(uint256 orderId, address caller, address expectedCaller);
99
+
100
+ /// @notice Thrown when trying to create an order with an expiration timestamp in the past.
101
+ error SablierEscrow_ExpiryTimeInPast(uint40 expiryTime, uint40 currentTime);
102
+
103
+ /// @notice Thrown when trying to create an order with the native token.
104
+ error SablierEscrow_ForbidNativeToken(address nativeToken);
105
+
106
+ /// @notice Thrown when trying to accept an order with a buy amount that is below the minimum amount required.
107
+ error SablierEscrow_InsufficientBuyAmount(uint128 buyAmount, uint128 minBuyAmount);
108
+
109
+ /// @notice Thrown when trying to create an order with a zero buy amount.
110
+ error SablierEscrow_MinBuyAmountZero();
111
+
112
+ /// @notice Thrown when trying to set the native token address when it is already set.
113
+ error SablierEscrow_NativeTokenAlreadySet(address nativeToken);
114
+
115
+ /// @notice Thrown when trying to set zero address as native token.
116
+ error SablierEscrow_NativeTokenZeroAddress();
117
+
118
+ /// @notice Thrown when trying to cancel an order that has already been canceled.
119
+ error SablierEscrow_OrderCancelled(uint256 orderId);
120
+
121
+ /// @notice Thrown when trying to cancel an order that has already been filled.
122
+ error SablierEscrow_OrderFilled(uint256 orderId);
123
+
124
+ /// @notice Thrown when trying to fill an order that has either been completed or canceled.
125
+ error SablierEscrow_OrderNotOpen(uint256 orderId, Escrow.Status status);
126
+
127
+ /// @notice Thrown when trying to create an order with the same sell and buy tokens.
128
+ error SablierEscrow_SameToken(IERC20 token);
129
+
130
+ /// @notice Thrown when trying to create an order with a zero sell amount.
131
+ error SablierEscrow_SellAmountZero();
132
+
133
+ /// @notice Thrown when trying to create an order with a zero address for the sell token.
134
+ error SablierEscrow_SellTokenZero();
135
+
136
+ /*//////////////////////////////////////////////////////////////////////////
137
+ SABLIER ESCROW STATE
138
+ //////////////////////////////////////////////////////////////////////////*/
139
+
140
+ /// @notice Thrown when trying to set a trade fee that exceeds the maximum allowed.
141
+ error SablierEscrowState_NewTradeFeeTooHigh(UD60x18 newTradeFee, UD60x18 maxTradeFee);
142
+
143
+ /// @notice Thrown when trying to interact with a non-existent order.
144
+ error SablierEscrowState_Null(uint256 orderId);
145
+
146
+ /*//////////////////////////////////////////////////////////////////////////
147
+ SABLIER LIDO ADAPTER
148
+ //////////////////////////////////////////////////////////////////////////*/
149
+
150
+ /// @notice Thrown when trying to request a Lido withdrawal for a vault that has already requested one.
151
+ error SablierLidoAdapter_LidoWithdrawalAlreadyRequested(uint256 vaultId);
152
+
153
+ /// @notice Thrown when trying to request a Lido withdrawal for a vault with no wstETH.
154
+ error SablierLidoAdapter_NoWstETHToWithdraw(uint256 vaultId);
155
+
156
+ /// @notice Thrown when a function is called by an address other than SablierBob.
157
+ error SablierLidoAdapter_OnlySablierBob(address caller, address expectedCaller);
158
+
159
+ /// @notice Thrown when the stETH/ETH oracle returns a zero price.
160
+ error SablierLidoAdapter_OraclePriceZero();
161
+
162
+ /// @notice Thrown when the Curve swap output is below the minimum acceptable amount.
163
+ error SablierLidoAdapter_SlippageExceeded(uint256 expected, uint256 actual);
164
+
165
+ /// @notice Thrown when trying to set a slippage that exceeds the maximum allowed.
166
+ error SablierLidoAdapter_SlippageToleranceTooHigh(UD60x18 tolerance, UD60x18 maxTolerance);
167
+
168
+ /// @notice Thrown when trying to update staked token balance but the user's balance is zero.
169
+ error SablierLidoAdapter_UserBalanceZero(uint256 vaultId, address user);
170
+
171
+ /// @notice Thrown when trying to request a Lido withdrawal for a vault that is active.
172
+ error SablierLidoAdapter_VaultActive(uint256 vaultId);
173
+
174
+ /// @notice Thrown when trying to request a Lido withdrawal for a vault that has already been unstaked.
175
+ error SablierLidoAdapter_VaultAlreadyUnstaked(uint256 vaultId);
176
+
177
+ /// @notice Thrown when the calculated wstETH transfer amount rounds down to zero due to floor division.
178
+ error SablierLidoAdapter_WstETHTransferAmountZero(uint256 vaultId, address from, address to);
179
+
180
+ /// @notice Thrown when the total amount to withdraw is below the minimum amount per request.
181
+ error SablierLidoAdapter_WithdrawalAmountBelowMinimum(
182
+ uint256 vaultId,
183
+ uint256 totalAmount,
184
+ uint256 minimumAmountPerRequest
185
+ );
186
+
187
+ /// @notice Thrown when trying to set a yield fee that exceeds the maximum allowed.
188
+ error SablierLidoAdapter_YieldFeeTooHigh(UD60x18 fee, UD60x18 maxFee);
189
+ }
@@ -0,0 +1,49 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity >=0.8.22;
3
+
4
+ import { AggregatorV3Interface } from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
5
+ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
6
+
7
+ import { IBobVaultShare } from "../interfaces/IBobVaultShare.sol";
8
+ import { ISablierBobAdapter } from "../interfaces/ISablierBobAdapter.sol";
9
+
10
+ /// @notice Namespace for the structs and enums used in the Sablier Bob protocol.
11
+ library Bob {
12
+ /// @notice Enum representing the different statuses of a vault.
13
+ /// @custom:value0 ACTIVE Vault is open for deposits.
14
+ /// @custom:value1 EXPIRED Vault has end time less than or equal to current timestamp.
15
+ /// @custom:value2 SETTLED Vault has target price less than or equal to last synced price.
16
+ enum Status {
17
+ ACTIVE,
18
+ EXPIRED,
19
+ SETTLED
20
+ }
21
+
22
+ /// @notice Struct encapsulating all the configuration and state of a vault.
23
+ /// @dev The fields are arranged for gas optimization via tight variable packing.
24
+ /// @param token The ERC-20 token accepted for deposits in this vault.
25
+ /// @param expiry The Unix timestamp when the vault expires.
26
+ /// @param lastSyncedAt The Unix timestamp when the oracle price was last synced.
27
+ /// @param shareToken The address of ERC-20 token representing shares in this vault.
28
+ /// @param oracle The address of the price oracle for the deposit token, provided by the vault creator.
29
+ /// @param adapter The adapter set for this vault, can be used to take action on the deposit token.
30
+ /// @param isStakedInAdapter Whether the deposit token is staked with the adapter or not.
31
+ /// @param targetPrice The target price at which the vault settles, denoted in 8 decimals where 1e8 is $1.
32
+ /// @param lastSyncedPrice The most recent price fetched from the oracle, denoted in 8 decimals where 1e8 is $1.
33
+ struct Vault {
34
+ // slot 0
35
+ IERC20 token;
36
+ uint40 expiry;
37
+ uint40 lastSyncedAt;
38
+ // slot 1
39
+ IBobVaultShare shareToken;
40
+ // slot 2
41
+ AggregatorV3Interface oracle;
42
+ // slot 3
43
+ ISablierBobAdapter adapter;
44
+ bool isStakedInAdapter;
45
+ // slot 4
46
+ uint128 targetPrice;
47
+ uint128 lastSyncedPrice;
48
+ }
49
+ }
@@ -0,0 +1,49 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity >=0.8.22;
3
+
4
+ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
5
+
6
+ /// @notice Namespace for the structs and enums used in the Sablier Escrow protocol.
7
+ library Escrow {
8
+ /// @notice Enum representing the different statuses of an order.
9
+ /// @dev The status is derived at runtime from boolean flags and timestamps, not stored directly.
10
+ /// @custom:value0 CANCELLED Order has been cancelled by the seller.
11
+ /// @custom:value1 EXPIRED Order has expired without being filled.
12
+ /// @custom:value2 FILLED Order has been successfully filled.
13
+ /// @custom:value3 OPEN Order is open and can be filled or cancelled.
14
+ enum Status {
15
+ CANCELLED,
16
+ EXPIRED,
17
+ FILLED,
18
+ OPEN
19
+ }
20
+
21
+ /// @notice Struct encapsulating all the configuration and state of an order.
22
+ /// @dev The fields are arranged for gas optimization via tight variable packing.
23
+ /// @param seller The address that created the order and deposited the sell token.
24
+ /// @param buyer The designated counterparty address specified by the seller. If its zero address, the order can be
25
+ /// filled by anyone.
26
+ /// @param sellToken The ERC-20 token being sold, deposited by the seller when the order is created.
27
+ /// @param buyToken The ERC-20 token the seller wants to receive.
28
+ /// @param sellAmount The amount of sell token that the seller is willing to exchange.
29
+ /// @param minBuyAmount The minimum amount of buy token required to fill the order.
30
+ /// @param expiryTime The Unix timestamp when the order expires. Zero is sentinel for orders that never expire.
31
+ /// @param wasCanceled Boolean indicating if the order was canceled.
32
+ /// @param wasFilled Boolean indicating if the order was filled.
33
+ struct Order {
34
+ // slot 0
35
+ address seller;
36
+ uint40 expiryTime;
37
+ bool wasCanceled;
38
+ bool wasFilled;
39
+ // slot 1
40
+ address buyer;
41
+ // slot 2
42
+ IERC20 sellToken;
43
+ // slot 3
44
+ IERC20 buyToken;
45
+ // slot 4
46
+ uint128 sellAmount;
47
+ uint128 minBuyAmount;
48
+ }
49
+ }