Skip to content

Commit

Permalink
Merge pull request #22 from rainprotocol/2023-09-01-simplify-take-orders
Browse files Browse the repository at this point in the history
2023 09 01 simplify take orders
  • Loading branch information
thedavidmeister authored Sep 4, 2023
2 parents fdb8424 + 19665c3 commit 3d33b32
Show file tree
Hide file tree
Showing 6 changed files with 263 additions and 125 deletions.
32 changes: 17 additions & 15 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ GenericPoolOrderBookV3FlashBorrowerTest:testTakeOrdersSender((address,bool,(addr
LibOrderTest:testHashEqual((address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[])) (runs: 5096, μ: 194389, ~: 191140)
LibOrderTest:testHashNotEqual((address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),(address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[])) (runs: 5096, μ: 298734, ~: 298554)
OrderBookAddOrderMockTest:testAddOrderSameAccountWithDifferentConfig(address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address,address) (runs: 5096, μ: 2771808, ~: 2761475)
OrderBookAddOrderMockTest:testAddOrderTwoAccountsWithDifferentConfig(address,address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address,address) (runs: 5096, μ: 2626737, ~: 2600883)
OrderBookAddOrderMockTest:testAddOrderTwoAccountsWithSameConfig(address,address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 2492972, ~: 2492266)
OrderBookAddOrderMockTest:testAddOrderTwoAccountsWithDifferentConfig(address,address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address,address) (runs: 5096, μ: 2626417, ~: 2600441)
OrderBookAddOrderMockTest:testAddOrderTwoAccountsWithSameConfig(address,address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 2493275, ~: 2492266)
OrderBookAddOrderMockTest:testAddOrderWithCalculationsInputsAndOutputsSucceeds(address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 1295793, ~: 1281958)
OrderBookAddOrderMockTest:testAddOrderWithNonEmptyMetaEmitsMetaV1(address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 1303904, ~: 1290881)
OrderBookAddOrderMockTest:testAddOrderWithNonEmptyMetaReverts(address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 703690, ~: 697922)
Expand All @@ -18,30 +18,32 @@ OrderBookAddOrderTest:testAddOrderRealThreeStackCalculate(address,((address,uint
OrderBookAddOrderTest:testAddOrderRealTwoStackCalculateReverts(address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes)) (runs: 5096, μ: 715326, ~: 711971)
OrderBookAddOrderTest:testAddOrderRealZeroStackCalculateReverts(address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes)) (runs: 5096, μ: 181302, ~: 180079)
OrderBookDepositTest:testDepositEvent(address,uint256,uint256) (runs: 5096, μ: 38710, ~: 38710)
OrderBookDepositTest:testDepositFail(address,uint256,uint256) (runs: 5096, μ: 8937393460516740787, ~: 8937393460516740786)
OrderBookDepositTest:testDepositFail(address,uint256,uint256) (runs: 5096, μ: 8937393460516740786, ~: 8937393460516740786)
OrderBookDepositTest:testDepositGas00() (gas: 8176)
OrderBookDepositTest:testDepositGas01() (gas: 34620)
OrderBookDepositTest:testDepositMany((address,address,uint256,uint248)[]) (runs: 5096, μ: 5162681, ~: 4894479)
OrderBookDepositTest:testDepositMany((address,address,uint256,uint248)[]) (runs: 5096, μ: 5184765, ~: 4940766)
OrderBookDepositTest:testDepositOverflow(address,uint256,uint256,uint256) (runs: 5096, μ: 46645, ~: 46645)
OrderBookDepositTest:testDepositReentrancy(address,uint256,uint256,address,uint256,uint256) (runs: 5096, μ: 495210, ~: 496632)
OrderBookDepositTest:testDepositReentrancy(address,uint256,uint256,address,uint256,uint256) (runs: 5096, μ: 495218, ~: 496632)
OrderBookDepositTest:testDepositSimple(address,uint256,uint256) (runs: 5096, μ: 37840, ~: 37840)
OrderBookDepositTest:testDepositZero(address,uint256) (runs: 5096, μ: 12639, ~: 12639)
OrderBookDepositTest:testVaultBalanceNoDeposits(address,uint256) (runs: 5096, μ: 8263, ~: 8263)
OrderBookDepositTest:testVaultBalanceReentrant(address,uint256,uint256,address,address,uint256) (runs: 5096, μ: 494148, ~: 495964)
OrderBookDepositTest:testVaultBalanceReentrant(address,uint256,uint256,address,address,uint256) (runs: 5096, μ: 494050, ~: 495964)
OrderBookRemoveOrderMockTest:testRemoveOrderAddRemoveMulti(address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 7256622, ~: 7139425)
OrderBookRemoveOrderMockTest:testRemoveOrderDifferent(address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 5070365, ~: 5046372)
OrderBookRemoveOrderMockTest:testRemoveOrderDifferentOwners(address,address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 4854788, ~: 4841901)
OrderBookRemoveOrderMockTest:testRemoveOrderDifferentOwners(address,address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 4854223, ~: 4841901)
OrderBookRemoveOrderMockTest:testRemoveOrderDifferentOwnersDifferent(address,address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 10466985, ~: 10453491)
OrderBookRemoveOrderMockTest:testRemoveOrderDoesNotExist(address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 386811, ~: 382063)
OrderBookRemoveOrderMockTest:testRemoveOrderOnlyOwner(address,address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 2603276, ~: 2601080)
OrderBookTakeOrderNoopTest:testTakeOrderNoopNonLiveOrderOne((address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),uint256,uint256,(address,uint256[],bytes)) (runs: 5096, μ: 427777, ~: 424024)
OrderBookTakeOrderNoopTest:testTakeOrderNoopNonLiveOrderTwo((address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),(address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),uint256,uint256,uint256,uint256,(address,uint256[],bytes),(address,uint256[],bytes)) (runs: 5096, μ: 841710, ~: 837539)
OrderBookRemoveOrderMockTest:testRemoveOrderOnlyOwner(address,address,((address,uint8,uint256)[],(address,uint8,uint256)[],(address,bytes,uint256[]),bytes),address) (runs: 5096, μ: 2603102, ~: 2601080)
OrderBookTakeOrderNoopTest:testTakeOrderNoopNonLiveOrderOne((address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),uint256,uint256,(address,uint256[],bytes)) (runs: 5096, μ: 428003, ~: 424249)
OrderBookTakeOrderNoopTest:testTakeOrderNoopNonLiveOrderTwo((address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),(address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),uint256,uint256,uint256,uint256,(address,uint256[],bytes),(address,uint256[],bytes)) (runs: 5096, μ: 842490, ~: 838321)
OrderBookTakeOrderNoopTest:testTakeOrderNoopZeroOrders() (gas: 12403)
OrderBookTakeOrderTest:testTakeOrderPrecisionKnownBad01() (gas: 2576588)
OrderBookTakeOrderTest:testTakeOrderPrecisionKnownBad01() (gas: 2576621)
OrderBookTakeOrderTokenMismatchTest:testTokenMismatchInputs((address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),uint256,uint256,(address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),uint256,uint256) (runs: 5096, μ: 613519, ~: 607165)
OrderBookTakeOrderTokenMismatchTest:testTokenMismatchOutputs((address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),uint256,uint256,(address,bool,(address,address,address),(address,uint8,uint256)[],(address,uint8,uint256)[]),uint256,uint256) (runs: 5096, μ: 613634, ~: 607304)
OrderBookWithdrawTest:testWithdrawEmptyVault(address,address,uint256,uint256) (runs: 5096, μ: 15251, ~: 15251)
OrderBookWithdrawTest:testWithdrawFailure(address,uint256,uint256,uint256) (runs: 5096, μ: 8937393460516719305, ~: 8937393460516700418)
OrderBookWithdrawTest:testWithdrawFullVault(address,uint256,uint256,uint256) (runs: 5096, μ: 41257, ~: 41254)
OrderBookWithdrawTest:testWithdrawMany((bool,address,address,uint256,uint248)[]) (runs: 5096, μ: 1447310, ~: 1371034)
OrderBookWithdrawTest:testWithdrawFailure(address,uint256,uint256,uint256) (runs: 5096, μ: 8937393460516719678, ~: 8937393460516738938)
OrderBookWithdrawTest:testWithdrawFullVault(address,uint256,uint256,uint256) (runs: 5096, μ: 41256, ~: 41254)
OrderBookWithdrawTest:testWithdrawMany((bool,address,address,uint256,uint248)[]) (runs: 5096, μ: 1443910, ~: 1381982)
OrderBookWithdrawTest:testWithdrawPartialVault(address,uint256,uint256,uint256) (runs: 5096, μ: 51929, ~: 51929)
OrderBookWithdrawTest:testWithdrawReentrant(address,uint256,uint256,address,address,uint256) (runs: 5096, μ: 506196, ~: 507997)
OrderBookWithdrawTest:testWithdrawReentrant(address,uint256,uint256,address,address,uint256) (runs: 5096, μ: 506294, ~: 507997)
OrderBookWithdrawTest:testWithdrawZero(address,address,uint256) (runs: 5096, μ: 12809, ~: 12809)
67 changes: 52 additions & 15 deletions src/concrete/OrderBook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,6 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash
if (config.orders.length == 0) {
revert NoOrders();
}
address expectedOrderInputToken = config.orders[0].order.validInputs[config.orders[0].inputIOIndex].token;
address expectedOrderOutputToken = config.orders[0].order.validOutputs[config.orders[0].outputIOIndex].token;

uint256 i = 0;
TakeOrderConfig memory takeOrderConfig;
Expand All @@ -353,19 +351,51 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash
while (i < config.orders.length && remainingTakerInput > 0) {
takeOrderConfig = config.orders[i];
order = takeOrderConfig.order;
// Every order needs the same input token.
if (
order.validInputs[takeOrderConfig.inputIOIndex].token
!= config.orders[0].order.validInputs[config.orders[0].inputIOIndex].token
) {
revert TokenMismatch(
order.validInputs[takeOrderConfig.inputIOIndex].token,
config.orders[0].order.validInputs[config.orders[0].inputIOIndex].token
);
}
// Every order needs the same output token.
if (
order.validOutputs[takeOrderConfig.outputIOIndex].token
!= config.orders[0].order.validOutputs[config.orders[0].outputIOIndex].token
) {
revert TokenMismatch(
order.validOutputs[takeOrderConfig.outputIOIndex].token,
config.orders[0].order.validOutputs[config.orders[0].outputIOIndex].token
);
}
// Every order needs the same input token decimals.
if (
order.validInputs[takeOrderConfig.inputIOIndex].decimals
!= config.orders[0].order.validInputs[config.orders[0].inputIOIndex].decimals
) {
revert TokenDecimalsMismatch(
order.validInputs[takeOrderConfig.inputIOIndex].decimals,
config.orders[0].order.validInputs[config.orders[0].inputIOIndex].decimals
);
}
// Every order needs the same output token decimals.
if (
order.validOutputs[takeOrderConfig.outputIOIndex].decimals
!= config.orders[0].order.validOutputs[config.orders[0].outputIOIndex].decimals
) {
revert TokenDecimalsMismatch(
order.validOutputs[takeOrderConfig.outputIOIndex].decimals,
config.orders[0].order.validOutputs[config.orders[0].outputIOIndex].decimals
);
}

bytes32 orderHash = order.hash();
if (sOrders[orderHash] == ORDER_DEAD) {
emit OrderNotFound(msg.sender, order.owner, orderHash);
} else {
if (order.validInputs[takeOrderConfig.inputIOIndex].token != expectedOrderInputToken) {
revert TokenMismatch(order.validInputs[takeOrderConfig.inputIOIndex].token, expectedOrderInputToken);
}
if (order.validOutputs[takeOrderConfig.outputIOIndex].token != expectedOrderOutputToken) {
revert TokenMismatch(
order.validOutputs[takeOrderConfig.outputIOIndex].token, expectedOrderOutputToken
);
}

OrderIOCalculation memory orderIOCalculation = calculateOrderIO(
order,
takeOrderConfig.inputIOIndex,
Expand Down Expand Up @@ -445,19 +475,26 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash
// trades, which is important if the order logic itself is dependent on
// external data (e.g. prices) that could be modified by the caller's
// trades.
uint256 takerInputAmountSent =
_decreaseFlashDebtThenSendToken(expectedOrderOutputToken, msg.sender, totalTakerInput);
uint256 takerInputAmountSent = _decreaseFlashDebtThenSendToken(
config.orders[0].order.validOutputs[config.orders[0].outputIOIndex].token, msg.sender, totalTakerInput
);
if (config.data.length > 0) {
IOrderBookV3OrderTaker(msg.sender).onTakeOrders(
expectedOrderOutputToken, expectedOrderInputToken, takerInputAmountSent, totalTakerOutput, config.data
config.orders[0].order.validOutputs[config.orders[0].outputIOIndex].token,
config.orders[0].order.validInputs[config.orders[0].inputIOIndex].token,
takerInputAmountSent,
totalTakerOutput,
config.data
);
}

if (totalTakerOutput > 0) {
// We already updated vault balances before we took tokens from
// `msg.sender` which is usually NOT the correct order of operations for
// depositing to a vault. We rely on reentrancy guards to make this safe.
IERC20(expectedOrderInputToken).safeTransferFrom(msg.sender, address(this), totalTakerOutput);
IERC20(config.orders[0].order.validInputs[config.orders[0].inputIOIndex].token).safeTransferFrom(
msg.sender, address(this), totalTakerOutput
);
}
}

Expand Down
Loading

0 comments on commit 3d33b32

Please sign in to comment.