Uniswap/UniswapX

Consider adding some simple fill macros for gas optimization

marktoda opened this issue · 2 comments

for ex:
if fillContract == address(1) -- directFill: permit2.permitTransferFrom(msg.sender, fillData)
if fillContract == address(2) -- matchOrders as in seaport: for (fromOrderIndex, toOrderIndex, outputIndex in abi.decode(fillData)) match(from, to, outputIndex)

...

Thinking we can have some simple executors coded internally for gas optimization / to avoid ownership issues like #70. DirectTakerExecutor is probably the most important one here, as it'll be highly used by market makers in RFQ. Maybe something like

contract BaseReactor {
   using FillStrategy for address;

   function _fill(...) {
      fillContract.fill(orders, fillData)
   }
}

library FillStrategy {
   function fill(...) {
      if (fillContract == address(0) {
        take(orders, fillData)
     }  else if (fillContract == address(1) {
        match(orders, fillData)
      } else {
        externalFill(orders, fillData)
     }
   }
}

This might make sense to combine with #40 to avoid having disparate output-safety checks, like

struct AddressBalance {
   address recipient;
  address token;
  uint256 expectedBalance;
}

fill(..) {
   AddressBalanceDiff[] memory balances = getPreBalances(orders);
   fillContract.fill(...)
   checkBalances(balances)
   
}