Filling on Arbitrum
Integrate a UniswapX filler on Arbitrum, retrieve Dutch orders, and execute fills with reactor-based strategies.
UniswapX on Arbitrum uses Dutch auctions with no RFQ and no exclusivity. All orders are open to all fillers immediately. Filling follows two steps: retrieving signed orders and executing fills.
Retrieving Signed Orders
All signed Dutch orders on Arbitrum, created through the Uniswap interface, are available via the UniswapX Orders Endpoint. Swagger documentation is available. Example request:
GET https://api.uniswap.org/v2/orders?orderStatus=open&chainId=42161&limit=1000Use the UniswapX SDK to parse the encodedOrder field returned from the endpoint. Each order represents a fillable user trade.
Filling Orders
To execute a discovered order, call the execute method of the reactor specified in the retrieved encodedOrder body. Always confirm the reactor address from the retrieved order before submitting.
Direct filler strategy
The simplest fill strategy is Direct Filler, where the trade is executed directly against tokens held in the filler's address. Approve the order's output tokens to the reactor and call execute or executeBatch (source):
// Execute direct filler order
outputToken.approve(reactor, type(uint256).max);
reactor.execute(order);Custom executor strategy
More sophisticated fillers can deploy their own Executor contracts implementing the IReactorCallback interface. The contract takes in an order with input tokens and acquires the allotted number of output tokens for the caller. It must approve the output tokens to the reactor, which then transfers them to the order output recipients to settle the order. Executor contracts must call reactor.executeWithCallback or reactor.executeBatchWithCallback. They can also specify arbitrary callback data that will be passed into the reactorCallback call.
contract Executor {
function execute(Order calldata order, bytes calldata callbackData) {
reactor.executeWithCallback(order, callbackData)
}
function reactorCallback(ResolvedOrder[] calldata orders, bytes calldata callbackData) {
// implement strategy here
}
}
// Execute custom fill strategy
address executor = /* Address of deployed executor contract */ ;
bytes fillData = /* Call data to be sent to your executor contract */;
executor.execute(order, fillData);For convenience, an example Executor contract demonstrates how to fill a UniswapX order against a Uniswap v3 pool. Deploy these contracts on each chain you want to support.
Order Types
On Arbitrum, DutchV3 order types are supported. You can query for a specific type using the orderType query parameter:
GET https://api.uniswap.org/v2/orders?orderStatus=open&chainId=42161&limit=1000&orderType=Dutch_V3DutchV3 orders use a block-based decay mechanism. This takes advantage of Arbitrum's 250ms block frequency, allowing more granular price updates compared to time-based decay systems limited by block.timestamp second-level granularity.
Order type references
| Order type | Contract address | Reactor | Example filler |
|---|---|---|---|
DutchV3 | 0xB274d5F4...a87c | V3DutchOrderReactor | dutchv3_strategy.rs |