diff --git a/src/BaseConditionalOrder.sol b/src/BaseConditionalOrder.sol index 511040c..842d0e7 100644 --- a/src/BaseConditionalOrder.sol +++ b/src/BaseConditionalOrder.sol @@ -8,7 +8,8 @@ import {IERC165, IConditionalOrder, IConditionalOrderGenerator} from "./interfac // --- error strings /// @dev This error is returned by the `verify` function if the *generated* order hash does not match /// the hash passed as a parameter. -string constant INVALID_HASH = "invalid hash"; +/// @dev The generated order hash does not match the hash passed to `verify` +error InvalidHash(); /** * @title Base logic for conditional orders. @@ -35,7 +36,7 @@ abstract contract BaseConditionalOrder is IConditionalOrderGenerator { /// @dev Verify that the *generated* order is valid and matches the payload. if (!(_hash == GPv2Order.hash(generatedOrder, domainSeparator))) { - revert IConditionalOrder.OrderNotValid(INVALID_HASH); + revert IConditionalOrder.OrderNotValid(InvalidHash.selector); } } diff --git a/src/ComposableCoW.sol b/src/ComposableCoW.sol index 568e6b6..3eaf60d 100644 --- a/src/ComposableCoW.sol +++ b/src/ComposableCoW.sol @@ -193,16 +193,17 @@ contract ComposableCoW is ISafeSignatureVerifier { } // Proof is valid, guard (if any) is valid, now check the handler - _payload.params.handler.verify( - address(safe), - sender, - _hash, - _domainSeparator, - ctx, - _payload.params.staticInput, - _payload.offchainInput, - order - ); + _payload.params.handler + .verify( + address(safe), + sender, + _hash, + _domainSeparator, + ctx, + _payload.params.staticInput, + _payload.offchainInput, + order + ); return ERC1271.isValidSignature.selector; } @@ -228,9 +229,10 @@ contract ComposableCoW is ISafeSignatureVerifier { bytes32 ctx = _auth(owner, params, proof); // Make sure the handler supports `IConditionalOrderGenerator` - try IConditionalOrderGenerator(address(params.handler)).supportsInterface( - type(IConditionalOrderGenerator).interfaceId - ) returns (bool supported) { + try IConditionalOrderGenerator(address(params.handler)) + .supportsInterface(type(IConditionalOrderGenerator).interfaceId) returns ( + bool supported + ) { if (!supported) { revert InterfaceNotSupported(); } @@ -238,9 +240,8 @@ contract ComposableCoW is ISafeSignatureVerifier { revert InterfaceNotSupported(); } - order = IConditionalOrderGenerator(address(params.handler)).generateOrder( - owner, msg.sender, ctx, params.staticInput, offchainInput - ); + order = IConditionalOrderGenerator(address(params.handler)) + .generateOrder(owner, msg.sender, ctx, params.staticInput, offchainInput); // Check with the swap guard if the order is restricted or not if (!(_guardCheck(owner, ctx, params, offchainInput, order))) { diff --git a/src/interfaces/IConditionalOrder.sol b/src/interfaces/IConditionalOrder.sol index 2ee3db2..f347c03 100644 --- a/src/interfaces/IConditionalOrder.sol +++ b/src/interfaces/IConditionalOrder.sol @@ -11,16 +11,17 @@ import {IERC165} from "safe/interfaces/IERC165.sol"; */ interface IConditionalOrder { /// @dev This error is returned by the `generateOrder` function if the order condition is not met. - /// A parameter of `string` type is included to allow the caller to specify the reason for the failure. - error OrderNotValid(string); + /// `reasonCode` is the selector of a handler-declared custom error, so any ABI-aware + /// consumer can resolve it to a name without a bespoke table. + error OrderNotValid(bytes4 reasonCode); // --- errors specific for polling // Signal to a watch tower that polling should be attempted again. - error PollTryNextBlock(string reason); + error PollTryNextBlock(bytes4 reasonCode); // Signal to a watch tower that polling should be attempted again at a specific block number. - error PollTryAtBlock(uint256 blockNumber, string reason); + error PollTryAtBlock(uint256 blockNumber, bytes4 reasonCode); // Signal to a watch tower that polling should be attempted again at a specific timestamp. - error PollTryAtTimestamp(uint256 timestamp, string reason); + error PollTryAtTimestamp(uint256 timestamp, bytes4 reasonCode); /** * @dev This struct is used to uniquely identify a conditional order for an owner. diff --git a/src/types/GoodAfterTime.sol b/src/types/GoodAfterTime.sol index 850e46e..422f111 100644 --- a/src/types/GoodAfterTime.sol +++ b/src/types/GoodAfterTime.sol @@ -8,12 +8,12 @@ import {IERC20, IConditionalOrder, GPv2Order, BaseConditionalOrder} from "../Bas import {ConditionalOrdersUtilsLib as Utils} from "./ConditionalOrdersUtilsLib.sol"; // --- error strings -/// @dev If the trade is called before the time it becomes valid. -string constant TOO_EARLY = "too early"; -/// @dev If the sell token balance is below the minimum. -string constant BALANCE_INSUFFICIENT = "balance insufficient"; -/// @dev If the price checker fails. -string constant PRICE_CHECKER_FAILED = "price checker failed"; +/// @dev The start time has not been reached +error TooEarly(); +/// @dev The sell token balance is below minSellBalance +error BalanceInsufficient(); +/// @dev The buy amount is below the price checker minimum +error PriceCheckerFailed(); /** * @title Good After Time (GAT) Conditional Order - with Milkman price checkers @@ -50,24 +50,23 @@ contract GoodAfterTime is BaseConditionalOrder { uint256 allowedSlippage; // in basis points } - function generateOrder( - address owner, - address, - bytes32, - bytes calldata staticInput, - bytes calldata offchainInput - ) public view override returns (GPv2Order.Data memory order) { + function generateOrder(address owner, address, bytes32, bytes calldata staticInput, bytes calldata offchainInput) + public + view + override + returns (GPv2Order.Data memory order) + { // Decode the payload into the good after time parameters. Data memory data = abi.decode(staticInput, (Data)); // Don't allow the order to be placed before it becomes valid. if (!(block.timestamp >= data.startTime)) { - revert IConditionalOrder.PollTryAtTimestamp(data.startTime, TOO_EARLY); + revert IConditionalOrder.PollTryAtTimestamp(data.startTime, TooEarly.selector); } // Require that the sell token balance is above the minimum. if (!(data.sellToken.balanceOf(owner) >= data.minSellBalance)) { - revert IConditionalOrder.OrderNotValid(BALANCE_INSUFFICIENT); + revert IConditionalOrder.OrderNotValid(BalanceInsufficient.selector); } uint256 buyAmount = abi.decode(offchainInput, (uint256)); @@ -82,7 +81,7 @@ contract GoodAfterTime is BaseConditionalOrder { // Don't allow the order to be placed if the buyAmount is less than the minimum out. if (!(buyAmount >= (_expectedOut * (Utils.MAX_BPS - p.allowedSlippage)) / Utils.MAX_BPS)) { - revert IConditionalOrder.PollTryNextBlock(PRICE_CHECKER_FAILED); + revert IConditionalOrder.PollTryNextBlock(PriceCheckerFailed.selector); } } diff --git a/src/types/PerpetualStableSwap.sol b/src/types/PerpetualStableSwap.sol index 05fbbf5..f47f23a 100644 --- a/src/types/PerpetualStableSwap.sol +++ b/src/types/PerpetualStableSwap.sol @@ -11,8 +11,8 @@ import { import {ConditionalOrdersUtilsLib as Utils} from "./ConditionalOrdersUtilsLib.sol"; // --- error strings -/// @dev The sell amount is insufficient (ie. not funded). -string constant NOT_FUNDED = "not funded"; +/// @dev Neither token balance is non-zero +error NotFunded(); /** * @title A smart contract that is always willing to trade between tokenA and tokenB 1:1, @@ -60,7 +60,7 @@ contract PerpetualStableSwap is BaseConditionalOrder { // Make sure the order is funded, otherwise it is not valid if (!(buySellData.sellAmount > 0)) { - revert IConditionalOrder.OrderNotValid(NOT_FUNDED); + revert IConditionalOrder.OrderNotValid(NotFunded.selector); } // Unless spread is 0 (and there is no surplus), order collision is not an issue as sell and buy amounts should @@ -98,14 +98,16 @@ contract PerpetualStableSwap is BaseConditionalOrder { sellToken: tokenA, buyToken: tokenB, sellAmount: balanceA, - buyAmount: convertAmount(tokenA, balanceA, tokenB) * (Utils.MAX_BPS + data.halfSpreadBps) / Utils.MAX_BPS + buyAmount: convertAmount(tokenA, balanceA, tokenB) * (Utils.MAX_BPS + data.halfSpreadBps) + / Utils.MAX_BPS }); } else { buySellData = BuySellData({ sellToken: tokenB, buyToken: tokenA, sellAmount: balanceB, - buyAmount: convertAmount(tokenB, balanceB, tokenA) * (Utils.MAX_BPS + data.halfSpreadBps) / Utils.MAX_BPS + buyAmount: convertAmount(tokenB, balanceB, tokenA) * (Utils.MAX_BPS + data.halfSpreadBps) + / Utils.MAX_BPS }); } } diff --git a/src/types/StopLoss.sol b/src/types/StopLoss.sol index 1250277..d7fac6b 100644 --- a/src/types/StopLoss.sol +++ b/src/types/StopLoss.sol @@ -7,14 +7,14 @@ import {ConditionalOrdersUtilsLib as Utils} from "./ConditionalOrdersUtilsLib.so // --- error strings -/// @dev Invalid price data returned by the oracle -string constant ORACLE_INVALID_PRICE = "oracle invalid price"; -/// @dev The oracle has returned stale data -string constant ORACLE_STALE_PRICE = "oracle stale price"; +/// @dev An oracle returned an invalid (non-positive) price +error OracleInvalidPrice(); +/// @dev An oracle price is older than maxTimeSinceLastOracleUpdate +error OracleStalePrice(); /// @dev The strike price has not been reached -string constant STRIKE_NOT_REACHED = "strike not reached"; -/// @dev The order is not valid anymore -string constant ORDER_EXPIRED = "order expired"; +error StrikeNotReached(); +/// @dev The order validity window has passed +error OrderExpired(); /** * @title StopLoss conditional order @@ -69,7 +69,7 @@ contract StopLoss is BaseConditionalOrder { { /// @dev Guard against expired orders if (data.validTo < block.timestamp) { - revert IConditionalOrder.OrderNotValid(ORDER_EXPIRED); + revert IConditionalOrder.OrderNotValid(OrderExpired.selector); } (, int256 basePrice,, uint256 sellUpdatedAt,) = data.sellTokenPriceOracle.latestRoundData(); @@ -77,17 +77,13 @@ contract StopLoss is BaseConditionalOrder { /// @dev Guard against invalid price data if (!(basePrice > 0 && quotePrice > 0)) { - revert IConditionalOrder.OrderNotValid(ORACLE_INVALID_PRICE); + revert IConditionalOrder.OrderNotValid(OracleInvalidPrice.selector); } /// @dev Guard against stale data at a user-specified interval. The maxTimeSinceLastOracleUpdate should at least exceed the both oracles' update intervals. - if ( - !( - sellUpdatedAt >= block.timestamp - data.maxTimeSinceLastOracleUpdate - && buyUpdatedAt >= block.timestamp - data.maxTimeSinceLastOracleUpdate - ) - ) { - revert IConditionalOrder.PollTryNextBlock(ORACLE_STALE_PRICE); + if (!(sellUpdatedAt >= block.timestamp - data.maxTimeSinceLastOracleUpdate + && buyUpdatedAt >= block.timestamp - data.maxTimeSinceLastOracleUpdate)) { + revert IConditionalOrder.PollTryNextBlock(OracleStalePrice.selector); } // Normalize the decimals for basePrice and quotePrice, scaling them to 18 decimals @@ -97,7 +93,7 @@ contract StopLoss is BaseConditionalOrder { /// @dev Scale the strike price to 18 decimals. if (!(basePrice * SCALING_FACTOR / quotePrice <= data.strike)) { - revert IConditionalOrder.PollTryNextBlock(STRIKE_NOT_REACHED); + revert IConditionalOrder.PollTryNextBlock(StrikeNotReached.selector); } } diff --git a/src/types/TradeAboveThreshold.sol b/src/types/TradeAboveThreshold.sol index 915cf44..67453b2 100644 --- a/src/types/TradeAboveThreshold.sol +++ b/src/types/TradeAboveThreshold.sol @@ -12,8 +12,8 @@ import {ConditionalOrdersUtilsLib as Utils} from "./ConditionalOrdersUtilsLib.so // --- error strings -/// @dev The sell token balance is below the threshold (ie. threshold not met). -string constant BALANCE_INSUFFICIENT = "balance insufficient"; +/// @dev The sell token balance is below the threshold or zero +error BalanceInsufficient(); /** * @title A smart contract that trades whenever its balance of a certain token exceeds a target threshold @@ -45,7 +45,7 @@ contract TradeAboveThreshold is BaseConditionalOrder { uint256 balance = data.sellToken.balanceOf(owner); // Don't allow the order to be placed if the balance is less than the threshold. if (!(balance >= data.threshold)) { - revert IConditionalOrder.PollTryNextBlock(BALANCE_INSUFFICIENT); + revert IConditionalOrder.PollTryNextBlock(BalanceInsufficient.selector); } // ensures that orders queried shortly after one another result in the same hash (to avoid spamming the orderbook) order = GPv2Order.Data( diff --git a/src/types/twap/TWAP.sol b/src/types/twap/TWAP.sol index e1bf17b..ede2f4c 100644 --- a/src/types/twap/TWAP.sol +++ b/src/types/twap/TWAP.sol @@ -13,8 +13,8 @@ import {TWAPOrder} from "./libraries/TWAPOrder.sol"; // --- error strings -/// @dev The order is not within the TWAP bundle's span. -string constant NOT_WITHIN_SPAN = "not within span"; +/// @dev The current time is outside the active part's span +error NotWithinSpan(); /** * @title TWAP Conditional Order @@ -61,7 +61,7 @@ contract TWAP is BaseConditionalOrder { /// @dev Revert if the order is outside the TWAP bundle's span. if (!(block.timestamp <= order.validTo)) { - revert IConditionalOrder.OrderNotValid(NOT_WITHIN_SPAN); + revert IConditionalOrder.OrderNotValid(NotWithinSpan.selector); } } } diff --git a/src/types/twap/libraries/TWAPOrder.sol b/src/types/twap/libraries/TWAPOrder.sol index 94e411a..4c4d5f8 100644 --- a/src/types/twap/libraries/TWAPOrder.sol +++ b/src/types/twap/libraries/TWAPOrder.sol @@ -9,14 +9,22 @@ import {TWAPOrderMathLib} from "./TWAPOrderMathLib.sol"; // --- error strings -string constant INVALID_SAME_TOKEN = "same token"; -string constant INVALID_TOKEN = "invalid token"; -string constant INVALID_PART_SELL_AMOUNT = "invalid part sell amount"; -string constant INVALID_MIN_PART_LIMIT = "invalid min part limit"; -string constant INVALID_START_TIME = "invalid start time"; -string constant INVALID_NUM_PARTS = "invalid num parts"; -string constant INVALID_FREQUENCY = "invalid frequency"; -string constant INVALID_SPAN = "invalid span"; +/// @dev Sell and buy token are identical +error InvalidSameToken(); +/// @dev A token is the zero address +error InvalidToken(); +/// @dev The part sell amount is zero +error InvalidPartSellAmount(); +/// @dev The minimum part limit is zero +error InvalidMinPartLimit(); +/// @dev The start time does not fit uint32 +error InvalidStartTime(); +/// @dev The number of parts is not in (1, uint32.max] +error InvalidNumParts(); +/// @dev The frequency is not in (0, 365 days] +error InvalidFrequency(); +/// @dev The span exceeds the frequency +error InvalidSpan(); /** * @title Time-weighted Average Order Library @@ -48,16 +56,18 @@ library TWAPOrder { * @param self The TWAP order to validate */ function validate(Data memory self) internal pure { - if (!(self.sellToken != self.buyToken)) revert IConditionalOrder.OrderNotValid(INVALID_SAME_TOKEN); + if (!(self.sellToken != self.buyToken)) revert IConditionalOrder.OrderNotValid(InvalidSameToken.selector); if (!(address(self.sellToken) != address(0) && address(self.buyToken) != address(0))) { - revert IConditionalOrder.OrderNotValid(INVALID_TOKEN); + revert IConditionalOrder.OrderNotValid(InvalidToken.selector); } - if (!(self.partSellAmount > 0)) revert IConditionalOrder.OrderNotValid(INVALID_PART_SELL_AMOUNT); - if (!(self.minPartLimit > 0)) revert IConditionalOrder.OrderNotValid(INVALID_MIN_PART_LIMIT); - if (!(self.t0 < type(uint32).max)) revert IConditionalOrder.OrderNotValid(INVALID_START_TIME); - if (!(self.n > 1 && self.n <= type(uint32).max)) revert IConditionalOrder.OrderNotValid(INVALID_NUM_PARTS); - if (!(self.t > 0 && self.t <= 365 days)) revert IConditionalOrder.OrderNotValid(INVALID_FREQUENCY); - if (!(self.span <= self.t)) revert IConditionalOrder.OrderNotValid(INVALID_SPAN); + if (!(self.partSellAmount > 0)) revert IConditionalOrder.OrderNotValid(InvalidPartSellAmount.selector); + if (!(self.minPartLimit > 0)) revert IConditionalOrder.OrderNotValid(InvalidMinPartLimit.selector); + if (!(self.t0 < type(uint32).max)) revert IConditionalOrder.OrderNotValid(InvalidStartTime.selector); + if (!(self.n > 1 && self.n <= type(uint32).max)) { + revert IConditionalOrder.OrderNotValid(InvalidNumParts.selector); + } + if (!(self.t > 0 && self.t <= 365 days)) revert IConditionalOrder.OrderNotValid(InvalidFrequency.selector); + if (!(self.span <= self.t)) revert IConditionalOrder.OrderNotValid(InvalidSpan.selector); } /** diff --git a/src/types/twap/libraries/TWAPOrderMathLib.sol b/src/types/twap/libraries/TWAPOrderMathLib.sol index a636776..eac6ca3 100644 --- a/src/types/twap/libraries/TWAPOrderMathLib.sol +++ b/src/types/twap/libraries/TWAPOrderMathLib.sol @@ -5,10 +5,10 @@ import {IConditionalOrder} from "../../../interfaces/IConditionalOrder.sol"; // --- error strings -/// @dev No discrete order is valid before the start of the TWAP conditional order. -string constant BEFORE_TWAP_START = "before twap start"; -/// @dev No discrete order is valid after it's last part. -string constant AFTER_TWAP_FINISH = "after twap finish"; +/// @dev No discrete order is valid before the start of the TWAP +error BeforeTwapStart(); +/// @dev No discrete order is valid after the last part +error AfterTwapFinish(); /** * @title CoWProtocol TWAP Order Math Library @@ -39,7 +39,7 @@ library TWAPOrderMathLib { unchecked { /// @dev Order is not valid before the start (order commences at `t0`). - if (!(startTime <= block.timestamp)) revert IConditionalOrder.OrderNotValid(BEFORE_TWAP_START); + if (!(startTime <= block.timestamp)) revert IConditionalOrder.OrderNotValid(BeforeTwapStart.selector); /** * @dev Order is expired after the last part (`n` parts, running at `t` time length). @@ -51,7 +51,7 @@ library TWAPOrderMathLib { * `type(uint32).max` so the sum of `startTime + (numParts * frequency)` is ≈ 2⁵⁵. */ if (!(block.timestamp < startTime + (numParts * frequency))) { - revert IConditionalOrder.OrderNotValid(AFTER_TWAP_FINISH); + revert IConditionalOrder.OrderNotValid(AfterTwapFinish.selector); } /** diff --git a/test/ComposableCoW.base.t.sol b/test/ComposableCoW.base.t.sol index ad6a351..86c904e 100644 --- a/test/ComposableCoW.base.t.sol +++ b/test/ComposableCoW.base.t.sol @@ -11,7 +11,7 @@ import {TestAccount, TestAccountLib} from "./libraries/TestAccountLib.t.sol"; import {SafeLib} from "./libraries/SafeLib.t.sol"; import {ComposableCoWLib} from "./libraries/ComposableCoWLib.t.sol"; -import {IConditionalOrder, IERC20, BaseConditionalOrder, INVALID_HASH} from "../src/BaseConditionalOrder.sol"; +import {IConditionalOrder, IERC20, BaseConditionalOrder, InvalidHash} from "../src/BaseConditionalOrder.sol"; import {BaseSwapGuard} from "../src/guards/BaseSwapGuard.sol"; import {TWAP, TWAPOrder} from "../src/types/twap/TWAP.sol"; @@ -185,9 +185,7 @@ contract BaseComposableCoWTest is Base, Merkle { returns (IConditionalOrder.ConditionalOrderParams memory params) { params = IConditionalOrder.ConditionalOrderParams({ - handler: IConditionalOrder(handler), - salt: salt, - staticInput: staticInput + handler: IConditionalOrder(handler), salt: salt, staticInput: staticInput }); } @@ -216,9 +214,7 @@ contract BaseComposableCoWTest is Base, Merkle { _leaves = new IConditionalOrder.ConditionalOrderParams[](n); for (uint256 i = 0; i < _leaves.length; i++) { _leaves[i] = IConditionalOrder.ConditionalOrderParams({ - handler: twap, - salt: keccak256(abi.encode(bytes32(i))), - staticInput: abi.encode(twapData) + handler: twap, salt: keccak256(abi.encode(bytes32(i))), staticInput: abi.encode(twapData) }); } diff --git a/test/ComposableCoW.gat.t.sol b/test/ComposableCoW.gat.t.sol index 0ac9f44..a41f105 100644 --- a/test/ComposableCoW.gat.t.sol +++ b/test/ComposableCoW.gat.t.sol @@ -17,9 +17,9 @@ import { import { IExpectedOutCalculator, GoodAfterTime, - TOO_EARLY, - BALANCE_INSUFFICIENT, - PRICE_CHECKER_FAILED + TooEarly, + BalanceInsufficient, + PriceCheckerFailed } from "../src/types/GoodAfterTime.sol"; contract ComposableCoWGatTest is BaseComposableCoWTest { @@ -54,7 +54,9 @@ contract ComposableCoWGatTest is BaseComposableCoWTest { vm.warp(currentTime); // should revert when the current time is before the start time - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.PollTryAtTimestamp.selector, startTime, TOO_EARLY)); + vm.expectRevert( + abi.encodeWithSelector(IConditionalOrder.PollTryAtTimestamp.selector, startTime, TooEarly.selector) + ); gat.generateOrder(address(safe1), address(0), bytes32(0), abi.encode(o), abi.encode(uint256(1e18))); } @@ -75,31 +77,22 @@ contract ComposableCoWGatTest is BaseComposableCoWTest { deal(address(o.sellToken), address(safe1), currentBalance); // should revert when the current balance is below the minimum balance - vm.expectRevert( - abi.encodeWithSelector( - IConditionalOrder.OrderNotValid.selector, - BALANCE_INSUFFICIENT - ) - ); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, BalanceInsufficient.selector)); gat.generateOrder(address(safe1), address(0), bytes32(0), abi.encode(o), abi.encode(uint256(1e18))); } /** * @dev Fuzz test revert when oracle supplied buyAmount is less than the price checker */ - function test_generateOrder_FuzzRevertTooLowOutput( - uint256 buyAmount, - uint256 expectedOut, - uint256 allowedSlippage - ) public { + function test_generateOrder_FuzzRevertTooLowOutput(uint256 buyAmount, uint256 expectedOut, uint256 allowedSlippage) + public + { vm.assume(expectedOut < type(uint256).max / 10000); allowedSlippage = bound(allowedSlippage, 0, 10000); vm.assume(buyAmount < expectedOut * (10000 - allowedSlippage) / 10000); GoodAfterTime.PriceCheckerPayload memory checker = GoodAfterTime.PriceCheckerPayload({ - checker: testOutCalculator, - payload: abi.encode(expectedOut), - allowedSlippage: allowedSlippage + checker: testOutCalculator, payload: abi.encode(expectedOut), allowedSlippage: allowedSlippage }); GoodAfterTime.Data memory o = _gatTest(abi.encode(checker)); @@ -111,10 +104,7 @@ contract ComposableCoWGatTest is BaseComposableCoWTest { deal(address(o.sellToken), address(safe1), o.minSellBalance); vm.expectRevert( - abi.encodeWithSelector( - IConditionalOrder.PollTryNextBlock.selector, - PRICE_CHECKER_FAILED - ) + abi.encodeWithSelector(IConditionalOrder.PollTryNextBlock.selector, PriceCheckerFailed.selector) ); gat.generateOrder(address(safe1), address(0), bytes32(0), abi.encode(o), abi.encode(buyAmount)); } @@ -236,9 +226,7 @@ contract ComposableCoWGatTest is BaseComposableCoWTest { // Create the price checker payload GoodAfterTime.PriceCheckerPayload memory checker = GoodAfterTime.PriceCheckerPayload({ - checker: testOutCalculator, - payload: abi.encode(expectedOut), - allowedSlippage: allowedSlippage + checker: testOutCalculator, payload: abi.encode(expectedOut), allowedSlippage: allowedSlippage }); // Create the order payload @@ -286,9 +274,7 @@ contract ComposableCoWGatTest is BaseComposableCoWTest { // Create the price checker payload GoodAfterTime.PriceCheckerPayload memory checker = GoodAfterTime.PriceCheckerPayload({ - checker: testOutCalculator, - payload: abi.encode(expectedOut), - allowedSlippage: allowedSlippage + checker: testOutCalculator, payload: abi.encode(expectedOut), allowedSlippage: allowedSlippage }); // Create the order payload @@ -323,8 +309,9 @@ contract ComposableCoWGatTest is BaseComposableCoWTest { */ function test_settle_e2e() public { // Create the price checker payload - GoodAfterTime.PriceCheckerPayload memory checker = - GoodAfterTime.PriceCheckerPayload({checker: testOutCalculator, payload: abi.encode(1), allowedSlippage: 50}); + GoodAfterTime.PriceCheckerPayload memory checker = GoodAfterTime.PriceCheckerPayload({ + checker: testOutCalculator, payload: abi.encode(1), allowedSlippage: 50 + }); // Create the order payload GoodAfterTime.Data memory o = _gatTest(abi.encode(checker)); diff --git a/test/ComposableCoW.stoploss.t.sol b/test/ComposableCoW.stoploss.t.sol index 899b090..57ff8e5 100644 --- a/test/ComposableCoW.stoploss.t.sol +++ b/test/ComposableCoW.stoploss.t.sol @@ -3,7 +3,13 @@ pragma solidity >=0.8.0 <0.9.0; import {IERC20, GPv2Order, IConditionalOrder, BaseComposableCoWTest} from "./ComposableCoW.base.t.sol"; import {IAggregatorV3Interface} from "../src/interfaces/IAggregatorV3Interface.sol"; -import {StopLoss, STRIKE_NOT_REACHED, ORACLE_STALE_PRICE, ORACLE_INVALID_PRICE, ORDER_EXPIRED} from "../src/types/StopLoss.sol"; +import { + StopLoss, + StrikeNotReached, + OracleStalePrice, + OracleInvalidPrice, + OrderExpired +} from "../src/types/StopLoss.sol"; contract ComposableCoWStopLossTest is BaseComposableCoWTest { IERC20 immutable SELL_TOKEN = IERC20(address(0x1)); @@ -63,12 +69,7 @@ contract ComposableCoWStopLossTest is BaseComposableCoWTest { createOrder(stopLoss, 0x0, abi.encode(data)); - vm.expectRevert( - abi.encodeWithSelector( - IConditionalOrder.PollTryNextBlock.selector, - STRIKE_NOT_REACHED - ) - ); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.PollTryNextBlock.selector, StrikeNotReached.selector)); stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); } @@ -106,12 +107,7 @@ contract ComposableCoWStopLossTest is BaseComposableCoWTest { maxTimeSinceLastOracleUpdate: staleTime }); - vm.expectRevert( - abi.encodeWithSelector( - IConditionalOrder.PollTryNextBlock.selector, - STRIKE_NOT_REACHED - ) - ); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.PollTryNextBlock.selector, StrikeNotReached.selector)); stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); } @@ -144,11 +140,9 @@ contract ComposableCoWStopLossTest is BaseComposableCoWTest { ), strike: int256( 1900 - * ( - sellTokenERC20Decimals > buyTokenERC20Decimals + * (sellTokenERC20Decimals > buyTokenERC20Decimals ? (10 ** (sellTokenERC20Decimals - buyTokenERC20Decimals + 18)) - : (10 ** (buyTokenERC20Decimals - sellTokenERC20Decimals + 18)) - ) + : (10 ** (buyTokenERC20Decimals - sellTokenERC20Decimals + 18))) ), // Strike price is to 18 decimals, base / quote. ie. 1900_000_000_000_000_000_000 = 1900 USDC/ETH sellAmount: 1 ether, buyAmount: 1, @@ -160,8 +154,7 @@ contract ComposableCoWStopLossTest is BaseComposableCoWTest { maxTimeSinceLastOracleUpdate: 15 minutes }); - GPv2Order.Data memory order = - stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); + GPv2Order.Data memory order = stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); assertEq(address(order.sellToken), address(SELL_TOKEN)); assertEq(address(order.buyToken), address(BUY_TOKEN)); assertEq(order.sellAmount, 1 ether); @@ -196,8 +189,7 @@ contract ComposableCoWStopLossTest is BaseComposableCoWTest { maxTimeSinceLastOracleUpdate: 15 minutes }); - GPv2Order.Data memory order = - stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); + GPv2Order.Data memory order = stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); assertEq(address(order.sellToken), address(SELL_TOKEN)); assertEq(address(order.buyToken), address(BUY_TOKEN)); assertEq(order.sellAmount, 1 ether); @@ -241,12 +233,7 @@ contract ComposableCoWStopLossTest is BaseComposableCoWTest { maxTimeSinceLastOracleUpdate: maxTimeSinceLastOracleUpdate }); - vm.expectRevert( - abi.encodeWithSelector( - IConditionalOrder.PollTryNextBlock.selector, - ORACLE_STALE_PRICE - ) - ); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.PollTryNextBlock.selector, OracleStalePrice.selector)); stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); } @@ -275,7 +262,7 @@ contract ComposableCoWStopLossTest is BaseComposableCoWTest { maxTimeSinceLastOracleUpdate: 15 minutes }); - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, ORACLE_INVALID_PRICE)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, OracleInvalidPrice.selector)); stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); // case where buy token price is invalid @@ -283,14 +270,11 @@ contract ComposableCoWStopLossTest is BaseComposableCoWTest { data.sellTokenPriceOracle = mockOracle(SELL_ORACLE, validPrice, block.timestamp, DEFAULT_DECIMALS); data.buyTokenPriceOracle = mockOracle(BUY_ORACLE, invalidPrice, block.timestamp, DEFAULT_DECIMALS); - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, ORACLE_INVALID_PRICE)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, OracleInvalidPrice.selector)); stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); } - function test_OracleRevertOnExpiredOrder_fuzz( - uint32 currentTime, - uint32 validTo - ) public { + function test_OracleRevertOnExpiredOrder_fuzz(uint32 currentTime, uint32 validTo) public { // enforce expired order vm.assume(currentTime > validTo); @@ -312,19 +296,8 @@ contract ComposableCoWStopLossTest is BaseComposableCoWTest { maxTimeSinceLastOracleUpdate: 15 minutes }); - vm.expectRevert( - abi.encodeWithSelector( - IConditionalOrder.OrderNotValid.selector, - ORDER_EXPIRED - ) - ); - stopLoss.generateOrder( - safe, - address(0), - bytes32(0), - abi.encode(data), - bytes("") - ); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, OrderExpired.selector)); + stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); } function test_strikePriceMet_fuzz( @@ -358,8 +331,7 @@ contract ComposableCoWStopLossTest is BaseComposableCoWTest { maxTimeSinceLastOracleUpdate: 15 minutes }); - GPv2Order.Data memory order = - stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); + GPv2Order.Data memory order = stopLoss.generateOrder(safe, address(0), bytes32(0), abi.encode(data), bytes("")); assertEq(address(order.sellToken), address(SELL_TOKEN)); assertEq(address(order.buyToken), address(BUY_TOKEN)); assertEq(order.sellAmount, 1 ether); diff --git a/test/ComposableCoW.t.sol b/test/ComposableCoW.t.sol index f1c3ec4..8caf477 100644 --- a/test/ComposableCoW.t.sol +++ b/test/ComposableCoW.t.sol @@ -8,7 +8,7 @@ import { GPv2Order, ComposableCoW, ComposableCoWLib, - INVALID_HASH, + InvalidHash, BaseComposableCoWTest, Safe, TestNonSafeWallet @@ -120,9 +120,7 @@ contract ComposableCoWTest is BaseComposableCoWTest { /// @dev Should disallow setting a handler that is address(0) function test_create_RevertOnInvalidHandler() public { IConditionalOrder.ConditionalOrderParams memory params = IConditionalOrder.ConditionalOrderParams({ - handler: IConditionalOrder(address(0)), - salt: keccak256("zero is invalid handler"), - staticInput: "" + handler: IConditionalOrder(address(0)), salt: keccak256("zero is invalid handler"), staticInput: "" }); vm.expectRevert(ComposableCoW.InvalidHandler.selector); @@ -139,9 +137,7 @@ contract ComposableCoWTest is BaseComposableCoWTest { vm.assume(handler != address(0)); IConditionalOrder.ConditionalOrderParams memory params = IConditionalOrder.ConditionalOrderParams({ - handler: IConditionalOrder(handler), - salt: salt, - staticInput: staticInput + handler: IConditionalOrder(handler), salt: salt, staticInput: staticInput }); bytes32 orderHash = keccak256(abi.encode(params)); @@ -167,9 +163,7 @@ contract ComposableCoWTest is BaseComposableCoWTest { vm.assume(handler != address(0)); IConditionalOrder.ConditionalOrderParams memory params = IConditionalOrder.ConditionalOrderParams({ - handler: IConditionalOrder(handler), - salt: salt, - staticInput: staticInput + handler: IConditionalOrder(handler), salt: salt, staticInput: staticInput }); bytes32 orderHash = keccak256(abi.encode(params)); @@ -246,7 +240,7 @@ contract ComposableCoWTest is BaseComposableCoWTest { bytes32 domainSeparator = composableCow.domainSeparator(); // should revert as the order hash mismatches - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, INVALID_HASH)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidHash.selector)); composableCow.isValidSafeSignature( Safe(payable(address(alice.addr))), address(0), @@ -255,7 +249,9 @@ contract ComposableCoWTest is BaseComposableCoWTest { bytes32(0), abi.encode(order1), abi.encode( - ComposableCoW.PayloadStruct({proof: new bytes32[](0), params: params, offchainInput: abi.encode(order2)}) + ComposableCoW.PayloadStruct({ + proof: new bytes32[](0), params: params, offchainInput: abi.encode(order2) + }) ) ); } @@ -273,9 +269,7 @@ contract ComposableCoWTest is BaseComposableCoWTest { vm.assume(proof.length > 0); IConditionalOrder.ConditionalOrderParams memory params = IConditionalOrder.ConditionalOrderParams({ - handler: IConditionalOrder(handler), - salt: salt, - staticInput: staticInput + handler: IConditionalOrder(handler), salt: salt, staticInput: staticInput }); // should set the root @@ -304,9 +298,7 @@ contract ComposableCoWTest is BaseComposableCoWTest { vm.assume(handler != address(0)); IConditionalOrder.ConditionalOrderParams memory params = IConditionalOrder.ConditionalOrderParams({ - handler: IConditionalOrder(handler), - salt: salt, - staticInput: staticInput + handler: IConditionalOrder(handler), salt: salt, staticInput: staticInput }); // should revert as the order has not been created @@ -327,9 +319,7 @@ contract ComposableCoWTest is BaseComposableCoWTest { // Use the mirror handler as we can use it to inspect the calldata // passed to the handler. IConditionalOrder.ConditionalOrderParams memory params = IConditionalOrder.ConditionalOrderParams({ - handler: IConditionalOrder(mirror), - salt: keccak256("mirror"), - staticInput: bytes("") + handler: IConditionalOrder(mirror), salt: keccak256("mirror"), staticInput: bytes("") }); // should create a single order @@ -381,9 +371,7 @@ contract ComposableCoWTest is BaseComposableCoWTest { function test_getTradeableOrderWithSignature_RevertInterfaceNotSupported() public { // use the mirror handler as it does not support the interface IConditionalOrder.ConditionalOrderParams memory params = IConditionalOrder.ConditionalOrderParams({ - handler: mirror, - salt: keccak256("mirror"), - staticInput: bytes("") + handler: mirror, salt: keccak256("mirror"), staticInput: bytes("") }); // should create a single order @@ -407,9 +395,7 @@ contract ComposableCoWTest is BaseComposableCoWTest { vm.assume(proof.length > 0); IConditionalOrder.ConditionalOrderParams memory params = IConditionalOrder.ConditionalOrderParams({ - handler: IConditionalOrder(handler), - salt: salt, - staticInput: staticInput + handler: IConditionalOrder(handler), salt: salt, staticInput: staticInput }); // should set the root @@ -428,9 +414,7 @@ contract ComposableCoWTest is BaseComposableCoWTest { bytes memory staticInput ) public { IConditionalOrder.ConditionalOrderParams memory params = IConditionalOrder.ConditionalOrderParams({ - handler: IConditionalOrder(handler), - salt: salt, - staticInput: staticInput + handler: IConditionalOrder(handler), salt: salt, staticInput: staticInput }); // should revert as the order has not been created diff --git a/test/ComposableCoW.tat.t.sol b/test/ComposableCoW.tat.t.sol index 28d7135..d383e7f 100644 --- a/test/ComposableCoW.tat.t.sol +++ b/test/ComposableCoW.tat.t.sol @@ -36,20 +36,12 @@ contract ComposableCoWTatTest is BaseComposableCoWTest { // should revert when the current balance is below the minimum balance vm.expectRevert( - abi.encodeWithSelector( - IConditionalOrder.PollTryNextBlock.selector, - BALANCE_INSUFFICIENT - ) + abi.encodeWithSelector(IConditionalOrder.PollTryNextBlock.selector, BalanceInsufficient.selector) ); tat.generateOrder(address(safe1), address(0), bytes32(0), abi.encode(o), bytes("")); } - function test_BalanceMet_fuzz( - address receiver, - uint256 threshold, - bytes32 appData, - uint256 currentBalance - ) public { + function test_BalanceMet_fuzz(address receiver, uint256 threshold, bytes32 appData, uint256 currentBalance) public { vm.assume(threshold > 0); vm.assume(currentBalance >= threshold); @@ -65,7 +57,6 @@ contract ComposableCoWTatTest is BaseComposableCoWTest { appData: appData }); - // // set the current balance deal(address(token0), address(safe1), currentBalance); @@ -73,7 +64,6 @@ contract ComposableCoWTatTest is BaseComposableCoWTest { GPv2Order.Data memory order = tat.generateOrder(address(safe1), address(0), bytes32(0), abi.encode(data), bytes("")); - assertEq(address(order.sellToken), address(token0)); assertEq(address(order.buyToken), address(token1)); assertEq(order.sellAmount, currentBalance); diff --git a/test/ComposableCoW.twap.t.sol b/test/ComposableCoW.twap.t.sol index 3351ad8..e8b21fb 100644 --- a/test/ComposableCoW.twap.t.sol +++ b/test/ComposableCoW.twap.t.sol @@ -16,21 +16,19 @@ import { BaseComposableCoWTest } from "./ComposableCoW.base.t.sol"; -import {TWAP, NOT_WITHIN_SPAN} from "../src/types/twap/TWAP.sol"; +import {TWAP, NotWithinSpan} from "../src/types/twap/TWAP.sol"; import { TWAPOrder, - INVALID_SAME_TOKEN, - INVALID_TOKEN, - INVALID_PART_SELL_AMOUNT, - INVALID_MIN_PART_LIMIT, - INVALID_START_TIME, - INVALID_NUM_PARTS, - INVALID_FREQUENCY, - INVALID_SPAN + InvalidSameToken, + InvalidToken, + InvalidPartSellAmount, + InvalidMinPartLimit, + InvalidStartTime, + InvalidNumParts, + InvalidFrequency, + InvalidSpan } from "../src/types/twap/libraries/TWAPOrder.sol"; -import { - TWAPOrderMathLib, BEFORE_TWAP_START, AFTER_TWAP_FINISH -} from "../src/types/twap/libraries/TWAPOrderMathLib.sol"; +import {TWAPOrderMathLib, BeforeTwapStart, AfterTwapFinish} from "../src/types/twap/libraries/TWAPOrderMathLib.sol"; import {CurrentBlockTimestampFactory} from "../src/value_factories/CurrentBlockTimestampFactory.sol"; @@ -77,7 +75,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { o.sellToken = token0; o.buyToken = token0; - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, INVALID_SAME_TOKEN)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidSameToken.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } @@ -89,13 +87,13 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { TWAPOrder.Data memory o = _twapTestBundle(block.timestamp); o.sellToken = IERC20(address(0)); - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, INVALID_TOKEN)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidToken.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); o.sellToken = token0; o.buyToken = IERC20(address(0)); - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, INVALID_TOKEN)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidToken.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } @@ -107,7 +105,9 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { TWAPOrder.Data memory o = _twapTestBundle(block.timestamp); o.partSellAmount = 0; - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, INVALID_PART_SELL_AMOUNT)); + vm.expectRevert( + abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidPartSellAmount.selector) + ); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } @@ -119,7 +119,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { TWAPOrder.Data memory o = _twapTestBundle(block.timestamp); o.minPartLimit = 0; - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, INVALID_MIN_PART_LIMIT)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidMinPartLimit.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } @@ -132,7 +132,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { TWAPOrder.Data memory o = _twapTestBundle(startTime); o.t0 = startTime; - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, INVALID_START_TIME)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidStartTime.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } @@ -145,7 +145,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { TWAPOrder.Data memory o = _twapTestBundle(block.timestamp); o.n = numParts; - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, INVALID_NUM_PARTS)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidNumParts.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } @@ -157,7 +157,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { TWAPOrder.Data memory o = _twapTestBundle(block.timestamp); o.t = frequency; - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, INVALID_FREQUENCY)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidFrequency.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } @@ -172,7 +172,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { o.t = frequency; o.span = span; - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, INVALID_SPAN)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidSpan.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } @@ -197,7 +197,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { // Warp to current time vm.warp(currentTime); - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, BEFORE_TWAP_START)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, BeforeTwapStart.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } @@ -223,7 +223,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { // Warp to expiry vm.warp(currentTime); - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, AFTER_TWAP_FINISH)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, AfterTwapFinish.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } @@ -251,14 +251,13 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { // Warp to outside of the span vm.warp(currentTime); - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, NOT_WITHIN_SPAN)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, NotWithinSpan.selector)); twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); } - function test_generateOrder_FuzzRevertIfOrderBeforeBlockTimestamp( - uint256 ctxBlockTimestamp, - uint256 currentTime - ) public { + function test_generateOrder_FuzzRevertIfOrderBeforeBlockTimestamp(uint256 ctxBlockTimestamp, uint256 currentTime) + public + { // guard against overflows vm.assume(ctxBlockTimestamp < type(uint32).max); vm.assume(currentTime < type(uint32).max); @@ -280,7 +279,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { vm.warp(currentTime); // The below should revert - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, BEFORE_TWAP_START)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, BeforeTwapStart.selector)); composableCow.getTradeableOrderWithSignature(address(safe1), params, bytes(""), new bytes32[](0)); } @@ -309,7 +308,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { vm.warp(currentTime); // The below should revert - vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, AFTER_TWAP_FINISH)); + vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, AfterTwapFinish.selector)); composableCow.getTradeableOrderWithSignature(address(safe1), params, bytes(""), new bytes32[](0)); } @@ -406,8 +405,7 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { // Warp to the current time vm.warp(currentTime); - GPv2Order.Data memory order = - twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); + GPv2Order.Data memory order = twap.generateOrder(address(0), address(0), bytes32(0), abi.encode(o), bytes("")); bytes32 domainSeparator = composableCow.domainSeparator(); // Verify that the order is valid - this shouldn't revert @@ -498,8 +496,11 @@ contract ComposableCoWTwapTest is BaseComposableCoWTest { while (true) { // Simulate being called by the watch tower - try composableCow.getTradeableOrderWithSignature(address(safe1), params, bytes(""), new bytes32[](0)) - returns (GPv2Order.Data memory order, bytes memory signature) { + try composableCow.getTradeableOrderWithSignature( + address(safe1), params, bytes(""), new bytes32[](0) + ) returns ( + GPv2Order.Data memory order, bytes memory signature + ) { bytes32 orderDigest = GPv2Order.hash(order, settlement.domainSeparator()); if ( orderFills[orderDigest] == 0 diff --git a/test/libraries/ComposableCoWLib.t.sol b/test/libraries/ComposableCoWLib.t.sol index afeb8f5..083547d 100644 --- a/test/libraries/ComposableCoWLib.t.sol +++ b/test/libraries/ComposableCoWLib.t.sol @@ -37,8 +37,8 @@ library ComposableCoWLib { IConditionalOrder.ConditionalOrderParams[] memory leaves, uint256 n, mapping(bytes32 => IConditionalOrder.ConditionalOrderParams) storage m, - function (bytes32[] memory) internal pure returns (bytes32) getRoot, - function (bytes32[] memory, uint256) internal pure returns (bytes32[] memory) getProof + function(bytes32[] memory) internal pure returns (bytes32) getRoot, + function(bytes32[] memory, uint256) internal pure returns (bytes32[] memory) getProof ) internal returns (bytes32, bytes32[] memory, IConditionalOrder.ConditionalOrderParams memory) { // 1. Create a mapping of hashes to leaves for (uint256 i = 0; i < leaves.length; i++) {