Odos
π§ How the Odos Parser Works
The Odos parser in the-parsoor is a modular, multi-version system that extracts swap-related data from Odos's routers deployed across various chains. It identifies and parses three distinct contract types:
V1 RouterV2 RouterLimit Order Router
Each of these contract versions is parsed in isolation using dedicated logic and ABIs. Letβs explore the architecture and code patterns used in depth.
π Directory Structure
src/lib/Odos/
ββ abis/ β ABIs for router versions
β ββ V1Router.json
β ββ V2Router.json
β ββ LimitOrderRouter.json
ββ parsers/ β Parsing logic per router version
β ββ RouterV1.ts
β ββ RouterV2.ts
β ββ LimitOrderRouter.ts
ββ contracts.ts β Deployment info, event hashes, and ABIs
ββ index.ts β Parser class implementing OpenRepβs parser interfaceπ contracts.ts β The Router Registry
This file defines:
Contract addresses per chain
Events emitted by each router
Associated ABIs for decoding those events
Each router version is represented using an enum (CONTRACT_ENUM), and its event signatures are listed in EVENT_ENUM.
Key Elements:
// V2 Event signature + ABI interface
[V2_SINGLE_SWAP]: {
abi: new ethers.Interface([
"event Swap(address sender,uint256 inputAmount,address inputToken,uint256 amountOut,address outputToken,int256 slippage,uint32 referralCode)"
])
}Why it matters:
This setup allows ProtocolHelper to dynamically decode logs just by checking the topic hash.
π§± index.ts β The Parser Entry Point
This is the class that integrates the parser into the OpenRep system.
What it does:
Implements
IProtocolParserExportRegisters a
protocolIdentifierfromconfig/protocols.tsUses
ProtocolHelper.txnToIsListenerContract()to route the transaction to the correct sub-parserSupports async behavior for future compatibility
Code Overview:
if (ProtocolHelper.txnToIsListenerContract(tx, CONTRACT_ENUM.V2_ROUTER, contracts)) {
actions.push(...RouterV2Parser.parseTransaction(tx));
}This keeps all router-specific logic decoupled and modular.
π§ Parsing Logic Per Router
β
V2 Router β RouterV2.ts
RouterV2.tsHandles the latest swap logic and detects two kinds of events:
Swapβ single-token swapSwapMultiβ multi-token route swap
const hasSingleSwap = transaction.logs.find(
(log) => log.topics[0] === EVENT_ENUM.V2_SINGLE_SWAP
);
if (hasSingleSwap) {
actions.push(this.parseSingleSwap(hasSingleSwap));
}Returned Action Types:
ISingleSwapActionIMultiSwapAction
β
V1 Router β RouterV1.ts
RouterV1.tsSupports legacy Odos swaps. Event structure is more complex, containing outputs as a nested struct:
"event Swapped(address sender,uint256[] amountsIn,address[] tokensIn,uint256[] amountsOut,(address tokenAddress,uint256 relativeValue,address receiver)[] outputs,uint256 valueOutQuote)"The parser differentiates between:
Single swap (1 input, 1 output)
Multi swap (multiple inputs/outputs)
Design Pattern:
if (tokensIn.length === 1 && outputs.length === 1) {
return this.parseSingleSwap(parsedLog);
}Returned Action Types:
ISingleSwapActionIMultiSwapAction
β
Limit Order Router β LimitOrderRouter.ts
LimitOrderRouter.tsParses on-chain fill logs from limit orders submitted via Odos.
Event Types:
LimitOrderFilledMultiLimitOrderFilled
const hasLimitOrderFill = transaction.logs.find(
(log) => log.topics[0] === EVENT_ENUM.LIMIT_ORDER_FILL
);Returned Action Types:
ISingleSwapActionIMultiSwapAction
Each order fill is mapped to a swap action with relevant:
fromToken,toTokenfromAmount,toAmountsender,recipient
π§ͺ Runtime Flow: How a Tx is Parsed
A transaction is passed to the Odos parser class (
index.ts)The class uses
ProtocolHelperto determine which router the transaction was sent toOnce matched, the class calls the appropriate
parseTransaction()from the correct router parserThe returned list of
ITransactionAction[]is sent downstream to OpenRep scoring logic
β
Benefits of This Architecture
Modular Parsers
Each contract version has isolated logic and tests
Enum-based Contracts
Easy to add more routers or events
ProtocolHelper usage
Shared logic for log decoding and routing
Scalable
Adding v3 routers or new chain support is plug-and-play
Typed actions
Ensures all outputs conform to OpenRepβs score engine format
Last updated