From ef555129feb6b02644e51cf9db73d61291504641 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Fri, 30 Jan 2026 20:07:58 +0000 Subject: [PATCH 1/6] init --- config.env.yaml | 2 + config.example.yaml | 6 + src/common/abis/orderbook.ts | 6 +- src/config/validators.test.ts | 311 +++++++ src/config/validators.ts | 9 +- src/config/yaml.test.ts | 5 + src/config/yaml.ts | 6 + src/core/modes/index.test.ts | 134 ++- src/core/modes/index.ts | 18 + src/core/modes/raindex/index.test.ts | 980 +++++++++++++++++++++ src/core/modes/raindex/index.ts | 296 +++++++ src/core/modes/raindex/simulation.test.ts | 454 ++++++++++ src/core/modes/raindex/simulation.ts | 250 ++++++ src/core/modes/raindex/utils.test.ts | 231 +++++ src/core/modes/raindex/utils.ts | 58 ++ src/core/modes/simulator.ts | 10 +- src/core/process/log.ts | 6 +- src/core/types.ts | 1 + src/order/index.test.ts | 566 ++++++++++++ src/order/index.ts | 36 + src/order/pair.test.ts | 215 ++++- src/order/pair.ts | 52 ++ src/state/contracts.test.ts | 62 ++ src/state/contracts.ts | 13 + test/abis/OrderBookV6.json | 1 + test/abis/RaindexRouterOrderBookV6Arb.json | 1 + 26 files changed, 3720 insertions(+), 9 deletions(-) create mode 100644 src/core/modes/raindex/index.test.ts create mode 100644 src/core/modes/raindex/index.ts create mode 100644 src/core/modes/raindex/simulation.test.ts create mode 100644 src/core/modes/raindex/simulation.ts create mode 100644 src/core/modes/raindex/utils.test.ts create mode 100644 src/core/modes/raindex/utils.ts create mode 100644 test/abis/OrderBookV6.json create mode 100644 test/abis/RaindexRouterOrderBookV6Arb.json diff --git a/config.env.yaml b/config.env.yaml index 9b55fd19..7e288461 100644 --- a/config.env.yaml +++ b/config.env.yaml @@ -23,6 +23,7 @@ contracts: genericArbAddress: $GENERIC_ARB_ADDRESS_V6 balancerArbAddress: $BALANCER_ARB_ADDRESS_V6 stabullArbAddress: $STABULL_ARB_ADDRESS_V6 + raindexArbAddress: $RAINDEX_ARB_ADDRESS_V6 dispair: $DISPAIR_V6 liquidityProviders: $LIQUIDITY_PROVIDERS route: $ROUTE @@ -51,3 +52,4 @@ orderbookTradeTypes: router: $ROUTER_ENABLED_ORDERBOOKS interOrderbook: $INTER_ENABLED_ORDERBOOKS intraOrderbook: $INTRA_ENABLED_ORDERBOOKS + raindexRouter: $RAINDEX_ENABLED_ORDERBOOKS diff --git a/config.example.yaml b/config.example.yaml index 405f4fca..68fed8db 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -73,6 +73,8 @@ contracts: balancerArbAddress: "0x1234...5678" # Stabull arb v6 contract address stabullArbAddress: "0x1234...5678" + # Raindex Router arb v6 contract address + raindexArbAddress: "0x1234...5678" # Dispair v6 contract address dispair: "0x1234...5678" @@ -192,3 +194,7 @@ orderbookTradeTypes: intraOrderbook: - "0xabcd..." - "0x1234..." + # Enable raindex router trades for the given orderbooks + raindexRouter: + - "0xabcd..." + - "0x1234..." diff --git a/src/common/abis/orderbook.ts b/src/common/abis/orderbook.ts index c3368b50..efd7697d 100644 --- a/src/common/abis/orderbook.ts +++ b/src/common/abis/orderbook.ts @@ -121,6 +121,7 @@ export namespace _v6 { `(${EvaluableV4} evaluable, ${IOV2}[] validInputs, ${IOV2}[] validOutputs, bytes32 nonce, bytes32 secret, bytes meta)` as const; export const ClearConfigV2 = "(uint256 aliceInputIOIndex, uint256 aliceOutputIOIndex, uint256 bobInputIOIndex, uint256 bobOutputIOIndex, bytes32 aliceBountyVaultId, bytes32 bobBountyVaultId)" as const; + export const RouteLeg = `(uint8 routeLegType, address destination, bytes data)[]`; // signatures export const Orderbook = [ @@ -149,7 +150,7 @@ export namespace _v6 { export const Arb = [ "function iRouteProcessor() external view returns (address)", `function arb5(address orderBook, ${TakeOrdersConfigV5} calldata takeOrders, ${TaskV2} calldata task) external payable`, - // `function arb4(address orderBook, ${TakeOrdersConfigV5} calldata startTakeOrders, ${TakeOrdersConfigV5} calldata endTakeOrders, bytes calldata exchangeData, ${TaskV2} calldata task) external payable`, + `function arb4(address orderBook, ${TakeOrdersConfigV5}[] calldata startTakeOrders, bytes calldata exchangeData, ${TaskV2} calldata task) external payable`, ] as const; } @@ -257,6 +258,8 @@ export namespace OrderbookAbi { /** Order v4 (for orderbook v6) struct ABI */ export const OrderStructAbi = parseAbiParameters(_v6.OrderV4); + + export const RouteLeg = parseAbiParameters(_v6.RouteLeg); } /** Orderbook v4 structs */ @@ -273,6 +276,7 @@ export namespace OrderbookAbi { export const TakeOrdersConfig = _v6.TakeOrdersConfigV5; export const ClearConfig = _v6.ClearConfigV2; export const Quote = _v6.QuoteV2; + export const RouteLeg = _v6.RouteLeg; } /** Signature ABI for Orderbook v4 and Arb contracts */ diff --git a/src/config/validators.test.ts b/src/config/validators.test.ts index 411c0fca..68685aa0 100644 --- a/src/config/validators.test.ts +++ b/src/config/validators.test.ts @@ -740,6 +740,317 @@ describe("Test yaml Validator methods", async function () { "unexpected error", ); }); + + it("test Validator resolveContracts", async function () { + const sushiArbV4 = `0x${"1".repeat(40)}`; + const dispairV4 = `0x${"2".repeat(40)}`; + const genericArbV4 = `0x${"3".repeat(40)}`; + const balancerArbV4 = `0x${"4".repeat(40)}`; + const stabullArbV4 = `0x${"5".repeat(40)}`; + + const sushiArbV5 = `0x${"6".repeat(40)}`; + const dispairV5 = `0x${"7".repeat(40)}`; + const genericArbV5 = `0x${"8".repeat(40)}`; + const balancerArbV5 = `0x${"9".repeat(40)}`; + const stabullArbV5 = `0x${"a".repeat(40)}`; + + const sushiArbV6 = `0x${"b".repeat(40)}`; + const dispairV6 = `0x${"c".repeat(40)}`; + const genericArbV6 = `0x${"d".repeat(40)}`; + const balancerArbV6 = `0x${"e".repeat(40)}`; + const stabullArbV6 = `0x${"f".repeat(40)}`; + const raindexArbV6 = `0x${"1".repeat(39)}1`; + + // happy path: all v4 contracts provided + let input: any = { + contracts: { + v4: { + sushiArbAddress: sushiArbV4, + dispair: dispairV4, + genericArbAddress: genericArbV4, + balancerArbAddress: balancerArbV4, + stabullArbAddress: stabullArbV4, + }, + }, + }; + let result = Validator.resolveContracts(input); + let expected: any = { + v4: { + sushiArb: sushiArbV4 as `0x${string}`, + dispair: dispairV4 as `0x${string}`, + genericArb: genericArbV4 as `0x${string}`, + balancerArb: balancerArbV4 as `0x${string}`, + stabullArb: stabullArbV4 as `0x${string}`, + }, + }; + assert.deepEqual(result, expected); + + // happy path: all v5 contracts provided + input = { + contracts: { + v5: { + sushiArbAddress: sushiArbV5, + dispair: dispairV5, + genericArbAddress: genericArbV5, + balancerArbAddress: balancerArbV5, + stabullArbAddress: stabullArbV5, + }, + }, + }; + result = Validator.resolveContracts(input); + expected = { + v5: { + sushiArb: sushiArbV5 as `0x${string}`, + dispair: dispairV5 as `0x${string}`, + genericArb: genericArbV5 as `0x${string}`, + balancerArb: balancerArbV5 as `0x${string}`, + stabullArb: stabullArbV5 as `0x${string}`, + }, + }; + assert.deepEqual(result, expected); + + // happy path: all v6 contracts provided including raindex + input = { + contracts: { + v6: { + sushiArbAddress: sushiArbV6, + dispair: dispairV6, + genericArbAddress: genericArbV6, + balancerArbAddress: balancerArbV6, + stabullArbAddress: stabullArbV6, + raindexArbAddress: raindexArbV6, + }, + }, + }; + result = Validator.resolveContracts(input); + expected = { + v6: { + sushiArb: sushiArbV6 as `0x${string}`, + dispair: dispairV6 as `0x${string}`, + genericArb: genericArbV6 as `0x${string}`, + balancerArb: balancerArbV6 as `0x${string}`, + stabullArb: stabullArbV6 as `0x${string}`, + raindexArb: raindexArbV6 as `0x${string}`, + }, + }; + assert.deepEqual(result, expected); + + // happy path: mix of v4, v5, and v6 contracts + input = { + contracts: { + v4: { + sushiArbAddress: sushiArbV4, + dispair: dispairV4, + }, + v5: { + genericArbAddress: genericArbV5, + }, + v6: { + balancerArbAddress: balancerArbV6, + raindexArbAddress: raindexArbV6, + }, + }, + }; + result = Validator.resolveContracts(input); + expected = { + v4: { + sushiArb: sushiArbV4 as `0x${string}`, + dispair: dispairV4 as `0x${string}`, + genericArb: undefined, + balancerArb: undefined, + stabullArb: undefined, + }, + v5: { + sushiArb: undefined, + dispair: undefined, + genericArb: genericArbV5 as `0x${string}`, + balancerArb: undefined, + stabullArb: undefined, + }, + v6: { + sushiArb: undefined, + dispair: undefined, + genericArb: undefined, + balancerArb: balancerArbV6 as `0x${string}`, + stabullArb: undefined, + raindexArb: raindexArbV6 as `0x${string}`, + }, + }; + assert.deepEqual(result, expected); + + // happy path: partial v4 contracts + input = { + contracts: { + v4: { + sushiArbAddress: sushiArbV4, + }, + }, + }; + result = Validator.resolveContracts(input); + expected = { + v4: { + sushiArb: sushiArbV4 as `0x${string}`, + dispair: undefined, + genericArb: undefined, + balancerArb: undefined, + stabullArb: undefined, + }, + }; + assert.deepEqual(result, expected); + + // happy path: partial v5 contracts + input = { + contracts: { + v5: { + dispair: dispairV5, + balancerArbAddress: balancerArbV5, + }, + }, + }; + result = Validator.resolveContracts(input); + expected = { + v5: { + sushiArb: undefined, + dispair: dispairV5 as `0x${string}`, + genericArb: undefined, + balancerArb: balancerArbV5 as `0x${string}`, + stabullArb: undefined, + }, + }; + assert.deepEqual(result, expected); + + // happy path: partial v6 contracts + input = { + contracts: { + v6: { + raindexArbAddress: raindexArbV6, + }, + }, + }; + result = Validator.resolveContracts(input); + expected = { + v6: { + sushiArb: undefined, + dispair: undefined, + genericArb: undefined, + balancerArb: undefined, + stabullArb: undefined, + raindexArb: raindexArbV6 as `0x${string}`, + }, + }; + assert.deepEqual(result, expected); + + // happy path: no contracts provided (empty object returned) + input = {}; + result = Validator.resolveContracts(input); + expected = {}; + assert.deepEqual(result, expected); + + // happy path: contracts object exists but no versions provided + input = { contracts: {} }; + result = Validator.resolveContracts(input); + expected = {}; + assert.deepEqual(result, expected); + + // happy path: using env variables for v4 + process.env.SUSHI_ARB_V4 = sushiArbV4; + process.env.DISPAIR_V4 = dispairV4; + input = { + contracts: { + v4: { + sushiArbAddress: "$SUSHI_ARB_V4", + dispair: "$DISPAIR_V4", + }, + }, + }; + result = Validator.resolveContracts(input); + expected = { + v4: { + sushiArb: sushiArbV4 as `0x${string}`, + dispair: dispairV4 as `0x${string}`, + genericArb: undefined, + balancerArb: undefined, + stabullArb: undefined, + }, + }; + assert.deepEqual(result, expected); + + // happy path: using env variables for v6 including raindex + process.env.RAINDEX_ARB_V6 = raindexArbV6; + process.env.BALANCER_ARB_V6 = balancerArbV6; + input = { + contracts: { + v6: { + raindexArbAddress: "$RAINDEX_ARB_V6", + balancerArbAddress: "$BALANCER_ARB_V6", + }, + }, + }; + result = Validator.resolveContracts(input); + expected = { + v6: { + sushiArb: undefined, + dispair: undefined, + genericArb: undefined, + balancerArb: balancerArbV6 as `0x${string}`, + stabullArb: undefined, + raindexArb: raindexArbV6 as `0x${string}`, + }, + }; + assert.deepEqual(result, expected); + + // unhappy: invalid address format for v4 sushiArbAddress + input = { + contracts: { + v4: { + sushiArbAddress: "invalid_address", + }, + }, + }; + assert.throws( + () => Validator.resolveContracts(input), + "expected valid sushiArbAddress v4 contract address", + ); + + // unhappy: invalid address format for v5 dispair + input = { + contracts: { + v5: { + dispair: "0x123", // too short + }, + }, + }; + assert.throws( + () => Validator.resolveContracts(input), + "expected valid dispair v5 contract address", + ); + + // unhappy: invalid address format for v6 raindexArbAddress + input = { + contracts: { + v6: { + raindexArbAddress: "not_an_address", + }, + }, + }; + assert.throws( + () => Validator.resolveContracts(input), + "expected valid raindexArbAddress v6 contract address", + ); + + // unhappy: undefined env variable + delete process.env.UNDEFINED_CONTRACT; + input = { + contracts: { + v4: { + sushiArbAddress: "$UNDEFINED_CONTRACT", + }, + }, + }; + result = Validator.resolveContracts(input); + expected = {}; + assert.deepEqual(result, expected); + }); }); describe("Test yaml Validator helpers", async function () { diff --git a/src/config/validators.ts b/src/config/validators.ts index 073ae6fe..1cdf45c2 100644 --- a/src/config/validators.ts +++ b/src/config/validators.ts @@ -533,6 +533,11 @@ export namespace Validator { "stabullArbAddress v6", true, ); + const raindexArbAddressV6 = resolveAddress( + input?.contracts?.v6?.raindexArbAddress, + "raindexArbAddress v6", + true, + ); const contracts: AppOptionsContracts = {}; if ( dispairV4 || @@ -569,7 +574,8 @@ export namespace Validator { sushiArbAddressV6 || genericArbAddressV6 || balancerArbAddressV6 || - stabullArbAddressV6 + stabullArbAddressV6 || + raindexArbAddressV6 ) { contracts.v6 = { sushiArb: sushiArbAddressV6 as `0x${string}` | undefined, @@ -577,6 +583,7 @@ export namespace Validator { genericArb: genericArbAddressV6 as `0x${string}` | undefined, balancerArb: balancerArbAddressV6 as `0x${string}` | undefined, stabullArb: stabullArbAddressV6 as `0x${string}` | undefined, + raindexArb: raindexArbAddressV6 as `0x${string}` | undefined, }; } return contracts; diff --git a/src/config/yaml.test.ts b/src/config/yaml.test.ts index b5c4ee9a..9ae3e9f8 100644 --- a/src/config/yaml.test.ts +++ b/src/config/yaml.test.ts @@ -73,6 +73,8 @@ orderbookTradeTypes: - "0x5555555555555555555555555555555555555555" - "0x6666666666666666666666666666666666666666" - "0x6666666666666666666666666666666666666666" + raindexRouter: + - "0x9999999999999999999999999999999999999999" `; const path = "./first.test.yaml"; @@ -145,6 +147,7 @@ orderbookTradeTypes: router: new Set([`0x${"1".repeat(40)}`, `0x${"2".repeat(40)}`]), interOrderbook: new Set([`0x${"3".repeat(40)}`, `0x${"4".repeat(40)}`]), intraOrderbook: new Set([`0x${"5".repeat(40)}`, `0x${"6".repeat(40)}`]), + raindexRouter: new Set([`0x${"9".repeat(40)}`]), }, maxConcurrency: 15, skipSweep: new Set([`0x${"8".repeat(40)}`, `0x${"9".repeat(40)}`]), @@ -227,6 +230,7 @@ orderbookTradeTypes: `0x${"6".repeat(40)}`, `0x${"6".repeat(40)}`, // duplicate to test set ], + raindexRouter: [`0x${"9".repeat(40)}`], }, }; const res = AppOptions.tryFrom(input); @@ -321,6 +325,7 @@ orderbookTradeTypes: router: new Set([`0x${"1".repeat(40)}`, `0x${"2".repeat(40)}`]), interOrderbook: new Set([`0x${"3".repeat(40)}`, `0x${"4".repeat(40)}`]), intraOrderbook: new Set([`0x${"5".repeat(40)}`, `0x${"6".repeat(40)}`]), + raindexRouter: new Set([`0x${"9".repeat(40)}`]), }); assert.deepEqual(result.skipSweep, new Set()); diff --git a/src/config/yaml.ts b/src/config/yaml.ts index 8dc1bc73..f54132cb 100644 --- a/src/config/yaml.ts +++ b/src/config/yaml.ts @@ -25,6 +25,7 @@ export type OrderbookTradeTypes = { router: Set; interOrderbook: Set; intraOrderbook: Set; + raindexRouter: Set; }; /** Represents a type for app options contracts addresses */ @@ -49,6 +50,7 @@ export type AppOptionsContracts = { genericArb?: `0x${string}`; balancerArb?: `0x${string}`; stabullArb?: `0x${string}`; + raindexArb?: `0x${string}`; }; }; @@ -283,6 +285,10 @@ export namespace AppOptions { input.orderbookTradeTypes?.intraOrderbook, "invalid orderbookTradeTypes.intraOrderbook, expected an array of orderbook addresses", ), + raindexRouter: Validator.resolveAddressSet( + input.orderbookTradeTypes?.raindexRouter, + "invalid orderbookTradeTypes.raindexRouter, expected an array of orderbook addresses", + ), }, skipSweep: Validator.resolveAddressSet( input.skipSweep, diff --git a/src/core/modes/index.test.ts b/src/core/modes/index.test.ts index 44df9706..44ee07ff 100644 --- a/src/core/modes/index.test.ts +++ b/src/core/modes/index.test.ts @@ -4,6 +4,7 @@ import { findBestRouterTrade } from "./router"; import { OrderbookTradeTypes } from "../../config"; import { findBestIntraOrderbookTrade } from "./intra"; import { findBestInterOrderbookTrade } from "./inter"; +import { findBestRaindexRouterTrade } from "./raindex"; import { findBestTrade, getEnabledTradeTypeFunctions } from "./index"; import { describe, it, expect, vi, beforeEach, Mock, assert } from "vitest"; @@ -19,8 +20,12 @@ vi.mock("./inter", () => ({ findBestInterOrderbookTrade: vi.fn(), })); -vi.mock("./balancer", () => ({ - findBestBalancerTrade: vi.fn(), +// vi.mock("./balancer", () => ({ +// findBestBalancerTrade: vi.fn(), +// })); + +vi.mock("./raindex", () => ({ + findBestRaindexRouterTrade: vi.fn(), })); describe("Test findBestTrade", () => { @@ -37,6 +42,7 @@ describe("Test findBestTrade", () => { router: new Set(), intraOrderbook: new Set(), interOrderbook: new Set(), + raindexRouter: new Set(), } as any, }, state: { @@ -79,10 +85,17 @@ describe("Test findBestTrade", () => { estimatedProfit: 150n, oppBlockNumber: 123, }); + const raindexResult = Result.ok({ + type: "raindex", + spanAttributes: { foundOpp: true }, + estimatedProfit: 50n, + oppBlockNumber: 123, + }); (findBestRouterTrade as Mock).mockResolvedValue(rpResult); (findBestIntraOrderbookTrade as Mock).mockResolvedValue(intraResult); (findBestInterOrderbookTrade as Mock).mockResolvedValue(interResult); + (findBestRaindexRouterTrade as Mock).mockResolvedValue(raindexResult); const result = await findBestTrade.call(mockRainSolver, args); @@ -110,10 +123,16 @@ describe("Test findBestTrade", () => { spanAttributes: { error: "no counterparty" }, noneNodeError: "inter orderbook failed", }); + const raindexResult = Result.err({ + type: "raindex", + spanAttributes: { error: "no route" }, + noneNodeError: "raindex router failed", + }); (findBestRouterTrade as Mock).mockResolvedValue(rpResult); (findBestIntraOrderbookTrade as Mock).mockResolvedValue(intraResult); (findBestInterOrderbookTrade as Mock).mockResolvedValue(interResult); + (findBestRaindexRouterTrade as Mock).mockResolvedValue(raindexResult); const result = await findBestTrade.call(mockRainSolver, args); @@ -140,10 +159,16 @@ describe("Test findBestTrade", () => { spanAttributes: { error: "no counterparty", pairs: 2 }, noneNodeError: "inter orderbook failed", }); + const raindexResult = Result.err({ + type: "raindex", + spanAttributes: { error: "failed", route: 1 }, + noneNodeError: "raindex router failed", + }); (findBestRouterTrade as Mock).mockResolvedValue(rpResult); (findBestIntraOrderbookTrade as Mock).mockResolvedValue(intraResult); (findBestInterOrderbookTrade as Mock).mockResolvedValue(interResult); + (findBestRaindexRouterTrade as Mock).mockResolvedValue(raindexResult); const result = await findBestTrade.call(mockRainSolver, args); @@ -155,6 +180,8 @@ describe("Test findBestTrade", () => { expect(result.error.spanAttributes["intraOrderbook.checked"]).toBe(5); expect(result.error.spanAttributes["interOrderbook.error"]).toBe("no counterparty"); expect(result.error.spanAttributes["interOrderbook.pairs"]).toBe(2); + expect(result.error.spanAttributes["raindex.error"]).toBe("failed"); + expect(result.error.spanAttributes["raindex.route"]).toBe(1); }); it("should only call route processor when rpOnly is true", async () => { @@ -185,6 +212,7 @@ describe("Test findBestTrade", () => { ); expect(findBestIntraOrderbookTrade).not.toHaveBeenCalled(); expect(findBestInterOrderbookTrade).not.toHaveBeenCalled(); + expect(findBestRaindexRouterTrade).not.toHaveBeenCalled(); }); it("should only call balancer router when balancerRouter is available", async () => { @@ -195,6 +223,7 @@ describe("Test findBestTrade", () => { router: new Set(), intraOrderbook: new Set(), interOrderbook: new Set(), + raindexRouter: new Set(), } as any, }, state: { @@ -223,10 +252,17 @@ describe("Test findBestTrade", () => { estimatedProfit: 120n, oppBlockNumber: 123, }); + const raindexResult = Result.ok({ + type: "raindex", + spanAttributes: { foundOpp: true }, + estimatedProfit: 120n, + oppBlockNumber: 123, + }); (findBestRouterTrade as Mock).mockResolvedValue(rpResult); (findBestIntraOrderbookTrade as Mock).mockResolvedValue(intraResult); (findBestInterOrderbookTrade as Mock).mockResolvedValue(interResult); + (findBestRaindexRouterTrade as Mock).mockResolvedValue(raindexResult); const result = await findBestTrade.call(mocksolver, args); @@ -255,6 +291,14 @@ describe("Test findBestTrade", () => { args.outputToEthPrice, args.blockNumber, ); + expect(findBestRaindexRouterTrade).toHaveBeenCalledWith( + args.orderDetails, + args.signer, + args.fromToken, + args.inputToEthPrice, + args.outputToEthPrice, + args.blockNumber, + ); }); it("should call all modes when rpOnly is false", async () => { @@ -276,10 +320,17 @@ describe("Test findBestTrade", () => { estimatedProfit: 120n, oppBlockNumber: 123, }); + const raindexResult = Result.ok({ + type: "interOrderbook", + spanAttributes: { foundOpp: true }, + estimatedProfit: 120n, + oppBlockNumber: 123, + }); (findBestRouterTrade as Mock).mockResolvedValue(rpResult); (findBestIntraOrderbookTrade as Mock).mockResolvedValue(intraResult); (findBestInterOrderbookTrade as Mock).mockResolvedValue(interResult); + (findBestRaindexRouterTrade as Mock).mockResolvedValue(raindexResult); const result = await findBestTrade.call(mockRainSolver, args); @@ -308,6 +359,14 @@ describe("Test findBestTrade", () => { args.outputToEthPrice, args.blockNumber, ); + expect(findBestRaindexRouterTrade).toHaveBeenCalledWith( + args.orderDetails, + args.signer, + args.fromToken, + args.inputToEthPrice, + args.outputToEthPrice, + args.blockNumber, + ); }); it("should sort results by estimated profit in descending order", async () => { @@ -329,10 +388,17 @@ describe("Test findBestTrade", () => { estimatedProfit: 200n, // middle oppBlockNumber: 123, }); + const raindexResult = Result.ok({ + type: "raindex", + spanAttributes: { foundOpp: true }, + estimatedProfit: 250n, // middle + oppBlockNumber: 123, + }); (findBestRouterTrade as Mock).mockResolvedValue(rpResult); (findBestIntraOrderbookTrade as Mock).mockResolvedValue(intraResult); (findBestInterOrderbookTrade as Mock).mockResolvedValue(interResult); + (findBestRaindexRouterTrade as Mock).mockResolvedValue(raindexResult); const result = await findBestTrade.call(mockRainSolver, args); @@ -358,10 +424,17 @@ describe("Test findBestTrade", () => { estimatedProfit: 75n, oppBlockNumber: 123, }); + const raindexResult = Result.ok({ + type: "raindex", + spanAttributes: { foundOpp: true }, + estimatedProfit: 65n, + oppBlockNumber: 123, + }); (findBestRouterTrade as Mock).mockResolvedValue(rpResult); (findBestIntraOrderbookTrade as Mock).mockResolvedValue(intraResult); (findBestInterOrderbookTrade as Mock).mockResolvedValue(interResult); + (findBestRaindexRouterTrade as Mock).mockResolvedValue(raindexResult); const result = await findBestTrade.call(mockRainSolver, args); @@ -394,6 +467,13 @@ describe("Test findBestTrade", () => { noneNodeError: "failed", }), ); + (findBestRaindexRouterTrade as Mock).mockResolvedValue( + Result.err({ + type: "raindex", + spanAttributes: { error: "failed" }, + noneNodeError: "failed", + }), + ); const result = await findBestTrade.call(mockRainSolver, args); @@ -426,6 +506,13 @@ describe("Test findBestTrade", () => { noneNodeError: "failed", }), ); + (findBestRaindexRouterTrade as Mock).mockResolvedValue( + Result.err({ + type: "raindex", + spanAttributes: { error: "failed" }, + noneNodeError: "failed", + }), + ); await findBestTrade.call(mockRainSolver, args); @@ -451,6 +538,14 @@ describe("Test findBestTrade", () => { args.outputToEthPrice, args.blockNumber, ); + expect(findBestRaindexRouterTrade).toHaveBeenCalledWith( + args.orderDetails, + args.signer, + args.fromToken, + args.inputToEthPrice, + args.outputToEthPrice, + args.blockNumber, + ); }); it("should preserve span attributes from error results with proper headers", async () => { @@ -469,10 +564,16 @@ describe("Test findBestTrade", () => { spanAttributes: { interError: "no counterparty", interPairs: 2 }, noneNodeError: "inter orderbook failed", }); + const raindexResult = Result.err({ + type: "raindex", + spanAttributes: { raindexError: "no route", route: 0 }, + noneNodeError: "raindex router failed", + }); (findBestRouterTrade as Mock).mockResolvedValue(rpResult); (findBestIntraOrderbookTrade as Mock).mockResolvedValue(intraResult); (findBestInterOrderbookTrade as Mock).mockResolvedValue(interResult); + (findBestRaindexRouterTrade as Mock).mockResolvedValue(raindexResult); const result = await findBestTrade.call(mockRainSolver, args); @@ -483,6 +584,8 @@ describe("Test findBestTrade", () => { expect(result.error.spanAttributes["intraOrderbook.intraChecked"]).toBe(5); expect(result.error.spanAttributes["interOrderbook.interError"]).toBe("no counterparty"); expect(result.error.spanAttributes["interOrderbook.interPairs"]).toBe(2); + expect(result.error.spanAttributes["raindex.raindexError"]).toBe("no route"); + expect(result.error.spanAttributes["raindex.route"]).toBe(0); }); }); @@ -496,6 +599,7 @@ describe("Test getEnabledTrades", () => { router: new Set([anotherAddress]), intraOrderbook: new Set([anotherAddress]), interOrderbook: new Set([anotherAddress]), + raindexRouter: new Set([anotherAddress]), }; const result = getEnabledTradeTypeFunctions(orderbookTradeTypes, mockOrderbookAddress); @@ -503,6 +607,7 @@ describe("Test getEnabledTrades", () => { expect(result.findBestRouterTrade).toBe(findBestRouterTrade); expect(result.findBestIntraOrderbookTrade).toBe(findBestIntraOrderbookTrade); expect(result.findBestInterOrderbookTrade).toBe(findBestInterOrderbookTrade); + expect(result.findBestRaindexRouterTrade).toBe(findBestRaindexRouterTrade); }); it("should return all trade functions when all sets are empty", () => { @@ -510,6 +615,7 @@ describe("Test getEnabledTrades", () => { router: new Set(), intraOrderbook: new Set(), interOrderbook: new Set(), + raindexRouter: new Set(), }; const result = getEnabledTradeTypeFunctions(orderbookTradeTypes, mockOrderbookAddress); @@ -517,6 +623,7 @@ describe("Test getEnabledTrades", () => { expect(result.findBestRouterTrade).toBe(findBestRouterTrade); expect(result.findBestIntraOrderbookTrade).toBe(findBestIntraOrderbookTrade); expect(result.findBestInterOrderbookTrade).toBe(findBestInterOrderbookTrade); + expect(result.findBestRaindexRouterTrade).toBe(findBestRaindexRouterTrade); }); it("should return only router trade when orderbook is in router set", () => { @@ -524,6 +631,7 @@ describe("Test getEnabledTrades", () => { router: new Set([mockOrderbookAddressLowercase]), intraOrderbook: new Set(), interOrderbook: new Set(), + raindexRouter: new Set(), }; const result = getEnabledTradeTypeFunctions(orderbookTradeTypes, mockOrderbookAddress); @@ -538,6 +646,7 @@ describe("Test getEnabledTrades", () => { router: new Set(), intraOrderbook: new Set([mockOrderbookAddressLowercase]), interOrderbook: new Set(), + raindexRouter: new Set(), }; const result = getEnabledTradeTypeFunctions(orderbookTradeTypes, mockOrderbookAddress); @@ -552,6 +661,7 @@ describe("Test getEnabledTrades", () => { router: new Set(), intraOrderbook: new Set(), interOrderbook: new Set([mockOrderbookAddressLowercase]), + raindexRouter: new Set(), }; const result = getEnabledTradeTypeFunctions(orderbookTradeTypes, mockOrderbookAddress); @@ -561,11 +671,28 @@ describe("Test getEnabledTrades", () => { expect(result.findBestInterOrderbookTrade).toBe(findBestInterOrderbookTrade); }); + it("should return only inter-orderbook trade when orderbook is in raindex router set", () => { + const orderbookTradeTypes: OrderbookTradeTypes = { + router: new Set(), + intraOrderbook: new Set(), + interOrderbook: new Set(), + raindexRouter: new Set([mockOrderbookAddressLowercase]), + }; + + const result = getEnabledTradeTypeFunctions(orderbookTradeTypes, mockOrderbookAddress); + + expect(result.findBestRouterTrade).toBeUndefined(); + expect(result.findBestIntraOrderbookTrade).toBeUndefined(); + expect(result.findBestInterOrderbookTrade).toBeUndefined(); + expect(result.findBestRaindexRouterTrade).toBe(findBestRaindexRouterTrade); + }); + it("should return multiple trade functions when orderbook is in multiple sets", () => { const orderbookTradeTypes: OrderbookTradeTypes = { router: new Set([mockOrderbookAddressLowercase]), intraOrderbook: new Set([mockOrderbookAddressLowercase]), interOrderbook: new Set(), + raindexRouter: new Set(), }; const result = getEnabledTradeTypeFunctions(orderbookTradeTypes, mockOrderbookAddress); @@ -573,6 +700,7 @@ describe("Test getEnabledTrades", () => { expect(result.findBestRouterTrade).toBe(findBestRouterTrade); expect(result.findBestIntraOrderbookTrade).toBe(findBestIntraOrderbookTrade); expect(result.findBestInterOrderbookTrade).toBeUndefined(); + expect(result.findBestRaindexRouterTrade).toBeUndefined(); }); it("should return all trade functions when orderbook is in all sets", () => { @@ -580,6 +708,7 @@ describe("Test getEnabledTrades", () => { router: new Set([mockOrderbookAddressLowercase]), intraOrderbook: new Set([mockOrderbookAddressLowercase]), interOrderbook: new Set([mockOrderbookAddressLowercase]), + raindexRouter: new Set([mockOrderbookAddressLowercase]), }; const result = getEnabledTradeTypeFunctions(orderbookTradeTypes, mockOrderbookAddress); @@ -587,5 +716,6 @@ describe("Test getEnabledTrades", () => { expect(result.findBestRouterTrade).toBe(findBestRouterTrade); expect(result.findBestIntraOrderbookTrade).toBe(findBestIntraOrderbookTrade); expect(result.findBestInterOrderbookTrade).toBe(findBestInterOrderbookTrade); + expect(result.findBestRaindexRouterTrade).toBe(findBestRaindexRouterTrade); }); }); diff --git a/src/core/modes/index.ts b/src/core/modes/index.ts index 5f843a2a..5ea20b5b 100644 --- a/src/core/modes/index.ts +++ b/src/core/modes/index.ts @@ -8,6 +8,7 @@ import { findBestRouterTrade } from "./router"; import { OrderbookTradeTypes } from "../../config"; import { findBestIntraOrderbookTrade } from "./intra"; import { findBestInterOrderbookTrade } from "./inter"; +import { findBestRaindexRouterTrade } from "./raindex"; import { Result, extendObjectWithHeader } from "../../common"; import { FindBestTradeResult, SimulationResult } from "../types"; @@ -59,6 +60,7 @@ export async function findBestTrade( findBestRouterTrade: findBestRouterTradeFn, findBestIntraOrderbookTrade: findBestIntraOrderbookTradeFn, findBestInterOrderbookTrade: findBestInterOrderbookTradeFn, + findBestRaindexRouterTrade: findBestRaindexRouterTradeFn, } = getEnabledTradeTypeFunctions(this.appOptions.orderbookTradeTypes, orderDetails.orderbook); const promises = [ @@ -87,6 +89,15 @@ export async function findBestTrade( outputToEthPrice, blockNumber, ), + findBestRaindexRouterTradeFn?.call( + this, + orderDetails, + signer, + fromToken, + inputToEthPrice, + outputToEthPrice, + blockNumber, + ), ]; const results = (await Promise.all(promises)).filter( (v) => v !== undefined, @@ -137,6 +148,7 @@ type TradeTypeFunctions = { findBestRouterTrade?: typeof findBestRouterTrade; findBestIntraOrderbookTrade?: typeof findBestIntraOrderbookTrade; findBestInterOrderbookTrade?: typeof findBestInterOrderbookTrade; + findBestRaindexRouterTrade?: typeof findBestRaindexRouterTrade; }; /** @@ -156,6 +168,7 @@ export function getEnabledTradeTypeFunctions( findBestRouterTrade: undefined, findBestIntraOrderbookTrade: undefined, findBestInterOrderbookTrade: undefined, + findBestRaindexRouterTrade: undefined, }; if (orderbookTradeTypes.router.has(address)) { @@ -170,11 +183,16 @@ export function getEnabledTradeTypeFunctions( result.findBestInterOrderbookTrade = findBestInterOrderbookTrade; allEnabled = false; } + if (orderbookTradeTypes.raindexRouter.has(address)) { + result.findBestRaindexRouterTrade = findBestRaindexRouterTrade; + allEnabled = false; + } if (allEnabled) { return { findBestRouterTrade, findBestIntraOrderbookTrade, findBestInterOrderbookTrade, + findBestRaindexRouterTrade, }; } else { return result; diff --git a/src/core/modes/raindex/index.test.ts b/src/core/modes/raindex/index.test.ts new file mode 100644 index 00000000..f66b9d6e --- /dev/null +++ b/src/core/modes/raindex/index.test.ts @@ -0,0 +1,980 @@ +import { Router } from "sushi"; +import * as utils from "./utils"; +import { parseUnits } from "viem"; +import { RainSolver } from "../.."; +import { Pair } from "../../../order"; +import { Token } from "sushi/currency"; +import { TradeType } from "../../types"; +import { Result } from "../../../common"; +import { SushiRouter } from "../../../router"; +import { RainSolverSigner } from "../../../signer"; +import { SimulationHaltReason } from "../simulator"; +import { extendObjectWithHeader } from "../../../common"; +import { RaindexRouterTradeSimulator } from "./simulation"; +import { estimateProfit, findBestRaindexRouterTrade } from "./index"; +import { describe, it, expect, vi, Mock, beforeEach, assert } from "vitest"; + +// mocks +vi.mock("../../../common", async (importOriginal) => ({ + ...(await importOriginal()), + extendObjectWithHeader: vi.fn(), +})); + +vi.mock("sushi/currency", async (importOriginal) => { + return { + ...(await importOriginal()), + Token: class { + constructor(args: any) { + return { ...args }; + } + }, + }; +}); + +describe("Test findBestRaindexRouterTrade function", () => { + let solver: RainSolver; + let signer: RainSolverSigner; + let fromToken: Token; + let isV4OrderbookV6Spy: any; + let routeProcessor4ParamsSpy: any; + let visualizeRouteSpy: any; + let raindexRouterTradeSimulatorWithArgsSpy: any; + let trySimulateTradeSpy: any; + const blockNumber = 1000n; + const inputToEthPrice = "0.5"; + const outputToEthPrice = "1.0"; + + beforeEach(() => { + vi.clearAllMocks(); + + // Setup mock solver + solver = { + state: { + chainConfig: { + id: 1, + routeProcessors: { + "4": "0xrouteprocessor", + }, + }, + contracts: { + getAddressesForTrade: vi.fn().mockReturnValue({ + destination: "0xdestination", + arb: "0xarb", + }), + }, + router: { + sushi: { + tryQuote: vi.fn(), + }, + }, + gasPrice: 50000000000n, + appOptions: { + route: "classic", + }, + }, + orderManager: { + getCounterpartyOrdersAgainstBaseTokens: vi.fn(), + }, + } as any; + + signer = { + address: "0xsigner", + } as any; + + fromToken = new Token({ + chainId: 1, + decimals: 18, + address: "0xfrom", + symbol: "FROM", + }); + + isV4OrderbookV6Spy = vi.spyOn(Pair, "isV4OrderbookV6"); + routeProcessor4ParamsSpy = vi.spyOn(Router, "routeProcessor4Params"); + visualizeRouteSpy = vi.spyOn(SushiRouter, "visualizeRoute"); + raindexRouterTradeSimulatorWithArgsSpy = vi.spyOn(RaindexRouterTradeSimulator, "withArgs"); + trySimulateTradeSpy = vi.fn(); + }); + + it("should return error for non-v6 orderbook order", async () => { + const orderDetails = { + orderbook: "0xorderbook", + takeOrder: { + id: "0xhash", + struct: { + orderbook: { id: "0xorderbook" }, + }, + }, + } as any; + + isV4OrderbookV6Spy.mockReturnValue(false); + + const result = await findBestRaindexRouterTrade.call( + solver, + orderDetails, + signer, + fromToken, + inputToEthPrice, + outputToEthPrice, + blockNumber, + ); + + assert(result.isErr()); + expect(result.error.type).toBe(TradeType.Raindex); + expect(result.error.reason).toBe(SimulationHaltReason.UndefinedTradeDestinationAddress); + expect(result.error.spanAttributes.error).toBe( + "Cannot trade as raindex router as order is not deployed on v6 orderbook", + ); + expect(extendObjectWithHeader).not.toHaveBeenCalled(); + expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); + expect(solver.state.contracts.getAddressesForTrade).not.toHaveBeenCalledWith(); + expect( + solver.orderManager.getCounterpartyOrdersAgainstBaseTokens, + ).not.toHaveBeenCalledWith(); + expect(solver.state.router.sushi!.tryQuote).not.toHaveBeenCalledWith(); + expect(routeProcessor4ParamsSpy).not.toHaveBeenCalled(); + expect(visualizeRouteSpy).not.toHaveBeenCalled(); + expect(raindexRouterTradeSimulatorWithArgsSpy).not.toHaveBeenCalled(); + expect(trySimulateTradeSpy).not.toHaveBeenCalled(); + }); + + it("should return error when raindex arb address is not configured", async () => { + const orderDetails = { + orderbook: "0xorderbook", + takeOrder: { + id: "0xhash", + struct: { + orderbook: { id: "0xorderbook" }, + }, + }, + } as any; + + isV4OrderbookV6Spy.mockReturnValue(true); + (solver.state.contracts.getAddressesForTrade as Mock).mockReturnValue(undefined); + + const result = await findBestRaindexRouterTrade.call( + solver, + orderDetails, + signer, + fromToken, + inputToEthPrice, + outputToEthPrice, + blockNumber, + ); + + assert(result.isErr()); + expect(result.error.type).toBe(TradeType.Raindex); + expect(result.error.reason).toBe(SimulationHaltReason.UndefinedTradeDestinationAddress); + expect(result.error.spanAttributes.error).toBe( + "Cannot trade as raindex router arb address is not configured for v6 orderbook trade", + ); + expect(extendObjectWithHeader).not.toHaveBeenCalled(); + expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); + expect(solver.state.contracts.getAddressesForTrade).toHaveBeenCalledWith( + orderDetails, + TradeType.Raindex, + ); + expect( + solver.orderManager.getCounterpartyOrdersAgainstBaseTokens, + ).not.toHaveBeenCalledWith(); + expect(solver.state.router.sushi!.tryQuote).not.toHaveBeenCalledWith(); + expect(routeProcessor4ParamsSpy).not.toHaveBeenCalled(); + expect(visualizeRouteSpy).not.toHaveBeenCalled(); + expect(raindexRouterTradeSimulatorWithArgsSpy).not.toHaveBeenCalled(); + expect(trySimulateTradeSpy).not.toHaveBeenCalled(); + }); + + it("should return error when no counterparty orders found", async () => { + const orderDetails = { + orderbook: "0xorderbook", + sellTokenDecimals: 18, + takeOrder: { + id: "0xhash", + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("1", 18), + }, + struct: { + orderbook: { id: "0xorderbook" }, + order: { owner: "0xowner" }, + }, + }, + } as any; + + isV4OrderbookV6Spy.mockReturnValue(true); + (solver.orderManager.getCounterpartyOrdersAgainstBaseTokens as Mock).mockReturnValue( + new Map(), + ); + + const result = await findBestRaindexRouterTrade.call( + solver, + orderDetails, + signer, + fromToken, + inputToEthPrice, + outputToEthPrice, + blockNumber, + ); + + assert(result.isErr()); + expect(result.error.type).toBe(TradeType.Raindex); + expect(result.error.spanAttributes.error).toContain( + "no counterparties found for raindex router trade", + ); + expect(extendObjectWithHeader).not.toHaveBeenCalled(); + expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); + expect(solver.state.contracts.getAddressesForTrade).toHaveBeenCalledWith( + orderDetails, + TradeType.Raindex, + ); + expect(solver.orderManager.getCounterpartyOrdersAgainstBaseTokens).toHaveBeenCalledWith( + orderDetails, + ); + expect(solver.state.router.sushi!.tryQuote).not.toHaveBeenCalledWith(); + expect(routeProcessor4ParamsSpy).not.toHaveBeenCalled(); + expect(visualizeRouteSpy).not.toHaveBeenCalled(); + expect(raindexRouterTradeSimulatorWithArgsSpy).not.toHaveBeenCalled(); + expect(trySimulateTradeSpy).not.toHaveBeenCalled(); + }); + + it("should skip counterparty when sushi quote fails", async () => { + const orderDetails = { + orderbook: "0xorderbook", + sellTokenDecimals: 18, + buyToken: "0xto", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xhash", + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("1", 18), + }, + struct: { + orderbook: { id: "0xorderbook" }, + order: { owner: "0xowner" }, + }, + }, + } as any; + + const counterpartyOrder = { + buyToken: "0xto", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xcounterpartyhash", + quote: { + maxOutput: parseUnits("50", 18), + ratio: parseUnits("1", 18), + }, + struct: { + order: { owner: "0xcounterpartyowner" }, + }, + }, + } as any; + + isV4OrderbookV6Spy.mockReturnValue(true); + (solver.orderManager.getCounterpartyOrdersAgainstBaseTokens as Mock).mockReturnValue( + new Map([["0xbasetoken", [counterpartyOrder]]]), + ); + + (solver.state.router.sushi!.tryQuote as Mock).mockResolvedValue(Result.err("Quote failed")); + + const result = await findBestRaindexRouterTrade.call( + solver, + orderDetails, + signer, + fromToken, + inputToEthPrice, + outputToEthPrice, + blockNumber, + ); + + assert(result.isErr()); + expect(result.error.type).toBe(TradeType.Raindex); + expect(result.error.spanAttributes.error).toContain( + "no counterparties found for raindex router trade", + ); + expect(extendObjectWithHeader).not.toHaveBeenCalled(); + expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); + expect(solver.state.contracts.getAddressesForTrade).toHaveBeenCalledWith( + orderDetails, + TradeType.Raindex, + ); + expect(solver.orderManager.getCounterpartyOrdersAgainstBaseTokens).toHaveBeenCalledWith( + orderDetails, + ); + expect(solver.state.router.sushi!.tryQuote).toHaveBeenCalledWith({ + fromToken, + toToken: new Token({ + chainId: solver.state.chainConfig.id, + decimals: counterpartyOrder.buyTokenDecimals, + address: counterpartyOrder.buyToken, + symbol: counterpartyOrder.buyTokenSymbol, + }), + amountIn: expect.any(BigInt), + gasPrice: solver.state.gasPrice, + blockNumber, + skipFetch: true, + sushiRouteType: solver.state.appOptions.route, + }); + expect(routeProcessor4ParamsSpy).not.toHaveBeenCalled(); + expect(visualizeRouteSpy).not.toHaveBeenCalled(); + expect(raindexRouterTradeSimulatorWithArgsSpy).not.toHaveBeenCalled(); + expect(trySimulateTradeSpy).not.toHaveBeenCalled(); + }); + + it("should filter out same order and same owner from counterparties", async () => { + const orderDetails = { + orderbook: "0xorderbook", + sellTokenDecimals: 18, + buyToken: "0xto", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xhash", + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("1", 18), + }, + struct: { + orderbook: { id: "0xorderbook" }, + order: { owner: "0xowner" }, + }, + }, + } as any; + + // Same order ID - should be filtered + const sameOrder = { + buyToken: "0xto", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xhash", + quote: { + maxOutput: parseUnits("50", 18), + ratio: parseUnits("1", 18), + }, + struct: { + order: { owner: "0xanotherowner" }, + }, + }, + } as any; + + // Same owner - should be filtered + const sameOwner = { + buyToken: "0xto", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xanotherhash", + quote: { + maxOutput: parseUnits("50", 18), + ratio: parseUnits("1", 18), + }, + struct: { + order: { owner: "0xOWNER" }, // case insensitive + }, + }, + } as any; + const toToken = new Token({ + chainId: solver.state.chainConfig.id, + decimals: sameOrder.buyTokenDecimals, + address: sameOrder.buyToken, + symbol: sameOrder.buyTokenSymbol, + }); + + isV4OrderbookV6Spy.mockReturnValue(true); + (solver.orderManager.getCounterpartyOrdersAgainstBaseTokens as Mock).mockReturnValue( + new Map([["0xbasetoken", [sameOrder, sameOwner]]]), + ); + + const mockQuote = { + amountOut: 100n, + price: parseUnits("1", 18), + route: { + pcMap: new Map(), + route: { + legs: [], + }, + }, + }; + + (solver.state.router.sushi!.tryQuote as Mock).mockResolvedValue(Result.ok(mockQuote)); + routeProcessor4ParamsSpy.mockReturnValue({} as any); + visualizeRouteSpy.mockReturnValue([]); + + const result = await findBestRaindexRouterTrade.call( + solver, + orderDetails, + signer, + fromToken, + inputToEthPrice, + outputToEthPrice, + blockNumber, + ); + + // Should return error as all counterparties are filtered + assert(result.isErr()); + expect(result.error.type).toBe(TradeType.Raindex); + expect(result.error.spanAttributes.error).toContain( + "no counterparties found for raindex router trade", + ); + expect(extendObjectWithHeader).not.toHaveBeenCalled(); + expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); + expect(solver.state.contracts.getAddressesForTrade).toHaveBeenCalledWith( + orderDetails, + TradeType.Raindex, + ); + expect(solver.orderManager.getCounterpartyOrdersAgainstBaseTokens).toHaveBeenCalledWith( + orderDetails, + ); + expect(solver.state.router.sushi!.tryQuote).toHaveBeenNthCalledWith(1, { + fromToken, + toToken: toToken, + amountIn: expect.any(BigInt), + gasPrice: solver.state.gasPrice, + blockNumber, + skipFetch: true, + sushiRouteType: solver.state.appOptions.route, + }); + expect(routeProcessor4ParamsSpy).toHaveBeenCalledTimes(1); + expect(visualizeRouteSpy).toHaveBeenNthCalledWith(1, fromToken, toToken, expect.any(Array)); + expect(raindexRouterTradeSimulatorWithArgsSpy).not.toHaveBeenCalled(); + expect(trySimulateTradeSpy).not.toHaveBeenCalled(); + }); + + it("should successfully simulate trade with valid counterparty", async () => { + const orderDetails = { + orderbook: "0xorderbook", + sellTokenDecimals: 18, + buyToken: "0xto", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xhash", + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("1", 18), + }, + struct: { + orderbook: { id: "0xorderbook" }, + order: { owner: "0xowner" }, + }, + }, + } as any; + + const counterpartyOrder = { + buyToken: "0xto", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xcounterpartyhash", + quote: { + maxOutput: parseUnits("50", 18), + ratio: parseUnits("1", 18), + }, + struct: { + orderbook: { id: "0xorderbook" }, + order: { owner: "0xcounterpartyowner" }, + }, + }, + } as any; + const toToken = new Token({ + chainId: solver.state.chainConfig.id, + decimals: counterpartyOrder.buyTokenDecimals, + address: counterpartyOrder.buyToken, + symbol: counterpartyOrder.buyTokenSymbol, + }); + + isV4OrderbookV6Spy.mockReturnValue(true); + (solver.orderManager.getCounterpartyOrdersAgainstBaseTokens as Mock).mockReturnValue( + new Map([["0xbasetoken", [counterpartyOrder]]]), + ); + + const mockQuote = { + amountOut: 100n, + price: parseUnits("1", 18), + route: { + pcMap: new Map(), + route: { + legs: [], + }, + }, + }; + + (solver.state.router.sushi!.tryQuote as Mock).mockResolvedValue(Result.ok(mockQuote)); + routeProcessor4ParamsSpy.mockReturnValue({ rp: "value" } as any); + visualizeRouteSpy.mockReturnValue(["route"]); + + const mockSimulationResult = Result.ok({ + type: TradeType.Raindex, + estimatedProfit: 1000n, + spanAttributes: { key: "value" }, + }); + + raindexRouterTradeSimulatorWithArgsSpy.mockReturnValue({ + trySimulateTrade: trySimulateTradeSpy.mockResolvedValue(mockSimulationResult), + }); + + const result = await findBestRaindexRouterTrade.call( + solver, + orderDetails, + signer, + fromToken, + inputToEthPrice, + outputToEthPrice, + blockNumber, + ); + + assert(result.isOk()); + expect(result.value.type).toBe(TradeType.Raindex); + expect(result.value.spanAttributes.key).toBe("value"); + expect(result.value.estimatedProfit).toBe(1000n); + expect(extendObjectWithHeader).not.toHaveBeenCalled(); + expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); + expect(solver.state.contracts.getAddressesForTrade).toHaveBeenCalledWith( + orderDetails, + TradeType.Raindex, + ); + expect(solver.orderManager.getCounterpartyOrdersAgainstBaseTokens).toHaveBeenCalledWith( + orderDetails, + ); + expect(solver.state.router.sushi!.tryQuote).toHaveBeenNthCalledWith(1, { + fromToken, + toToken: toToken, + amountIn: expect.any(BigInt), + gasPrice: solver.state.gasPrice, + blockNumber, + skipFetch: true, + sushiRouteType: solver.state.appOptions.route, + }); + expect(routeProcessor4ParamsSpy).toHaveBeenCalledTimes(1); + expect(visualizeRouteSpy).toHaveBeenNthCalledWith(1, fromToken, toToken, expect.any(Array)); + expect(raindexRouterTradeSimulatorWithArgsSpy).toHaveBeenCalledWith({ + type: TradeType.Raindex, + solver, + orderDetails, + counterpartyOrderDetails: counterpartyOrder, + signer, + maximumInputFixed: expect.any(BigInt), + counterpartyInputToEthPrice: expect.any(BigInt), + counterpartyOutputToEthPrice: expect.any(BigInt), + blockNumber, + quote: expect.anything(), + profit: expect.any(BigInt), + rpParams: { rp: "value" }, + routeVisual: ["route"], + }); + expect(trySimulateTradeSpy).toHaveBeenCalledTimes(1); + }); + + it("should pick trade with highest estimated profit from multiple options", async () => { + const orderDetails = { + orderbook: "0xorderbook", + sellTokenDecimals: 18, + buyToken: "0xto", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xhash", + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("1", 18), + }, + struct: { + orderbook: { id: "0xorderbook" }, + order: { owner: "0xowner" }, + }, + }, + } as any; + + const counterparty1 = { + buyToken: "0xto1", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xcounterparty1", + quote: { + maxOutput: parseUnits("50", 18), + ratio: parseUnits("1", 18), + }, + struct: { + orderbook: { id: "0xorderbook" }, + order: { owner: "0xowner1" }, + }, + }, + } as any; + + const counterparty2 = { + buyToken: "0xto2", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xcounterparty2", + quote: { + maxOutput: parseUnits("60", 18), + ratio: parseUnits("1.2", 18), + }, + struct: { + orderbook: { id: "0xorderbook" }, + order: { owner: "0xowner2" }, + }, + }, + } as any; + const toToken1 = new Token({ + chainId: solver.state.chainConfig.id, + decimals: counterparty1.buyTokenDecimals, + address: counterparty1.buyToken, + symbol: counterparty1.buyTokenSymbol, + }); + const toToken2 = new Token({ + chainId: solver.state.chainConfig.id, + decimals: counterparty2.buyTokenDecimals, + address: counterparty2.buyToken, + symbol: counterparty2.buyTokenSymbol, + }); + + isV4OrderbookV6Spy.mockReturnValue(true); + (solver.orderManager.getCounterpartyOrdersAgainstBaseTokens as Mock).mockReturnValue( + new Map([ + ["0xbasetoken1", [counterparty1]], + ["0xbasetoken2", [counterparty2]], + ]), + ); + + const mockQuote = { + amountOut: 100n, + price: parseUnits("1", 18), + route: { + pcMap: new Map(), + route: { legs: [] }, + }, + }; + + (solver.state.router.sushi!.tryQuote as Mock).mockResolvedValue(Result.ok(mockQuote)); + routeProcessor4ParamsSpy.mockReturnValue({ rp: "value" } as any); + visualizeRouteSpy.mockReturnValue(["route"]); + + let callCount = 0; + raindexRouterTradeSimulatorWithArgsSpy.mockReturnValue({ + trySimulateTrade: trySimulateTradeSpy.mockImplementation(() => { + callCount++; + // First call returns lower profit, second returns higher profit + return Promise.resolve( + Result.ok({ + type: TradeType.Raindex, + estimatedProfit: callCount === 1 ? 500n : 1500n, + spanAttributes: { key: "value" }, + }), + ); + }), + } as any); + + const result = await findBestRaindexRouterTrade.call( + solver, + orderDetails, + signer, + fromToken, + inputToEthPrice, + outputToEthPrice, + blockNumber, + ); + + assert(result.isOk()); + // Should pick the one with highest profit (1500n) + expect(result.value.estimatedProfit).toBe(1500n); + expect(result.value.spanAttributes.key).toBe("value"); + expect(extendObjectWithHeader).not.toHaveBeenCalled(); + expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); + expect(solver.state.contracts.getAddressesForTrade).toHaveBeenCalledWith( + orderDetails, + TradeType.Raindex, + ); + expect(solver.orderManager.getCounterpartyOrdersAgainstBaseTokens).toHaveBeenCalledWith( + orderDetails, + ); + expect(solver.state.router.sushi!.tryQuote).toHaveBeenNthCalledWith(1, { + fromToken, + toToken: toToken1, + amountIn: expect.any(BigInt), + gasPrice: solver.state.gasPrice, + blockNumber, + skipFetch: true, + sushiRouteType: solver.state.appOptions.route, + }); + expect(solver.state.router.sushi!.tryQuote).toHaveBeenNthCalledWith(2, { + fromToken, + toToken: toToken2, + amountIn: expect.any(BigInt), + gasPrice: solver.state.gasPrice, + blockNumber, + skipFetch: true, + sushiRouteType: solver.state.appOptions.route, + }); + expect(routeProcessor4ParamsSpy).toHaveBeenCalledTimes(2); + expect(visualizeRouteSpy).toHaveBeenNthCalledWith( + 1, + fromToken, + toToken1, + expect.any(Array), + ); + expect(visualizeRouteSpy).toHaveBeenNthCalledWith( + 2, + fromToken, + toToken2, + expect.any(Array), + ); + expect(raindexRouterTradeSimulatorWithArgsSpy).toHaveBeenNthCalledWith(1, { + type: TradeType.Raindex, + solver, + orderDetails, + counterpartyOrderDetails: counterparty1, + signer, + maximumInputFixed: expect.any(BigInt), + counterpartyInputToEthPrice: expect.any(BigInt), + counterpartyOutputToEthPrice: expect.any(BigInt), + blockNumber, + quote: expect.anything(), + profit: expect.any(BigInt), + rpParams: { rp: "value" }, + routeVisual: ["route"], + }); + expect(raindexRouterTradeSimulatorWithArgsSpy).toHaveBeenNthCalledWith(2, { + type: TradeType.Raindex, + solver, + orderDetails, + counterpartyOrderDetails: counterparty2, + signer, + maximumInputFixed: expect.any(BigInt), + counterpartyInputToEthPrice: expect.any(BigInt), + counterpartyOutputToEthPrice: expect.any(BigInt), + blockNumber, + quote: expect.anything(), + profit: expect.any(BigInt), + rpParams: { rp: "value" }, + routeVisual: ["route"], + }); + expect(trySimulateTradeSpy).toHaveBeenCalledTimes(2); + }); + + it("should aggregate errors when all simulations fail", async () => { + const orderDetails = { + orderbook: "0xorderbook", + sellTokenDecimals: 18, + buyToken: "0xto", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xhash", + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("1", 18), + }, + struct: { + orderbook: { id: "0xorderbook" }, + order: { owner: "0xowner" }, + }, + }, + } as any; + + const counterpartyOrder = { + buyToken: "0xto", + buyTokenDecimals: 18, + buyTokenSymbol: "TO", + takeOrder: { + id: "0xcounterpartyhash", + quote: { + maxOutput: parseUnits("50", 18), + ratio: parseUnits("1", 18), + }, + struct: { + orderbook: { id: "0xorderbook" }, + order: { owner: "0xcounterpartyowner" }, + }, + }, + } as any; + const toToken = new Token({ + chainId: solver.state.chainConfig.id, + decimals: counterpartyOrder.buyTokenDecimals, + address: counterpartyOrder.buyToken, + symbol: counterpartyOrder.buyTokenSymbol, + }); + + isV4OrderbookV6Spy.mockReturnValue(true); + (solver.orderManager.getCounterpartyOrdersAgainstBaseTokens as Mock).mockReturnValue( + new Map([["0xbasetoken", [counterpartyOrder]]]), + ); + + const mockQuote = { + amountOut: 100n, + price: parseUnits("1", 18), + route: { + pcMap: new Map(), + route: { legs: [] }, + }, + }; + + (solver.state.router.sushi!.tryQuote as Mock).mockResolvedValue(Result.ok(mockQuote)); + routeProcessor4ParamsSpy.mockReturnValue({ rp: "value" } as any); + visualizeRouteSpy.mockReturnValue(["route"]); + + const mockError = Result.err({ + type: TradeType.Raindex, + spanAttributes: { error: "Simulation failed" }, + noneNodeError: "Node error", + }); + + raindexRouterTradeSimulatorWithArgsSpy.mockReturnValue({ + trySimulateTrade: trySimulateTradeSpy.mockResolvedValue(mockError), + } as any); + + const result = await findBestRaindexRouterTrade.call( + solver, + orderDetails, + signer, + fromToken, + inputToEthPrice, + outputToEthPrice, + blockNumber, + ); + + assert(result.isErr()); + expect(result.error.type).toBe(TradeType.Raindex); + expect(result.error.noneNodeError).toBe("Node error"); + expect(extendObjectWithHeader).toHaveBeenCalledWith( + expect.any(Object), + { error: "Simulation failed" }, + "raindexRouter.0", + ); + expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); + expect(solver.state.contracts.getAddressesForTrade).toHaveBeenCalledWith( + orderDetails, + TradeType.Raindex, + ); + expect(solver.orderManager.getCounterpartyOrdersAgainstBaseTokens).toHaveBeenCalledWith( + orderDetails, + ); + expect(solver.state.router.sushi!.tryQuote).toHaveBeenNthCalledWith(1, { + fromToken, + toToken: toToken, + amountIn: expect.any(BigInt), + gasPrice: solver.state.gasPrice, + blockNumber, + skipFetch: true, + sushiRouteType: solver.state.appOptions.route, + }); + expect(routeProcessor4ParamsSpy).toHaveBeenCalledTimes(1); + expect(visualizeRouteSpy).toHaveBeenNthCalledWith(1, fromToken, toToken, expect.any(Array)); + expect(raindexRouterTradeSimulatorWithArgsSpy).toHaveBeenNthCalledWith(1, { + type: TradeType.Raindex, + solver, + orderDetails, + counterpartyOrderDetails: counterpartyOrder, + signer, + maximumInputFixed: expect.any(BigInt), + counterpartyInputToEthPrice: expect.any(BigInt), + counterpartyOutputToEthPrice: expect.any(BigInt), + blockNumber, + quote: expect.anything(), + profit: expect.any(BigInt), + rpParams: { rp: "value" }, + routeVisual: ["route"], + }); + expect(trySimulateTradeSpy).toHaveBeenCalledTimes(1); + }); +}); + +describe("Test estimateProfit function", () => { + let calcCounterpartyInputProfitSpy: any; + let calcCounterpartyOutputToEthPriceSpy: any; + let calcCounterpartyInputToEthPriceSpy: any; + + beforeEach(() => { + calcCounterpartyInputProfitSpy = vi.spyOn(utils, "calcCounterpartyInputProfit"); + calcCounterpartyOutputToEthPriceSpy = vi.spyOn(utils, "calcCounterpartyOutputToEthPrice"); + calcCounterpartyInputToEthPriceSpy = vi.spyOn(utils, "calcCounterpartyInputToEthPrice"); + }); + + it("should return zero profit when order max input exceeds counterparty max output", () => { + const orderDetails = { + takeOrder: { + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("3", 18), // High ratio + }, + }, + } as any; + + const counterparty = { + buyTokenDecimals: 18, + takeOrder: { + quote: { + maxOutput: parseUnits("50", 18), + ratio: parseUnits("1", 18), + }, + }, + } as any; + + const quote = {} as any; + + (calcCounterpartyInputProfitSpy as Mock).mockReturnValueOnce({ + counterpartyMaxOutput: 0n, + counterpartyInputProfit: parseUnits("200", 18), + }); + const result = estimateProfit(orderDetails, counterparty, quote); + + // orderMaxInput: 100e18 * 3e18 / 1e18 = 300e18 + // counterpartyMaxOutput: 40e18 (less than 300e18) + // Cannot trade, returns zero + expect(result.profit).toBe(0n); + expect(result.counterpartyInputToEthPrice).toBe(0n); + expect(result.counterpartyOutputToEthPrice).toBe(0n); + expect(calcCounterpartyInputProfitSpy).toHaveBeenCalledWith(counterparty, quote); + expect(calcCounterpartyInputToEthPriceSpy).not.toHaveBeenCalled(); + expect(calcCounterpartyOutputToEthPriceSpy).not.toHaveBeenCalled(); + }); + + it("should return corrrect profit when order max input is lower counterparty max output", () => { + const orderDetails = { + takeOrder: { + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("3", 18), + }, + }, + } as any; + + const counterparty = { + buyTokenDecimals: 18, + takeOrder: { + quote: { + maxOutput: parseUnits("50", 18), + ratio: parseUnits("1", 18), + }, + }, + } as any; + + const quote = {} as any; + + (calcCounterpartyInputProfitSpy as Mock).mockReturnValueOnce({ + counterpartyMaxOutput: parseUnits("400", 18), + counterpartyInputProfit: parseUnits("100", 18), + }); + (calcCounterpartyInputToEthPriceSpy as Mock).mockReturnValueOnce(parseUnits("1.5", 18)); + (calcCounterpartyOutputToEthPriceSpy as Mock).mockReturnValueOnce(parseUnits("2.5", 18)); + const result = estimateProfit(orderDetails, counterparty, quote, "1", "2"); + + // orderMaxInput: 100e18 * 3e18 / 1e18 = 300e18 + // counterpartyMaxOutput: 400e18 (more than 300e18) + expect(result.profit).toBe(parseUnits("250", 18) + parseUnits("150", 18)); + expect(result.counterpartyInputToEthPrice).toBe(parseUnits("1.5", 18)); + expect(result.counterpartyOutputToEthPrice).toBe(parseUnits("2.5", 18)); + expect(calcCounterpartyInputProfitSpy).toHaveBeenCalledWith(counterparty, quote); + expect(calcCounterpartyInputToEthPriceSpy).toHaveBeenCalledWith(quote, "2"); + expect(calcCounterpartyOutputToEthPriceSpy).toHaveBeenCalledWith( + parseUnits("1.5", 18), + counterparty.takeOrder.quote!.ratio, + "1", + ); + }); +}); diff --git a/src/core/modes/raindex/index.ts b/src/core/modes/raindex/index.ts new file mode 100644 index 00000000..c5058354 --- /dev/null +++ b/src/core/modes/raindex/index.ts @@ -0,0 +1,296 @@ +import assert from "assert"; +import { RainSolver } from "../.."; +import { Pair } from "../../../order"; +import { Token } from "sushi/currency"; +import { Router, RPParams } from "sushi"; +import { Attributes } from "@opentelemetry/api"; +import { RainSolverSigner } from "../../../signer"; +import { ONE18, scaleFrom18 } from "../../../math"; +import { SimulationHaltReason } from "../simulator"; +import { RaindexRouterTradeSimulator } from "./simulation"; +import { SimulationResult, TradeType } from "../../types"; +import { getOptimalSortedList } from "../../../order/pair"; +import { SushiRouter, SushiRouterQuote } from "../../../router"; +import { Result, extendObjectWithHeader } from "../../../common"; +import { calcCounterpartyInputProfit, calcCounterpartyInputToEthPrice, calcCounterpartyOutputToEthPrice } from "./utils"; + +export enum RouteLegType { + RAINDEX, + SUSHI, + BALANCER, + STABULL, +} + +/** + * Tries to find the best raindex routed trade for the given order, + * it will simultaneously try to find the best trade against other + * orders routed through a middle base token swaped through sushi RP + * @param this - RainSolver instance + * @param orderDetails - The details of the order to be processed + * @param signer - The signer to be used for the trade + * @param fromToken - Order's output token + * @param inputToEthPrice - The current price of input token to ETH price + * @param outputToEthPrice - The current price of output token to ETH price + * @param blockNumber - The current block number + */ +export async function findBestRaindexRouterTrade( + this: RainSolver, + orderDetails: Pair, + signer: RainSolverSigner, + fromToken: Token, + inputToEthPrice: string, + outputToEthPrice: string, + blockNumber: bigint, +): Promise { + const spanAttributes: Attributes = {}; + + if (!Pair.isV4OrderbookV6(orderDetails)) { + spanAttributes["error"] = + "Cannot trade as raindex router as order is not deployed on v6 orderbook"; + return Result.err({ + type: TradeType.Raindex, + spanAttributes, + reason: SimulationHaltReason.UndefinedTradeDestinationAddress, + }); + } + + // exit early if required trade addresses are not configured + const addresses = this.state.contracts.getAddressesForTrade(orderDetails, TradeType.Raindex); + if (!addresses) { + spanAttributes["error"] = + "Cannot trade as raindex router arb address is not configured for v6 orderbook trade"; + return Result.err({ + type: TradeType.Raindex, + spanAttributes, + reason: SimulationHaltReason.UndefinedTradeDestinationAddress, + }); + } + + const counterpartyOrders = + this.orderManager.getCounterpartyOrdersAgainstBaseTokens(orderDetails); + const maximumInputFixed = orderDetails.takeOrder.quote!.maxOutput; + const maximumInput = scaleFrom18(maximumInputFixed, orderDetails.sellTokenDecimals); + + // get quotes and swap routes for each token base + const quotes: Map< + string, + { rpParams: RPParams; quote: SushiRouterQuote; routeVisual: string[] } + > = new Map(); + for (const [baseTkn, counterpartyList] of counterpartyOrders) { + if (!counterpartyList.length || !this.state.router.sushi) continue; + + const toToken = new Token({ + chainId: this.state.chainConfig.id, + decimals: counterpartyList[0].buyTokenDecimals, + address: counterpartyList[0].buyToken, + symbol: counterpartyList[0].buyTokenSymbol, + }); + + // get route details from sushi dataFetcher + const quoteResult = await this.state.router.sushi?.tryQuote({ + fromToken, + toToken, + amountIn: maximumInput, + gasPrice: this.state.gasPrice, + blockNumber, + skipFetch: true, + sushiRouteType: this.state.appOptions.route, + }); + + // exit early if no route found + if (quoteResult.isErr()) { + continue; + } + const quote = quoteResult.value; + + const routeVisual: string[] = []; + try { + SushiRouter.visualizeRoute( + fromToken, + toToken, + quoteResult.value.route.route.legs, + ).forEach((v) => { + routeVisual.push(v); + }); + } catch { + /**/ + } + + const rpParams = Router.routeProcessor4Params( + quoteResult.value.route.pcMap, + quoteResult.value.route.route, + fromToken, + toToken, + addresses.destination, // destination is the sushi rp arb address + this.state.chainConfig.routeProcessors["4"], + ); + + quotes.set(baseTkn, { + rpParams, + quote, + routeVisual, + }); + } + + // get optimal trades for each route and estimate profit + // for each optimal trade option and then sort them desc + const optimalTradeOptions: ({ + counterparty: Pair; + rpParams: RPParams; + quote: SushiRouterQuote; + routeVisual: string[]; + } & ReturnType)[] = []; + for (const [baseTkn, quote] of quotes) { + const counterpartyList = counterpartyOrders.get(baseTkn); + if (!counterpartyList) continue; + + const optimals = getOptimalSortedList( + counterpartyList.filter( + (v) => + v.takeOrder.quote && + // not same order + v.takeOrder.id !== orderDetails.takeOrder.id && + // not same owner + v.takeOrder.struct.order.owner.toLowerCase() !== + orderDetails.takeOrder.struct.order.owner.toLowerCase(), + ), + ); + + const listWithProfits = []; + for (const counterparty of optimals) { + listWithProfits.push({ + ...estimateProfit( + orderDetails, + counterparty, + quote.quote, + inputToEthPrice, + outputToEthPrice, + ), + ...quote, + counterparty, + }); + } + // sort desc and pick the best + listWithProfits.sort((a, b) => { + if (a.profit < b.profit) return 1; + else if (a.profit > b.profit) return -1; + else return 0; + }); + optimalTradeOptions.push(...listWithProfits.slice(0, 1)); + } + + // sort desc based on profitability + optimalTradeOptions.sort((a, b) => { + if (a.profit < b.profit) return 1; + else if (a.profit > b.profit) return -1; + else return 0; + }); + + // simulate top picks + const promises = optimalTradeOptions.map((args) => { + const { + quote, + profit, + rpParams, + routeVisual, + counterparty: counterpartyOrderDetails, + counterpartyInputToEthPrice, + counterpartyOutputToEthPrice, + } = args; + if (!Pair.isV4OrderbookV6(counterpartyOrderDetails)) { + spanAttributes["error"] = + "Cannot trade as raindex router as counterparty order is not deployed on v6 orderbook"; + return Result.err({ + type: TradeType.Raindex, + spanAttributes, + reason: SimulationHaltReason.UndefinedTradeDestinationAddress, + }) as SimulationResult; + } + return RaindexRouterTradeSimulator.withArgs({ + type: TradeType.Raindex, + solver: this, + orderDetails, + counterpartyOrderDetails, + signer, + maximumInputFixed, + counterpartyInputToEthPrice, + counterpartyOutputToEthPrice, + blockNumber, + quote, + profit, + rpParams, + routeVisual, + }).trySimulateTrade(); + }); + + const results = await Promise.all(promises); + if (results.some((res) => res.isOk())) { + // pick the one with highest estimated profit + return results.sort((a, b) => { + if (a.isErr() && b.isErr()) return 0; + if (a.isErr()) return 1; + if (b.isErr()) return -1; + return a.value.estimatedProfit < b.value.estimatedProfit + ? 1 + : a.value.estimatedProfit > b.value.estimatedProfit + ? -1 + : 0; + })[0]; + } else { + const allNoneNodeErrors: (string | undefined)[] = []; + for (let i = 0; i < results.length; i++) { + const res = results[i]; + assert(res.isErr()); // for type check as we know all results are errors + extendObjectWithHeader(spanAttributes, res.error.spanAttributes, "raindexRouter." + i); + allNoneNodeErrors.push(res.error.noneNodeError); + } + if (!results.length) { + spanAttributes["error"] = "no counterparties found for raindex router trade"; + } + return Result.err({ + type: TradeType.Raindex, + spanAttributes, + noneNodeError: allNoneNodeErrors[0], + }); + } +} + +export function estimateProfit( + orderDetails: Pair, + counterparty: Pair, + quote: SushiRouterQuote, + inputToEthPrice?: string, + outputToEthPrice?: string, +): { + profit: bigint; + counterpartyInputToEthPrice: bigint; + counterpartyOutputToEthPrice: bigint; +} { + const { counterpartyMaxOutput, counterpartyInputProfit } = calcCounterpartyInputProfit(counterparty, quote) + const orderMaxInput = + (orderDetails.takeOrder.quote!.maxOutput * orderDetails.takeOrder.quote!.ratio) / ONE18; + // cant trade, so 0 profit + if (orderMaxInput > counterpartyMaxOutput) { + return { + profit: 0n, + counterpartyInputToEthPrice: 0n, + counterpartyOutputToEthPrice: 0n, + }; + } + const counterpartyOutputProfit = counterpartyMaxOutput - orderMaxInput; + + const counterpartyInputToEthPrice = calcCounterpartyInputToEthPrice(quote, outputToEthPrice); + const counterpartyOutputToEthPrice = calcCounterpartyOutputToEthPrice( + counterpartyInputToEthPrice, + counterparty.takeOrder.quote!.ratio, + inputToEthPrice, + ); + + const inputProfitEth = (counterpartyInputProfit * counterpartyInputToEthPrice) / ONE18; + const outputProfitEth = (counterpartyOutputProfit * counterpartyOutputToEthPrice) / ONE18; + return { + profit: inputProfitEth + outputProfitEth, + counterpartyInputToEthPrice, + counterpartyOutputToEthPrice, + }; +} diff --git a/src/core/modes/raindex/simulation.test.ts b/src/core/modes/raindex/simulation.test.ts new file mode 100644 index 00000000..13bcb814 --- /dev/null +++ b/src/core/modes/raindex/simulation.test.ts @@ -0,0 +1,454 @@ +import { RainSolver } from "../.."; +import { TradeType } from "../../types"; +import { Order, PairV4 } from "../../../order"; +import { RainSolverSigner } from "../../../signer"; +import { SimulationHaltReason } from "../simulator"; +import { ABI, Dispair, maxFloat, minFloat, Result } from "../../../common"; +import { describe, it, expect, vi, beforeEach, Mock, assert } from "vitest"; +import { encodeAbiParameters, encodeFunctionData, formatUnits, parseUnits } from "viem"; +import { + RaindexRouterTradeSimulator, + SimulateRaindexRouterTradeArgs, + RaindexRouterTradePreparedParams, +} from "./simulation"; +import { + EnsureBountyTaskType, + EnsureBountyTaskError, + EnsureBountyTaskErrorType, + getEnsureBountyTaskBytecode, +} from "../../../task"; + +vi.mock("../../../task", async (importOriginal) => ({ + ...(await importOriginal()), + getEnsureBountyTaskBytecode: vi.fn(), +})); + +vi.mock("viem", async (importOriginal) => ({ + ...(await importOriginal()), + encodeFunctionData: vi.fn(), + encodeAbiParameters: vi.fn().mockReturnValue("0xexchangeData"), +})); + +function makeOrderDetails(id = "0xhash"): PairV4 { + return { + orderbook: "0xorderbook", + sellTokenDecimals: 18, + buyTokenDecimals: 18, + buyTokenSymbol: "BUY", + sellTokenSymbol: "SELL", + takeOrder: { + id, + struct: { + order: { type: Order.Type.V4, owner: "0xowner" }, + orderbook: { id: "0xorderbook" }, + }, + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("1", 18), + }, + }, + } as any; +} + +describe("Test RaindexRouterTradeSimulator", () => { + let mockSolver: RainSolver; + let mockSigner: RainSolverSigner; + let tradeArgs: SimulateRaindexRouterTradeArgs; + let simulator: RaindexRouterTradeSimulator; + let preparedParams: RaindexRouterTradePreparedParams; + let dispair: Dispair; + let destination: `0x${string}`; + + beforeEach(() => { + vi.clearAllMocks(); + dispair = { + deployer: "0xdeployer", + interpreter: "0xinterpreter", + store: "0xstore", + }; + destination = "0xdestination"; + mockSolver = { + state: { + gasPrice: 1000000000000000000n, + chainConfig: { + id: 1, + }, + contracts: { + getAddressesForTrade: vi.fn().mockReturnValue({ + dispair, + destination, + }), + }, + client: {}, + }, + appOptions: { + gasCoveragePercentage: "100", + }, + } as any as RainSolver; + mockSigner = { account: { address: "0xsigner" } } as any as RainSolverSigner; + tradeArgs = { + type: TradeType.Raindex, + solver: mockSolver, + orderDetails: makeOrderDetails("0xhash1"), + counterpartyOrderDetails: makeOrderDetails("0xhash2"), + signer: mockSigner, + maximumInputFixed: parseUnits("50", 18), + blockNumber: 123n, + counterpartyInputToEthPrice: parseUnits("2", 18), + counterpartyOutputToEthPrice: parseUnits("3", 18), + quote: { + amountOut: 100n, + price: parseUnits("1.5", 18), + route: { + pcMap: new Map(), + route: { legs: [] }, + }, + } as any, + profit: parseUnits("10", 18), + rpParams: { + routeCode: "0xroutecode", + } as any, + routeVisual: ["TokenA", "TokenB", "TokenC"], + }; + preparedParams = { + type: TradeType.Raindex, + rawtx: { + to: destination, + gasPrice: mockSolver.state.gasPrice, + }, + takeOrders: [ + { + minimumIO: minFloat(18), + maximumIO: maxFloat(18), + maximumIORatio: maxFloat(18), + orders: [tradeArgs.orderDetails.takeOrder.struct], + data: "0x", + IOIsInput: false, + }, + { + minimumIO: minFloat(18), + maximumIO: maxFloat(18), + maximumIORatio: maxFloat(18), + orders: [tradeArgs.counterpartyOrderDetails.takeOrder.struct], + data: "0x", + IOIsInput: false, + }, + ], + exchangeData: "0xexchangedata", + minimumExpected: 0n, + }; + simulator = new RaindexRouterTradeSimulator(tradeArgs); + }); + + describe("Test withArgs static method", () => { + it("should create instance with provided args", () => { + const instance = RaindexRouterTradeSimulator.withArgs(tradeArgs); + expect(instance).toBeInstanceOf(RaindexRouterTradeSimulator); + expect(instance.tradeArgs).toBe(tradeArgs); + }); + }); + + describe("Test prepareTradeParams method", () => { + it("should set span attributes correctly", async () => { + const result = await simulator.prepareTradeParams(); + assert(result.isOk()); + + expect(simulator.spanAttributes["against"]).toBe("0xhash2"); + expect(simulator.spanAttributes["counterpartyInputToEthPrice"]).toBe( + formatUnits(tradeArgs.counterpartyInputToEthPrice, 18), + ); + expect(simulator.spanAttributes["counterpartyOutputToEthPrice"]).toBe( + formatUnits(tradeArgs.counterpartyOutputToEthPrice, 18), + ); + expect(simulator.spanAttributes["route"]).toEqual(tradeArgs.routeVisual); + expect(simulator.spanAttributes["routeQuote"]).toBe( + formatUnits(tradeArgs.quote.price, 18), + ); + expect(simulator.spanAttributes["oppBlockNumber"]).toBe(Number(tradeArgs.blockNumber)); + expect(simulator.spanAttributes["counterpartyPair"]).toBe("BUY/SELL"); + expect(simulator.spanAttributes["counterpartyOrderQuote"]).toBe( + JSON.stringify({ + maxOutput: formatUnits( + tradeArgs.counterpartyOrderDetails.takeOrder.quote!.maxOutput, + 18, + ), + ratio: formatUnits( + tradeArgs.counterpartyOrderDetails.takeOrder.quote!.ratio, + 18, + ), + }), + ); + expect(simulator.spanAttributes["maxInput"]).toBe(parseUnits("50", 18).toString()); + }); + + it("should return error when trade addresses are not configured", async () => { + (mockSolver.state.contracts.getAddressesForTrade as Mock).mockReturnValueOnce( + undefined, + ); + + const result = await simulator.prepareTradeParams(); + assert(result.isErr()); + expect(result.error.type).toBe(TradeType.Raindex); + expect(result.error.reason).toBe(SimulationHaltReason.UndefinedTradeDestinationAddress); + expect(result.error.spanAttributes["error"]).toContain( + "Cannot trade as generic arb address is not configured", + ); + expect(result.error.spanAttributes["duration"]).toBeGreaterThan(0); + expect(mockSolver.state.contracts.getAddressesForTrade).toHaveBeenCalledTimes(1); + expect(mockSolver.state.contracts.getAddressesForTrade).toHaveBeenCalledWith( + tradeArgs.orderDetails, + TradeType.Raindex, + ); + }); + + it("should return success with correct parameters", async () => { + const result = await simulator.prepareTradeParams(); + assert(result.isOk()); + + expect(result.value.type).toBe(TradeType.Raindex); + expect(result.value.rawtx).toEqual({ + to: destination, + gasPrice: mockSolver.state.gasPrice, + }); + expect(result.value.minimumExpected).toBe(0n); + expect(result.value.takeOrders).toHaveLength(2); + expect(result.value.takeOrders[0].orders).toEqual([ + tradeArgs.orderDetails.takeOrder.struct, + ]); + expect(result.value.takeOrders[1].orders).toEqual([ + tradeArgs.counterpartyOrderDetails.takeOrder.struct, + ]); + expect(result.value.exchangeData).toBe("0xexchangeData"); + expect(mockSolver.state.contracts.getAddressesForTrade).toHaveBeenCalledTimes(1); + expect(mockSolver.state.contracts.getAddressesForTrade).toHaveBeenCalledWith( + tradeArgs.orderDetails, + TradeType.Raindex, + ); + }); + + it("should encode exchange data with correct route leg", async () => { + const result = await simulator.prepareTradeParams(); + assert(result.isOk()); + + // Exchange data should be encoded with single route leg + expect(result.value.exchangeData).toBe("0xexchangeData"); + expect(encodeAbiParameters).toHaveBeenCalledWith( + ABI.Orderbook.V6.Primary.RouteLeg, + expect.any(Array), + ); + }); + + it("should create takeOrders with correct min/max float values", async () => { + const result = await simulator.prepareTradeParams(); + assert(result.isOk()); + + const takeOrders = result.value.takeOrders; + expect(takeOrders).toHaveLength(2); + + // First order (main order) + expect(takeOrders[0].IOIsInput).toBe(false); + expect(takeOrders[0].data).toBe("0x"); + + // Second order (counterparty) + expect(takeOrders[1].IOIsInput).toBe(false); + expect(takeOrders[1].data).toBe("0x"); + }); + }); + + describe("Test setTransactionData method", () => { + it("should return error if getEnsureBountyTaskBytecode fails with parse error", async () => { + const error = new EnsureBountyTaskError( + "parse error", + EnsureBountyTaskErrorType.ParseError, + ); + (getEnsureBountyTaskBytecode as Mock).mockResolvedValueOnce(Result.err(error)); + const getCalldataSpy = vi.spyOn(simulator, "getCalldata"); + + const result = await simulator.setTransactionData(preparedParams); + assert(result.isErr()); + expect(result.error.type).toBe(TradeType.Raindex); + expect(result.error.reason).toBe(SimulationHaltReason.FailedToGetTaskBytecode); + expect(result.error.spanAttributes["error"]).toContain("parse error"); + expect(result.error.spanAttributes["duration"]).toBeGreaterThan(0); + expect(result.error.spanAttributes["isNodeError"]).toBe(true); + expect(getEnsureBountyTaskBytecode).toHaveBeenCalledTimes(1); + expect(getEnsureBountyTaskBytecode).toHaveBeenCalledWith( + { + type: EnsureBountyTaskType.External, + inputToEthPrice: tradeArgs.counterpartyInputToEthPrice, + outputToEthPrice: tradeArgs.counterpartyOutputToEthPrice, + minimumExpected: preparedParams.minimumExpected, + sender: tradeArgs.signer.account.address, + }, + tradeArgs.solver.state.client, + dispair, + ); + expect(mockSolver.state.contracts.getAddressesForTrade).toHaveBeenCalledTimes(1); + expect(mockSolver.state.contracts.getAddressesForTrade).toHaveBeenCalledWith( + tradeArgs.orderDetails, + TradeType.Raindex, + ); + expect(getCalldataSpy).not.toHaveBeenCalled(); + + getCalldataSpy.mockRestore(); + }); + + it("should return error if getEnsureBountyTaskBytecode fails with compose error", async () => { + const error = new EnsureBountyTaskError( + "compose error", + EnsureBountyTaskErrorType.ComposeError, + ); + (getEnsureBountyTaskBytecode as Mock).mockResolvedValueOnce(Result.err(error)); + + const result = await simulator.setTransactionData(preparedParams); + assert(result.isErr()); + expect(result.error.type).toBe(TradeType.Raindex); + expect(result.error.reason).toBe(SimulationHaltReason.FailedToGetTaskBytecode); + expect(result.error.spanAttributes["isNodeError"]).toBe(false); + expect(result.error.spanAttributes["duration"]).toBeGreaterThan(0); + }); + + it("should return success with bytecode when gasCoveragePercentage is not zero", async () => { + (getEnsureBountyTaskBytecode as Mock).mockResolvedValueOnce(Result.ok("0xtaskdata")); + const getCalldataSpy = vi.spyOn(simulator, "getCalldata"); + getCalldataSpy.mockReturnValue("0xencodedCalldata"); + + const result = await simulator.setTransactionData(preparedParams); + assert(result.isOk()); + expect(preparedParams.rawtx.data).toBe("0xencodedCalldata"); + expect(getEnsureBountyTaskBytecode).toHaveBeenCalledTimes(1); + expect(getEnsureBountyTaskBytecode).toHaveBeenCalledWith( + { + type: EnsureBountyTaskType.External, + inputToEthPrice: tradeArgs.counterpartyInputToEthPrice, + outputToEthPrice: tradeArgs.counterpartyOutputToEthPrice, + minimumExpected: preparedParams.minimumExpected, + sender: tradeArgs.signer.account.address, + }, + tradeArgs.solver.state.client, + dispair, + ); + expect(getCalldataSpy).toHaveBeenCalledTimes(1); + expect(getCalldataSpy).toHaveBeenCalledWith( + preparedParams.takeOrders, + preparedParams.exchangeData, + { + evaluable: { + interpreter: dispair.interpreter as `0x${string}`, + store: dispair.store as `0x${string}`, + bytecode: "0xtaskdata", + }, + signedContext: [], + }, + ); + + getCalldataSpy.mockRestore(); + }); + + it("should use empty bytecode when gasCoveragePercentage is zero", async () => { + (getEnsureBountyTaskBytecode as Mock).mockResolvedValueOnce(Result.ok("0xtaskdata")); + tradeArgs.solver.appOptions.gasCoveragePercentage = "0"; + const getCalldataSpy = vi.spyOn(simulator, "getCalldata"); + getCalldataSpy.mockReturnValue("0xencodedCalldata"); + + const result = await simulator.setTransactionData(preparedParams); + assert(result.isOk()); + expect(getCalldataSpy).toHaveBeenCalledWith( + preparedParams.takeOrders, + preparedParams.exchangeData, + { + evaluable: { + interpreter: dispair.interpreter as `0x${string}`, + store: dispair.store as `0x${string}`, + bytecode: "0x", + }, + signedContext: [], + }, + ); + + getCalldataSpy.mockRestore(); + }); + }); + + describe("Test estimateProfit method", () => { + it("should return the profit from tradeArgs", () => { + const result = simulator.estimateProfit(); + expect(result).toBe(tradeArgs.profit); + }); + }); + + describe("Test getCalldata method", () => { + it("should encode arb4 function call with correct parameters", () => { + (encodeFunctionData as Mock).mockReturnValueOnce("0xcalldata"); + const takeOrders = [{ key: "order1" }, { key: "order2" }] as any; + const exchangeData = "0xexchangedata" as `0x${string}`; + const task = { task: "task-value" } as any; + + const result = simulator.getCalldata(takeOrders, exchangeData, task); + + expect(result).toBe("0xcalldata"); + expect(encodeFunctionData).toHaveBeenCalledTimes(1); + expect(encodeFunctionData).toHaveBeenCalledWith({ + abi: ABI.Orderbook.V6.Primary.Arb, + functionName: "arb4", + args: [tradeArgs.orderDetails.orderbook, takeOrders, exchangeData, task], + }); + }); + + it("should use correct orderbook address", () => { + (encodeFunctionData as Mock).mockReturnValueOnce("0xcalldata"); + tradeArgs.orderDetails.orderbook = "0xcustomorderbook"; + simulator.tradeArgs = tradeArgs; + const takeOrders = [] as any; + const exchangeData = "0x" as `0x${string}`; + const task = {} as any; + + simulator.getCalldata(takeOrders, exchangeData, task); + + expect(encodeFunctionData).toHaveBeenCalledWith({ + abi: ABI.Orderbook.V6.Primary.Arb, + functionName: "arb4", + args: ["0xcustomorderbook", takeOrders, exchangeData, task], + }); + }); + + it("should handle empty takeOrders array", () => { + (encodeFunctionData as Mock).mockReturnValueOnce("0xcalldata"); + const takeOrders = [] as any; + const exchangeData = "0xexchangedata" as `0x${string}`; + const task = { task: "task-value" } as any; + + const result = simulator.getCalldata(takeOrders, exchangeData, task); + + expect(result).toBe("0xcalldata"); + expect(encodeFunctionData).toHaveBeenCalledWith({ + abi: ABI.Orderbook.V6.Primary.Arb, + functionName: "arb4", + args: [tradeArgs.orderDetails.orderbook, takeOrders, exchangeData, task], + }); + }); + + it("should handle complex task structure", () => { + (encodeFunctionData as Mock).mockReturnValueOnce("0xcalldata"); + const takeOrders = [{ key: "order" }] as any; + const exchangeData = "0xdata" as `0x${string}`; + const task = { + evaluable: { + interpreter: "0xinterpreter", + store: "0xstore", + bytecode: "0xbytecode", + }, + signedContext: [{ signer: "0xsigner", context: [] }], + } as any; + + const result = simulator.getCalldata(takeOrders, exchangeData, task); + + expect(result).toBe("0xcalldata"); + expect(encodeFunctionData).toHaveBeenCalledWith({ + abi: ABI.Orderbook.V6.Primary.Arb, + functionName: "arb4", + args: [tradeArgs.orderDetails.orderbook, takeOrders, exchangeData, task], + }); + }); + }); +}); diff --git a/src/core/modes/raindex/simulation.ts b/src/core/modes/raindex/simulation.ts new file mode 100644 index 00000000..d0dc31da --- /dev/null +++ b/src/core/modes/raindex/simulation.ts @@ -0,0 +1,250 @@ +import { RPParams } from "sushi"; +import { RouteLegType } from "."; +import { RainSolver } from "../.."; +import { scaleFrom18 } from "../../../math"; +import { errorSnapshot } from "../../../error"; +import { RainSolverSigner } from "../../../signer"; +import { SushiRouterQuote } from "../../../router"; +import { PairV4, TakeOrdersConfigTypeV5 } from "../../../order"; +import { TradeType, FailedSimulation, TaskType } from "../../types"; +import { SimulationHaltReason, TradeSimulatorBase } from "../simulator"; +import { encodeAbiParameters, encodeFunctionData, formatUnits } from "viem"; +import { Result, ABI, RawTransaction, maxFloat, minFloat } from "../../../common"; +import { + EnsureBountyTaskType, + EnsureBountyTaskErrorType, + getEnsureBountyTaskBytecode, +} from "../../../task"; + +/** Arguments for simulating inter-orderbook trade */ +export type SimulateRaindexRouterTradeArgs = { + /** The type of trade */ + type: TradeType.Raindex; + /** The RainSolver instance used for simulation */ + solver: RainSolver; + /** The bundled order details including tokens, decimals, and take orders */ + orderDetails: PairV4; + /** The counterparty order to trade against */ + counterpartyOrderDetails: PairV4; + /** The RainSolverSigner instance used for signing transactions */ + signer: RainSolverSigner; + /** The maximum input amount (in 18 decimals) */ + maximumInputFixed: bigint; + /** The current block number for context */ + blockNumber: bigint; + /** The counterparty input token to ETH price (in 18 decimals) */ + counterpartyInputToEthPrice: bigint; + /** The counterparty output token to ETH price (in 18 decimals) */ + counterpartyOutputToEthPrice: bigint; + /** Sushi RP quote for route leg swap */ + quote: SushiRouterQuote; + /** Estimated profit */ + profit: bigint; + /** Prebuilt Sushi RP params that include the routecode needed for the intermediate swap as exchange data */ + rpParams: RPParams; + /** Sushi RP route visualization */ + routeVisual: string[]; +}; + +/** Arguments for preparing router trade type parameters required for simulation and building tx object */ +export type RaindexRouterTradePreparedParams = { + type: TradeType.Raindex; + rawtx: RawTransaction; + takeOrders: TakeOrdersConfigTypeV5[]; + minimumExpected: bigint; + exchangeData: `0x${string}`; + price?: bigint; +}; + +/** + * Simulates a trade between 2 orders wwith different IO through a external route + * + * The `RaindexRouterTradeSimulator` class extends {@link TradeSimulatorBase} and is responsible for: + * - Simulating trades between two order with external route such as A/B (order) -> B/C (external) -> C/A (order) + * - Preparing and encoding the transaction data required to execute the trade on-chain. + * - Estimating the profit from the simulated trade based on input/output prices and order quotes. + * - Managing simulation state, error handling, and span attributes for tracing and observability. + */ +export class RaindexRouterTradeSimulator extends TradeSimulatorBase { + declare tradeArgs: SimulateRaindexRouterTradeArgs; + + static withArgs(tradeArgs: SimulateRaindexRouterTradeArgs): RaindexRouterTradeSimulator { + return new RaindexRouterTradeSimulator(tradeArgs); + } + + async prepareTradeParams(): Promise< + Result + > { + const { + orderDetails, + counterpartyOrderDetails, + maximumInputFixed, + blockNumber, + // type, + // solver, + // signer, + counterpartyInputToEthPrice, + counterpartyOutputToEthPrice, + quote, + // profit, + rpParams, + routeVisual, + } = this.tradeArgs; + const gasPrice = this.tradeArgs.solver.state.gasPrice; + + this.spanAttributes["against"] = counterpartyOrderDetails.takeOrder.id; + this.spanAttributes["counterpartyInputToEthPrice"] = formatUnits( + counterpartyInputToEthPrice, + 18, + ); + this.spanAttributes["counterpartyOutputToEthPrice"] = formatUnits( + counterpartyOutputToEthPrice, + 18, + ); + this.spanAttributes["route"] = routeVisual; + this.spanAttributes["routeQuote"] = formatUnits(quote.price, 18); + this.spanAttributes["oppBlockNumber"] = Number(blockNumber); + this.spanAttributes["counterpartyPair"] = + `${counterpartyOrderDetails.buyTokenSymbol}/${counterpartyOrderDetails.sellTokenSymbol}`; + this.spanAttributes["counterpartyOrderQuote"] = JSON.stringify({ + maxOutput: formatUnits(counterpartyOrderDetails.takeOrder.quote!.maxOutput, 18), + ratio: formatUnits(counterpartyOrderDetails.takeOrder.quote!.ratio, 18), + }); + + const maximumInput = scaleFrom18(maximumInputFixed, orderDetails.sellTokenDecimals); + this.spanAttributes["maxInput"] = maximumInput.toString(); + + // exit early if required trade addresses are not configured + const addresses = this.tradeArgs.solver.state.contracts.getAddressesForTrade( + orderDetails, + TradeType.Raindex, + ); + if (!addresses) { + this.spanAttributes["error"] = + `Cannot trade as generic arb address is not configured for order ${orderDetails.takeOrder.struct.order.type} trade`; + this.spanAttributes["duration"] = performance.now() - this.startTime; + return Result.err({ + type: TradeType.Raindex, + spanAttributes: this.spanAttributes, + reason: SimulationHaltReason.UndefinedTradeDestinationAddress, + }); + } + + // Single RouteLeg + const legs = [ + { + routeLegType: RouteLegType.SUSHI, + destination: addresses.destination as `0x${string}`, + data: rpParams.routeCode, + }, + ]; + const exchangeData = encodeAbiParameters(ABI.Orderbook.V6.Primary.RouteLeg, [legs]); + const takeOrders: TakeOrdersConfigTypeV5[] = [ + { + minimumIO: minFloat(this.tradeArgs.orderDetails.sellTokenDecimals), + maximumIO: maxFloat(this.tradeArgs.orderDetails.sellTokenDecimals), + maximumIORatio: maxFloat(18), + orders: [this.tradeArgs.orderDetails.takeOrder.struct], + data: "0x", + IOIsInput: false, + }, + { + minimumIO: minFloat(this.tradeArgs.orderDetails.buyTokenDecimals), + maximumIO: maxFloat(this.tradeArgs.orderDetails.buyTokenDecimals), + maximumIORatio: maxFloat(18), + orders: [this.tradeArgs.counterpartyOrderDetails.takeOrder.struct], + data: "0x", + IOIsInput: false, + }, + ]; + + const rawtx: RawTransaction = { + to: addresses.destination, + gasPrice, + }; + return Result.ok({ + type: TradeType.Raindex, + rawtx, + takeOrders, + exchangeData, + minimumExpected: 0n, + }); + } + + async setTransactionData( + params: RaindexRouterTradePreparedParams, + ): Promise> { + // we can be sure the addresses exist here since we checked in prepareTradeParams + const addresses = this.tradeArgs.solver.state.contracts.getAddressesForTrade( + this.tradeArgs.orderDetails, + params.type, + )!; + + // try to get task bytecode for ensure bounty task + const taskBytecodeResult = await getEnsureBountyTaskBytecode( + { + type: EnsureBountyTaskType.External, + inputToEthPrice: this.tradeArgs.counterpartyInputToEthPrice, + outputToEthPrice: this.tradeArgs.counterpartyOutputToEthPrice, + minimumExpected: params.minimumExpected, + sender: this.tradeArgs.signer.account.address, + }, + this.tradeArgs.solver.state.client, + addresses.dispair, + ); + if (taskBytecodeResult.isErr()) { + const errMsg = await errorSnapshot("", taskBytecodeResult.error); + this.spanAttributes["isNodeError"] = + taskBytecodeResult.error.type === EnsureBountyTaskErrorType.ParseError; + this.spanAttributes["error"] = errMsg; + const result = { + type: TradeType.Raindex, + spanAttributes: this.spanAttributes, + reason: SimulationHaltReason.FailedToGetTaskBytecode, + }; + this.spanAttributes["duration"] = performance.now() - this.startTime; + return Result.err(result); + } + const task = { + evaluable: { + interpreter: addresses.dispair.interpreter as `0x${string}`, + store: addresses.dispair.store as `0x${string}`, + bytecode: + this.tradeArgs.solver.appOptions.gasCoveragePercentage === "0" + ? "0x" + : taskBytecodeResult.value, + }, + signedContext: [], + }; + + params.rawtx.data = this.getCalldata(params.takeOrders, params.exchangeData, task); + return Result.ok(void 0); + } + + estimateProfit(): bigint { + return this.tradeArgs.profit; + } + + /** + * Builds the calldata + * @param takeOrdersConfigStruct - The take orders config structs + * @param exchangeData + * @param task - The ensure bounty task object + */ + getCalldata( + takeOrders: TakeOrdersConfigTypeV5[], + exchangeData: `0x${string}`, + task: TaskType, + ): `0x${string}` { + return encodeFunctionData({ + abi: ABI.Orderbook.V6.Primary.Arb, + functionName: "arb4", + args: [ + this.tradeArgs.orderDetails.orderbook as `0x${string}`, + takeOrders, + exchangeData, + task, + ], + }); + } +} diff --git a/src/core/modes/raindex/utils.test.ts b/src/core/modes/raindex/utils.test.ts new file mode 100644 index 00000000..2bc58b66 --- /dev/null +++ b/src/core/modes/raindex/utils.test.ts @@ -0,0 +1,231 @@ +import { parseUnits } from "viem"; +import { describe, it, expect } from "vitest"; +import { + calcCounterpartyInputProfit, + calcCounterpartyInputToEthPrice, + calcCounterpartyOutputToEthPrice, +} from "./utils"; + +describe("Test calcCounterpartyInputProfit function", () => { + it("should return zero input profit when sushi output equals counterparty max input", () => { + const counterparty = { + buyTokenDecimals: 18, + takeOrder: { + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("2", 18), + }, + }, + } as any; + + const quote = { + amountOut: parseUnits("200", 18), + price: parseUnits("1", 18), + } as any; + + const result = calcCounterpartyInputProfit(counterparty, quote); + + // maxSushiOutput: 200e18 + // counterpartyMaxInputFixed: 100e18 * 2e18 / 1e18 = 200e18 + // counterpartyInputProfit: 0 (equal) + // counterpartyMaxOutput: 100e18 (full capacity) + expect(result.counterpartyInputProfit).toBe(0n); + expect(result.counterpartyMaxOutput).toBe(parseUnits("100", 18)); + }); + + it("should calculate positive input profit when sushi output exceeds counterparty max input", () => { + const counterparty = { + buyTokenDecimals: 18, + takeOrder: { + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("2", 18), + }, + }, + } as any; + + const quote = { + amountOut: parseUnits("250", 18), + price: parseUnits("1", 18), + } as any; + + const result = calcCounterpartyInputProfit(counterparty, quote); + + // maxSushiOutput: 250e18 + // counterpartyMaxInputFixed: 100e18 * 2e18 / 1e18 = 200e18 + // counterpartyInputProfit: 250e18 - 200e18 = 50e18 + // counterpartyMaxOutput: 100e18 (at full capacity) + expect(result.counterpartyInputProfit).toBe(parseUnits("50", 18)); + expect(result.counterpartyMaxOutput).toBe(parseUnits("100", 18)); + }); + + it("should return zero input profit when sushi output is less than counterparty max input", () => { + const counterparty = { + buyTokenDecimals: 18, + takeOrder: { + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("2", 18), + }, + }, + } as any; + + const quote = { + amountOut: parseUnits("150", 18), + price: parseUnits("1", 18), + } as any; + + const result = calcCounterpartyInputProfit(counterparty, quote); + + // maxSushiOutput: 150e18 + // counterpartyMaxInputFixed: 100e18 * 2e18 / 1e18 = 200e18 + // counterpartyInputProfit: 0 (less than max) + // counterpatryMaxInput: 150e18 + // counterpartyMaxOutput: 150e18 * 1e18 / 2e18 = 75e18 + expect(result.counterpartyInputProfit).toBe(0n); + expect(result.counterpartyMaxOutput).toBe(parseUnits("75", 18)); + }); + + it("should handle counterparty ratio of zero", () => { + const counterparty = { + buyTokenDecimals: 18, + takeOrder: { + quote: { + maxOutput: parseUnits("100", 18), + ratio: 0n, + }, + }, + } as any; + + const quote = { + amountOut: parseUnits("50", 18), + price: parseUnits("1", 18), + } as any; + + const result = calcCounterpartyInputProfit(counterparty, quote); + + // maxSushiOutput: 50e18 + // counterpartyMaxInputFixed: 100e18 * 0 / 1e18 = 0 + // counterpartyInputProfit: 50e18 - 0 = 50e18 + // ratio is 0, so counterpartyMaxOutput uses original maxOutput + expect(result.counterpartyInputProfit).toBe(parseUnits("50", 18)); + expect(result.counterpartyMaxOutput).toBe(parseUnits("100", 18)); + }); + + it("should calculate counterparty max output when not at full capacity", () => { + const counterparty = { + buyTokenDecimals: 18, + takeOrder: { + quote: { + maxOutput: parseUnits("200", 18), + ratio: parseUnits("2", 18), + }, + }, + } as any; + + const quote = { + amountOut: parseUnits("300", 18), + price: parseUnits("1", 18), + } as any; + + const result = calcCounterpartyInputProfit(counterparty, quote); + + // maxSushiOutput: 300e18 + // counterpartyMaxInputFixed: 200e18 * 2e18 / 1e18 = 400e18 + // counterpartyInputProfit: 0 (300 < 400) + // counterpatryMaxInput: 300e18 + // counterpartyMaxOutput: 300e18 * 1e18 / 2e18 = 150e18 + expect(result.counterpartyInputProfit).toBe(0n); + expect(result.counterpartyMaxOutput).toBe(parseUnits("150", 18)); + }); +}); + +describe("Test calcCounterpartyOutputToEthPrice function", () => { + it("should use provided counterpartyOutputToEthPrice when available", () => { + const counterpartyInputToEthPrice = parseUnits("2", 18); + const ratio = parseUnits("1.5", 18); + const counterpartyOutputToEthPrice = "3.5"; + + const result = calcCounterpartyOutputToEthPrice( + counterpartyInputToEthPrice, + ratio, + counterpartyOutputToEthPrice, + ); + + // Should return the provided price + expect(result).toBe(parseUnits("3.5", 18)); + }); + + it("should calculate from ratio when counterpartyOutputToEthPrice is not provided", () => { + const counterpartyInputToEthPrice = parseUnits("2", 18); + const ratio = parseUnits("1.5", 18); + + const result = calcCounterpartyOutputToEthPrice(counterpartyInputToEthPrice, ratio); + + // Should calculate: (2e18 * 1.5e18) / 1e18 = 3e18 + expect(result).toBe(parseUnits("3", 18)); + }); +}); + +describe("Test calcCounterpartyInputToEthPrice function", () => { + it("should return zero when outputToEthPrice is not provided", () => { + const quote = { + amountOut: 100n, + price: parseUnits("2", 18), + } as any; + + const result = calcCounterpartyInputToEthPrice(quote); + + expect(result).toBe(0n); + }); + + it("should return zero when outputToEthPrice is undefined", () => { + const quote = { + amountOut: 100n, + price: parseUnits("2", 18), + } as any; + + const result = calcCounterpartyInputToEthPrice(quote, undefined); + + expect(result).toBe(0n); + }); + + it("should calculate input to ETH price with 1:1 quote price", () => { + const quote = { + amountOut: 100n, + price: parseUnits("1", 18), + } as any; + const outputToEthPrice = "2.0"; + + const result = calcCounterpartyInputToEthPrice(quote, outputToEthPrice); + + // (2e18 * 1e18) / 1e18 = 2e18 + expect(result).toBe(parseUnits("2", 18)); + }); + + it("should calculate input to ETH price with high quote price", () => { + const quote = { + amountOut: 100n, + price: parseUnits("2", 18), + } as any; + const outputToEthPrice = "4.0"; + + const result = calcCounterpartyInputToEthPrice(quote, outputToEthPrice); + + // (4e18 * 1e18) / 2e18 = 2e18 + expect(result).toBe(parseUnits("2", 18)); + }); + + it("should calculate input to ETH price with low quote price", () => { + const quote = { + amountOut: 100n, + price: parseUnits("0.5", 18), + } as any; + const outputToEthPrice = "1.0"; + + const result = calcCounterpartyInputToEthPrice(quote, outputToEthPrice); + + // (1e18 * 1e18) / 0.5e18 = 2e18 + expect(result).toBe(parseUnits("2", 18)); + }); +}); diff --git a/src/core/modes/raindex/utils.ts b/src/core/modes/raindex/utils.ts new file mode 100644 index 00000000..9b60b977 --- /dev/null +++ b/src/core/modes/raindex/utils.ts @@ -0,0 +1,58 @@ +import { parseUnits } from "viem"; +import { Pair } from "../../../order"; +import { ONE18, scaleTo18 } from "../../../math"; +import { SushiRouterQuote } from "../../../router"; + +export function calcCounterpartyInputProfit( + counterparty: Pair, + quote: SushiRouterQuote, +): { + counterpartyInputProfit: bigint; + counterpartyMaxOutput: bigint; +} { + const maxSushiOutput = scaleTo18(quote.amountOut, counterparty.buyTokenDecimals); + const counterpartyMaxInputFixed = + (counterparty.takeOrder.quote!.maxOutput * counterparty.takeOrder.quote!.ratio) / ONE18; + let counterpartyInputProfit = 0n; + let counterpatryMaxInput = maxSushiOutput; + if (maxSushiOutput > counterpartyMaxInputFixed) { + counterpartyInputProfit = maxSushiOutput - counterpartyMaxInputFixed; + counterpatryMaxInput = counterpartyMaxInputFixed; + } + let counterpartyMaxOutput = counterparty.takeOrder.quote!.maxOutput; + if ( + counterparty.takeOrder.quote!.ratio === 0n || + counterpatryMaxInput === counterpartyMaxInputFixed + ) { + counterpartyMaxOutput = counterparty.takeOrder.quote!.maxOutput; + } else { + counterpartyMaxOutput = + (counterpatryMaxInput * ONE18) / counterparty.takeOrder.quote!.ratio; + } + + return { + counterpartyInputProfit, + counterpartyMaxOutput, + }; +} + +export function calcCounterpartyOutputToEthPrice( + counterpartyInputToEthPrice: bigint, + ratio: bigint, + counterpartyOutputToEthPrice?: string, +): bigint { + if (counterpartyOutputToEthPrice) { + return parseUnits(counterpartyOutputToEthPrice, 18); + } else { + return (counterpartyInputToEthPrice * ratio) / ONE18; + } +} + +export function calcCounterpartyInputToEthPrice( + quote: SushiRouterQuote, + outputToEthPrice?: string, +): bigint { + if (!outputToEthPrice) return 0n; + const outputEthPrice = parseUnits(outputToEthPrice, 18); + return (outputEthPrice * ONE18) / quote.price; +} diff --git a/src/core/modes/simulator.ts b/src/core/modes/simulator.ts index fb2e01d1..94c2b5e0 100644 --- a/src/core/modes/simulator.ts +++ b/src/core/modes/simulator.ts @@ -11,6 +11,10 @@ import { SimulateInterOrderbookTradeArgs, InterOrderbookTradePreparedParams, } from "./inter/simulate"; +import { + RaindexRouterTradePreparedParams, + SimulateRaindexRouterTradeArgs, +} from "./raindex/simulation"; /** Specifies the reason that simulation failed */ export enum SimulationHaltReason { @@ -24,12 +28,14 @@ export enum SimulationHaltReason { export type SimulateTradeArgs = | SimulateRouterTradeArgs | SimulateIntraOrderbookTradeArgs - | SimulateInterOrderbookTradeArgs; + | SimulateInterOrderbookTradeArgs + | SimulateRaindexRouterTradeArgs; export type PreparedTradeParams = | RouterTradePreparedParams | IntraOrderbookTradePrepareedParams - | InterOrderbookTradePreparedParams; + | InterOrderbookTradePreparedParams + | RaindexRouterTradePreparedParams; /** * Base class for simulating trades against different platforms. diff --git a/src/core/process/log.ts b/src/core/process/log.ts index 3598e97c..d748f5a0 100644 --- a/src/core/process/log.ts +++ b/src/core/process/log.ts @@ -67,7 +67,11 @@ export function getActualClearAmount( } else { try { const logs = parseEventLogs({ - abi: [ABI.Orderbook.V4.Primary.Orderbook[2], ABI.Orderbook.V5.Primary.Orderbook[4]], + abi: [ + ABI.Orderbook.V4.Primary.Orderbook[2], + ABI.Orderbook.V5.Primary.Orderbook[4], + ABI.Orderbook.V6.Primary.Orderbook[4], + ], eventName: ["AfterClear", "AfterClearV2"], logs: receipt.logs, }); diff --git a/src/core/types.ts b/src/core/types.ts index 9e6cbf81..f6e17cc9 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -31,6 +31,7 @@ export enum TradeType { Balancer = "balancer", Router = "router", Stabull = "stabull", + Raindex = "raindex", } /** Base type for process order results containing shared fields */ diff --git a/src/order/index.test.ts b/src/order/index.test.ts index ba53530e..ae54d6c0 100644 --- a/src/order/index.test.ts +++ b/src/order/index.test.ts @@ -9,6 +9,7 @@ import { downscaleProtection } from "./protection"; import { CounterpartySource, Order, Pair } from "./types"; import { OrderManager, DEFAULT_OWNER_LIMIT, OrderbookVersions } from "./index"; import { describe, it, expect, beforeEach, vi, Mock, assert } from "vitest"; +import { BASES_TO_CHECK_TRADES_AGAINST } from "sushi/config"; vi.mock("./sync", () => ({ syncOrders: vi.fn(), @@ -18,6 +19,12 @@ vi.mock("./protection", () => ({ downscaleProtection: vi.fn(), })); +vi.mock("sushi/config", () => ({ + BASES_TO_CHECK_TRADES_AGAINST: { + [1]: [], + }, +})); + vi.mock("viem", async (importOriginal) => ({ ...(await importOriginal()), erc20Abi: [], @@ -80,6 +87,9 @@ describe("Test OrderManager", () => { beforeEach(async () => { vi.clearAllMocks(); state = new (SharedState as Mock)(); + (state.chainConfig as any) = { + id: 1, + }; (state as any).orderManagerConfig = { quoteGas: 1000000n, ownerLimits: { @@ -1527,4 +1537,560 @@ describe("Test OrderManager", () => { totalDistinctPairsCount: 1, }); }); + + describe("test getCounterpartyOrdersAgainstBaseTokens() method", async () => { + it("should return empty map when no counterparty orders exist against base tokens", () => { + const pair = getPair("0xorderbook", "0xhash", "0xoutput", "0xinput"); + + const result = orderManager.getCounterpartyOrdersAgainstBaseTokens(pair); + + expect(result).toBeInstanceOf(Map); + expect(result.size).toBe(0); + }); + + it("should return routed counterparty orders against base tokens", async () => { + // Mock BASES_TO_CHECK_TRADES_AGAINST to include a specific base token + const mockBaseToken = { address: "0xbasetoken", symbol: "BASE", decimals: 18 }; + (BASES_TO_CHECK_TRADES_AGAINST as any)[state.chainConfig.id] = [mockBaseToken as any]; + + const orderARes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xoutput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + const orderBRes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xbasetoken", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + (Order.tryFromBytes as Mock) + .mockReturnValueOnce(orderARes) + .mockReturnValueOnce(orderBRes); + const orderA = { + __version: SubgraphVersions.V6, + orderHash: "0xhashA", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesA", + outputs: [ + { + token: { address: "0xoutput", symbol: "OUT", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + const orderB = { + __version: SubgraphVersions.V6, + orderHash: "0xhashB", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesB", + outputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xbasetoken", symbol: "BASE", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + + await orderManager.addOrder(orderA as any); + await orderManager.addOrder(orderB as any); + + const pairA = getPair("0xorderbook", "0xhashA", "0xoutput", "0xinput"); + const result = orderManager.getCounterpartyOrdersAgainstBaseTokens(pairA); + + expect(result).toBeInstanceOf(Map); + expect(result.size).toBe(1); + expect(result.has("0xbasetoken")).toBe(true); + + const baseTokenPairs = result.get("0xbasetoken"); + expect(Array.isArray(baseTokenPairs)).toBe(true); + expect(baseTokenPairs?.length).toBe(1); + expect(baseTokenPairs?.[0].takeOrder.id).toBe("0xhashb"); + expect(baseTokenPairs?.[0].buyToken).toBe("0xbasetoken"); + expect(baseTokenPairs?.[0].sellToken).toBe("0xinput"); + }); + + it("should skip mirrored pairs (same input/output)", async () => { + const mockBaseToken = { address: "0xbasetoken", symbol: "BASE", decimals: 18 }; + (BASES_TO_CHECK_TRADES_AGAINST as any)[state.chainConfig.id] = [mockBaseToken as any]; + + const orderARes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xoutput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + const orderBRes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xoutput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + (Order.tryFromBytes as Mock) + .mockReturnValueOnce(orderARes) + .mockReturnValueOnce(orderBRes); + const orderA = { + __version: SubgraphVersions.V6, + orderHash: "0xhashA", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesA", + outputs: [ + { + token: { address: "0xoutput", symbol: "OUT", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + const orderB = { + __version: SubgraphVersions.V6, + orderHash: "0xhashB", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesB", + outputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xoutput", symbol: "BASE", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + + await orderManager.addOrder(orderA as any); + await orderManager.addOrder(orderB as any); + + const pairA = getPair("0xorderbook", "0xhashA", "0xoutput", "0xinput"); + const result = orderManager.getCounterpartyOrdersAgainstBaseTokens(pairA); + + // Should not include the mirrored pair + expect(result.size).toBe(0); + }); + + it("should skip non-base tokens", async () => { + const mockBaseToken = { address: "0xbasetoken", symbol: "BASE", decimals: 18 }; + (BASES_TO_CHECK_TRADES_AGAINST as any)[state.chainConfig.id] = [mockBaseToken as any]; + + const orderARes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xoutput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + const orderBRes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xnonebasetoken", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + (Order.tryFromBytes as Mock) + .mockReturnValueOnce(orderARes) + .mockReturnValueOnce(orderBRes); + const orderA = { + __version: SubgraphVersions.V6, + orderHash: "0xhashA", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesA", + outputs: [ + { + token: { address: "0xoutput", symbol: "OUT", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + const orderB = { + __version: SubgraphVersions.V6, + orderHash: "0xhashB", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesB", + outputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xnonebasetoken", symbol: "BASE", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + + await orderManager.addOrder(orderA as any); + await orderManager.addOrder(orderB as any); + + const pairA = getPair("0xorderbook", "0xhashA", "0xoutput", "0xinput"); + const result = orderManager.getCounterpartyOrdersAgainstBaseTokens(pairA); + + // Should not include non-base token pairs + expect(result.size).toBe(0); + }); + + it("should return multiple routed counterparty orders for different base tokens", async () => { + const mockBaseToken1 = { address: "0xbasetoken1", symbol: "BASE1", decimals: 18 }; + const mockBaseToken2 = { address: "0xbasetoken2", symbol: "BASE2", decimals: 6 }; + (BASES_TO_CHECK_TRADES_AGAINST as any)[state.chainConfig.id] = [ + mockBaseToken1 as any, + mockBaseToken2 as any, + ]; + + const orderARes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xoutput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + const orderBRes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xbasetoken1", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + const orderCRes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xbasetoken2", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + (Order.tryFromBytes as Mock) + .mockReturnValueOnce(orderARes) + .mockReturnValueOnce(orderBRes) + .mockReturnValueOnce(orderCRes); + const orderA = { + __version: SubgraphVersions.V6, + orderHash: "0xhashA", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesA", + outputs: [ + { + token: { address: "0xoutput", symbol: "OUT", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + const orderB = { + __version: SubgraphVersions.V6, + orderHash: "0xhashB", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesB", + outputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xbasetoken1", symbol: "BASE", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + const orderC = { + __version: SubgraphVersions.V6, + orderHash: "0xhashC", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesC", + outputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xbasetoken2", symbol: "BASE", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + + await orderManager.addOrder(orderA as any); + await orderManager.addOrder(orderB as any); + await orderManager.addOrder(orderC as any); + + const pairA = getPair("0xorderbook", "0xhashA", "0xoutput", "0xinput"); + const result = orderManager.getCounterpartyOrdersAgainstBaseTokens(pairA); + + expect(result.size).toBe(2); + expect(result.has("0xbasetoken1")).toBe(true); + expect(result.has("0xbasetoken2")).toBe(true); + + const baseToken1Pairs = result.get("0xbasetoken1"); + expect(baseToken1Pairs?.length).toBe(1); + expect(baseToken1Pairs?.[0].takeOrder.id).toBe("0xhashb"); + expect(baseToken1Pairs?.[0].buyToken).toBe("0xbasetoken1"); + expect(baseToken1Pairs?.[0].sellToken).toBe("0xinput"); + + const baseToken2Pairs = result.get("0xbasetoken2"); + expect(baseToken2Pairs?.length).toBe(1); + expect(baseToken2Pairs?.[0].takeOrder.id).toBe("0xhashc"); + expect(baseToken2Pairs?.[0].buyToken).toBe("0xbasetoken2"); + expect(baseToken2Pairs?.[0].sellToken).toBe("0xinput"); + }); + + it("should call getSortedPairList with correct parameters", async () => { + const mockBaseToken = { address: "0xbasetoken", symbol: "BASE", decimals: 18 }; + (BASES_TO_CHECK_TRADES_AGAINST as any)[state.chainConfig.id] = [mockBaseToken as any]; + + const orderARes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xoutput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + const orderBRes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xbasetoken", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + (Order.tryFromBytes as Mock) + .mockReturnValueOnce(orderARes) + .mockReturnValueOnce(orderBRes); + const orderA = { + __version: SubgraphVersions.V6, + orderHash: "0xhashA", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesA", + outputs: [ + { + token: { address: "0xoutput", symbol: "OUT", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + const orderB = { + __version: SubgraphVersions.V6, + orderHash: "0xhashB", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesB", + outputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xbasetoken", symbol: "BASE", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + + await orderManager.addOrder(orderA as any); + await orderManager.addOrder(orderB as any); + + const getSortedPairListSpy = vi.spyOn(pairFns, "getSortedPairList"); + + const pairA = getPair("0xorderbook", "0xhashA", "0xoutput", "0xinput"); + orderManager.getCounterpartyOrdersAgainstBaseTokens(pairA); + + expect(getSortedPairListSpy).toHaveBeenCalledWith( + orderManager.oiPairMap, + "0xorderbook", + "0xinput", + "0xbasetoken", + CounterpartySource.IntraOrderbook, + ); + + getSortedPairListSpy.mockRestore(); + }); + }); }); diff --git a/src/order/index.ts b/src/order/index.ts index ac765c0e..93307c4c 100644 --- a/src/order/index.ts +++ b/src/order/index.ts @@ -7,6 +7,7 @@ import { quoteSingleOrder } from "./quote"; import { PreAssembledSpan } from "../logger"; import { SubgraphManager } from "../subgraph"; import { downscaleProtection } from "./protection"; +import { BASES_TO_CHECK_TRADES_AGAINST } from "sushi/config"; import { normalizeFloat, Result, TokenDetails } from "../common"; import { OrderManagerError, OrderManagerErrorType } from "./error"; import { addToPairMap, removeFromPairMap, getSortedPairList } from "./pair"; @@ -512,6 +513,41 @@ export class OrderManager { return getSortedPairList(this.oiPairMap, ob, buyToken, sellToken, counterpartySource); } + /** + * Gets descending sorted list of counterparty orders against routed base tokens by their ratios for a given order + * @param orderDetails - Details of the order to find counterparty orders for + */ + getCounterpartyOrdersAgainstBaseTokens(orderDetails: Pair): Map { + const sellToken = orderDetails.sellToken.toLowerCase(); + const buyToken = orderDetails.buyToken.toLowerCase(); + const ob = orderDetails.orderbook.toLowerCase(); + + const result = new Map(); + // get orders that have same output as the order's input as array + // and loop through them to get every possible combination + const arr = Array.from(this.oiPairMap.get(ob)?.get(buyToken) ?? []); + for (const [tkn] of arr) { + // skip mirrored order pairs and pairs with middle token that is not in routing base tokens + if ( + tkn === sellToken || + BASES_TO_CHECK_TRADES_AGAINST[this.state.chainConfig.id].every( + (baseToken) => baseToken.address.toLowerCase() !== tkn, + ) + ) { + continue; + } + const pairs = getSortedPairList( + this.oiPairMap, + ob, + buyToken, + tkn, + CounterpartySource.IntraOrderbook, + ); + result.set(tkn, pairs); + } + return result; + } + /** * Gets the current metadata of all orders that being processed, which includes total * orders count, total owners count, total pairs count and total distinct pairs count diff --git a/src/order/pair.test.ts b/src/order/pair.test.ts index 1bda2a6d..f0ac241a 100644 --- a/src/order/pair.test.ts +++ b/src/order/pair.test.ts @@ -1,6 +1,12 @@ -import { CounterpartySource, OrderbooksPairMap, Pair } from "./types"; -import { addToPairMap, removeFromPairMap, getSortedPairList, sortPairList } from "./pair"; import { describe, it, expect, beforeEach } from "vitest"; +import { CounterpartySource, OrderbooksPairMap, Pair } from "./types"; +import { + sortPairList, + addToPairMap, + removeFromPairMap, + getSortedPairList, + getOptimalSortedList, +} from "./pair"; describe("Test add/remove to pairMap functions", () => { const orderbook1 = "0xorderbook1"; @@ -453,3 +459,208 @@ describe("Test sortPairList function", () => { expect(sorted[6][1].takeOrder.quote).toBeUndefined(); }); }); + +describe("Test getOptimalSortedList function", () => { + const createPair = (hash: string, quote?: { ratio: bigint; maxOutput: bigint }): Pair => + ({ + orderbook: "0xorderbook", + buyToken: "0xinput", + sellToken: "0xoutput", + takeOrder: { + id: hash, + quote, + }, + }) as any; + + it("should return empty array for empty input", () => { + const result = getOptimalSortedList([]); + expect(result).toEqual([]); + }); + + it("should return single pair when only one option exists", () => { + const pair = createPair("hash1", { ratio: 10n, maxOutput: 100n }); + const result = getOptimalSortedList([pair]); + + expect(result).toHaveLength(1); + expect(result[0]).toBe(pair); + }); + + it("should filter out pairs without quotes", () => { + const pairs = [ + createPair("hash1", { ratio: 10n, maxOutput: 100n }), + createPair("hash2"), // no quote + createPair("hash3", { ratio: 5n, maxOutput: 200n }), + createPair("hash4"), // no quote + ]; + + const result = getOptimalSortedList(pairs); + + // Should only include pairs with quotes + expect(result.every((p) => p.takeOrder.quote !== undefined)).toBe(true); + }); + + it("should return Pareto-optimal options sorted descending by maxOutput", () => { + // Create pairs with different input/output combinations + // Pair format: [input (ratio * maxOutput), maxOutput] + const pairs = [ + createPair("hash1", { ratio: 2n, maxOutput: 100n }), // input: 200, output: 100 + createPair("hash2", { ratio: 3n, maxOutput: 150n }), // input: 450, output: 150 (dominated) + createPair("hash3", { ratio: 1n, maxOutput: 200n }), // input: 200, output: 200 (Pareto) + createPair("hash4", { ratio: 2n, maxOutput: 250n }), // input: 500, output: 250 (dominated) + createPair("hash5", { ratio: 1n, maxOutput: 300n }), // input: 300, output: 300 (Pareto) + ]; + + const result = getOptimalSortedList(pairs); + + // Pareto-optimal set (least input, most output): + // hash3: input 200, output 200 + // hash5: input 300, output 300 + // Sorted descending by maxOutput: hash5, hash3 + expect(result).toHaveLength(2); + expect(result[0].takeOrder.id).toBe("hash5"); + expect(result[0].takeOrder.quote?.maxOutput).toBe(300n); + expect(result[1].takeOrder.id).toBe("hash3"); + expect(result[1].takeOrder.quote?.maxOutput).toBe(200n); + }); + + it("should handle pairs with equal input but different outputs", () => { + const pairs = [ + createPair("hash1", { ratio: 2n, maxOutput: 100n }), // input: 200, output: 100 + createPair("hash2", { ratio: 1n, maxOutput: 200n }), // input: 200, output: 200 (better) + createPair("hash3", { ratio: 4n, maxOutput: 50n }), // input: 200, output: 50 + ]; + + const result = getOptimalSortedList(pairs); + + // With same input (200), highest output (200) wins + expect(result).toHaveLength(1); + expect(result[0].takeOrder.id).toBe("hash2"); + expect(result[0].takeOrder.quote?.maxOutput).toBe(200n); + }); + + it("should handle pairs with equal output but different inputs", () => { + const pairs = [ + createPair("hash1", { ratio: 5n, maxOutput: 100n }), // input: 500, output: 100 + createPair("hash2", { ratio: 3n, maxOutput: 100n }), // input: 300, output: 100 (better) + createPair("hash3", { ratio: 2n, maxOutput: 100n }), // input: 200, output: 100 (best) + ]; + + const result = getOptimalSortedList(pairs); + + // With same output (100), lowest input (200) wins + expect(result).toHaveLength(1); + expect(result[0].takeOrder.id).toBe("hash3"); + expect(result[0].takeOrder.quote?.ratio).toBe(2n); + }); + + it("should correctly identify Pareto frontier with multiple options", () => { + const pairs = [ + createPair("hash1", { ratio: 10n, maxOutput: 50n }), // input: 500, output: 50 (dominated) + createPair("hash2", { ratio: 5n, maxOutput: 100n }), // input: 500, output: 100 (Pareto) + createPair("hash3", { ratio: 4n, maxOutput: 150n }), // input: 600, output: 150 (Pareto) + createPair("hash4", { ratio: 6n, maxOutput: 120n }), // input: 720, output: 120 (dominated) + createPair("hash5", { ratio: 3n, maxOutput: 200n }), // input: 600, output: 200 (Pareto) + createPair("hash6", { ratio: 2n, maxOutput: 350n }), // input: 700, output: 350 (Pareto) + ]; + + const result = getOptimalSortedList(pairs); + + // Pareto frontier (sorted by input, then by output): + // hash2: input 500, output 100 + // hash5: input 600, output 200 (better output than hash3 with same input) + // hash6: input 700, output 350 + expect(result).toHaveLength(3); + + // Should be sorted descending by maxOutput + expect(result[0].takeOrder.id).toBe("hash6"); + expect(result[0].takeOrder.quote?.maxOutput).toBe(350n); + + expect(result[1].takeOrder.id).toBe("hash5"); + expect(result[1].takeOrder.quote?.maxOutput).toBe(200n); + + expect(result[2].takeOrder.id).toBe("hash2"); + expect(result[2].takeOrder.quote?.maxOutput).toBe(100n); + }); + + it("should handle all pairs being Pareto-optimal", () => { + // Each pair has progressively more input and more output + const pairs = [ + createPair("hash1", { ratio: 1n, maxOutput: 100n }), // input: 100, output: 100 + createPair("hash2", { ratio: 1n, maxOutput: 200n }), // input: 200, output: 200 + createPair("hash3", { ratio: 1n, maxOutput: 300n }), // input: 300, output: 300 + ]; + + const result = getOptimalSortedList(pairs); + + // All are Pareto-optimal + expect(result).toHaveLength(3); + + // Sorted descending by maxOutput + expect(result[0].takeOrder.id).toBe("hash3"); + expect(result[1].takeOrder.id).toBe("hash2"); + expect(result[2].takeOrder.id).toBe("hash1"); + }); + + it("should handle pairs with very small differences", () => { + const pairs = [ + createPair("hash1", { ratio: 1n, maxOutput: 100n }), // input: 100, output: 100 + createPair("hash2", { ratio: 1n, maxOutput: 101n }), // input: 101, output: 101 + createPair("hash3", { ratio: 1n, maxOutput: 102n }), // input: 102, output: 102 + ]; + + const result = getOptimalSortedList(pairs); + + // All are Pareto-optimal (each has more input and more output) + expect(result).toHaveLength(3); + expect(result[0].takeOrder.quote?.maxOutput).toBe(102n); + expect(result[1].takeOrder.quote?.maxOutput).toBe(101n); + expect(result[2].takeOrder.quote?.maxOutput).toBe(100n); + }); + + it("should handle edge case where all pairs have same input and output", () => { + const pairs = [ + createPair("hash1", { ratio: 2n, maxOutput: 50n }), // input: 100, output: 50 + createPair("hash2", { ratio: 5n, maxOutput: 20n }), // input: 100, output: 20 + createPair("hash3", { ratio: 1n, maxOutput: 100n }), // input: 100, output: 100 + ]; + + const result = getOptimalSortedList(pairs); + + // With same input, only the one with highest output is Pareto-optimal + expect(result).toHaveLength(1); + expect(result[0].takeOrder.id).toBe("hash3"); + expect(result[0].takeOrder.quote?.maxOutput).toBe(100n); + }); + + it("should handle mix of pairs with and without quotes", () => { + const pairs = [ + createPair("hash1", { ratio: 2n, maxOutput: 100n }), // input: 200, output: 100 + createPair("hash2"), // no quote + createPair("hash3", { ratio: 1n, maxOutput: 200n }), // input: 200, output: 200 (Pareto) + createPair("hash4"), // no quote + createPair("hash5", { ratio: 1n, maxOutput: 300n }), // input: 300, output: 300 (Pareto) + ]; + + const result = getOptimalSortedList(pairs); + + // Only pairs with quotes, and only Pareto-optimal ones + expect(result).toHaveLength(2); + expect(result[0].takeOrder.id).toBe("hash5"); + expect(result[1].takeOrder.id).toBe("hash3"); + expect(result.every((p) => p.takeOrder.quote !== undefined)).toBe(true); + }); + + it("should maintain stability for equivalent Pareto options", () => { + const pairs = [ + createPair("hash1", { ratio: 2n, maxOutput: 100n }), // input: 200, output: 100 + createPair("hash2", { ratio: 4n, maxOutput: 50n }), // input: 200, output: 50 + createPair("hash3", { ratio: 1n, maxOutput: 200n }), // input: 200, output: 200 + ]; + + const result = getOptimalSortedList(pairs); + + // With same input, only highest output is Pareto-optimal + expect(result).toHaveLength(1); + expect(result[0].takeOrder.id).toBe("hash3"); + }); +}); diff --git a/src/order/pair.ts b/src/order/pair.ts index 13db468d..66bfc613 100644 --- a/src/order/pair.ts +++ b/src/order/pair.ts @@ -79,6 +79,7 @@ export function removeFromPairMap( * @param output - The output token address to get pairs from * @param input - The input token address to get pairs from * @param counterpartySource - Determines the type of counterparty orders source to return + * @param sortBy - Either by ratio first (default) or by max out first */ export function getSortedPairList< counterpartySource extends CounterpartySource = CounterpartySource.IntraOrderbook, @@ -146,3 +147,54 @@ export function sortPairList(a: [string, Pair], b: [string, Pair]): number { } } } + +/** + * Picks the optimal trade options from the given list based on Pareto-optimization + * algo (least given away, most taken) sorted descending by the max output. + * + * @remarks in Pareto algo, there is never a single best pick (well actually in picking + * the best trade option there almost never is a best option, its a relative choice as + * its a problem with 2 variables that needs optimization, which are trade size and + * exchange rate, e.g. there can be a trade option with worse exchange rate than the + * other but with larger trade size which would result in larger absolute profit), but + * rather group of optimal options which our strategy is to sort them based on the + * highest maxout to lowest which would give the counterparty order owner the most + * cleared amount while the solver makes the most optimal profit + * + * @param options - The trade options + */ +export function getOptimalSortedList(options: Pair[]): Pair[] { + // sort based on least input and most output + options.sort((a, b) => { + if (!a.takeOrder.quote && !b.takeOrder.quote) return 0; + if (!a.takeOrder.quote) return 1; + if (!b.takeOrder.quote) return -1; + const aInput = a.takeOrder.quote.ratio * a.takeOrder.quote.maxOutput; + const bInput = b.takeOrder.quote.ratio * b.takeOrder.quote.maxOutput; + if (aInput < bInput) { + return -1; + } else if (aInput > bInput) { + return 1; + } else { + // if maxinputs are equal, sort by maxoutput + if (a.takeOrder.quote.maxOutput < b.takeOrder.quote.maxOutput) { + return 1; + } else if (a.takeOrder.quote.maxOutput > b.takeOrder.quote.maxOutput) { + return -1; + } else { + return 0; + } + } + }); + + // pick pareto optimized options + const paretoOpts: Pair[] = []; + let maxoutBase = -1n; + for (const opt of options) { + if (opt.takeOrder.quote?.maxOutput && opt.takeOrder.quote.maxOutput > maxoutBase) { + paretoOpts.push(opt); + maxoutBase = opt.takeOrder.quote.maxOutput; + } + } + return paretoOpts.reverse(); // reverse to be sorted desc based on maxout +} diff --git a/src/state/contracts.test.ts b/src/state/contracts.test.ts index a5603a33..2ff8eead 100644 --- a/src/state/contracts.test.ts +++ b/src/state/contracts.test.ts @@ -40,6 +40,7 @@ describe("SolverContracts.fromAppOptions", () => { genericArb: "0xv6genericArb" as `0x${string}`, balancerArb: "0xv6balancerArb" as `0x${string}`, stabullArb: "0xv6stabullArb" as `0x${string}`, + raindexArb: "0xv6raindexArb" as `0x${string}`, }, }, } as AppOptions; @@ -85,6 +86,7 @@ describe("SolverContracts.fromAppOptions", () => { genericArb: "0xv6genericArb", balancerArb: "0xv6balancerArb", stabullArb: "0xv6stabullArb", + raindexArb: "0xv6raindexArb", dispair: { deployer: "0xv6dispair", interpreter: "0xv6interpreter", @@ -158,6 +160,7 @@ describe("SolverContracts.fromAppOptions", () => { genericArb: "0xv6genericArb", balancerArb: "0xv6balancerArb", stabullArb: "0xv6stabullArb", + raindexArb: "0xv6raindexArb", dispair: { deployer: "0xv6dispair", interpreter: "0xv6interpreter", @@ -200,6 +203,7 @@ describe("SolverContracts.fromAppOptions", () => { genericArb: "0xv6genericArb", balancerArb: "0xv6balancerArb", stabullArb: "0xv6stabullArb", + raindexArb: "0xv6raindexArb", dispair: { deployer: "0xv6dispair", interpreter: "0xv6interpreter", @@ -603,6 +607,49 @@ describe("resolveVersionContracts", () => { abi: ABI.Deployer.Primary.Deployer, }); }); + + it("should resolve version contracts for v6 with all addresses when all contract calls succeed", async () => { + const mockAddresses = { + dispair: "0xdispairAddress" as `0x${string}`, + sushiArb: "0xsushiArbAddress" as `0x${string}`, + genericArb: "0xgenericArbAddress" as `0x${string}`, + balancerArb: "0xbalancerArbAddress" as `0x${string}`, + stabullArb: "0xstabullArbAddress" as `0x${string}`, + raindexArb: "0xraindexArb" as `0x${string}`, + }; + + // Mock successful contract calls + mockClient.readContract + .mockResolvedValueOnce("0xinterpreterAddress" as `0x${string}`) // iInterpreter + .mockResolvedValueOnce("0xstoreAddress" as `0x${string}`); // iStore + + const result = await resolveVersionContracts(mockClient, mockAddresses, "v6"); + + expect(result).toEqual({ + dispair: { + deployer: "0xdispairAddress", + interpreter: "0xinterpreterAddress", + store: "0xstoreAddress", + }, + sushiArb: "0xsushiArbAddress", + genericArb: "0xgenericArbAddress", + balancerArb: "0xbalancerArbAddress", + stabullArb: "0xstabullArbAddress", + raindexArb: "0xraindexArb", + }); + + expect(mockClient.readContract).toHaveBeenCalledTimes(2); + expect(mockClient.readContract).toHaveBeenNthCalledWith(1, { + address: "0xdispairAddress", + functionName: "I_INTERPRETER", + abi: ABI.Deployer.Primary.DeployerV6, + }); + expect(mockClient.readContract).toHaveBeenNthCalledWith(2, { + address: "0xdispairAddress", + functionName: "I_STORE", + abi: ABI.Deployer.Primary.DeployerV6, + }); + }); }); describe("versionAddressGetter", () => { @@ -807,4 +854,19 @@ describe("versionAddressGetter", () => { destination: "0xorderbookAddress", }); }); + + it("should return raindexArb for Raindex tradeType when available", () => { + mockContracts.raindexArb = "0xraindexArb"; + const result = versionAddressGetter(mockContracts, mockOrder, TradeType.Raindex); + + expect(result).toEqual({ + dispair: mockContracts.dispair, + destination: "0xraindexArb", + }); + }); + + it("should return undefined for Raindex tradeType when raindexRab is not available", () => { + const result = versionAddressGetter(mockContracts, mockOrder, TradeType.Raindex); + expect(result).toBeUndefined(); + }); }); diff --git a/src/state/contracts.ts b/src/state/contracts.ts index beedbbaa..db152d94 100644 --- a/src/state/contracts.ts +++ b/src/state/contracts.ts @@ -30,6 +30,7 @@ export type SolverContracts = { genericArb?: `0x${string}`; balancerArb?: `0x${string}`; stabullArb?: `0x${string}`; + raindexArb?: `0x${string}`; dispair: Dispair; }; @@ -119,6 +120,9 @@ export async function resolveVersionContracts( if (addresses.stabullArb) { result.stabullArb = addresses.stabullArb; } + if ("raindexArb" in addresses && addresses.raindexArb) { + result.raindexArb = addresses.raindexArb; + } return result; } @@ -199,6 +203,15 @@ export function versionAddressGetter< destination: order.orderbook as `0x${string}`, }; } + case TradeType.Raindex: { + if ("raindexArb" in contracts && contracts.raindexArb) { + return { + dispair: contracts.dispair, + destination: contracts.raindexArb as `0x${string}`, + }; + } + return undefined; + } default: { return undefined; } diff --git a/test/abis/OrderBookV6.json b/test/abis/OrderBookV6.json new file mode 100644 index 00000000..112e113a --- /dev/null +++ b/test/abis/OrderBookV6.json @@ -0,0 +1 @@ +{"abi":[{"type":"function","name":"addOrder4","inputs":[{"name":"orderConfig","type":"tuple","internalType":"struct OrderConfigV4","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"},{"name":"secret","type":"bytes32","internalType":"bytes32"},{"name":"meta","type":"bytes","internalType":"bytes"}]},{"name":"post","type":"tuple[]","internalType":"struct TaskV2[]","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"clear3","inputs":[{"name":"aliceOrder","type":"tuple","internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]},{"name":"bobOrder","type":"tuple","internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]},{"name":"clearConfig","type":"tuple","internalType":"struct ClearConfigV2","components":[{"name":"aliceInputIOIndex","type":"uint256","internalType":"uint256"},{"name":"aliceOutputIOIndex","type":"uint256","internalType":"uint256"},{"name":"bobInputIOIndex","type":"uint256","internalType":"uint256"},{"name":"bobOutputIOIndex","type":"uint256","internalType":"uint256"},{"name":"aliceBountyVaultId","type":"bytes32","internalType":"bytes32"},{"name":"bobBountyVaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"aliceSignedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]},{"name":"bobSignedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"deposit4","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"},{"name":"depositAmount","type":"bytes32","internalType":"Float"},{"name":"post","type":"tuple[]","internalType":"struct TaskV2[]","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"entask2","inputs":[{"name":"post","type":"tuple[]","internalType":"struct TaskV2[]","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"flashFee","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"pure"},{"type":"function","name":"flashLoan","inputs":[{"name":"receiver","type":"address","internalType":"contract IERC3156FlashBorrower"},{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"maxFlashLoan","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"multicall","inputs":[{"name":"data","type":"bytes[]","internalType":"bytes[]"}],"outputs":[{"name":"results","type":"bytes[]","internalType":"bytes[]"}],"stateMutability":"nonpayable"},{"type":"function","name":"orderExists","inputs":[{"name":"orderHash","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"quote2","inputs":[{"name":"quoteConfig","type":"tuple","internalType":"struct QuoteV2","components":[{"name":"order","type":"tuple","internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]},{"name":"inputIOIndex","type":"uint256","internalType":"uint256"},{"name":"outputIOIndex","type":"uint256","internalType":"uint256"},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]}],"outputs":[{"name":"","type":"bool","internalType":"bool"},{"name":"","type":"bytes32","internalType":"Float"},{"name":"","type":"bytes32","internalType":"Float"}],"stateMutability":"view"},{"type":"function","name":"removeOrder3","inputs":[{"name":"order","type":"tuple","internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]},{"name":"post","type":"tuple[]","internalType":"struct TaskV2[]","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]}],"outputs":[{"name":"stateChanged","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"takeOrders4","inputs":[{"name":"config","type":"tuple","internalType":"struct TakeOrdersConfigV5","components":[{"name":"minimumIO","type":"bytes32","internalType":"Float"},{"name":"maximumIO","type":"bytes32","internalType":"Float"},{"name":"maximumIORatio","type":"bytes32","internalType":"Float"},{"name":"IOIsInput","type":"bool","internalType":"bool"},{"name":"orders","type":"tuple[]","internalType":"struct TakeOrderConfigV4[]","components":[{"name":"order","type":"tuple","internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]},{"name":"inputIOIndex","type":"uint256","internalType":"uint256"},{"name":"outputIOIndex","type":"uint256","internalType":"uint256"},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"data","type":"bytes","internalType":"bytes"}]}],"outputs":[{"name":"totalTakerInput","type":"bytes32","internalType":"Float"},{"name":"totalTakerOutput","type":"bytes32","internalType":"Float"}],"stateMutability":"nonpayable"},{"type":"function","name":"vaultBalance2","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bytes32","internalType":"Float"}],"stateMutability":"view"},{"type":"function","name":"withdraw4","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"},{"name":"targetAmount","type":"bytes32","internalType":"Float"},{"name":"post","type":"tuple[]","internalType":"struct TaskV2[]","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"AddOrderV3","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"orderHash","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"order","type":"tuple","indexed":false,"internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]}],"anonymous":false},{"type":"event","name":"AfterClearV2","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"clearStateChange","type":"tuple","indexed":false,"internalType":"struct ClearStateChangeV2","components":[{"name":"aliceOutput","type":"bytes32","internalType":"Float"},{"name":"bobOutput","type":"bytes32","internalType":"Float"},{"name":"aliceInput","type":"bytes32","internalType":"Float"},{"name":"bobInput","type":"bytes32","internalType":"Float"}]}],"anonymous":false},{"type":"event","name":"ClearV3","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"alice","type":"tuple","indexed":false,"internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]},{"name":"bob","type":"tuple","indexed":false,"internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]},{"name":"clearConfig","type":"tuple","indexed":false,"internalType":"struct ClearConfigV2","components":[{"name":"aliceInputIOIndex","type":"uint256","internalType":"uint256"},{"name":"aliceOutputIOIndex","type":"uint256","internalType":"uint256"},{"name":"bobInputIOIndex","type":"uint256","internalType":"uint256"},{"name":"bobOutputIOIndex","type":"uint256","internalType":"uint256"},{"name":"aliceBountyVaultId","type":"bytes32","internalType":"bytes32"},{"name":"bobBountyVaultId","type":"bytes32","internalType":"bytes32"}]}],"anonymous":false},{"type":"event","name":"ContextV2","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"context","type":"bytes32[][]","indexed":false,"internalType":"bytes32[][]"}],"anonymous":false},{"type":"event","name":"DepositV2","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"token","type":"address","indexed":false,"internalType":"address"},{"name":"vaultId","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"depositAmountUint256","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"MetaV1_2","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"subject","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"meta","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"OrderExceedsMaxRatio","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"owner","type":"address","indexed":false,"internalType":"address"},{"name":"orderHash","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"OrderNotFound","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"owner","type":"address","indexed":false,"internalType":"address"},{"name":"orderHash","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"OrderZeroAmount","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"owner","type":"address","indexed":false,"internalType":"address"},{"name":"orderHash","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"RemoveOrderV3","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"orderHash","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"order","type":"tuple","indexed":false,"internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]}],"anonymous":false},{"type":"event","name":"TakeOrderV3","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"config","type":"tuple","indexed":false,"internalType":"struct TakeOrderConfigV4","components":[{"name":"order","type":"tuple","internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]},{"name":"inputIOIndex","type":"uint256","internalType":"uint256"},{"name":"outputIOIndex","type":"uint256","internalType":"uint256"},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"input","type":"bytes32","indexed":false,"internalType":"Float"},{"name":"output","type":"bytes32","indexed":false,"internalType":"Float"}],"anonymous":false},{"type":"event","name":"WithdrawV2","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"token","type":"address","indexed":false,"internalType":"address"},{"name":"vaultId","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"targetAmount","type":"bytes32","indexed":false,"internalType":"Float"},{"name":"withdrawAmount","type":"bytes32","indexed":false,"internalType":"Float"},{"name":"withdrawAmountUint256","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"AddressEmptyCode","inputs":[{"name":"target","type":"address","internalType":"address"}]},{"type":"error","name":"ClearZeroAmount","inputs":[]},{"type":"error","name":"DivisionByZero","inputs":[{"name":"signedCoefficient","type":"int256","internalType":"int256"},{"name":"exponent","type":"int256","internalType":"int256"}]},{"type":"error","name":"ExponentOverflow","inputs":[{"name":"signedCoefficient","type":"int256","internalType":"int256"},{"name":"exponent","type":"int256","internalType":"int256"}]},{"type":"error","name":"FailedCall","inputs":[]},{"type":"error","name":"FlashLenderCallbackFailed","inputs":[{"name":"result","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"InvalidSignature","inputs":[{"name":"i","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"MaximizeOverflow","inputs":[{"name":"signedCoefficient","type":"int256","internalType":"int256"},{"name":"exponent","type":"int256","internalType":"int256"}]},{"type":"error","name":"MinimumIO","inputs":[{"name":"minimumIO","type":"bytes32","internalType":"Float"},{"name":"actualIO","type":"bytes32","internalType":"Float"}]},{"type":"error","name":"MulDivOverflow","inputs":[{"name":"x","type":"uint256","internalType":"uint256"},{"name":"y","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"NegativeBounty","inputs":[]},{"type":"error","name":"NegativeFixedDecimalConversion","inputs":[{"name":"signedCoefficient","type":"int256","internalType":"int256"},{"name":"exponent","type":"int256","internalType":"int256"}]},{"type":"error","name":"NegativePull","inputs":[]},{"type":"error","name":"NegativePush","inputs":[]},{"type":"error","name":"NegativeVaultBalance","inputs":[{"name":"vaultBalance","type":"bytes32","internalType":"Float"}]},{"type":"error","name":"NegativeVaultBalanceChange","inputs":[{"name":"amount","type":"bytes32","internalType":"Float"}]},{"type":"error","name":"NoOrders","inputs":[]},{"type":"error","name":"NotOrderOwner","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"owner","type":"address","internalType":"address"}]},{"type":"error","name":"NotRainMetaV1","inputs":[{"name":"unmeta","type":"bytes","internalType":"bytes"}]},{"type":"error","name":"OrderNoHandleIO","inputs":[]},{"type":"error","name":"OrderNoInputs","inputs":[]},{"type":"error","name":"OrderNoOutputs","inputs":[]},{"type":"error","name":"OrderNoSources","inputs":[]},{"type":"error","name":"ReentrancyGuardReentrantCall","inputs":[]},{"type":"error","name":"SafeERC20FailedOperation","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"type":"error","name":"SameOwner","inputs":[]},{"type":"error","name":"TokenDecimalsReadFailure","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"tofuOutcome","type":"uint8","internalType":"enum TOFUOutcome"}]},{"type":"error","name":"TokenMismatch","inputs":[]},{"type":"error","name":"TokenSelfTrade","inputs":[]},{"type":"error","name":"UnsupportedCalculateOutputs","inputs":[{"name":"outputs","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ZeroDepositAmount","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"ZeroMaximumIO","inputs":[]},{"type":"error","name":"ZeroVaultId","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"token","type":"address","internalType":"address"}]},{"type":"error","name":"ZeroWithdrawTargetAmount","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]}],"bytecode":{"object":"0x6080604052348015600e575f80fd5b5060017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055615cda806100405f395ff3fe608060405234801561000f575f80fd5b50600436106100f0575f3560e01c8063613255ab11610093578063ac9650d811610063578063ac9650d814610257578063d7e442ec14610277578063d9d98ce41461028a578063fa5011821461029f575f80fd5b8063613255ab146101d957806369c72856146101ec578063709fb8a5146102145780639235084d14610227575f80fd5b80632fbc4ba0116100ce5780632fbc4ba01461015157806341d1514f146101665780635cffe9de146101b357806360746119146101c6575f80fd5b806301ffc9a7146100f45780631f69cb751461011c5780632cb77e9f1461012f575b5f80fd5b6101076101023660046146d2565b6102b2565b60405190151581526020015b60405180910390f35b61010761012a366004614752565b61034a565b61010761013d3660046147bd565b5f9081526020819052604090205460011490565b61016461015f3660046147f3565b6104c6565b005b6101a5610174366004614858565b6001600160a01b039283165f9081526001602090815260408083209490951682529283528381209181529152205490565b604051908152602001610113565b6101076101c1366004614896565b610626565b6101646101d43660046147f3565b610758565b6101a56101e736600461492d565b6108fe565b6101ff6101fa36600461495e565b61097f565b60408051928352602083019190915201610113565b610107610222366004614998565b61107e565b61023a6102353660046149e2565b611382565b604080519315158452602084019290925290820152606001610113565b61026a610265366004614a19565b611443565b6040516101139190614a86565b610164610285366004614a19565b611529565b6101a5610298366004614ae8565b5f92915050565b6101646102ad366004614f5a565b611596565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167fe414309100000000000000000000000000000000000000000000000000000000148061034457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f610353611a93565b610360602085018561492d565b6001600160a01b0316336001600160a01b0316146103d05733610386602086018661492d565b6040517f4702b9140000000000000000000000000000000000000000000000000000000081526001600160a01b039283166004820152911660248201526044015b60405180910390fd5b5f6103e26103dd86615014565b611ac1565b5f818152602081905260409020549091505f1901610495575f818152602081905260408082209190915551600192507f09d18501db0080ca2d6cd7c17fa7255daff4b2d503ea93b76ff68b6752ea8e63906104429033908490899061516a565b60405180910390a160408051600281526020810183905233818301526060810190915261049590610486905b60408051600181526020810192909252818101905290565b610490858761522e565b611af0565b506104bf60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b9392505050565b6104ce611a93565b6104d8835f611cc0565b610526576040517f6dde9c300000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0386166024820152604481018590526064016103c7565b5f806105328786611cfa565b604080513381526001600160a01b038b1660208201529081018990526060810183905291935091507f7f9dfa19cf1cc2f806f2f860fbc9c056b601fb1afc0e9b843dfe5c63616268e69060800160405180910390a15f80610595338a8a8a611dec565b909250905084156105f25760408051600581526001600160a01b038b1660208201528082018a9052606081018490526080810183905260ff851660a082015260c081019091526105f2906105e89061046e565b610490878961522e565b5050505061061f60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050505050565b5f61063b6001600160a01b0386168786611ed7565b6040517f23e30c8b0000000000000000000000000000000000000000000000000000000081525f906001600160a01b038816906323e30c8b9061068c9033908a908a9087908b908b906004016152ee565b6020604051808303815f875af11580156106a8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106cc9190615332565b90507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9811461072a576040517f5b62c548000000000000000000000000000000000000000000000000000000008152600481018290526024016103c7565b61074b87306107395f8961535d565b6001600160a01b038a16929190611f11565b5060019695505050505050565b610760611a93565b61076a835f611cc0565b6107b7576040517ee8e9340000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0386166024820152604481018590526064016103c7565b335f9081526001602090815260408083206001600160a01b03891684528252808320878452909152812054906107ed8583611f4d565b90505f806107fd338a8a86611f69565b915091505f8061080d8b86611fd0565b604080513381526001600160a01b038f1660208201529081018d9052606081018c90526080810188905260a0810183905291935091507f8045c25080b0868951141ed0a91720bcad09a8364a2b3109ee1fd49c1f0bc8b89060c00160405180910390a186156108cf5760408051600681526001600160a01b038d1660208201528082018c9052606081018690526080810185905260a081018b905260ff831660c082015260e081019091526108cf906108c59061046e565b610490898b61522e565b50505050505061061f60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa15801561095b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103449190615332565b5f80610989611a93565b6109966080840184615370565b90505f036109d0576040517f9c95219f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109d86145fa565b6109e0614626565b5f6109ee6080870187615370565b5f8181106109fe576109fe6153b6565b9050602002810190610a1091906153ca565b610a1a90806153e8565b610a289060408101906153fc565b610a356080890189615370565b5f818110610a4557610a456153b6565b9050602002810190610a5791906153ca565b60200135818110610a6a57610a6a6153b6565b610a80926020604090920201908101915061492d565b90505f610a906080880188615370565b5f818110610aa057610aa06153b6565b9050602002810190610ab291906153ca565b610abc90806153e8565b610aca9060608101906153fc565b610ad760808a018a615370565b5f818110610ae757610ae76153b6565b9050602002810190610af991906153ca565b60400135818110610b0c57610b0c6153b6565b610b22926020604090920201908101915061492d565b905060605f610b3460808a018a615370565b6040805160206001939093018302810190915293508a01359150610b5a9050815f611cc0565b610b90576040517fc57e788c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5b610b9f60808b018b615370565b905081108015610bb45750610bb4825f611cc0565b15610f1157610bc660808b018b615370565b82818110610bd657610bd66153b6565b9050602002810190610be891906153ca565b610bf190615442565b9650865f01519550846001600160a01b03168660400151886020015181518110610c1d57610c1d6153b6565b60200260200101515f01516001600160a01b0316141580610c745750836001600160a01b03168660600151886040015181518110610c5d57610c5d6153b6565b60200260200101515f01516001600160a01b031614155b15610c925760405163936bb5ad60e01b815260040160405180910390fd5b610ca586886020015189604001516120a3565b5f610caf87611ac1565b5f81815260208190526040902054909150610d14578651604080513381526001600160a01b03909216602083015281018290527fb70c12fa453793fa6818ec07c91e74363a47aa6a6829dcd9533937fdf30314f39060600160405180910390a1610f08565b5f610d2e888a602001518b60400151338d60600151612115565b6060810151909150610d449060408e0135611cc0565b15610d9a578751604080513381526001600160a01b03909216602083015281018390527fe3151dc8cb7a54ffc4baabd28c1f241c94d510b5e5b502491ac3cad6c16316d5906060015b60405180910390a1610f06565b60408101516001600160e01b0316610df4578751604080513381526001600160a01b03909216602083015281018390527f500b713857325f9e6dcb52ae832eca9109d107ed1aae9cb4928b4c1e13f051aa90606001610d8d565b5f808d6060016020810190610e0991906154d8565b15610e42576040830151610e1d9087611f4d565b6060840151909250610e2f90836127d1565b9050610e3b8683612821565b9550610e93565b5f610e5e846040015185606001516127d190919063ffffffff16565b9050610e6a8188611f4d565b9150610e8384606001518361285190919063ffffffff16565b9250610e8f8783612821565b9650505b610e9d8c82612881565b9b50610ea98d83612881565b9c50610eb68183856128b1565b7f194f1feb3b4d7076a2c272e774e792e0c48bb8c7aa1a9a3671c1cd6da9e6b4c1338c8484604051610eeb9493929190615600565b60405180910390a15050845160010180865260200285018190525b505b50600101610b92565b505f9050610f2560808a0160608b016154d8565b610f2f5786610f31565b875b9050610f3e818a35612a79565b15610f7f576040517f573b6f4100000000000000000000000000000000000000000000000000000000815289356004820152602481018290526044016103c7565b50610f8a8288611fd0565b505f9050610f9b60a08a018a6156ea565b90501115611009573363691f9ed783858a8a610fba60a08f018f6156ea565b6040518763ffffffff1660e01b8152600401610fdb969594939291906152ee565b5f604051808303815f87803b158015610ff2575f80fd5b505af1158015611004573d5f803e3d5ffd5b505050505b6110138387611cfa565b50505f5b815181101561104a57611042828281518110611035576110356153b6565b6020026020010151612ab3565b600101611017565b50505050505061107960017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b915091565b5f611087611a93565b61109460208501856153fc565b90505f036110ce576040517f6c44ef8f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110db60408501856153fc565b90505f03611115576040517f540e5f0b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a081019091523381525f9060208101611133878061572d565b61113c90615741565b815260200186806020019061115191906153fc565b808060200260200160405190810160405280939291908181526020015f905b8282101561119c5761118d6040830286013681900381019061574c565b81526020019060010190611170565b50505091835250506020016111b460408801886153fc565b808060200260200160405190810160405280939291908181526020015f905b828210156111ff576111f06040830286013681900381019061574c565b815260200190600101906111d3565b50505050508152602001866060013581525090505f61121d82611ac1565b5f81815260208190526040902054909150158015611355575f828152602081905260409081902060019055835190517f87491344dfbcf91f6cbbc610cbbeedc85313d37a02df0c93527f7ea5f8db717f9161127b9185908790615766565b60405180910390a15f61129160a08901896156ea565b9050111561132d576112e26112a960a08901896156ea565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250612cf892505050565b82517fd46c2c56b35c8210e9e712ec3f02242d5fc90187c0ac8ed80cc33626846ec369908361131460a08b018b6156ea565b604051611324949392919061578d565b60405180910390a15b604080516002815260208101849052338183015260608101909152611355906105e89061046e565b925050506104bf60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5f80808061139c61139386806153e8565b6103dd90615014565b5f818152602081905260409020549091506001146113c357505f925082915081905061143c565b6113e86113d086806153e8565b6113d990615014565b866020013587604001356120a3565b5f6114256113f687806153e8565b6113ff90615014565b602088013560408901353361141760608c018c615370565b611420916157bf565b612115565b905060018160400151826060015194509450945050505b9193909250565b604080515f8152602081019091526060908267ffffffffffffffff81111561146d5761146d614b12565b6040519080825280602002602001820160405280156114a057816020015b606081526020019060019003908161148b5790505b5091505f5b83811015611521576114fc308686848181106114c3576114c36153b6565b90506020028101906114d591906156ea565b856040516020016114e8939291906157cb565b604051602081830303815290604052612d3c565b83828151811061150e5761150e6153b6565b60209081029190910101526001016114a5565b505092915050565b611531611a93565b604080515f808252602082019092526115699161155e565b60608152602001906001900390816115495790505b50610490838561522e565b61159260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050565b61159e611a93565b835185516001600160a01b039182169116036115e6576040517f2a63c7cc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360400151836040013581518110611600576116006153b6565b60200260200101515f01516001600160a01b0316856060015184602001358151811061162e5761162e6153b6565b60200260200101515f01516001600160a01b03161415806116a75750604085015180518435908110611662576116626153b6565b60200260200101515f01516001600160a01b03168460600151846060013581518110611690576116906153b6565b60200260200101515f01516001600160a01b031614155b156116c55760405163936bb5ad60e01b815260040160405180910390fd5b84606001518360200135815181106116df576116df6153b6565b60200260200101515f01516001600160a01b03168560400151845f01358151811061170c5761170c6153b6565b60200260200101515f01516001600160a01b03160361173e57604051631cd2f1c760e21b815260040160405180910390fd5b5f805f61174a88611ac1565b81526020019081526020015f2054036117ba577fb70c12fa453793fa6818ec07c91e74363a47aa6a6829dcd9533937fdf30314f333865f015161178c88611ac1565b604080516001600160a01b0394851681529390921660208401529082015260600160405180910390a1611a6a565b5f805f6117c687611ac1565b81526020019081526020015f205403611808577fb70c12fa453793fa6818ec07c91e74363a47aa6a6829dcd9533937fdf30314f333855f015161178c87611ac1565b7f6fa7f4c28634b0a9d6831401c45ae468195fb63aed07308935c35374ff5d9e393386868660405161183d94939291906157ee565b60405180910390a15f61185d86855f01358660200135885f015186612115565b90505f61187886866040013587606001358a5f015188612115565b90505f6118858383612e0e565b90506118998160400151825f0151856128b1565b6118ac81606001518260200151846128b1565b606081015181515f916118bf9190612821565b90505f6118dd8360400151846020015161282190919063ffffffff16565b90506118e9825f612a79565b806118f957506118f9815f612a79565b15611930576040517f0d86822100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611964338b606001518a602001358151811061194e5761194e6153b6565b60200260200101515f01518a6080013585611dec565b505061199a338a606001518a6060013581518110611984576119846153b6565b60200260200101515f01518a60a0013584611dec565b5050604080513381528451602080830191909152850151818301529084015160608083019190915284015160808201527fd9fa84dd790c969daa5c33d8050dc06b4a9b59d5b42e2be5f5e8ae20447f618d925060a001905060405180910390a1611a0383612ab3565b611a0c82612ab3565b80516001600160e01b0316158015611a2f575060208101516001600160e01b0316155b15611a66576040517f21badf1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505b61061f60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b611a9b612e5c565b60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5f81604051602001611ad3919061586a565b604051602081830303815290604052805190602001209050919050565b335f8181523060209081526040808320815160a0810183528083018581526060808301879052608083018190529082528185015282518581529384018581528484019093529093909291905b8651811015611cb657868181518110611b5757611b576153b6565b602002602001015193505f845f015160400151511115611cae575f80855f01515f01516001600160a01b031663d04dfe236040518060e00160405280895f0151602001516001600160a01b031681526020018a8152602001895f01516040015181526020015f8152602001611bd08e8b60200151612eb9565b8152602001888152602001878152506040518263ffffffff1660e01b8152600401611bfb91906158d4565b5f60405180830381865afa158015611c15573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611c3c91908101906159cc565b8051919350915015611cab5785516020015160405163012c676d60e21b81526001600160a01b03909116906304b19db490611c7d908b908590600401615a82565b5f604051808303815f87803b158015611c94575f80fd5b505af1158015611ca6573d5f803e3d5ffd5b505050505b50505b600101611b3c565b5050505050505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d611cee848484846131b4565b12979650505050505050565b5f805f80611d0786613288565b90925090506001826003811115611d2057611d20615a9a565b14158015611d3f57505f826003811115611d3c57611d3c615a9a565b14155b15611d6157858260405163ee07877f60e01b81526004016103c7929190615aae565b611d6b855f612a79565b15611da2576040517fbabbeb0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80611dae8784613328565b9150915080611dc357611dc082615ae7565b91505b8115611dde57611dde6001600160a01b038916333085611f11565b5093509150505b9250929050565b5f80611df88382612a79565b15611e195760405163793a8f5560e01b8152600481018490526024016103c7565b6001600160a01b038087165f908152600160209081526040808320938916835292815282822087835290529081205490611e538286612881565b9050611e5f815f612a79565b15611e99576040517fc5e12af5000000000000000000000000000000000000000000000000000000008152600481018290526024016103c7565b6001600160a01b038089165f908152600160209081526040808320938b16835292815282822089835290522081905590925090505b94509492505050565b611ee48383836001613354565b611f0c57604051635274afe760e01b81526001600160a01b03841660048201526024016103c7565b505050565b611f1f8484848460016133cf565b611f4757604051635274afe760e01b81526001600160a01b03851660048201526024016103c7565b50505050565b5f611f588383612a79565b611f6257816104bf565b5090919050565b5f80611f758382612a79565b15611f965760405163793a8f5560e01b8152600481018490526024016103c7565b6001600160a01b038087165f908152600160209081526040808320938916835292815282822087835290529081205490611e538286612821565b5f805f80611fdd86613288565b90925090506001826003811115611ff657611ff6615a9a565b1415801561201557505f82600381111561201257612012615a9a565b14155b1561203757858260405163ee07877f60e01b81526004016103c7929190615aae565b612041855f612a79565b15612078576040517f5a2ce34600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f806120848784613328565b90925090508115611dde57611dde6001600160a01b0389163384611ed7565b826060015181815181106120b9576120b96153b6565b60200260200101515f01516001600160a01b0316836040015183815181106120e3576120e36153b6565b60200260200101515f01516001600160a01b031603611f0c57604051631cd2f1c760e21b815260040160405180910390fd5b61211d61468d565b5f61212787611ac1565b60408051600480825260a082019092529192506060915f91816020015b60608152602001906001900390816121445790505089516040805160038152602081018790526001600160a01b0392831681830152918916606083015260808201905290915081600180038151811061219f5761219f6153b6565b60200260200101819052505f806121d58b604001518b815181106121c5576121c56153b6565b60200260200101515f0151613455565b909250905060018260038111156121ee576121ee615a9a565b1415801561220d57505f82600381111561220a5761220a615a9a565b14155b1561224f578a604001518a81518110612228576122286153b6565b60200260200101515f01518260405163ee07877f60e01b81526004016103c7929190615aae565b8a516001600160a01b03165f90815260016020526040808220908d015180518391908e908110612281576122816153b6565b60200260200101515f01516001600160a01b03166001600160a01b031681526020019081526020015f205f8d604001518d815181106122c2576122c26153b6565b60200260200101516020015181526020019081526020015f2054905061236b8c604001518c815181106122f7576122f76153b6565b60200260200101515f01516001600160a01b03165f1b8360ff165f1b8e604001518e81518110612329576123296153b6565b602002602001015160200151845f801b60408051600581526020810196909652858101949094526060850192909252608084015260a083015260c08201905290565b84600160030381518110612381576123816153b6565b60200260200101819052505050505f806123aa8b606001518a815181106121c5576121c56153b6565b909250905060018260038111156123c3576123c3615a9a565b141580156123e257505f8260038111156123df576123df615a9a565b14155b156123fd578a606001518981518110612228576122286153b6565b8a516001600160a01b03165f90815260016020526040812060608d015180518391908d90811061242f5761242f6153b6565b60200260200101515f01516001600160a01b03166001600160a01b031681526020019081526020015f205f8d606001518c81518110612470576124706153b6565b60200260200101516020015181526020019081526020015f205490506124d78c606001518b815181106124a5576124a56153b6565b60200260200101515f01516001600160a01b03165f1b8360ff165f1b8e606001518d81518110612329576123296153b6565b846001600403815181106124ed576124ed6153b6565b60200260200101819052505050506125058186612eb9565b9150505f885f01516001600160a01b031690505f808a602001515f01516001600160a01b031663d04dfe236040518060e001604052808e60200151602001516001600160a01b0316815260200161256587305f9182526020526040902090565b81526020018e602001516040015181526020015f81526020018781526020015f67ffffffffffffffff81111561259d5761259d614b12565b6040519080825280602002602001820160405280156125c6578160200160208202803683370190505b5081526020015f6040519080825280602002602001820160405280156125f6578160200160208202803683370190505b508152506040518263ffffffff1660e01b815260040161261691906158d4565b5f60405180830381865afa158015612630573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261265791908101906159cc565b9150915060028251101561269c5781516040517f3eee39540000000000000000000000000000000000000000000000000000000081526004016103c791815260200190565b6020828101516040808501518e516001600160a01b03165f908152600190945290832060608f01518051939492938391908f9081106126dd576126dd6153b6565b60200260200101515f01516001600160a01b03166001600160a01b031681526020019081526020015f205f8f606001518e8151811061271e5761271e6153b6565b60200260200101516020015181526020019081526020015f2054905061274d8183611f4d90919063ffffffff16565b60408051600281526020810183905280820186905260608101909152909250905086600281518110612781576127816153b6565b60200260200101819052506040518060e001604052808e81526020018c81526020018281526020018381526020018781526020018681526020018481525097505050505050505095945050505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d8480612801868686866134c7565b915091505f8061281184846135e6565b509b9a5050505050505050505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d8480612801868686866136be565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d8480612801868686866136e8565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d848061280186868686613c1b565b8281608001516003815181106128c9576128c96153b6565b60200260200101516004815181106128e3576128e36153b6565b602002602001018181525050818160800151600481518110612907576129076153b6565b6020026020010151600481518110612921576129216153b6565b6020026020010181815250506129b0815f01515f0151826080015160038151811061294e5761294e6153b6565b60200260200101515f81518110612967576129676153b6565b60200260200101515f1c8360800151600381518110612988576129886153b6565b60200260200101516002815181106129a2576129a26153b6565b602002602001015186611dec565b5050612a35815f01515f015182608001516004815181106129d3576129d36153b6565b60200260200101515f815181106129ec576129ec6153b6565b60200260200101515f1c8360800151600481518110612a0d57612a0d6153b6565b6020026020010151600281518110612a2757612a276153b6565b602002602001015185611f69565b50507f4cb6e22a3e7e651d7cf0376cff48f20f5007a54147777865be7f5f6c38c50f4a338260800151604051612a6c929190615aff565b60405180910390a1505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d612aa7848484846131b4565b13979650505050505050565b60c08101515115612b2d578051602090810151015160a082015160c083015160405163012c676d60e21b81526001600160a01b03909316926304b19db492612aff929091600401615a82565b5f604051808303815f87803b158015612b16575f80fd5b505af1158015612b28573d5f803e3d5ffd5b505050505b5f80825f0151602001515f01516001600160a01b031663d04dfe236040518060e00160405280865f015160200151602001516001600160a01b03168152602001612b848760a00151305f9182526020526040902090565b8152602001865f01516020015160400151815260200160018152602001866080015181526020015f67ffffffffffffffff811115612bc457612bc4614b12565b604051908082528060200260200182016040528015612bed578160200160208202803683370190505b5081526020015f604051908082528060200260200182016040528015612c1d578160200160208202803683370190505b508152506040518263ffffffff1660e01b8152600401612c3d91906158d4565b5f60405180830381865afa158015612c57573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612c7e91908101906159cc565b8051919350915015611f0c578251602090810151015160a084015160405163012c676d60e21b81526001600160a01b03909216916304b19db491612cc6918590600401615a82565b5f604051808303815f87803b158015612cdd575f80fd5b505af1158015612cef573d5f803e3d5ffd5b50505050505050565b612d0181613d19565b612d3957806040517f644cc2580000000000000000000000000000000000000000000000000000000081526004016103c79190615b20565b50565b60605f612d498484613d47565b9050808015612d6a57505f3d1180612d6a57505f846001600160a01b03163b115b15612d7f57612d77613d5a565b915050610344565b8015612dc2576040517f9996b3150000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024016103c7565b3d15612dd557612dd0613d73565b612e07565b6040517fd6bda27500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5092915050565b604080516080810182525f808252602082018190529181018290526060810191909152612e3b8383613d7e565b82526040820152612e4c8284613d7e565b6020830152606082015292915050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0054600203612eb7576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60605f825167ffffffffffffffff811115612ed657612ed6614b12565b604051908082528060200260200182016040528015612eff578160200160208202803683370190505b5090505f80845111612f11575f612f17565b83516001015b85516001010190505f8167ffffffffffffffff811115612f3957612f39614b12565b604051908082528060200260200182016040528015612f6c57816020015b6060815260200190600190039081612f575790505b5090505f612f90604080516002815233602082015230818301526060810190915290565b828281518110612fa257612fa26153b6565b60200260200101819052505f5b8751811015612fff578180600101925050878181518110612fd257612fd26153b6565b6020026020010151838381518110612fec57612fec6153b6565b6020908102919091010152600101612faf565b508551156131aa57808060010191505083828281518110613022576130226153b6565b60200260200101819052505f5b86518110156131a8576130de87828151811061304d5761304d6153b6565b60200260200101515f01516130bb6130898a8581518110613070576130706153b6565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f908152601c91909152603c902090565b8984815181106130cd576130cd6153b6565b602002602001015160400151613de7565b613117576040517f52bf9848000000000000000000000000000000000000000000000000000000008152600481018290526024016103c7565b868181518110613129576131296153b6565b60200260200101515f01516001600160a01b03165f1b858281518110613151576131516153b6565b6020026020010181815250508180600101925050868181518110613177576131776153b6565b602002602001015160200151838381518110613195576131956153b6565b602090810291909101015260010161302f565b505b5095945050505050565b5f80851584151781871282861218178584141780156131d95786859250925050611ece565b505f858413156131ed575092949193919260015b8386035f8112604c8213178015613220578215613212575f8994509450505050611ece565b885f94509450505050611ece565b600a82900a8981028a82828161323857613238615b32565b0514613264578415613254575f8b965096505050505050611ece565b8a5f965096505050505050611ece565b8415613279578896509450611ece9350505050565b9550879450611ece9350505050565b6040517fb7bad1b10000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201525f90819073f66761f6b5f58202998d6cd944c81b22dc6d4f1e9063b7bad1b19060240160408051808303815f875af11580156132fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061331f9190615b46565b91509150915091565b5f806001600160e01b038416601b0b60e085901d613347828287613e57565b9350935050509250929050565b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f511483166133c35783831516156133b7573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b6040517f23b872dd000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038781166004528616602452604485905291602083606481808c5af1925060015f51148316613444578383151615613438573d5f823e3d81fd5b5f883b113d1516831692505b604052505f60605295945050505050565b6040517f0782d7e10000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201525f90819073f66761f6b5f58202998d6cd944c81b22dc6d4f1e90630782d7e1906024016040805180830381865afa1580156132fb573d5f803e3d5ffd5b5f80851584151780156134df575f92505f91506135dc565b6134e98487615b86565b91505f6134f588613f6f565b90505f61350187613f6f565b90505f61350e8383613f9d565b5090505f6f0785ee10d5da46d900f436a000000000821115613543576f0785ee10d5da46d900f436a000000000820491506025015b670de0b6b3a764000082111561356457670de0b6b3a7640000820491506012015b633b9aca0082111561357d57633b9aca00820491506009015b61271082111561359257612710820491506004015b81156135a657600a82049150600101613592565b6135b08187615b86565b95506135d28b8a6135cc87876135c787600a615c85565b613fb9565b8961409e565b9097509550505050505b5094509492505050565b5f601b83900b831483838261364a577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e100000000000000000086051561362a57620186a0860595506005850194505b8586601b0b1461364557600a8605955084600101945061362a565b613660565b855f0361366057505f925060019150611de59050565b848560030b146136a3575f85121561368057505f9250829150611de59050565b60405163d556b11160e01b815260048101839052602481018290526044016103c7565b50506001600160e01b03841660e084901b1791509250929050565b5f806136ca848461413e565b90945092506136db86868686613c1b565b9150915094509492505050565b5f80835f0361372d576040517f7a97930f00000000000000000000000000000000000000000000000000000000815260048101879052602481018690526044016103c7565b855f0361373e57505f905080611ece565b5f805f8061374c8a8a614193565b919b509950915061375d8888614193565b919950975090505f61376e8b613f6f565b90505f61377a8a613f6f565b90507f161bcca7119915b50764b4abe86529797775a5f1719510000000000000000000604c81831015613b1c5784156137d857507f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee80000000000000000009050604b613af4565b6f4b3b4ca85a86c47a098a22400000000083101561390457678ac7230489e80000831015613868576402540be40083101561383657620186a08310156138265750620186a090506005613adf565b506402540be4009050600a613adf565b655af3107a40008310156138555750655af3107a40009050600e613adf565b50678ac7230489e8000090506013613adf565b6b204fce5e3e250261100000008310156138ba5769152d02c7e14af68000008310156138a3575069152d02c7e14af680000090506017613adf565b506b204fce5e3e250261100000009050601c613adf565b6d314dc6448d9338c15b0a000000008310156138e957506d314dc6448d9338c15b0a0000000090506021613adf565b506f4b3b4ca85a86c47a098a22400000000090506026613adf565b780197d4df19d605767337e9f14d3eec8920e4000000000000008310156139fc5773af298d050e4395d69670b12b7f41000000000000831015613997577172cb5bd86321e38cb6ce6682e8000000000083101561397857507172cb5bd86321e38cb6ce6682e800000000009050602b613adf565b5073af298d050e4395d69670b12b7f4100000000000090506030613adf565b76010b46c6cdd6e3e0828f4db456ff0c8ea00000000000008310156139d8575076010b46c6cdd6e3e0828f4db456ff0c8ea000000000000090506035613adf565b50780197d4df19d605767337e9f14d3eec8920e4000000000000009050603a613adf565b7c03b58e88c75313ec9d329eaaa18fb92f75215b17100000000000000000831015613a92577a026e4d30eccc3215dd8f3157d27e23acbdcfe68000000000000000831015613a6a57507a026e4d30eccc3215dd8f3157d27e23acbdcfe680000000000000009050603f613adf565b507c03b58e88c75313ec9d329eaaa18fb92f75215b1710000000000000000090506044613adf565b7e05a8e89d75252446eb5d5d5b1cc5edf20a1a059e10ca000000000000000000831015613adf57507e05a8e89d75252446eb5d5d5b1cc5edf20a1a059e10ca000000000000000000905060495b818311613af457600a820491505f1901613adf565b85613b1c576040516305e51ecb60e01b8152600481018f9052602481018e90526044016103c7565b80600160ff1b018d12613b3357808d039c50613b71565b600160ff1b9c90038c015f811315613b7157806001600160ff1b03038b13613b5e57998a0199613b71565b5f80995099505050505050505050611ece565b5f808e128015613b8057505f8c135b15613ba157600160ff1b8e01808d13613b99575f613b9d565b808d035b9150505b8b818f01039750613bbe8f8e613bb8888789613fb9565b8b61409e565b90995097505f811315613c0857604c811315613be8575f809a509a50505050505050505050611ece565b80600a0a8981613bfa57613bfa615b32565b059850885f03613c08575f97505b50969850949650611ece95505050505050565b5f8085158415178015613c4757865f03613c3b5784849250925050611ece565b86869250925050611ece565b613c518787614439565b9097509550613c608585614439565b909550935085841315613c74579395929492935b838603604c811115613c8d578787935093505050611ece565b80600a0a8681613c9f57613c9f615b32565b0595505086850180881860ff90811c151589881890911c15168015613d0857876001600160ff1b0303613cef5760405163d556b11160e01b8152600481018a9052602481018990526044016103c7565b600a968790059690980586019760019790970196613d0c565b8198505b5096979596505050505050565b5f600882511015613d2b57505f919050565b506008015167ffffffffffffffff1667ff0a89c674ee78741490565b5f805f835160208501865af49392505050565b6040513d81523d5f602083013e3d602001810160405290565b6040513d5f823e3d81fd5b5f80613d9b846060015185604001516127d190919063ffffffff16565b915083604001519050613dbb836040015183611cc090919063ffffffff16565b15611de55782604001519150613dde84606001518361285190919063ffffffff16565b90509250929050565b5f836001600160a01b03163b5f03613e45575f80613e058585614482565b5090925090505f816003811115613e1e57613e1e615a9a565b148015613e3c5750856001600160a01b0316826001600160a01b0316145b925050506104bf565b613e508484846144c8565b90506104bf565b5f805f851215613e9d576040517f4a7d166b00000000000000000000000000000000000000000000000000000000815260048101869052602481018590526044016103c7565b845f03613eaf57505f90506001613f67565b8460ff8416850185811215613ee15760405163d556b11160e01b815260048101889052602481018790526044016103c7565b5f805f831215613f2d57604c19831215613f04575f809550955050505050613f67565b825f03600a0a9150818481613f1b57613f1b615b32565b0495505084029091149150613f679050565b5f831315613f5c57613f4083600a615c85565b9150613f4c8285615c90565b955060019450613f679350505050565b509193506001925050505b935093915050565b5f80821215613f9457600160ff1b8203613f8e5750600160ff1b919050565b505f0390565b5090565b919050565b5f805f1983850993909202808410938190039390930393915050565b5f805f613fc68686613f9d565b91509150815f03613fea57838181613fe057613fe0615b32565b04925050506104bf565b838210614034576040517f6c59da120000000000000000000000000000000000000000000000000000000081526004810187905260248101869052604481018590526064016103c7565b5f84868809600186198101871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103025f82900382900490920185841190960395909502919093039390930492909217029150509392505050565b5f805f858718121561411a576001600160ff1b03841115614107576140cb6001600160ff1b03600161535d565b84036140df5750600160ff1b905081611ece565b6140ea600a85615ca7565b6140f390615cc6565b6140fe846001615b86565b91509150611ece565b61411084615cc6565b8391509150611ece565b6001600160ff1b03841115614134576140f3600a85615ca7565b5082905081611ece565b5f80600160ff1b8403614189576001600160ff1b03830361417c5760405163d556b11160e01b815260048101859052602481018490526044016103c7565b600a840593508260010192505b50505f9190910391565b5f805f845f036141ab57505f91508190506001614432565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee800000000000000000085055f036143bf576f4b3b4ca85a86c47a098a224000000000850515801561421457507f80000000000000000000000000000000000000000000000000000000000000268412155b15614235576f4b3b4ca85a86c47a098a224000000000850294506026840393505b7728c87cb5c89a2571ebfdcb54864ada834a00000000000000850515801561427d57507f80000000000000000000000000000000000000000000000000000000000000138412155b1561429657678ac7230489e80000850294506013840393505b7b097edd871cfda3a5697758bf0e3cbb5ac5741c64000000000000000085051580156142e257507f800000000000000000000000000000000000000000000000000000000000000a8412155b156142f8576402540be40085029450600a840393505b7e3899162693736ac531a5a58f1fbb4b746504382ca7e4000000000000000000850515801561434757507f80000000000000000000000000000000000000000000000000000000000000028412155b1561435d576064850294506002840393506142f8565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee800000000000000000085051580156143ad57507f80000000000000000000000000000000000000000000000000000000000000018412155b156143bf57600a850294506001840393505b600a808602908105861480156143f557507f80000000000000000000000000000000000000000000000000000000000000018512155b15614404578095506001850394505b50849250839150507f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee8000000000000000000820515155b9250925092565b5f805f805f6144488787614193565b92509250925080614476576040516305e51ecb60e01b815260048101889052602481018790526044016103c7565b50909590945092505050565b5f805f83516041036144b9576020840151604085015160608601515f1a6144ab88828585614532565b955095509550505050614432565b505081515f9150600290614432565b8051604080517f1626ba7e000000000000000000000000000000000000000000000000000000008082526004820186905260248201929092525f92906020820185604483015e60205f60648401838a5afa9050825f5114601f3d1116811693505050509392505050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561456b57505f915060039050826145f0565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa1580156145bc573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b0381166145e757505f9250600191508290506145f0565b92505f91508190505b9450945094915050565b604051806080016040528061460d614626565b81526020015f81526020015f8152602001606081525090565b6040518060a001604052805f6001600160a01b0316815260200161467460405180606001604052805f6001600160a01b031681526020015f6001600160a01b03168152602001606081525090565b8152606060208201819052604082018190525f91015290565b6040518060e001604052806146a0614626565b81526020015f81526020015f80191681526020015f8019168152602001606081526020015f8152602001606081525090565b5f602082840312156146e2575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146104bf575f80fd5b5f8083601f840112614721575f80fd5b50813567ffffffffffffffff811115614738575f80fd5b6020830191508360208260051b8501011115611de5575f80fd5b5f805f60408486031215614764575f80fd5b833567ffffffffffffffff8082111561477b575f80fd5b9085019060a0828803121561478e575f80fd5b909350602085013590808211156147a3575f80fd5b506147b086828701614711565b9497909650939450505050565b5f602082840312156147cd575f80fd5b5035919050565b6001600160a01b0381168114612d39575f80fd5b8035613f98816147d4565b5f805f805f60808688031215614807575f80fd5b8535614812816147d4565b94506020860135935060408601359250606086013567ffffffffffffffff81111561483b575f80fd5b61484788828901614711565b969995985093965092949392505050565b5f805f6060848603121561486a575f80fd5b8335614875816147d4565b92506020840135614885816147d4565b929592945050506040919091013590565b5f805f805f608086880312156148aa575f80fd5b85356148b5816147d4565b945060208601356148c5816147d4565b935060408601359250606086013567ffffffffffffffff808211156148e8575f80fd5b818801915088601f8301126148fb575f80fd5b813581811115614909575f80fd5b89602082850101111561491a575f80fd5b9699959850939650602001949392505050565b5f6020828403121561493d575f80fd5b81356104bf816147d4565b5f60c08284031215614958575f80fd5b50919050565b5f6020828403121561496e575f80fd5b813567ffffffffffffffff811115614984575f80fd5b61499084828501614948565b949350505050565b5f805f604084860312156149aa575f80fd5b833567ffffffffffffffff808211156149c1575f80fd5b6149cd87838801614948565b945060208601359150808211156147a3575f80fd5b5f602082840312156149f2575f80fd5b813567ffffffffffffffff811115614a08575f80fd5b8201608081850312156104bf575f80fd5b5f8060208385031215614a2a575f80fd5b823567ffffffffffffffff811115614a40575f80fd5b614a4c85828601614711565b90969095509350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f60208083016020845280855180835260408601915060408160051b8701019250602087015f5b82811015614adb57603f19888603018452614ac9858351614a58565b94509285019290850190600101614aad565b5092979650505050505050565b5f8060408385031215614af9575f80fd5b8235614b04816147d4565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff81118282101715614b4957614b49614b12565b60405290565b6040805190810167ffffffffffffffff81118282101715614b4957614b49614b12565b60405160a0810167ffffffffffffffff81118282101715614b4957614b49614b12565b604051601f8201601f1916810167ffffffffffffffff81118282101715614bbe57614bbe614b12565b604052919050565b5f82601f830112614bd5575f80fd5b813567ffffffffffffffff811115614bef57614bef614b12565b614c02601f8201601f1916602001614b95565b818152846020838601011115614c16575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60608284031215614c42575f80fd5b614c4a614b26565b90508135614c57816147d4565b81526020820135614c67816147d4565b6020820152604082013567ffffffffffffffff811115614c85575f80fd5b614c9184828501614bc6565b60408301525092915050565b5f67ffffffffffffffff821115614cb657614cb6614b12565b5060051b60200190565b5f60408284031215614cd0575f80fd5b614cd8614b4f565b90508135614ce5816147d4565b808252506020820135602082015292915050565b5f82601f830112614d08575f80fd5b81356020614d1d614d1883614c9d565b614b95565b8083825260208201915060208460061b870101935086841115614d3e575f80fd5b602086015b84811015614d6357614d558882614cc0565b835291830191604001614d43565b509695505050505050565b5f60a08284031215614d7e575f80fd5b614d86614b72565b9050614d91826147e8565b8152602082013567ffffffffffffffff80821115614dad575f80fd5b614db985838601614c32565b60208401526040840135915080821115614dd1575f80fd5b614ddd85838601614cf9565b60408401526060840135915080821115614df5575f80fd5b50614e0284828501614cf9565b6060830152506080820135608082015292915050565b5f614e25614d1884614c9d565b8381529050602080820190600585811b850187811115614e43575f80fd5b855b81811015614f3057803567ffffffffffffffff80821115614e64575f80fd5b908801906060828c031215614e77575f80fd5b614e7f614b26565b8235614e8a816147d4565b81528287013582811115614e9c575f80fd5b8301601f81018d13614eac575f80fd5b8035614eba614d1882614c9d565b81815290881b8201890190898101908f831115614ed5575f80fd5b928a01925b82841015614ef35783358252928a0192908a0190614eda565b848b01525060409150508381013583811115614f0d575f80fd5b614f198e828701614bc6565b918301919091525087525050938301938301614e45565b50505050509392505050565b5f82601f830112614f4b575f80fd5b6104bf83833560208501614e18565b5f805f805f6101408688031215614f6f575f80fd5b853567ffffffffffffffff80821115614f86575f80fd5b614f9289838a01614d6e565b96506020880135915080821115614fa7575f80fd5b614fb389838a01614d6e565b9550614fc28960408a01614948565b9450610100880135915080821115614fd8575f80fd5b614fe489838a01614f3c565b9350610120880135915080821115614ffa575f80fd5b5061500788828901614f3c565b9150509295509295909350565b5f6103443683614d6e565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f8135615053816147d4565b6001600160a01b03908116845260208301359061506f826147d4565b166020840152604082013536839003601e1901811261508c575f80fd5b820160208101903567ffffffffffffffff8111156150a8575f80fd5b8036038213156150b6575f80fd5b606060408601526150cb60608601828461501f565b95945050505050565b5f808335601e198436030181126150e9575f80fd5b830160208101925035905067ffffffffffffffff811115615108575f80fd5b8060061b3603821315611de5575f80fd5b8183525f60208085019450825f5b8581101561515f57813561513a816147d4565b6001600160a01b03168752818301358388015260409687019690910190600101615127565b509495945050505050565b5f6001600160a01b038086168352846020840152606060408401528335615190816147d4565b166060830152602083013536849003605e190181126151ad575f80fd5b60a060808401526151c46101008401858301615047565b90506151d360408501856150d4565b605f19808685030160a08701526151eb848385615119565b93506151fa60608801886150d4565b93509150808685030160c087015250615214838383615119565b92505050608084013560e084015280915050949350505050565b5f61523b614d1884614c9d565b80848252602080830192508560051b850136811115615258575f80fd5b855b818110156152e257803567ffffffffffffffff80821115615279575f80fd5b81890191506040823603121561528d575f80fd5b615295614b4f565b8235828111156152a3575f80fd5b6152af36828601614c32565b82525085830135828111156152c2575f80fd5b6152ce36828601614f3c565b82880152508752505093820193820161525a565b50919695505050505050565b5f6001600160a01b03808916835280881660208401525085604083015284606083015260a0608083015261532660a08301848661501f565b98975050505050505050565b5f60208284031215615342575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561034457610344615349565b5f808335601e19843603018112615385575f80fd5b83018035915067ffffffffffffffff82111561539f575f80fd5b6020019150600581901b3603821315611de5575f80fd5b634e487b7160e01b5f52603260045260245ffd5b5f8235607e198336030181126153de575f80fd5b9190910192915050565b5f8235609e198336030181126153de575f80fd5b5f808335601e19843603018112615411575f80fd5b83018035915067ffffffffffffffff82111561542b575f80fd5b6020019150600681901b3603821315611de5575f80fd5b5f60808236031215615452575f80fd5b6040516080810167ffffffffffffffff828210818311171561547657615476614b12565b81604052843591508082111561548a575f80fd5b61549636838701614d6e565b8352602085013560208401526040850135604084015260608501359150808211156154bf575f80fd5b506154cc36828601614f3c565b60608301525092915050565b5f602082840312156154e8575f80fd5b813580151581146104bf575f80fd5b5f815180845260208085019450602084015f5b8381101561515f57815180516001600160a01b03168852830151838801526040909601959082019060010161550a565b5f6001600160a01b03808351168452602083015160a060208601528181511660a08601528160208201511660c08601526040810151915050606060e0850152615587610100850182614a58565b9050604083015184820360408601526155a082826154f7565b915050606083015184820360608601526155ba82826154f7565b915050608083015160808501528091505092915050565b5f815180845260208085019450602084015f5b8381101561515f578151875295820195908201906001016155e4565b5f6001600160a01b0380871683526020608081850152865160808086015261562c61010086018261553a565b90508188015160a086015260408089015160c08701526060808a0151607f198885030160e08901528381518086528686019150868160051b87010187840193505f5b828110156156c857601f1988830301845284518a815116835289810151878b85015261569c888501826155d1565b91890151848303858b01529190506156b48183614a58565b968b0196958b01959350505060010161566e565b5080995050505050505050505083604083015282606083015295945050505050565b5f808335601e198436030181126156ff575f80fd5b83018035915067ffffffffffffffff821115615719575f80fd5b602001915036819003821315611de5575f80fd5b5f8235605e198336030181126153de575f80fd5b5f6103443683614c32565b5f6040828403121561575c575f80fd5b6104bf8383614cc0565b6001600160a01b0384168152826020820152606060408201525f6150cb606083018461553a565b6001600160a01b0385168152836020820152606060408201525f6157b560608301848661501f565b9695505050505050565b5f6104bf368484614e18565b828482375f8382015f815283518060208601835e5f910190815295945050505050565b5f6101206001600160a01b03871683528060208401526158108184018761553a565b90508281036040840152615824818661553a565b9150508235606083015260208301356080830152604083013560a0830152606083013560c0830152608083013560e083015260a083013561010083015295945050505050565b602081525f6104bf602083018461553a565b5f8282518085526020808601955060208260051b840101602086015f5b848110156158c757601f198684030189526158b58383516155d1565b98840198925090830190600101615899565b5090979650505050505050565b602081526001600160a01b038251166020820152602082015160408201525f604083015160e0606084015261590d610100840182614a58565b9050606084015160808401526080840151601f19808584030160a0860152615935838361587c565b925060a08601519150808584030160c086015261595283836155d1565b925060c08601519150808584030160e0860152506150cb82826155d1565b5f82601f83011261597f575f80fd5b8151602061598f614d1883614c9d565b8083825260208201915060208460051b8701019350868411156159b0575f80fd5b602086015b84811015614d6357805183529183019183016159b5565b5f80604083850312156159dd575f80fd5b825167ffffffffffffffff808211156159f4575f80fd5b818501915085601f830112615a07575f80fd5b81516020615a17614d1883614c9d565b82815260059290921b84018101918181019089841115615a35575f80fd5b948201945b83861015615a5357855182529482019490820190615a3a565b91880151919650909350505080821115615a6b575f80fd5b50615a7885828601615970565b9150509250929050565b828152604060208201525f61499060408301846155d1565b634e487b7160e01b5f52602160045260245ffd5b6001600160a01b03831681526040810160048310615ada57634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b5f60018201615af857615af8615349565b5060010190565b6001600160a01b0383168152604060208201525f614990604083018461587c565b602081525f6104bf6020830184614a58565b634e487b7160e01b5f52601260045260245ffd5b5f8060408385031215615b57575f80fd5b825160048110615b65575f80fd5b602084015190925060ff81168114615b7b575f80fd5b809150509250929050565b8082018281125f83128015821682158216171561152157611521615349565b600181815b80851115615bdf57815f1904821115615bc557615bc5615349565b80851615615bd257918102915b93841c9390800290615baa565b509250929050565b5f82615bf557506001610344565b81615c0157505f610344565b8160018114615c175760028114615c2157615c3d565b6001915050610344565b60ff841115615c3257615c32615349565b50506001821b610344565b5060208310610133831016604e8410600b8410161715615c60575081810a610344565b615c6a8383615ba5565b805f1904821115615c7d57615c7d615349565b029392505050565b5f6104bf8383615be7565b808202811582820484141761034457610344615349565b5f82615cc157634e487b7160e01b5f52601260045260245ffd5b500490565b5f600160ff1b8203613f8e57613f8e61534956","sourceMap":"8701:36248:253:-:0;;;;;;;;;;;;-1:-1:-1;2365:1:171;1505:66;2539;8701:36248:253;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x608060405234801561000f575f80fd5b50600436106100f0575f3560e01c8063613255ab11610093578063ac9650d811610063578063ac9650d814610257578063d7e442ec14610277578063d9d98ce41461028a578063fa5011821461029f575f80fd5b8063613255ab146101d957806369c72856146101ec578063709fb8a5146102145780639235084d14610227575f80fd5b80632fbc4ba0116100ce5780632fbc4ba01461015157806341d1514f146101665780635cffe9de146101b357806360746119146101c6575f80fd5b806301ffc9a7146100f45780631f69cb751461011c5780632cb77e9f1461012f575b5f80fd5b6101076101023660046146d2565b6102b2565b60405190151581526020015b60405180910390f35b61010761012a366004614752565b61034a565b61010761013d3660046147bd565b5f9081526020819052604090205460011490565b61016461015f3660046147f3565b6104c6565b005b6101a5610174366004614858565b6001600160a01b039283165f9081526001602090815260408083209490951682529283528381209181529152205490565b604051908152602001610113565b6101076101c1366004614896565b610626565b6101646101d43660046147f3565b610758565b6101a56101e736600461492d565b6108fe565b6101ff6101fa36600461495e565b61097f565b60408051928352602083019190915201610113565b610107610222366004614998565b61107e565b61023a6102353660046149e2565b611382565b604080519315158452602084019290925290820152606001610113565b61026a610265366004614a19565b611443565b6040516101139190614a86565b610164610285366004614a19565b611529565b6101a5610298366004614ae8565b5f92915050565b6101646102ad366004614f5a565b611596565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167fe414309100000000000000000000000000000000000000000000000000000000148061034457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f610353611a93565b610360602085018561492d565b6001600160a01b0316336001600160a01b0316146103d05733610386602086018661492d565b6040517f4702b9140000000000000000000000000000000000000000000000000000000081526001600160a01b039283166004820152911660248201526044015b60405180910390fd5b5f6103e26103dd86615014565b611ac1565b5f818152602081905260409020549091505f1901610495575f818152602081905260408082209190915551600192507f09d18501db0080ca2d6cd7c17fa7255daff4b2d503ea93b76ff68b6752ea8e63906104429033908490899061516a565b60405180910390a160408051600281526020810183905233818301526060810190915261049590610486905b60408051600181526020810192909252818101905290565b610490858761522e565b611af0565b506104bf60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b9392505050565b6104ce611a93565b6104d8835f611cc0565b610526576040517f6dde9c300000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0386166024820152604481018590526064016103c7565b5f806105328786611cfa565b604080513381526001600160a01b038b1660208201529081018990526060810183905291935091507f7f9dfa19cf1cc2f806f2f860fbc9c056b601fb1afc0e9b843dfe5c63616268e69060800160405180910390a15f80610595338a8a8a611dec565b909250905084156105f25760408051600581526001600160a01b038b1660208201528082018a9052606081018490526080810183905260ff851660a082015260c081019091526105f2906105e89061046e565b610490878961522e565b5050505061061f60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050505050565b5f61063b6001600160a01b0386168786611ed7565b6040517f23e30c8b0000000000000000000000000000000000000000000000000000000081525f906001600160a01b038816906323e30c8b9061068c9033908a908a9087908b908b906004016152ee565b6020604051808303815f875af11580156106a8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106cc9190615332565b90507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9811461072a576040517f5b62c548000000000000000000000000000000000000000000000000000000008152600481018290526024016103c7565b61074b87306107395f8961535d565b6001600160a01b038a16929190611f11565b5060019695505050505050565b610760611a93565b61076a835f611cc0565b6107b7576040517ee8e9340000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0386166024820152604481018590526064016103c7565b335f9081526001602090815260408083206001600160a01b03891684528252808320878452909152812054906107ed8583611f4d565b90505f806107fd338a8a86611f69565b915091505f8061080d8b86611fd0565b604080513381526001600160a01b038f1660208201529081018d9052606081018c90526080810188905260a0810183905291935091507f8045c25080b0868951141ed0a91720bcad09a8364a2b3109ee1fd49c1f0bc8b89060c00160405180910390a186156108cf5760408051600681526001600160a01b038d1660208201528082018c9052606081018690526080810185905260a081018b905260ff831660c082015260e081019091526108cf906108c59061046e565b610490898b61522e565b50505050505061061f60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa15801561095b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103449190615332565b5f80610989611a93565b6109966080840184615370565b90505f036109d0576040517f9c95219f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109d86145fa565b6109e0614626565b5f6109ee6080870187615370565b5f8181106109fe576109fe6153b6565b9050602002810190610a1091906153ca565b610a1a90806153e8565b610a289060408101906153fc565b610a356080890189615370565b5f818110610a4557610a456153b6565b9050602002810190610a5791906153ca565b60200135818110610a6a57610a6a6153b6565b610a80926020604090920201908101915061492d565b90505f610a906080880188615370565b5f818110610aa057610aa06153b6565b9050602002810190610ab291906153ca565b610abc90806153e8565b610aca9060608101906153fc565b610ad760808a018a615370565b5f818110610ae757610ae76153b6565b9050602002810190610af991906153ca565b60400135818110610b0c57610b0c6153b6565b610b22926020604090920201908101915061492d565b905060605f610b3460808a018a615370565b6040805160206001939093018302810190915293508a01359150610b5a9050815f611cc0565b610b90576040517fc57e788c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5b610b9f60808b018b615370565b905081108015610bb45750610bb4825f611cc0565b15610f1157610bc660808b018b615370565b82818110610bd657610bd66153b6565b9050602002810190610be891906153ca565b610bf190615442565b9650865f01519550846001600160a01b03168660400151886020015181518110610c1d57610c1d6153b6565b60200260200101515f01516001600160a01b0316141580610c745750836001600160a01b03168660600151886040015181518110610c5d57610c5d6153b6565b60200260200101515f01516001600160a01b031614155b15610c925760405163936bb5ad60e01b815260040160405180910390fd5b610ca586886020015189604001516120a3565b5f610caf87611ac1565b5f81815260208190526040902054909150610d14578651604080513381526001600160a01b03909216602083015281018290527fb70c12fa453793fa6818ec07c91e74363a47aa6a6829dcd9533937fdf30314f39060600160405180910390a1610f08565b5f610d2e888a602001518b60400151338d60600151612115565b6060810151909150610d449060408e0135611cc0565b15610d9a578751604080513381526001600160a01b03909216602083015281018390527fe3151dc8cb7a54ffc4baabd28c1f241c94d510b5e5b502491ac3cad6c16316d5906060015b60405180910390a1610f06565b60408101516001600160e01b0316610df4578751604080513381526001600160a01b03909216602083015281018390527f500b713857325f9e6dcb52ae832eca9109d107ed1aae9cb4928b4c1e13f051aa90606001610d8d565b5f808d6060016020810190610e0991906154d8565b15610e42576040830151610e1d9087611f4d565b6060840151909250610e2f90836127d1565b9050610e3b8683612821565b9550610e93565b5f610e5e846040015185606001516127d190919063ffffffff16565b9050610e6a8188611f4d565b9150610e8384606001518361285190919063ffffffff16565b9250610e8f8783612821565b9650505b610e9d8c82612881565b9b50610ea98d83612881565b9c50610eb68183856128b1565b7f194f1feb3b4d7076a2c272e774e792e0c48bb8c7aa1a9a3671c1cd6da9e6b4c1338c8484604051610eeb9493929190615600565b60405180910390a15050845160010180865260200285018190525b505b50600101610b92565b505f9050610f2560808a0160608b016154d8565b610f2f5786610f31565b875b9050610f3e818a35612a79565b15610f7f576040517f573b6f4100000000000000000000000000000000000000000000000000000000815289356004820152602481018290526044016103c7565b50610f8a8288611fd0565b505f9050610f9b60a08a018a6156ea565b90501115611009573363691f9ed783858a8a610fba60a08f018f6156ea565b6040518763ffffffff1660e01b8152600401610fdb969594939291906152ee565b5f604051808303815f87803b158015610ff2575f80fd5b505af1158015611004573d5f803e3d5ffd5b505050505b6110138387611cfa565b50505f5b815181101561104a57611042828281518110611035576110356153b6565b6020026020010151612ab3565b600101611017565b50505050505061107960017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b915091565b5f611087611a93565b61109460208501856153fc565b90505f036110ce576040517f6c44ef8f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110db60408501856153fc565b90505f03611115576040517f540e5f0b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a081019091523381525f9060208101611133878061572d565b61113c90615741565b815260200186806020019061115191906153fc565b808060200260200160405190810160405280939291908181526020015f905b8282101561119c5761118d6040830286013681900381019061574c565b81526020019060010190611170565b50505091835250506020016111b460408801886153fc565b808060200260200160405190810160405280939291908181526020015f905b828210156111ff576111f06040830286013681900381019061574c565b815260200190600101906111d3565b50505050508152602001866060013581525090505f61121d82611ac1565b5f81815260208190526040902054909150158015611355575f828152602081905260409081902060019055835190517f87491344dfbcf91f6cbbc610cbbeedc85313d37a02df0c93527f7ea5f8db717f9161127b9185908790615766565b60405180910390a15f61129160a08901896156ea565b9050111561132d576112e26112a960a08901896156ea565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250612cf892505050565b82517fd46c2c56b35c8210e9e712ec3f02242d5fc90187c0ac8ed80cc33626846ec369908361131460a08b018b6156ea565b604051611324949392919061578d565b60405180910390a15b604080516002815260208101849052338183015260608101909152611355906105e89061046e565b925050506104bf60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5f80808061139c61139386806153e8565b6103dd90615014565b5f818152602081905260409020549091506001146113c357505f925082915081905061143c565b6113e86113d086806153e8565b6113d990615014565b866020013587604001356120a3565b5f6114256113f687806153e8565b6113ff90615014565b602088013560408901353361141760608c018c615370565b611420916157bf565b612115565b905060018160400151826060015194509450945050505b9193909250565b604080515f8152602081019091526060908267ffffffffffffffff81111561146d5761146d614b12565b6040519080825280602002602001820160405280156114a057816020015b606081526020019060019003908161148b5790505b5091505f5b83811015611521576114fc308686848181106114c3576114c36153b6565b90506020028101906114d591906156ea565b856040516020016114e8939291906157cb565b604051602081830303815290604052612d3c565b83828151811061150e5761150e6153b6565b60209081029190910101526001016114a5565b505092915050565b611531611a93565b604080515f808252602082019092526115699161155e565b60608152602001906001900390816115495790505b50610490838561522e565b61159260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050565b61159e611a93565b835185516001600160a01b039182169116036115e6576040517f2a63c7cc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360400151836040013581518110611600576116006153b6565b60200260200101515f01516001600160a01b0316856060015184602001358151811061162e5761162e6153b6565b60200260200101515f01516001600160a01b03161415806116a75750604085015180518435908110611662576116626153b6565b60200260200101515f01516001600160a01b03168460600151846060013581518110611690576116906153b6565b60200260200101515f01516001600160a01b031614155b156116c55760405163936bb5ad60e01b815260040160405180910390fd5b84606001518360200135815181106116df576116df6153b6565b60200260200101515f01516001600160a01b03168560400151845f01358151811061170c5761170c6153b6565b60200260200101515f01516001600160a01b03160361173e57604051631cd2f1c760e21b815260040160405180910390fd5b5f805f61174a88611ac1565b81526020019081526020015f2054036117ba577fb70c12fa453793fa6818ec07c91e74363a47aa6a6829dcd9533937fdf30314f333865f015161178c88611ac1565b604080516001600160a01b0394851681529390921660208401529082015260600160405180910390a1611a6a565b5f805f6117c687611ac1565b81526020019081526020015f205403611808577fb70c12fa453793fa6818ec07c91e74363a47aa6a6829dcd9533937fdf30314f333855f015161178c87611ac1565b7f6fa7f4c28634b0a9d6831401c45ae468195fb63aed07308935c35374ff5d9e393386868660405161183d94939291906157ee565b60405180910390a15f61185d86855f01358660200135885f015186612115565b90505f61187886866040013587606001358a5f015188612115565b90505f6118858383612e0e565b90506118998160400151825f0151856128b1565b6118ac81606001518260200151846128b1565b606081015181515f916118bf9190612821565b90505f6118dd8360400151846020015161282190919063ffffffff16565b90506118e9825f612a79565b806118f957506118f9815f612a79565b15611930576040517f0d86822100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611964338b606001518a602001358151811061194e5761194e6153b6565b60200260200101515f01518a6080013585611dec565b505061199a338a606001518a6060013581518110611984576119846153b6565b60200260200101515f01518a60a0013584611dec565b5050604080513381528451602080830191909152850151818301529084015160608083019190915284015160808201527fd9fa84dd790c969daa5c33d8050dc06b4a9b59d5b42e2be5f5e8ae20447f618d925060a001905060405180910390a1611a0383612ab3565b611a0c82612ab3565b80516001600160e01b0316158015611a2f575060208101516001600160e01b0316155b15611a66576040517f21badf1f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505b61061f60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b611a9b612e5c565b60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5f81604051602001611ad3919061586a565b604051602081830303815290604052805190602001209050919050565b335f8181523060209081526040808320815160a0810183528083018581526060808301879052608083018190529082528185015282518581529384018581528484019093529093909291905b8651811015611cb657868181518110611b5757611b576153b6565b602002602001015193505f845f015160400151511115611cae575f80855f01515f01516001600160a01b031663d04dfe236040518060e00160405280895f0151602001516001600160a01b031681526020018a8152602001895f01516040015181526020015f8152602001611bd08e8b60200151612eb9565b8152602001888152602001878152506040518263ffffffff1660e01b8152600401611bfb91906158d4565b5f60405180830381865afa158015611c15573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611c3c91908101906159cc565b8051919350915015611cab5785516020015160405163012c676d60e21b81526001600160a01b03909116906304b19db490611c7d908b908590600401615a82565b5f604051808303815f87803b158015611c94575f80fd5b505af1158015611ca6573d5f803e3d5ffd5b505050505b50505b600101611b3c565b5050505050505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d611cee848484846131b4565b12979650505050505050565b5f805f80611d0786613288565b90925090506001826003811115611d2057611d20615a9a565b14158015611d3f57505f826003811115611d3c57611d3c615a9a565b14155b15611d6157858260405163ee07877f60e01b81526004016103c7929190615aae565b611d6b855f612a79565b15611da2576040517fbabbeb0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80611dae8784613328565b9150915080611dc357611dc082615ae7565b91505b8115611dde57611dde6001600160a01b038916333085611f11565b5093509150505b9250929050565b5f80611df88382612a79565b15611e195760405163793a8f5560e01b8152600481018490526024016103c7565b6001600160a01b038087165f908152600160209081526040808320938916835292815282822087835290529081205490611e538286612881565b9050611e5f815f612a79565b15611e99576040517fc5e12af5000000000000000000000000000000000000000000000000000000008152600481018290526024016103c7565b6001600160a01b038089165f908152600160209081526040808320938b16835292815282822089835290522081905590925090505b94509492505050565b611ee48383836001613354565b611f0c57604051635274afe760e01b81526001600160a01b03841660048201526024016103c7565b505050565b611f1f8484848460016133cf565b611f4757604051635274afe760e01b81526001600160a01b03851660048201526024016103c7565b50505050565b5f611f588383612a79565b611f6257816104bf565b5090919050565b5f80611f758382612a79565b15611f965760405163793a8f5560e01b8152600481018490526024016103c7565b6001600160a01b038087165f908152600160209081526040808320938916835292815282822087835290529081205490611e538286612821565b5f805f80611fdd86613288565b90925090506001826003811115611ff657611ff6615a9a565b1415801561201557505f82600381111561201257612012615a9a565b14155b1561203757858260405163ee07877f60e01b81526004016103c7929190615aae565b612041855f612a79565b15612078576040517f5a2ce34600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f806120848784613328565b90925090508115611dde57611dde6001600160a01b0389163384611ed7565b826060015181815181106120b9576120b96153b6565b60200260200101515f01516001600160a01b0316836040015183815181106120e3576120e36153b6565b60200260200101515f01516001600160a01b031603611f0c57604051631cd2f1c760e21b815260040160405180910390fd5b61211d61468d565b5f61212787611ac1565b60408051600480825260a082019092529192506060915f91816020015b60608152602001906001900390816121445790505089516040805160038152602081018790526001600160a01b0392831681830152918916606083015260808201905290915081600180038151811061219f5761219f6153b6565b60200260200101819052505f806121d58b604001518b815181106121c5576121c56153b6565b60200260200101515f0151613455565b909250905060018260038111156121ee576121ee615a9a565b1415801561220d57505f82600381111561220a5761220a615a9a565b14155b1561224f578a604001518a81518110612228576122286153b6565b60200260200101515f01518260405163ee07877f60e01b81526004016103c7929190615aae565b8a516001600160a01b03165f90815260016020526040808220908d015180518391908e908110612281576122816153b6565b60200260200101515f01516001600160a01b03166001600160a01b031681526020019081526020015f205f8d604001518d815181106122c2576122c26153b6565b60200260200101516020015181526020019081526020015f2054905061236b8c604001518c815181106122f7576122f76153b6565b60200260200101515f01516001600160a01b03165f1b8360ff165f1b8e604001518e81518110612329576123296153b6565b602002602001015160200151845f801b60408051600581526020810196909652858101949094526060850192909252608084015260a083015260c08201905290565b84600160030381518110612381576123816153b6565b60200260200101819052505050505f806123aa8b606001518a815181106121c5576121c56153b6565b909250905060018260038111156123c3576123c3615a9a565b141580156123e257505f8260038111156123df576123df615a9a565b14155b156123fd578a606001518981518110612228576122286153b6565b8a516001600160a01b03165f90815260016020526040812060608d015180518391908d90811061242f5761242f6153b6565b60200260200101515f01516001600160a01b03166001600160a01b031681526020019081526020015f205f8d606001518c81518110612470576124706153b6565b60200260200101516020015181526020019081526020015f205490506124d78c606001518b815181106124a5576124a56153b6565b60200260200101515f01516001600160a01b03165f1b8360ff165f1b8e606001518d81518110612329576123296153b6565b846001600403815181106124ed576124ed6153b6565b60200260200101819052505050506125058186612eb9565b9150505f885f01516001600160a01b031690505f808a602001515f01516001600160a01b031663d04dfe236040518060e001604052808e60200151602001516001600160a01b0316815260200161256587305f9182526020526040902090565b81526020018e602001516040015181526020015f81526020018781526020015f67ffffffffffffffff81111561259d5761259d614b12565b6040519080825280602002602001820160405280156125c6578160200160208202803683370190505b5081526020015f6040519080825280602002602001820160405280156125f6578160200160208202803683370190505b508152506040518263ffffffff1660e01b815260040161261691906158d4565b5f60405180830381865afa158015612630573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261265791908101906159cc565b9150915060028251101561269c5781516040517f3eee39540000000000000000000000000000000000000000000000000000000081526004016103c791815260200190565b6020828101516040808501518e516001600160a01b03165f908152600190945290832060608f01518051939492938391908f9081106126dd576126dd6153b6565b60200260200101515f01516001600160a01b03166001600160a01b031681526020019081526020015f205f8f606001518e8151811061271e5761271e6153b6565b60200260200101516020015181526020019081526020015f2054905061274d8183611f4d90919063ffffffff16565b60408051600281526020810183905280820186905260608101909152909250905086600281518110612781576127816153b6565b60200260200101819052506040518060e001604052808e81526020018c81526020018281526020018381526020018781526020018681526020018481525097505050505050505095945050505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d8480612801868686866134c7565b915091505f8061281184846135e6565b509b9a5050505050505050505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d8480612801868686866136be565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d8480612801868686866136e8565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d848061280186868686613c1b565b8281608001516003815181106128c9576128c96153b6565b60200260200101516004815181106128e3576128e36153b6565b602002602001018181525050818160800151600481518110612907576129076153b6565b6020026020010151600481518110612921576129216153b6565b6020026020010181815250506129b0815f01515f0151826080015160038151811061294e5761294e6153b6565b60200260200101515f81518110612967576129676153b6565b60200260200101515f1c8360800151600381518110612988576129886153b6565b60200260200101516002815181106129a2576129a26153b6565b602002602001015186611dec565b5050612a35815f01515f015182608001516004815181106129d3576129d36153b6565b60200260200101515f815181106129ec576129ec6153b6565b60200260200101515f1c8360800151600481518110612a0d57612a0d6153b6565b6020026020010151600281518110612a2757612a276153b6565b602002602001015185611f69565b50507f4cb6e22a3e7e651d7cf0376cff48f20f5007a54147777865be7f5f6c38c50f4a338260800151604051612a6c929190615aff565b60405180910390a1505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d612aa7848484846131b4565b13979650505050505050565b60c08101515115612b2d578051602090810151015160a082015160c083015160405163012c676d60e21b81526001600160a01b03909316926304b19db492612aff929091600401615a82565b5f604051808303815f87803b158015612b16575f80fd5b505af1158015612b28573d5f803e3d5ffd5b505050505b5f80825f0151602001515f01516001600160a01b031663d04dfe236040518060e00160405280865f015160200151602001516001600160a01b03168152602001612b848760a00151305f9182526020526040902090565b8152602001865f01516020015160400151815260200160018152602001866080015181526020015f67ffffffffffffffff811115612bc457612bc4614b12565b604051908082528060200260200182016040528015612bed578160200160208202803683370190505b5081526020015f604051908082528060200260200182016040528015612c1d578160200160208202803683370190505b508152506040518263ffffffff1660e01b8152600401612c3d91906158d4565b5f60405180830381865afa158015612c57573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612c7e91908101906159cc565b8051919350915015611f0c578251602090810151015160a084015160405163012c676d60e21b81526001600160a01b03909216916304b19db491612cc6918590600401615a82565b5f604051808303815f87803b158015612cdd575f80fd5b505af1158015612cef573d5f803e3d5ffd5b50505050505050565b612d0181613d19565b612d3957806040517f644cc2580000000000000000000000000000000000000000000000000000000081526004016103c79190615b20565b50565b60605f612d498484613d47565b9050808015612d6a57505f3d1180612d6a57505f846001600160a01b03163b115b15612d7f57612d77613d5a565b915050610344565b8015612dc2576040517f9996b3150000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024016103c7565b3d15612dd557612dd0613d73565b612e07565b6040517fd6bda27500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5092915050565b604080516080810182525f808252602082018190529181018290526060810191909152612e3b8383613d7e565b82526040820152612e4c8284613d7e565b6020830152606082015292915050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0054600203612eb7576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60605f825167ffffffffffffffff811115612ed657612ed6614b12565b604051908082528060200260200182016040528015612eff578160200160208202803683370190505b5090505f80845111612f11575f612f17565b83516001015b85516001010190505f8167ffffffffffffffff811115612f3957612f39614b12565b604051908082528060200260200182016040528015612f6c57816020015b6060815260200190600190039081612f575790505b5090505f612f90604080516002815233602082015230818301526060810190915290565b828281518110612fa257612fa26153b6565b60200260200101819052505f5b8751811015612fff578180600101925050878181518110612fd257612fd26153b6565b6020026020010151838381518110612fec57612fec6153b6565b6020908102919091010152600101612faf565b508551156131aa57808060010191505083828281518110613022576130226153b6565b60200260200101819052505f5b86518110156131a8576130de87828151811061304d5761304d6153b6565b60200260200101515f01516130bb6130898a8581518110613070576130706153b6565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f908152601c91909152603c902090565b8984815181106130cd576130cd6153b6565b602002602001015160400151613de7565b613117576040517f52bf9848000000000000000000000000000000000000000000000000000000008152600481018290526024016103c7565b868181518110613129576131296153b6565b60200260200101515f01516001600160a01b03165f1b858281518110613151576131516153b6565b6020026020010181815250508180600101925050868181518110613177576131776153b6565b602002602001015160200151838381518110613195576131956153b6565b602090810291909101015260010161302f565b505b5095945050505050565b5f80851584151781871282861218178584141780156131d95786859250925050611ece565b505f858413156131ed575092949193919260015b8386035f8112604c8213178015613220578215613212575f8994509450505050611ece565b885f94509450505050611ece565b600a82900a8981028a82828161323857613238615b32565b0514613264578415613254575f8b965096505050505050611ece565b8a5f965096505050505050611ece565b8415613279578896509450611ece9350505050565b9550879450611ece9350505050565b6040517fb7bad1b10000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201525f90819073f66761f6b5f58202998d6cd944c81b22dc6d4f1e9063b7bad1b19060240160408051808303815f875af11580156132fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061331f9190615b46565b91509150915091565b5f806001600160e01b038416601b0b60e085901d613347828287613e57565b9350935050509250929050565b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f511483166133c35783831516156133b7573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b6040517f23b872dd000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038781166004528616602452604485905291602083606481808c5af1925060015f51148316613444578383151615613438573d5f823e3d81fd5b5f883b113d1516831692505b604052505f60605295945050505050565b6040517f0782d7e10000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201525f90819073f66761f6b5f58202998d6cd944c81b22dc6d4f1e90630782d7e1906024016040805180830381865afa1580156132fb573d5f803e3d5ffd5b5f80851584151780156134df575f92505f91506135dc565b6134e98487615b86565b91505f6134f588613f6f565b90505f61350187613f6f565b90505f61350e8383613f9d565b5090505f6f0785ee10d5da46d900f436a000000000821115613543576f0785ee10d5da46d900f436a000000000820491506025015b670de0b6b3a764000082111561356457670de0b6b3a7640000820491506012015b633b9aca0082111561357d57633b9aca00820491506009015b61271082111561359257612710820491506004015b81156135a657600a82049150600101613592565b6135b08187615b86565b95506135d28b8a6135cc87876135c787600a615c85565b613fb9565b8961409e565b9097509550505050505b5094509492505050565b5f601b83900b831483838261364a577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e100000000000000000086051561362a57620186a0860595506005850194505b8586601b0b1461364557600a8605955084600101945061362a565b613660565b855f0361366057505f925060019150611de59050565b848560030b146136a3575f85121561368057505f9250829150611de59050565b60405163d556b11160e01b815260048101839052602481018290526044016103c7565b50506001600160e01b03841660e084901b1791509250929050565b5f806136ca848461413e565b90945092506136db86868686613c1b565b9150915094509492505050565b5f80835f0361372d576040517f7a97930f00000000000000000000000000000000000000000000000000000000815260048101879052602481018690526044016103c7565b855f0361373e57505f905080611ece565b5f805f8061374c8a8a614193565b919b509950915061375d8888614193565b919950975090505f61376e8b613f6f565b90505f61377a8a613f6f565b90507f161bcca7119915b50764b4abe86529797775a5f1719510000000000000000000604c81831015613b1c5784156137d857507f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee80000000000000000009050604b613af4565b6f4b3b4ca85a86c47a098a22400000000083101561390457678ac7230489e80000831015613868576402540be40083101561383657620186a08310156138265750620186a090506005613adf565b506402540be4009050600a613adf565b655af3107a40008310156138555750655af3107a40009050600e613adf565b50678ac7230489e8000090506013613adf565b6b204fce5e3e250261100000008310156138ba5769152d02c7e14af68000008310156138a3575069152d02c7e14af680000090506017613adf565b506b204fce5e3e250261100000009050601c613adf565b6d314dc6448d9338c15b0a000000008310156138e957506d314dc6448d9338c15b0a0000000090506021613adf565b506f4b3b4ca85a86c47a098a22400000000090506026613adf565b780197d4df19d605767337e9f14d3eec8920e4000000000000008310156139fc5773af298d050e4395d69670b12b7f41000000000000831015613997577172cb5bd86321e38cb6ce6682e8000000000083101561397857507172cb5bd86321e38cb6ce6682e800000000009050602b613adf565b5073af298d050e4395d69670b12b7f4100000000000090506030613adf565b76010b46c6cdd6e3e0828f4db456ff0c8ea00000000000008310156139d8575076010b46c6cdd6e3e0828f4db456ff0c8ea000000000000090506035613adf565b50780197d4df19d605767337e9f14d3eec8920e4000000000000009050603a613adf565b7c03b58e88c75313ec9d329eaaa18fb92f75215b17100000000000000000831015613a92577a026e4d30eccc3215dd8f3157d27e23acbdcfe68000000000000000831015613a6a57507a026e4d30eccc3215dd8f3157d27e23acbdcfe680000000000000009050603f613adf565b507c03b58e88c75313ec9d329eaaa18fb92f75215b1710000000000000000090506044613adf565b7e05a8e89d75252446eb5d5d5b1cc5edf20a1a059e10ca000000000000000000831015613adf57507e05a8e89d75252446eb5d5d5b1cc5edf20a1a059e10ca000000000000000000905060495b818311613af457600a820491505f1901613adf565b85613b1c576040516305e51ecb60e01b8152600481018f9052602481018e90526044016103c7565b80600160ff1b018d12613b3357808d039c50613b71565b600160ff1b9c90038c015f811315613b7157806001600160ff1b03038b13613b5e57998a0199613b71565b5f80995099505050505050505050611ece565b5f808e128015613b8057505f8c135b15613ba157600160ff1b8e01808d13613b99575f613b9d565b808d035b9150505b8b818f01039750613bbe8f8e613bb8888789613fb9565b8b61409e565b90995097505f811315613c0857604c811315613be8575f809a509a50505050505050505050611ece565b80600a0a8981613bfa57613bfa615b32565b059850885f03613c08575f97505b50969850949650611ece95505050505050565b5f8085158415178015613c4757865f03613c3b5784849250925050611ece565b86869250925050611ece565b613c518787614439565b9097509550613c608585614439565b909550935085841315613c74579395929492935b838603604c811115613c8d578787935093505050611ece565b80600a0a8681613c9f57613c9f615b32565b0595505086850180881860ff90811c151589881890911c15168015613d0857876001600160ff1b0303613cef5760405163d556b11160e01b8152600481018a9052602481018990526044016103c7565b600a968790059690980586019760019790970196613d0c565b8198505b5096979596505050505050565b5f600882511015613d2b57505f919050565b506008015167ffffffffffffffff1667ff0a89c674ee78741490565b5f805f835160208501865af49392505050565b6040513d81523d5f602083013e3d602001810160405290565b6040513d5f823e3d81fd5b5f80613d9b846060015185604001516127d190919063ffffffff16565b915083604001519050613dbb836040015183611cc090919063ffffffff16565b15611de55782604001519150613dde84606001518361285190919063ffffffff16565b90509250929050565b5f836001600160a01b03163b5f03613e45575f80613e058585614482565b5090925090505f816003811115613e1e57613e1e615a9a565b148015613e3c5750856001600160a01b0316826001600160a01b0316145b925050506104bf565b613e508484846144c8565b90506104bf565b5f805f851215613e9d576040517f4a7d166b00000000000000000000000000000000000000000000000000000000815260048101869052602481018590526044016103c7565b845f03613eaf57505f90506001613f67565b8460ff8416850185811215613ee15760405163d556b11160e01b815260048101889052602481018790526044016103c7565b5f805f831215613f2d57604c19831215613f04575f809550955050505050613f67565b825f03600a0a9150818481613f1b57613f1b615b32565b0495505084029091149150613f679050565b5f831315613f5c57613f4083600a615c85565b9150613f4c8285615c90565b955060019450613f679350505050565b509193506001925050505b935093915050565b5f80821215613f9457600160ff1b8203613f8e5750600160ff1b919050565b505f0390565b5090565b919050565b5f805f1983850993909202808410938190039390930393915050565b5f805f613fc68686613f9d565b91509150815f03613fea57838181613fe057613fe0615b32565b04925050506104bf565b838210614034576040517f6c59da120000000000000000000000000000000000000000000000000000000081526004810187905260248101869052604481018590526064016103c7565b5f84868809600186198101871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103025f82900382900490920185841190960395909502919093039390930492909217029150509392505050565b5f805f858718121561411a576001600160ff1b03841115614107576140cb6001600160ff1b03600161535d565b84036140df5750600160ff1b905081611ece565b6140ea600a85615ca7565b6140f390615cc6565b6140fe846001615b86565b91509150611ece565b61411084615cc6565b8391509150611ece565b6001600160ff1b03841115614134576140f3600a85615ca7565b5082905081611ece565b5f80600160ff1b8403614189576001600160ff1b03830361417c5760405163d556b11160e01b815260048101859052602481018490526044016103c7565b600a840593508260010192505b50505f9190910391565b5f805f845f036141ab57505f91508190506001614432565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee800000000000000000085055f036143bf576f4b3b4ca85a86c47a098a224000000000850515801561421457507f80000000000000000000000000000000000000000000000000000000000000268412155b15614235576f4b3b4ca85a86c47a098a224000000000850294506026840393505b7728c87cb5c89a2571ebfdcb54864ada834a00000000000000850515801561427d57507f80000000000000000000000000000000000000000000000000000000000000138412155b1561429657678ac7230489e80000850294506013840393505b7b097edd871cfda3a5697758bf0e3cbb5ac5741c64000000000000000085051580156142e257507f800000000000000000000000000000000000000000000000000000000000000a8412155b156142f8576402540be40085029450600a840393505b7e3899162693736ac531a5a58f1fbb4b746504382ca7e4000000000000000000850515801561434757507f80000000000000000000000000000000000000000000000000000000000000028412155b1561435d576064850294506002840393506142f8565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee800000000000000000085051580156143ad57507f80000000000000000000000000000000000000000000000000000000000000018412155b156143bf57600a850294506001840393505b600a808602908105861480156143f557507f80000000000000000000000000000000000000000000000000000000000000018512155b15614404578095506001850394505b50849250839150507f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee8000000000000000000820515155b9250925092565b5f805f805f6144488787614193565b92509250925080614476576040516305e51ecb60e01b815260048101889052602481018790526044016103c7565b50909590945092505050565b5f805f83516041036144b9576020840151604085015160608601515f1a6144ab88828585614532565b955095509550505050614432565b505081515f9150600290614432565b8051604080517f1626ba7e000000000000000000000000000000000000000000000000000000008082526004820186905260248201929092525f92906020820185604483015e60205f60648401838a5afa9050825f5114601f3d1116811693505050509392505050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561456b57505f915060039050826145f0565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa1580156145bc573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b0381166145e757505f9250600191508290506145f0565b92505f91508190505b9450945094915050565b604051806080016040528061460d614626565b81526020015f81526020015f8152602001606081525090565b6040518060a001604052805f6001600160a01b0316815260200161467460405180606001604052805f6001600160a01b031681526020015f6001600160a01b03168152602001606081525090565b8152606060208201819052604082018190525f91015290565b6040518060e001604052806146a0614626565b81526020015f81526020015f80191681526020015f8019168152602001606081526020015f8152602001606081525090565b5f602082840312156146e2575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146104bf575f80fd5b5f8083601f840112614721575f80fd5b50813567ffffffffffffffff811115614738575f80fd5b6020830191508360208260051b8501011115611de5575f80fd5b5f805f60408486031215614764575f80fd5b833567ffffffffffffffff8082111561477b575f80fd5b9085019060a0828803121561478e575f80fd5b909350602085013590808211156147a3575f80fd5b506147b086828701614711565b9497909650939450505050565b5f602082840312156147cd575f80fd5b5035919050565b6001600160a01b0381168114612d39575f80fd5b8035613f98816147d4565b5f805f805f60808688031215614807575f80fd5b8535614812816147d4565b94506020860135935060408601359250606086013567ffffffffffffffff81111561483b575f80fd5b61484788828901614711565b969995985093965092949392505050565b5f805f6060848603121561486a575f80fd5b8335614875816147d4565b92506020840135614885816147d4565b929592945050506040919091013590565b5f805f805f608086880312156148aa575f80fd5b85356148b5816147d4565b945060208601356148c5816147d4565b935060408601359250606086013567ffffffffffffffff808211156148e8575f80fd5b818801915088601f8301126148fb575f80fd5b813581811115614909575f80fd5b89602082850101111561491a575f80fd5b9699959850939650602001949392505050565b5f6020828403121561493d575f80fd5b81356104bf816147d4565b5f60c08284031215614958575f80fd5b50919050565b5f6020828403121561496e575f80fd5b813567ffffffffffffffff811115614984575f80fd5b61499084828501614948565b949350505050565b5f805f604084860312156149aa575f80fd5b833567ffffffffffffffff808211156149c1575f80fd5b6149cd87838801614948565b945060208601359150808211156147a3575f80fd5b5f602082840312156149f2575f80fd5b813567ffffffffffffffff811115614a08575f80fd5b8201608081850312156104bf575f80fd5b5f8060208385031215614a2a575f80fd5b823567ffffffffffffffff811115614a40575f80fd5b614a4c85828601614711565b90969095509350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f60208083016020845280855180835260408601915060408160051b8701019250602087015f5b82811015614adb57603f19888603018452614ac9858351614a58565b94509285019290850190600101614aad565b5092979650505050505050565b5f8060408385031215614af9575f80fd5b8235614b04816147d4565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff81118282101715614b4957614b49614b12565b60405290565b6040805190810167ffffffffffffffff81118282101715614b4957614b49614b12565b60405160a0810167ffffffffffffffff81118282101715614b4957614b49614b12565b604051601f8201601f1916810167ffffffffffffffff81118282101715614bbe57614bbe614b12565b604052919050565b5f82601f830112614bd5575f80fd5b813567ffffffffffffffff811115614bef57614bef614b12565b614c02601f8201601f1916602001614b95565b818152846020838601011115614c16575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60608284031215614c42575f80fd5b614c4a614b26565b90508135614c57816147d4565b81526020820135614c67816147d4565b6020820152604082013567ffffffffffffffff811115614c85575f80fd5b614c9184828501614bc6565b60408301525092915050565b5f67ffffffffffffffff821115614cb657614cb6614b12565b5060051b60200190565b5f60408284031215614cd0575f80fd5b614cd8614b4f565b90508135614ce5816147d4565b808252506020820135602082015292915050565b5f82601f830112614d08575f80fd5b81356020614d1d614d1883614c9d565b614b95565b8083825260208201915060208460061b870101935086841115614d3e575f80fd5b602086015b84811015614d6357614d558882614cc0565b835291830191604001614d43565b509695505050505050565b5f60a08284031215614d7e575f80fd5b614d86614b72565b9050614d91826147e8565b8152602082013567ffffffffffffffff80821115614dad575f80fd5b614db985838601614c32565b60208401526040840135915080821115614dd1575f80fd5b614ddd85838601614cf9565b60408401526060840135915080821115614df5575f80fd5b50614e0284828501614cf9565b6060830152506080820135608082015292915050565b5f614e25614d1884614c9d565b8381529050602080820190600585811b850187811115614e43575f80fd5b855b81811015614f3057803567ffffffffffffffff80821115614e64575f80fd5b908801906060828c031215614e77575f80fd5b614e7f614b26565b8235614e8a816147d4565b81528287013582811115614e9c575f80fd5b8301601f81018d13614eac575f80fd5b8035614eba614d1882614c9d565b81815290881b8201890190898101908f831115614ed5575f80fd5b928a01925b82841015614ef35783358252928a0192908a0190614eda565b848b01525060409150508381013583811115614f0d575f80fd5b614f198e828701614bc6565b918301919091525087525050938301938301614e45565b50505050509392505050565b5f82601f830112614f4b575f80fd5b6104bf83833560208501614e18565b5f805f805f6101408688031215614f6f575f80fd5b853567ffffffffffffffff80821115614f86575f80fd5b614f9289838a01614d6e565b96506020880135915080821115614fa7575f80fd5b614fb389838a01614d6e565b9550614fc28960408a01614948565b9450610100880135915080821115614fd8575f80fd5b614fe489838a01614f3c565b9350610120880135915080821115614ffa575f80fd5b5061500788828901614f3c565b9150509295509295909350565b5f6103443683614d6e565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f8135615053816147d4565b6001600160a01b03908116845260208301359061506f826147d4565b166020840152604082013536839003601e1901811261508c575f80fd5b820160208101903567ffffffffffffffff8111156150a8575f80fd5b8036038213156150b6575f80fd5b606060408601526150cb60608601828461501f565b95945050505050565b5f808335601e198436030181126150e9575f80fd5b830160208101925035905067ffffffffffffffff811115615108575f80fd5b8060061b3603821315611de5575f80fd5b8183525f60208085019450825f5b8581101561515f57813561513a816147d4565b6001600160a01b03168752818301358388015260409687019690910190600101615127565b509495945050505050565b5f6001600160a01b038086168352846020840152606060408401528335615190816147d4565b166060830152602083013536849003605e190181126151ad575f80fd5b60a060808401526151c46101008401858301615047565b90506151d360408501856150d4565b605f19808685030160a08701526151eb848385615119565b93506151fa60608801886150d4565b93509150808685030160c087015250615214838383615119565b92505050608084013560e084015280915050949350505050565b5f61523b614d1884614c9d565b80848252602080830192508560051b850136811115615258575f80fd5b855b818110156152e257803567ffffffffffffffff80821115615279575f80fd5b81890191506040823603121561528d575f80fd5b615295614b4f565b8235828111156152a3575f80fd5b6152af36828601614c32565b82525085830135828111156152c2575f80fd5b6152ce36828601614f3c565b82880152508752505093820193820161525a565b50919695505050505050565b5f6001600160a01b03808916835280881660208401525085604083015284606083015260a0608083015261532660a08301848661501f565b98975050505050505050565b5f60208284031215615342575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561034457610344615349565b5f808335601e19843603018112615385575f80fd5b83018035915067ffffffffffffffff82111561539f575f80fd5b6020019150600581901b3603821315611de5575f80fd5b634e487b7160e01b5f52603260045260245ffd5b5f8235607e198336030181126153de575f80fd5b9190910192915050565b5f8235609e198336030181126153de575f80fd5b5f808335601e19843603018112615411575f80fd5b83018035915067ffffffffffffffff82111561542b575f80fd5b6020019150600681901b3603821315611de5575f80fd5b5f60808236031215615452575f80fd5b6040516080810167ffffffffffffffff828210818311171561547657615476614b12565b81604052843591508082111561548a575f80fd5b61549636838701614d6e565b8352602085013560208401526040850135604084015260608501359150808211156154bf575f80fd5b506154cc36828601614f3c565b60608301525092915050565b5f602082840312156154e8575f80fd5b813580151581146104bf575f80fd5b5f815180845260208085019450602084015f5b8381101561515f57815180516001600160a01b03168852830151838801526040909601959082019060010161550a565b5f6001600160a01b03808351168452602083015160a060208601528181511660a08601528160208201511660c08601526040810151915050606060e0850152615587610100850182614a58565b9050604083015184820360408601526155a082826154f7565b915050606083015184820360608601526155ba82826154f7565b915050608083015160808501528091505092915050565b5f815180845260208085019450602084015f5b8381101561515f578151875295820195908201906001016155e4565b5f6001600160a01b0380871683526020608081850152865160808086015261562c61010086018261553a565b90508188015160a086015260408089015160c08701526060808a0151607f198885030160e08901528381518086528686019150868160051b87010187840193505f5b828110156156c857601f1988830301845284518a815116835289810151878b85015261569c888501826155d1565b91890151848303858b01529190506156b48183614a58565b968b0196958b01959350505060010161566e565b5080995050505050505050505083604083015282606083015295945050505050565b5f808335601e198436030181126156ff575f80fd5b83018035915067ffffffffffffffff821115615719575f80fd5b602001915036819003821315611de5575f80fd5b5f8235605e198336030181126153de575f80fd5b5f6103443683614c32565b5f6040828403121561575c575f80fd5b6104bf8383614cc0565b6001600160a01b0384168152826020820152606060408201525f6150cb606083018461553a565b6001600160a01b0385168152836020820152606060408201525f6157b560608301848661501f565b9695505050505050565b5f6104bf368484614e18565b828482375f8382015f815283518060208601835e5f910190815295945050505050565b5f6101206001600160a01b03871683528060208401526158108184018761553a565b90508281036040840152615824818661553a565b9150508235606083015260208301356080830152604083013560a0830152606083013560c0830152608083013560e083015260a083013561010083015295945050505050565b602081525f6104bf602083018461553a565b5f8282518085526020808601955060208260051b840101602086015f5b848110156158c757601f198684030189526158b58383516155d1565b98840198925090830190600101615899565b5090979650505050505050565b602081526001600160a01b038251166020820152602082015160408201525f604083015160e0606084015261590d610100840182614a58565b9050606084015160808401526080840151601f19808584030160a0860152615935838361587c565b925060a08601519150808584030160c086015261595283836155d1565b925060c08601519150808584030160e0860152506150cb82826155d1565b5f82601f83011261597f575f80fd5b8151602061598f614d1883614c9d565b8083825260208201915060208460051b8701019350868411156159b0575f80fd5b602086015b84811015614d6357805183529183019183016159b5565b5f80604083850312156159dd575f80fd5b825167ffffffffffffffff808211156159f4575f80fd5b818501915085601f830112615a07575f80fd5b81516020615a17614d1883614c9d565b82815260059290921b84018101918181019089841115615a35575f80fd5b948201945b83861015615a5357855182529482019490820190615a3a565b91880151919650909350505080821115615a6b575f80fd5b50615a7885828601615970565b9150509250929050565b828152604060208201525f61499060408301846155d1565b634e487b7160e01b5f52602160045260245ffd5b6001600160a01b03831681526040810160048310615ada57634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b5f60018201615af857615af8615349565b5060010190565b6001600160a01b0383168152604060208201525f614990604083018461587c565b602081525f6104bf6020830184614a58565b634e487b7160e01b5f52601260045260245ffd5b5f8060408385031215615b57575f80fd5b825160048110615b65575f80fd5b602084015190925060ff81168114615b7b575f80fd5b809150509250929050565b8082018281125f83128015821682158216171561152157611521615349565b600181815b80851115615bdf57815f1904821115615bc557615bc5615349565b80851615615bd257918102915b93841c9390800290615baa565b509250929050565b5f82615bf557506001610344565b81615c0157505f610344565b8160018114615c175760028114615c2157615c3d565b6001915050610344565b60ff841115615c3257615c32615349565b50506001821b610344565b5060208310610133831016604e8410600b8410161715615c60575081810a610344565b615c6a8383615ba5565b805f1904821115615c7d57615c7d615349565b029392505050565b5f6104bf8383615be7565b808202811582820484141761034457610344615349565b5f82615cc157634e487b7160e01b5f52601260045260245ffd5b500490565b5f600160ff1b8203613f8e57613f8e61534956","sourceMap":"8701:36248:253:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1541:207:247;;;;;;:::i;:::-;;:::i;:::-;;;516:14:316;;509:22;491:41;;479:2;464:18;1541:207:247;;;;;;;;15228:697:253;;;;;;:::i;:::-;;:::i;10406:134::-;;;;;;:::i;:::-;10478:4;10501:18;;;;;;;;;;;5177:1;10501:32;;10406:134;10743:1248;;;;;;:::i;:::-;;:::i;:::-;;10197:170;;;;;;:::i;:::-;-1:-1:-1;;;;;10323:21:253;;;10299:5;10323:21;;;:14;:21;;;;;;;;:28;;;;;;;;;;;;:37;;;;;;;;10197:170;;;;3601:25:316;;;3589:2;3574:18;10197:170:253;3428:204:316;1794:1578:247;;;;;;:::i;:::-;;:::i;12030:1289:253:-;;;;;;:::i;:::-;;:::i;3813:140:247:-;;;;;;:::i;:::-;;:::i;17164:7857:253:-;;;;;;:::i;:::-;;:::i;:::-;;;;5827:25:316;;;5883:2;5868:18;;5861:34;;;;5800:18;17164:7857:253;5599:302:316;13358:1831:253;;;;;;:::i;:::-;;:::i;16230:707::-;;;;;;:::i;:::-;;:::i;:::-;;;;7331:14:316;;7324:22;7306:41;;7378:2;7363:18;;7356:34;;;;7406:18;;;7399:34;7294:2;7279:18;16230:707:253;7056:383:316;1224:482:169;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;10579:125:253:-;;;;;;:::i;:::-;;:::i;3418:110:247:-;;;;;;:::i;:::-;3486:7;3418:110;;;;;25060:3951:253;;;;;;:::i;:::-;;:::i;1541:207:247:-;1626:4;1649:52;;;1664:37;1649:52;;:92;;-1:-1:-1;844:25:177;829:40;;;;1705:36:247;1642:99;1541:207;-1:-1:-1;;1541:207:247:o;15228:697:253:-;15353:17;3023:21:171;:19;:21::i;:::-;15404:11:253::1;;::::0;::::1;:5:::0;:11:::1;:::i;:::-;-1:-1:-1::0;;;;;15390:25:253::1;:10;-1:-1:-1::0;;;;;15390:25:253::1;;15386:101;;15452:10;15464:11;;::::0;::::1;:5:::0;:11:::1;:::i;:::-;15438:38;::::0;::::1;::::0;;-1:-1:-1;;;;;18233:15:316;;;15438:38:253::1;::::0;::::1;18215:34:316::0;18285:15;;18265:18;;;18258:43;18127:18;;15438:38:253::1;;;;;;;;15386:101;15496:17;15516:12;:10;:5:::0;:10:::1;:::i;:::-;;:12::i;:::-;15542:7;:18:::0;;;::::1;::::0;;;;;;;15496:32;;-1:-1:-1;;;15542:32:253;15538:381:::1;;5381:1;15623:18:::0;;;::::1;::::0;;;;;;;:31;;;;15673:43;15605:4:::1;::::0;-1:-1:-1;15673:43:253::1;::::0;::::1;::::0;15687:10:::1;::::0;15631:9;;15710:5;;15673:43:::1;:::i;:::-;;;;;;;;3152:4:195::0;3146:11;;3184:1;3170:16;;3217:4;3206:16;;3199:27;;;15857:10:253::1;3246:16:195::0;;;3239:27;3064:22;3292:16;;3279:30;;;15731:177:253::1;::::0;15768:104:::1;::::0;15796:75:::1;2770:4:196::0;2764:11;;2803:1;2788:17;;2837:4;2825:17;;2818:28;;;;2872:17;;;2859:31;;2764:11;2615:291;15768:104:253::1;15731:177;15890:4:::0;;15731:177:::1;:::i;:::-;:19;:177::i;:::-;15376:549;3065:20:171::0;2365:1;1505:66;3972:62;3749:292;3065:20;15228:697:253;;;;;:::o;10743:1248::-;3023:21:171;:19;:21::i;:::-;10895:31:253::1;:13:::0;10923:1:::1;10895:16;:31::i;:::-;10890:115;;10949:45;::::0;::::1;::::0;;10967:10:::1;10949:45;::::0;::::1;24185:34:316::0;-1:-1:-1;;;;;24255:15:316;;24235:18;;;24228:43;24287:18;;;24280:34;;;24097:18;;10949:45:253::1;23922:398:316::0;10890:115:253::1;11016:28;11046:14:::0;11064:32:::1;11075:5;11082:13;11064:10;:32::i;:::-;11306:59;::::0;;11316:10:::1;24617:34:316::0;;-1:-1:-1;;;;;24687:15:316;;24682:2;24667:18;;24660:43;24719:18;;;24712:34;;;24777:2;24762:18;;24755:34;;;11015:81:253;;-1:-1:-1;11015:81:253;-1:-1:-1;11306:59:253::1;::::0;24543:3:316;24528:19;11306:59:253::1;;;;;;;11377:19;11398:18:::0;11420:63:::1;11441:10;11453:5;11460:7;11469:13;11420:20;:63::i;:::-;11376:107:::0;;-1:-1:-1;11376:107:253;-1:-1:-1;11498:16:253;;11494:491:::1;;5849:4:195::0;5843:11;;5881:1;5867:16;;-1:-1:-1;;;;;11675:23:253;::::1;5914:4:195::0;5903:16;;5896:27;5943:16;;;5936:27;;;5757:22;5983:16;;5976:27;;;6034:4;6023:16;;6016:27;;;11880:17:253::1;::::0;::::1;6074:4:195::0;6063:16;;6056:27;6120:4;6109:16;;6096:30;;;11530:444:253::1;::::0;11567:371:::1;::::0;11616:304:::1;5636:506:195::0;11567:371:253::1;11530:444;11956:4:::0;;11530:444:::1;:::i;:::-;10880:1111;;;;3065:20:171::0;2365:1;1505:66;3972:62;3749:292;3065:20;10743:1248:253;;;;;:::o;1794:1578:247:-;1948:4;1968:53;-1:-1:-1;;;;;1968:26:247;;2003:8;2014:6;1968:26;:53::i;:::-;2049:64;;;;;2032:14;;-1:-1:-1;;;;;2049:20:247;;;;;:64;;2070:10;;2082:5;;2089:6;;2032:14;;2108:4;;;;2049:64;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2032:81;;453:45:234;2127:6:247;:40;2123:111;;2190:33;;;;;;;;3601:25:316;;;3574:18;;2190:33:247;3428:204:316;2123:111:247;3259:84;3298:8;3317:4;3324:18;1145:1;3324:6;:18;:::i;:::-;-1:-1:-1;;;;;3259:30:247;;;:84;;:30;:84::i;:::-;-1:-1:-1;3361:4:247;;1794:1578;-1:-1:-1;;;;;;1794:1578:247:o;12030:1289:253:-;3023:21:171;:19;:21::i;:::-;12182:30:253::1;:12:::0;12209:1:::1;12182:15;:30::i;:::-;12177:121;;12235:52;::::0;::::1;::::0;;12260:10:::1;12235:52;::::0;::::1;24185:34:316::0;-1:-1:-1;;;;;24255:15:316;;24235:18;;;24228:43;24287:18;;;24280:34;;;24097:18;;12235:52:253::1;23922:398:316::0;12177:121:253::1;12351:10;12308:25;12336:26:::0;;;:14:::1;:26;::::0;;;;;;;-1:-1:-1;;;;;12336:33:253;::::1;::::0;;;;;;;:42;;;;;;;;;;12411:37:::1;:12:::0;12336:42;12411:16:::1;:37::i;:::-;12388:60;;12460:19;12481:18:::0;12503:64:::1;12524:10;12536:5;12543:7;12552:14;12503:20;:64::i;:::-;12459:108;;;;12579:29;12610:14:::0;12628:33:::1;12639:5;12646:14;12628:10;:33::i;:::-;12677:91;::::0;;12688:10:::1;26507:34:316::0;;-1:-1:-1;;;;;26577:15:316;;26572:2;26557:18;;26550:43;26609:18;;;26602:34;;;26667:2;26652:18;;26645:34;;;26710:3;26695:19;;26688:35;;;26754:3;26739:19;;26732:35;;;12578:83:253;;-1:-1:-1;12578:83:253;-1:-1:-1;12677:91:253::1;::::0;26433:3:316;26418:19;12677:91:253::1;;;;;;;12783:16:::0;;12779:534:::1;;7001:4:195::0;6995:11;;7033:1;7019:16;;-1:-1:-1;;;;;12960:23:253;::::1;7066:4:195::0;7055:16;;7048:27;7095:16;;;7088:27;;;6909:22;7135:16;;7128:27;;;7186:4;7175:16;;7168:27;;;7226:4;7215:16;;7208:27;;;13208:17:253::1;::::0;::::1;7266:4:195::0;7255:16;;7248:27;7312:4;7301:16;;7288:30;;;12815:487:253::1;::::0;12852:414:::1;::::0;12901:347:::1;6777:557:195::0;12852:414:253::1;12815:487;13284:4:::0;;12815:487:::1;:::i;:::-;12167:1152;;;;;;3065:20:171::0;2365:1;1505:66;3972:62;3749:292;3813:140:247;3908:38;;;;;3940:4;3908:38;;;26924:74:316;3882:7:247;;-1:-1:-1;;;;;3908:23:247;;;;;26897:18:316;;3908:38:247;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;17164:7857:253:-;17276:21;17299:22;3023:21:171;:19;:21::i;:::-;17341:13:253::1;;::::0;::::1;:6:::0;:13:::1;:::i;:::-;:20;;17365:1;17341:25:::0;17337:73:::1;;17389:10;;;;;;;;;;;;;;17337:73;17420:40;;:::i;:::-;17470:20;;:::i;:::-;17500:23;17526:13;;::::0;::::1;:6:::0;:13:::1;:::i;:::-;17540:1;17526:16;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:22;::::0;;::::1;:::i;:::-;:34;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;17561:13;;::::0;::::1;:6:::0;:13:::1;:::i;:::-;17575:1;17561:16;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:29;;;17526:65;;;;;;;:::i;:::-;:71;::::0;::::1;:65;::::0;;::::1;;:71:::0;;::::1;::::0;-1:-1:-1;17526:71:253::1;:::i;:::-;17500:97:::0;-1:-1:-1;17607:24:253::1;17634:13;;::::0;::::1;:6:::0;:13:::1;:::i;:::-;17648:1;17634:16;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:22;::::0;;::::1;:::i;:::-;:35;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;17670:13;;::::0;::::1;:6:::0;:13:::1;:::i;:::-;17684:1;17670:16;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:30;;;17634:67;;;;;;;:::i;:::-;:73;::::0;::::1;:67;::::0;;::::1;;:73:::0;;::::1;::::0;-1:-1:-1;17634:73:253::1;:::i;:::-;17607:100:::0;-1:-1:-1;18135:57:253::1;18216:14;18233:13;;::::0;::::1;:6:::0;:13:::1;:::i;:::-;18327:4;18321:11:::0;;18442:4:::1;18438:1;18426:14:::0;;;::::1;18422:25:::0;::::1;18413:35:::0;::::1;18400:49:::0;;;18321:11;-1:-1:-1;18522:16:253;::::1;;::::0;-1:-1:-1;18557:34:253::1;::::0;-1:-1:-1;18522:16:253;-1:-1:-1;18557:19:253::1;:34::i;:::-;18552:96;;18618:15;;;;;;;;;;;;;;18552:96;18662:9;18689:4856;18700:13;;::::0;::::1;:6:::0;:13:::1;:::i;:::-;:20;;18696:1;:24;:62;;;;-1:-1:-1::0;18724:34:253::1;:16:::0;18755:1:::1;18724:19;:34::i;:::-;18689:4856;;;18796:13;;::::0;::::1;:6:::0;:13:::1;:::i;:::-;18810:1;18796:16;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;18778:34;;;:::i;:::-;;;18838:15;:21;;;18830:29;;19079:15;-1:-1:-1::0;;;;;19022:72:253::1;:5;:17;;;19040:15;:28;;;19022:47;;;;;;;;:::i;:::-;;;;;;;:53;;;-1:-1:-1::0;;;;;19022:72:253::1;;;19021:179;;;;19183:16;-1:-1:-1::0;;;;;19124:75:253::1;:5;:18;;;19143:15;:29;;;19124:49;;;;;;;;:::i;:::-;;;;;;;:55;;;-1:-1:-1::0;;;;;19124:75:253::1;;;19021:179;18996:286;;;19248:15;;-1:-1:-1::0;;;19248:15:253::1;;;;;;;;;;;18996:286;19300:87;19320:5;19327:15;:28;;;19357:15;:29;;;19300:19;:87::i;:::-;19406:17;19426:12;:5;:10;:12::i;:::-;5381:1;19460:18:::0;;;::::1;::::0;;;;;;;19406:32;;-1:-1:-1;19456:4003:253::1;;19547:11:::0;;19521:49:::1;::::0;;19535:10:::1;24185:34:316::0;;-1:-1:-1;;;;;24255:15:316;;;24250:2;24235:18;;24228:43;24287:18;;24280:34;;;19521:49:253::1;::::0;24112:2:316;24097:18;19521:49:253::1;;;;;;;19456:4003;;;19617:46;19666:269;19708:5;19739:15;:28;;;19793:15;:29;;;19848:10;19884:15;:29;;;19666:16;:269::i;:::-;20305:26;::::0;::::1;::::0;19617:318;;-1:-1:-1;20305:52:253::1;::::0;20335:21:::1;::::0;::::1;;20305:29;:52::i;:::-;20301:3140;;;20423:11:::0;;20390:56:::1;::::0;;20411:10:::1;24185:34:316::0;;-1:-1:-1;;;;;24255:15:316;;;24250:2;24235:18;;24228:43;24287:18;;24280:34;;;20390:56:253::1;::::0;24112:2:316;24097:18;20390:56:253::1;;;;;;;;20301:3140;;;20479:28;::::0;::::1;::::0;-1:-1:-1;;;;;37668:12:186;20475:2966:253::1;;20577:11:::0;;20549:51:::1;::::0;;20565:10:::1;24185:34:316::0;;-1:-1:-1;;;;;24255:15:316;;;24250:2;24235:18;;24228:43;24287:18;;24280:34;;;20549:51:253::1;::::0;24112:2:316;24097:18;20549:51:253::1;23922:398:316::0;20475:2966:253::1;20655:16;20697:17:::0;20744:6:::1;:16;;;;;;;;;;:::i;:::-;20740:1547;;;20959:28;::::0;::::1;::::0;:50:::1;::::0;20992:16;20959:32:::1;:50::i;:::-;21581:26;::::0;::::1;::::0;20946:63;;-1:-1:-1;21581:42:253::1;::::0;20946:63;21581:30:::1;:42::i;:::-;21567:56:::0;-1:-1:-1;21673:32:253::1;:16:::0;21694:10;21673:20:::1;:32::i;:::-;21654:51;;20740:1547;;;21853:19;21875:60;21906:18;:28;;;21875:18;:26;;;:30;;:60;;;;:::i;:::-;21853:82:::0;-1:-1:-1;21979:35:253::1;21853:82:::0;21997:16;21979:17:::1;:35::i;:::-;21965:49;;22134:43;22150:18;:26;;;22134:11;:15;;:43;;;;:::i;:::-;22121:56:::0;-1:-1:-1;22227:33:253::1;:16:::0;22248:11;22227:20:::1;:33::i;:::-;22208:52;;21738:549;20740:1547;22332:33;:16:::0;22353:11;22332:20:::1;:33::i;:::-;22313:52:::0;-1:-1:-1;22409:31:253::1;:15:::0;22429:10;22409:19:::1;:31::i;:::-;22391:49;;22467:58;22481:11;22494:10;22506:18;22467:13;:58::i;:::-;22556:65;22568:10;22580:15;22597:10;22609:11;22556:65;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;23091:34:253;;23127:1:::1;23087:42;23158:46:::0;;;23366:4:::1;23351:20;23318:54:::0;::::1;23311:82:::0;;;20475:2966:::1;19595:3864;19456:4003;-1:-1:-1::0;23509:3:253::1;;18689:4856;;;-1:-1:-1::0;23579:27:253::1;::::0;-1:-1:-1;23609:16:253::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;:53;;23646:16;23609:53;;;23628:15;23609:53;23579:83:::0;-1:-1:-1;23680:42:253::1;23579:83:::0;23705:16;::::1;23680:24;:42::i;:::-;23676:138;;;23749:50;::::0;::::1;::::0;;23759:16;::::1;23749:50;::::0;::::1;5827:25:316::0;5868:18;;;5861:34;;;5800:18;;23749:50:253::1;5599:302:316::0;23676:138:253::1;23565:259;24507:45;24518:16;24536:15;24507:10;:45::i;:::-;-1:-1:-1::0;24588:1:253::1;::::0;-1:-1:-1;24567:11:253::1;;::::0;::::1;:6:::0;:11:::1;:::i;:::-;:18;;:22;24563:214;;;24628:10;24605:48;24671:16:::0;24689:15;24706;24723:16;24741:11:::1;;::::0;::::1;:6:::0;:11:::1;:::i;:::-;24605:161;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;24563:214;24787:45;24798:15;24815:16;24787:10;:45::i;:::-;;;24872:9;24867:138;24891:27;:34;24887:1;:38;24867:138;;;24950:40;24959:27;24987:1;24959:30;;;;;;;;:::i;:::-;;;;;;;24950:8;:40::i;:::-;24927:3;;24867:138;;;;17327:7694;;;;;3065:20:171::0;2365:1;1505:66;3972:62;3749:292;3065:20;17164:7857:253;;;:::o;13358:1831::-;13492:4;3023:21:171;:19;:21::i;:::-;13516:23:253::1;;::::0;::::1;:11:::0;:23:::1;:::i;:::-;:30;;13550:1;13516:35:::0;13512:88:::1;;13574:15;;;;;;;;;;;;;;13512:88;13613:24;;::::0;::::1;:11:::0;:24:::1;:::i;:::-;:31;;13648:1;13613:36:::0;13609:90:::1;;13672:16;;;;;;;;;;;;;;13609:90;13909:134;::::0;;::::1;::::0;::::1;::::0;;;13930:10:::1;13909:134:::0;;13886:20:::1;::::0;13909:134:::1;::::0;::::1;13942:21;:11:::0;;:21:::1;:::i;:::-;13909:134;;;:::i;:::-;;;;;13965:11;:23;;;;;;;;:::i;:::-;13909:134;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;:::i;:::-;;;;;;;;;;;;-1:-1:-1::0;;;13909:134:253;;;-1:-1:-1;;13909:134:253::1;;13990:24;;::::0;::::1;:11:::0;:24:::1;:::i;:::-;13909:134;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;::::1;;::::0;;::::1;::::0;::::1;::::0;::::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;14016:11;:17;;;13909:134;;::::0;13886:157:::1;;14053:17;14073:12;:5;:10;:12::i;:::-;14096:16;14115:18:::0;;;::::1;::::0;;;;;;;14053:32;;-1:-1:-1;14115:32:253;14233:921;::::1;;;14510:7;:18:::0;;;::::1;::::0;;;;;;;;5177:1:::1;14510:31:::0;;14571:11;;14560:41;;::::1;::::0;::::1;::::0;14518:9;;14571:5;;14560:41:::1;:::i;:::-;;;;;;;;14798:1;14772:16;;::::0;::::1;:11:::0;:16:::1;:::i;:::-;:23;;:27;14768:184;;;14819:45;14847:16;;::::0;::::1;:11:::0;:16:::1;:::i;:::-;14819:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;14819:27:253::1;::::0;-1:-1:-1;;;14819:45:253:i:1;:::-;14896:11:::0;;14887:50:::1;::::0;14909:9;14920:16:::1;;::::0;::::1;:11:::0;:16:::1;:::i;:::-;14887:50;;;;;;;;;:::i;:::-;;;;;;;;14768:184;3152:4:195::0;3146:11;;3184:1;3170:16;;3217:4;3206:16;;3199:27;;;15092:10:253::1;3246:16:195::0;;;3239:27;3064:22;3292:16;;3279:30;;;14966:177:253::1;::::0;15003:104:::1;::::0;15031:75:::1;3000:325:195::0;14966:177:253::1;15171:11:::0;-1:-1:-1;;;3065:20:171;2365:1;1505:66;3972:62;3749:292;16230:707:253;16299:4;;;;16349:24;:17;:11;;:17;:::i;:::-;:22;;;:::i;:24::-;16388:7;:18;;;;;;;;;;;16329:44;;-1:-1:-1;5177:1:253;16388:32;16384:107;;-1:-1:-1;16444:5:253;;-1:-1:-1;16444:5:253;;-1:-1:-1;16444:5:253;;-1:-1:-1;16436:44:253;;16384:107;16501:91;16521:17;:11;;:17;:::i;:::-;16501:91;;;:::i;:::-;16540:11;:24;;;16566:11;:25;;;16501:19;:91::i;:::-;16603:46;16652:197;16682:17;:11;;:17;:::i;:::-;16652:197;;;:::i;:::-;16713:24;;;;16751:25;;;;16790:10;16814:25;;;;16713:11;16814:25;:::i;:::-;16652:197;;;:::i;:::-;:16;:197::i;:::-;16603:246;;16867:4;16873:18;:28;;;16903:18;:26;;;16859:71;;;;;;;;16230:707;;;;;;:::o;1224:482:169:-;1388:12;;;1324:20;1388:12;;;;;;;;1290:22;;1499:4;1487:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1477:34;;1526:9;1521:155;1541:15;;;1521:155;;;1590:75;1627:4;1647;;1652:1;1647:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1656;1634:30;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1590:28;:75::i;:::-;1577:7;1585:1;1577:10;;;;;;;;:::i;:::-;;;;;;;;;;:88;1558:3;;1521:155;;;;1685:14;1224:482;;;;:::o;10579:125:253:-;3023:21:171;:19;:21::i;:::-;10672:18:253::1;::::0;;10688:1:::1;10672:18:::0;;;::::1;::::0;::::1;::::0;;;10652:45:::1;::::0;10672:18:::1;::::0;::::1;;;;;;;;;;;;;;;;;-1:-1:-1::0;10652:45:253::1;10692:4:::0;;10652:45:::1;:::i;:::-;3065:20:171::0;2365:1;1505:66;3972:62;3749:292;3065:20;10579:125:253;;:::o;25060:3951::-;3023:21:171;:19;:21::i;:::-;25368:14:253;;25348:16;;-1:-1:-1;;;;;25348:34:253;;::::1;::::0;::::1;::::0;25344:91:::1;;25409:11;;;;;;;;;;;;;;25344:91;25580:8;:20;;;25601:11;:27;;;25580:49;;;;;;;;:::i;:::-;;;;;;;:55;;;-1:-1:-1::0;;;;;25491:144:253::1;:10;:23;;;25515:11;:30;;;25491:55;;;;;;;;:::i;:::-;;;;;;;:61;;;-1:-1:-1::0;;;;;25491:144:253::1;;;25469:404;;;-1:-1:-1::0;25792:22:253::1;::::0;::::1;::::0;:53;;25815:29;::::1;::::0;25792:53;::::1;;;;;:::i;:::-;;;;;;;:59;;;-1:-1:-1::0;;;;;25703:148:253::1;:8;:21;;;25725:11;:28;;;25703:51;;;;;;;;:::i;:::-;;;;;;;:57;;;-1:-1:-1::0;;;;;25703:148:253::1;;;25469:404;25448:495;;;25913:15;;-1:-1:-1::0;;;25913:15:253::1;;;;;;;;;;;25448:495;26061:10;:23;;;26085:11;:30;;;26061:55;;;;;;;;:::i;:::-;;;;;;;:61;;;-1:-1:-1::0;;;;;25978:144:253::1;:10;:22;;;26001:11;:29;;;25978:53;;;;;;;;:::i;:::-;;;;;;;:59;;;-1:-1:-1::0;;;;;25978:144:253::1;::::0;25957:236:::1;;26162:16;;-1:-1:-1::0;;;26162:16:253::1;;;;;;;;;;;25957:236;5381:1;26418:7:::0;:26:::1;26426:17;:10;:15;:17::i;:::-;26418:26;;;;;;;;;;;;:40:::0;26414:170:::1;;26483:62;26497:10;26509;:16;;;26527:17;:10;:15;:17::i;:::-;26483:62;::::0;;-1:-1:-1;;;;;24203:15:316;;;24185:34;;24255:15;;;;24250:2;24235:18;;24228:43;24287:18;;;24280:34;24112:2;24097:18;26483:62:253::1;;;;;;;26563:7;;26414:170;5381:1;26601:7:::0;:24:::1;26609:15;:8;:13;:15::i;:::-;26601:24;;;;;;;;;;;;:38:::0;26597:164:::1;;26664:58;26678:10;26690:8;:14;;;26706:15;:8;:13;:15::i;26597:164::-;26832:54;26840:10;26852;26864:8;26874:11;26832:54;;;;;;;;;:::i;:::-;;;;;;;;26906:51;26960:147;26990:10;27002:11;:29;;;27033:11;:30;;;27065:8;:14;;;27081:16;26960;:147::i;:::-;26906:201;;27117:49;27169:145;27199:8;27209:11;:27;;;27238:11;:28;;;27268:10;:16;;;27286:18;27169:16;:145::i;:::-;27117:197;;27324:42;27381:73;27407:23;27432:21;27381:25;:73::i;:::-;27324:130;;27465:97;27479:16;:27;;;27508:16;:28;;;27538:23;27465:13;:97::i;:::-;27572:91;27586:16;:25;;;27613:16;:26;;;27641:21;27572:13;:91::i;:::-;27741:25;::::0;::::1;::::0;27708:28;;27688:17:::1;::::0;27708:59:::1;::::0;:28;:32:::1;:59::i;:::-;27688:79;;27781:15;27799:59;27830:16;:27;;;27799:16;:26;;;:30;;:59;;;;:::i;:::-;27781:77:::0;-1:-1:-1;28065:29:253::1;:11:::0;28091:1:::1;28065:14;:29::i;:::-;:60;;;-1:-1:-1::0;28098:27:253::1;:9:::0;28122:1:::1;28098:12;:27::i;:::-;28061:122;;;28152:16;;;;;;;;;;;;;;28061:122;28197:218;28235:10;28263;:23;;;28287:11;:30;;;28263:55;;;;;;;;:::i;:::-;;;;;;;:61;;;28342:11;:30;;;28390:11;28197:20;:218::i;:::-;;;28429:210;28467:10;28495:8;:21;;;28517:11;:28;;;28495:51;;;;;;;;:::i;:::-;;;;;;;:57;;;28570:11;:28;;;28616:9;28429:20;:210::i;:::-;-1:-1:-1::0;;28665:42:253::1;::::0;;28678:10:::1;40506:74:316::0;;40616:13;;40611:2;40596:18;;;40589:41;;;;40672:15;;40666:22;40646:18;;;40639:50;40731:15;;;40725:22;40720:2;40705:18;;;40698:50;;;;40791:15;;40785:22;40779:3;40764:19;;40757:51;28665:42:253::1;::::0;-1:-1:-1;40493:3:316;40478:19;;-1:-1:-1;28665:42:253::1;;;;;;;28718:33;28727:23;28718:8;:33::i;:::-;28761:31;28770:21;28761:8;:31::i;:::-;28878:28:::0;;-1:-1:-1;;;;;37668:12:186;37661:20;28878:76:253::1;;;;-1:-1:-1::0;28919:26:253::1;::::0;::::1;::::0;-1:-1:-1;;;;;37668:12:186;37661:20;28919:35:253::1;28874:131;;;28977:17;;;;;;;;;;;;;;28874:131;25320:3691;;;3054:1:171;3065:20:::0;2365:1;1505:66;3972:62;3749:292;;3872:25;:23;:25::i;:::-;2407:1;1505:66;3972:62;3749:292::o;669:120:256:-;728:7;775:5;764:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;754:28;;;;;;747:35;;669:120;;;:::o;4763:1318:257:-;4911:10;4848:24;1232:25:228;;;5028:4:257;1277::228;1270:20;;;1338:4;1325:18;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5104:18:257;;;;;;;;5169:16;;;;;;;;;1325:18:228;;-1:-1:-1;;5104:18:257;;5195:880;5219:4;:11;5215:1;:15;5195:880;;;5258:4;5263:1;5258:7;;;;;;;;:::i;:::-;;;;;;;5251:14;;5316:1;5283:4;:14;;;:23;;;:30;:34;5279:786;;;5338:24;5364:23;5391:4;:14;;;:26;;;-1:-1:-1;;;;;5391:32:257;;5445:438;;;;;;;;5485:4;:14;;;:20;;;-1:-1:-1;;;;;5445:438:257;;;;;5542:18;5445:438;;;;5596:4;:14;;;:23;;;5445:438;;;;5677:1;5445:438;;;;5714:45;5731:7;5740:4;:18;;;5714:16;:45::i;:::-;5445:438;;;;5793:10;5445:438;;;;5843:17;5445:438;;;5391:510;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5391:510:257;;;;;;;;;;;;:::i;:::-;5948:13;;5337:564;;-1:-1:-1;5337:564:257;-1:-1:-1;5948:17:257;5944:107;;5989:14;;:20;;;:43;;-1:-1:-1;;;5989:43:257;;-1:-1:-1;;;;;5989:24:257;;;;;;:43;;6014:9;;6025:6;;5989:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5944:107;5319:746;;5279:786;5232:3;;5195:880;;;;4838:1243;;;;;4763:1318;;:::o;26445:429:186:-;26498:4;-1:-1:-1;;;;;17672:16:186;;;17668:2;17657:32;;;;17718:4;17714:16;;;;17672;;;17657:32;;;;17714:16;;;26705:106;17657:32;17714:16;17657:32;17714:16;26705:44;:106::i;:::-;-1:-1:-1;;26445:429:186;-1:-1:-1;;;;;;;26445:429:186:o;43269:933:253:-;43336:7;43345:5;43363:23;43388:14;43406:44;43444:5;43406:37;:44::i;:::-;43362:88;;-1:-1:-1;43362:88:253;-1:-1:-1;43479:22:253;43464:11;:37;;;;;;;;:::i;:::-;;;:75;;;;-1:-1:-1;43520:19:253;43505:11;:34;;;;;;;;:::i;:::-;;;43464:75;43460:157;;;43587:5;43594:11;43562:44;;-1:-1:-1;;;43562:44:253;;;;;;;;;:::i;43460:157::-;43630:24;:6;43651:1;43630:9;:24::i;:::-;43626:76;;;43677:14;;;;;;;;;;;;;;43626:76;43713:16;43731:13;43748:53;43784:6;43792:8;43748:35;:53::i;:::-;43712:89;;;;43861:8;43856:184;;44019:10;;;:::i;:::-;;;43856:184;44053:12;;44049:110;;44081:67;-1:-1:-1;;;;;44081:30:253;;44112:10;44132:4;44139:8;44081:30;:67::i;:::-;-1:-1:-1;44176:8:253;-1:-1:-1;44186:8:253;-1:-1:-1;;43269:933:253;;;;;;:::o;35549:743::-;35674:5;;35706:24;:6;35674:5;35706:9;:24::i;:::-;35702:96;;;35753:34;;-1:-1:-1;;;35753:34:253;;;;;3601:25:316;;;3574:18;;35753:34:253;3428:204:316;35702:96:253;-1:-1:-1;;;;;35827:21:253;;;35808:16;35827:21;;;:14;:21;;;;;;;;:28;;;;;;;;;;;:37;;;;;;;;;;35893:22;35827:37;35908:6;35893:14;:22::i;:::-;35874:41;-1:-1:-1;36090:28:253;35874:41;36115:1;36090:13;:28::i;:::-;36086:98;;;36141:32;;;;;;;;3601:25:316;;;3574:18;;36141:32:253;3428:204:316;36086:98:253;-1:-1:-1;;;;;36193:21:253;;;;;;;:14;:21;;;;;;;;:28;;;;;;;;;;;:37;;;;;;:50;;;36262:10;;-1:-1:-1;36233:10:253;-1:-1:-1;35549:743:253;;;;;;;;:::o;1219:204:161:-;1306:37;1320:5;1327:2;1331:5;1338:4;1306:13;:37::i;:::-;1301:116;;1366:40;;-1:-1:-1;;;1366:40:161;;-1:-1:-1;;;;;26942:55:316;;1366:40:161;;;26924:74:316;26897:18;;1366:40:161;26778:226:316;1301:116:161;1219:204;;;:::o;1662:232::-;1767:47;1785:5;1792:4;1798:2;1802:5;1809:4;1767:17;:47::i;:::-;1762:126;;1837:40;;-1:-1:-1;;;1837:40:161;;-1:-1:-1;;;;;26942:55:316;;1837:40:161;;;26924:74:316;26897:18;;1837:40:161;26778:226:316;1762:126:161;1662:232;;;;:::o;37000:101:186:-;37054:5;37078:8;37081:1;37084;37078:2;:8::i;:::-;:16;;37093:1;37078:16;;;-1:-1:-1;37089:1:186;;37071:23;-1:-1:-1;37000:101:186:o;36298:810:253:-;36423:5;;36455:24;:6;36423:5;36455:9;:24::i;:::-;36451:96;;;36502:34;;-1:-1:-1;;;36502:34:253;;;;;3601:25:316;;;3574:18;;36502:34:253;3428:204:316;36451:96:253;-1:-1:-1;;;;;36576:21:253;;;36557:16;36576:21;;;:14;:21;;;;;;;;:28;;;;;;;;;;;:37;;;;;;;;;;36642:22;36576:37;36657:6;36642:14;:22::i;44208:739::-;44280:7;44289:5;44307:23;44332:14;44350:44;44388:5;44350:37;:44::i;:::-;44306:88;;-1:-1:-1;44306:88:253;-1:-1:-1;44423:22:253;44408:11;:37;;;;;;;;:::i;:::-;;;:75;;;;-1:-1:-1;44464:19:253;44449:11;:34;;;;;;;;:::i;:::-;;;44408:75;44404:157;;;44531:5;44538:11;44506:44;;-1:-1:-1;;;44506:44:253;;;;;;;;;:::i;44404:157::-;44575:29;:11;44601:1;44575:14;:29::i;:::-;44571:81;;;44627:14;;;;;;;;;;;;;;44571:81;44663:14;44679:13;44696:58;44732:11;44745:8;44696:35;:58::i;:::-;44662:92;;-1:-1:-1;44662:92:253;-1:-1:-1;44822:10:253;;44818:87;;44848:46;-1:-1:-1;;;;;44848:26:253;;44875:10;44887:6;44848:26;:46::i;15931:260::-;16096:5;:18;;;16115:13;16096:33;;;;;;;;:::i;:::-;;;;;;;:39;;;-1:-1:-1;;;;;16055:80:253;:5;:17;;;16073:12;16055:31;;;;;;;;:::i;:::-;;;;;;;:37;;;-1:-1:-1;;;;;16055:80:253;;16051:134;;16158:16;;-1:-1:-1;;;16158:16:253;;;;;;;;;;;29715:5828;29939:27;;:::i;:::-;30002:17;30022:12;:5;:10;:12::i;:::-;30143:40;;;1336:1:257;30143:40:253;;;;;;;;;30002:32;;-1:-1:-1;30049:26:253;;30107:33;;30143:40;;;;;;;;;;;;;;;;;;;-1:-1:-1;30336:11:253;;3924:4:195;3918:11;;3956:1;3942:16;;3989:4;3978:16;;3971:27;;;-1:-1:-1;;;;;30320:29:253;;;4018:16:195;;;4011:27;30360:30:253;;;3836:22:195;4058:16;;4051:27;4115:4;4104:16;;4091:30;;30107:76:253;;-1:-1:-1;30201:14:253;30249:1;1753::257;30216:34:253;30201:50;;;;;;;;:::i;:::-;;;;;;:208;;;;30451:24;30477:19;30524:84;30570:5;:17;;;30588:12;30570:31;;;;;;;;:::i;:::-;;;;;;;:37;;;30524:45;:84::i;:::-;30450:158;;-1:-1:-1;30450:158:253;-1:-1:-1;30650:22:253;30634:12;:38;;;;;;;;:::i;:::-;;;:77;;;;-1:-1:-1;30692:19:253;30676:12;:35;;;;;;;;:::i;:::-;;;30634:77;30630:216;;;30771:5;:17;;;30789:12;30771:31;;;;;;;;:::i;:::-;;;;;;;:37;;;30810:12;30746:77;;-1:-1:-1;;;30746:77:253;;;;;;;;;:::i;30630:216::-;30914:11;;-1:-1:-1;;;;;30899:27:253;30868:28;30899:27;;;:14;:27;;;;;;30927:17;;;;:31;;30868:28;;30927:17;30945:12;;30927:31;;;;;;:::i;:::-;;;;;;;:37;;;-1:-1:-1;;;;;30899:66:253;-1:-1:-1;;;;;30899:66:253;;;;;;;;;;;;:132;30966:5;:42;;;31009:12;30966:56;;;;;;;;:::i;:::-;;;;;;;:64;;;30899:132;;;;;;;;;;;;30868:163;;31103:408;31178:5;:17;;;31196:12;31178:31;;;;;;;;:::i;:::-;;;;;;;:37;;;-1:-1:-1;;;;;31162:55:253;31154:64;;31260:13;31252:22;;31244:31;;31301:5;:17;;;31319:12;31301:31;;;;;;;;:::i;:::-;;;;;;;:39;;;31379:22;31488:1;31103:408;;5849:4:195;5843:11;;5881:1;5867:16;;5914:4;5903:16;;5896:27;;;;5943:16;;;5936:27;;;;5757:22;5983:16;;5976:27;;;;6034:4;6023:16;;6016:27;6074:4;6063:16;;6056:27;6120:4;6109:16;;6096:30;;5843:11;5636:506;31103:408:253;31053:14;31098:1;3320::257;31068:31:253;31053:47;;;;;;;;:::i;:::-;;;;;;:458;;;;30428:1102;;;31571:25;31598:20;31646:86;31692:5;:18;;;31711:13;31692:33;;;;;;;;:::i;31646:86::-;31570:162;;-1:-1:-1;31570:162:253;-1:-1:-1;31775:22:253;31758:13;:39;;;;;;;;:::i;:::-;;;:79;;;;-1:-1:-1;31818:19:253;31801:13;:36;;;;;;;;:::i;:::-;;;31758:79;31754:221;;;31897:5;:18;;;31916:13;31897:33;;;;;;;;:::i;31754:221::-;32044:11;;-1:-1:-1;;;;;32029:27:253;31997:29;32029:27;;;:14;:27;;;;;32057:18;;;;:33;;31997:29;;32057:18;32076:13;;32057:33;;;;;;:::i;:::-;;;;;;;:39;;;-1:-1:-1;;;;;32029:68:253;-1:-1:-1;;;;;32029:68:253;;;;;;;;;;;;:136;32098:5;:43;;;32142:13;32098:58;;;;;;;;:::i;:::-;;;;;;;:66;;;32029:136;;;;;;;;;;;;31997:168;;32238:414;32313:5;:18;;;32332:13;32313:33;;;;;;;;:::i;:::-;;;;;;;:39;;;-1:-1:-1;;;;;32297:57:253;32289:66;;32397:14;32389:23;;32381:32;;32439:5;:18;;;32458:13;32439:33;;;;;;;;:::i;32238:414::-;32187:14;32233:1;3487::257;32202:32:253;32187:48;;;;;;;;:::i;:::-;;;;;;:465;;;;31548:1123;;;32699:47;32716:14;32732:13;32699:16;:47::i;:::-;32689:57;;30089:2672;32937:24;33000:5;:11;;;-1:-1:-1;;;;;32984:29:253;32937:77;;33356:38;33396:34;33434:5;:32;;;:61;;;-1:-1:-1;;;;;33434:84:253;;33536:419;;;;;;;;33572:5;:15;;;:21;;;-1:-1:-1;;;;;33536:419:253;;;;;33626:55;33656:9;33675:4;1135:42:228;1232:25;;;1277:4;1270:20;1338:4;1325:18;;;1015:344;33626:55:253;33536:419;;;;33713:5;:15;;;:24;;;33536:419;;;;5525:1;33536:419;;;;33829:7;33536:419;;;;33882:1;33866:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33866:18:253;-1:-1:-1;33536:419:253;;;;33934:1;33920:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33920:16:253;;33536:419;;;33434:535;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;33434:535:253;;;;;;;;;;;;:::i;:::-;33355:614;;;;5838:1;34135:19;:26;:56;34131:157;;;34246:19;:26;34218:55;;;;;;;;;3601:25:316;;3589:2;3574:18;;3428:204;34131:157:253;34458:4;34433:30;;;34427:37;34530:4;34505:30;;;34499:37;34759:11;;-1:-1:-1;;;;;34744:27:253;34302:18;34744:27;;;:14;:27;;;;;;34772:18;;;;:33;;34427:37;;34499;;34302:18;;34772;34791:13;;34772:33;;;;;;:::i;:::-;;;;;;;:39;;;-1:-1:-1;;;;;34744:68:253;-1:-1:-1;;;;;34744:68:253;;;;;;;;;;;;:132;34813:5;:39;;;34853:13;34813:54;;;;;;;;:::i;:::-;;;;;;;:62;;;34744:132;;;;;;;;;;;;34718:158;;34911:37;34930:17;34911:14;:18;;:37;;;;:::i;:::-;3152:4:195;3146:11;;3184:1;3170:16;;3217:4;3206:16;;3199:27;;;3246:16;;;3239:27;;;3064:22;3292:16;;3279:30;;;34894:54:253;;-1:-1:-1;3146:11:195;-1:-1:-1;35060:7:253;2816:1:257;35060:36:253;;;;;;;;:::i;:::-;;;;;;:138;;;;35220:306;;;;;;;;35266:5;35220:306;;;;35304:13;35220:306;;;;35346:14;35220:306;;;;35387:12;35220:306;;;;35426:7;35220:306;;;;35462:9;35220:306;;;;35494:17;35220:306;;;35213:313;;;;;;;;;29715:5828;;;;;;;:::o;22558:561:186:-;22612:5;-1:-1:-1;;;;;17672:16:186;;;17668:2;17657:32;;;;17718:4;17714:16;;;;17672;;;17657:32;;;;17714:16;;;22612:5;;22823:95;17657:32;17714:16;17657:32;17714:16;22823:33;:95::i;:::-;22765:153;;;;22929:7;22938:13;22955:38;22965:17;22984:8;22955:9;:38::i;:::-;-1:-1:-1;22928:65:186;22558:561;-1:-1:-1;;;;;;;;;;;22558:561:186:o;18990:521::-;19044:5;-1:-1:-1;;;;;17672:16:186;;;17668:2;17657:32;;;;17718:4;17714:16;;;;17672;;;17657:32;;;;17714:16;;;19044:5;;19257:95;17657:32;17714:16;17657:32;17714:16;19257:33;:95::i;23563:599::-;23617:5;-1:-1:-1;;;;;17672:16:186;;;17668:2;17657:32;;;;17718:4;17714:16;;;;17672;;;17657:32;;;;17714:16;;;23617:5;;23828:95;17657:32;17714:16;17657:32;17714:16;23828:33;:95::i;18187:514::-;18241:5;-1:-1:-1;;;;;17672:16:186;;;17668:2;17657:32;;;;17718:4;17714:16;;;;17672;;;17657:32;;;;17714:16;;;18241:5;;18452:95;17657:32;17714:16;17657:32;17714:16;18452:33;:95::i;37486:1211:253:-;37705:5;37603:18;:26;;;3320:1:257;37603:55:253;;;;;;;;:::i;:::-;;;;;;;4304:1:257;37603:86:253;;;;;;;;:::i;:::-;;;;;;:108;;;;;37824:6;37721:18;:26;;;3487:1:257;37721:56:253;;;;;;;;:::i;:::-;;;;;;;4304:1:257;37721:87:253;;;;;;;;:::i;:::-;;;;;;:110;;;;;37842:309;37876:18;:24;;;:30;;;37944:18;:26;;;3320:1:257;37944:55:253;;;;;;;;:::i;:::-;;;;;;;3605:1:257;37944:79:253;;;;;;;;:::i;:::-;;;;;;;37936:88;;38040:18;:26;;;3320:1:257;38040:55:253;;;;;;;;:::i;:::-;;;;;;;3847:1:257;38040:82:253;;;;;;;;:::i;:::-;;;;;;;38136:5;37842:20;:309::i;:::-;;;38162:312;38196:18;:24;;;:30;;;38264:18;:26;;;3487:1:257;38264:56:253;;;;;;;;:::i;:::-;;;;;;;3605:1:257;38264:80:253;;;;;;;;:::i;:::-;;;;;;;38256:89;;38361:18;:26;;;3487:1:257;38361:56:253;;;;;;;;:::i;:::-;;;;;;;3847:1:257;38361:83:253;;;;;;;;:::i;:::-;;;;;;;38458:6;38162:20;:312::i;:::-;;;38641:49;38651:10;38663:18;:26;;;38641:49;;;;;;;:::i;:::-;;;;;;;;37486:1211;;;:::o;25714:430:186:-;25767:4;-1:-1:-1;;;;;17672:16:186;;;17668:2;17657:32;;;;17718:4;17714:16;;;;17672;;;17657:32;;;;17714:16;;;25974:106;17657:32;17714:16;17657:32;17714:16;25974:44;:106::i;:::-;-1:-1:-1;;25714:430:186;-1:-1:-1;;;;;;;25714:430:186:o;38703:2527:253:-;39008:22;;;;:29;:33;39004:489;;39384:24;;:34;;;;;:40;;39429:28;;;;39459:22;;;;39384:98;;-1:-1:-1;;;39384:98:253;;-1:-1:-1;;;;;39384:44:253;;;;;;:98;;39429:28;;39384:98;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39004:489;39919:32;39953:28;39985:18;:37;;;:60;;;:85;;;-1:-1:-1;;;;;39985:104:253;;40103:457;;;;;;;;40135:18;:24;;;:34;;;:40;;;-1:-1:-1;;;;;40103:457:253;;;;;40204:74;40234:18;:28;;;40272:4;1135:42:228;1232:25;;;1277:4;1270:20;1338:4;1325:18;;;1015:344;40204:74:253;40103:457;;;;40306:18;:24;;;:34;;;:43;;;40103:457;;;;5715:1;40103:457;;;;40427:18;:26;;;40103:457;;;;40495:1;40479:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40479:18:253;-1:-1:-1;40103:457:253;;;;40543:1;40529:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40529:16:253;;40103:457;;;39985:585;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;39985:585:253;;;;;;;;;;;;:::i;:::-;40761:18;;39918:652;;-1:-1:-1;39918:652:253;-1:-1:-1;40761:22:253;40757:467;;41126:24;;:34;;;;;:40;;41171:28;;;;41126:87;;-1:-1:-1;;;41126:87:253;;-1:-1:-1;;;;;41126:44:253;;;;;;:87;;41201:11;;41126:87;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38778:2452;;38703:2527;:::o;1297:154:37:-;1374:18;1387:4;1374:12;:18::i;:::-;1369:76;;1429:4;1415:19;;;;;;;;;;;:::i;1369:76::-;1297:154;:::o;4691:549:163:-;4774:12;4798;4813:47;4847:6;4855:4;4813:33;:47::i;:::-;4798:62;;4874:7;:72;;;;-1:-1:-1;4918:1:163;4583:16:168;4886:33:163;:59;;;;4944:1;4923:6;-1:-1:-1;;;;;4923:18:163;;:22;4886:59;4870:364;;;4969:25;:23;:25::i;:::-;4962:32;;;;;4870:364;5015:7;5011:223;;;5045:24;;;;;-1:-1:-1;;;;;26942:55:316;;5045:24:163;;;26924:74:316;26897:18;;5045:24:163;26778:226:316;5011:223:163;4583:16:168;5090:33:163;5086:148;;5139:27;:25;:27::i;:::-;5086:148;;;5204:19;;;;;;;;;;;;;;5086:148;4788:452;4691:549;;;;:::o;41774:656:253:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42141:72:253;42166:23;42191:21;42141:24;:72::i;:::-;42067:146;;42068:27;;;42067:146;42351:72;42376:21;42399:23;42351:24;:72::i;:::-;42309:26;;;42281:142;42282:25;;;42281:142;42282:16;41774:656;-1:-1:-1;;41774:656:253:o;3586:157:171:-;1505:66;4560:52;2407:1;4560:63;3644:93;;3696:30;;;;;;;;;;;;;;3644:93;3586:157::o;7835:2310:225:-;7970:18;8028:24;8069:14;:21;8055:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8055:36:225;;8028:63;;8240:21;8314:1;8290:14;:21;:25;:57;;8346:1;8290:57;;;8318:14;:21;8342:1;8318:25;8290:57;8268:11;:18;8264:1;:22;:84;8240:108;;8363:26;8408:13;8392:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8363:59;;8436:14;8486:17;2806:4;2800:11;;2842:1;2824:20;;2886:8;2879:4;2864:20;;2857:38;2937:9;2915:20;;;2908:39;2710:26;2973:20;;2960:34;;;2800:11;2671:339;8486:17;8468:7;8476:6;8468:15;;;;;;;;:::i;:::-;;;;;;:35;;;;8523:9;8518:140;8542:11;:18;8538:1;:22;8518:140;;;8585:8;;;;;;;8629:11;8641:1;8629:14;;;;;;;;:::i;:::-;;;;;;;8611:7;8619:6;8611:15;;;;;;;;:::i;:::-;;;;;;;;;;:32;8562:3;;8518:140;;;-1:-1:-1;8676:21:225;;:25;8672:1428;;8721:8;;;;;;;8765:7;8747;8755:6;8747:15;;;;;;;;:::i;:::-;;;;;;:25;;;;8796:9;8791:1295;8815:14;:21;8811:1;:25;8791:1295;;;9493:295;9559:14;9574:1;9559:17;;;;;;;;:::i;:::-;;;;;;;:24;;;9613:92;9653:51;9678:14;9693:1;9678:17;;;;;;;;:::i;:::-;;;;;;;:25;;;3956:13:22;;3971:4;3952:24;;;3933:17;;3923:54;;3783:210;9653:51:225;1401:34:175;1323:14;1388:48;;;1497:4;1490:25;;;;1595:4;1579:21;;;1247:433;9613:92:225;9735:14;9750:1;9735:17;;;;;;;;:::i;:::-;;;;;;;:27;;;9493:36;:295::i;:::-;8865:1021;;9844:19;;;;;;;;3601:25:316;;;3574:18;;9844:19:225;3428:204:316;8865:1021:225;9945:14;9960:1;9945:17;;;;;;;;:::i;:::-;;;;;;;:24;;;-1:-1:-1;;;;;9929:42:225;9921:51;;9908:7;9916:1;9908:10;;;;;;;;:::i;:::-;;;;;;:64;;;;;9994:8;;;;;;;10042:14;10057:1;10042:17;;;;;;;;:::i;:::-;;;;;;;:25;;;10024:7;10032:6;10024:15;;;;;;;;:::i;:::-;;;;;;;;;;:43;8838:3;;8791:1295;;;;8672:1428;-1:-1:-1;10121:7:225;7835:2310;-1:-1:-1;;;;;7835:2310:225:o;46861:2749:188:-;47022:6;;47608:26;;47636;;47605:58;47762:26;;;47790;;;47758:59;47519:328;47934:24;;;47487:497;48019:105;;;;48066:18;48086;48058:47;;;;;;;48019:105;47349:789;48152:12;48202:9;48190;:21;48186:329;;;-1:-1:-1;48301:18:188;;48425:9;;48244:18;;48496:4;48186:329;48551:21;;;48529:19;48677:20;;48717:2;48699:21;;48674:47;48748:210;;;;48787:7;48783:161;;;48826:1;48829:18;48818:30;;;;;;;;;48783:161;48903:18;48923:1;48895:30;;;;;;;;;48783:161;49091:2;:27;;;49151:26;;;:18;49091:27;49151:26;49091:27;49196:16;;;;:::i;:::-;;:38;49192:402;;49258:7;49254:161;;;49297:1;49300:18;49289:30;;;;;;;;;;;49254:161;49374:18;49394:1;49366:30;;;;;;;;;;;49192:402;49439:7;49435:159;;;49474:18;;-1:-1:-1;49494:8:188;-1:-1:-1;49466:37:188;;-1:-1:-1;;;;49466:37:188;49435:159;49550:8;-1:-1:-1;49560:18:188;;-1:-1:-1;49542:37:188;;-1:-1:-1;;;;49542:37:188;1308:151:241;1404:48;;;;;-1:-1:-1;;;;;26942:55:316;;1404:48:241;;;26924:74:316;1367:11:241;;;;1080:42;;1404:41;;26897:18:316;;1404:48:241;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1397:55;;;;1308:151;;;:::o;12173:248:186:-;12254:7;;-1:-1:-1;;;;;17672:16:186;;17668:2;17657:32;17718:4;17714:16;;;12356:58;17657:32;17714:16;12405:8;12356:19;:58::i;:::-;12349:65;;;;;;12173:248;;;;;:::o;8373:1244:161:-;8600:4;8594:11;8509:24;8467:12;8618:22;;;-1:-1:-1;;;;;8666:24:161;;8660:4;8653:38;8711:4;8704:19;;;8467:12;8787:4;8467:12;8775:4;8467:12;;8759:5;8752;8747:45;8736:56;;9004:1;8997:4;8991:11;8988:18;8979:7;8975:32;8965:606;;9136:6;9126:7;9119:15;9115:28;9112:165;;;9192:16;9186:4;9181:3;9166:43;9242:16;9237:3;9230:29;9112:165;9553:1;9545:5;9533:18;9530:25;9511:16;9504:24;9500:56;9491:7;9487:70;9476:81;;8965:606;9591:4;9584:17;-1:-1:-1;8373:1244:161;;-1:-1:-1;;;;8373:1244:161:o;10165:1393::-;10460:4;10454:11;10365:28;10323:12;10478:22;;;-1:-1:-1;;;;;10526:26:161;;;10520:4;10513:40;10579:24;;10573:4;10566:38;10624:4;10617:19;;;10323:12;10700:4;10323:12;10688:4;10323:12;;10672:5;10665;10660:45;10649:56;;10917:1;10910:4;10904:11;10901:18;10892:7;10888:32;10878:606;;11049:6;11039:7;11032:15;11028:28;11025:165;;;11105:16;11099:4;11094:3;11079:43;11155:16;11150:3;11143:29;11025:165;11466:1;11458:5;11446:18;11443:25;11424:16;11417:24;11413:56;11404:7;11400:70;11389:81;;10878:606;11504:4;11497:17;-1:-1:-1;11540:1:161;11534:4;11527:15;10165:1393;;-1:-1:-1;;;;;10165:1393:161:o;1130:172:241:-;1239:56;;;;;-1:-1:-1;;;;;26942:55:316;;1239:56:241;;;26924:74:316;1202:11:241;;;;1080:42;;1239:49;;26897:18:316;;1239:56:241;;;;;;;;;;;;;;;;;;;;;;5339:2230:188;5489:24;;5619:26;;5647;;5616:58;5693:1870;;;;1256:1;5836:53;;1342:1;5903:34;;5693:1870;;;5979:21;5991:9;5979;:21;:::i;:::-;5968:32;;6135:29;6167:48;6196:18;6167:28;:48::i;:::-;6135:80;;6229:29;6261:48;6290:18;6261:28;:48::i;:::-;6229:80;;6325:13;6343:52;6350:21;6373;6343:6;:52::i;:::-;6324:71;;;6410:22;6490:4;6482:5;:12;6478:114;;;6527:4;6518:13;;;-1:-1:-1;6571:2:188;6553:20;6478:114;6621:4;6613:5;:12;6609:114;;;6658:4;6649:13;;;-1:-1:-1;6702:2:188;6684:20;6609:114;6752:3;6744:5;:11;6740:111;;;6788:3;6779:12;;;-1:-1:-1;6831:1:188;6813:19;6740:111;6880:3;6872:5;:11;6868:111;;;6916:3;6907:12;;;-1:-1:-1;6959:1:188;6941:19;6868:111;7003:9;;6996:108;;7045:2;7036:11;;;-1:-1:-1;7069:16:188;;6996:108;;;7232:34;7251:14;7232:34;;:::i;:::-;;-1:-1:-1;7313:239:188;7357:18;7393;7429:83;7436:21;7459;7482:29;7497:14;7490:2;7482:29;:::i;:::-;7429:6;:83::i;:::-;7530:8;7313:26;:239::i;:::-;7281:271;;-1:-1:-1;7281:271:188;-1:-1:-1;;;;;5693:1870:188;5536:2033;5339:2230;;;;;;;:::o;14352:2402:186:-;14437:11;14869:46;;;;;;14533:17;14589:8;14869:46;15193:668;;15250:4;15230:17;:24;:29;15226:135;;15304:3;15283:24;;;;15341:1;15329:13;;;;15226:135;15600:17;15578;15571:46;;;15564:151;;15662:2;15641:23;;;;15686:10;;;;;15564:151;;;15193:668;;;15757:17;15778:1;15757:22;15753:94;;-1:-1:-1;2277:1:186;;-1:-1:-1;15823:4:186;;-1:-1:-1;15803:25:186;;-1:-1:-1;15803:25:186;15753:94;16071:8;16058;16052:27;;;16048:393;;16273:1;16262:8;:12;16258:85;;;-1:-1:-1;2277:1:186;;-1:-1:-1;2277:1:186;;-1:-1:-1;16298:26:186;;-1:-1:-1;16298:26:186;16258:85;16367:59;;-1:-1:-1;;;16367:59:186;;;;;5827:25:316;;;5868:18;;;5861:34;;;5800:18;;16367:59:186;5599:302:316;16048:393:186;-1:-1:-1;;;;;;;16674:28:186;;16708:4;16704:19;;;16671:53;;-1:-1:-1;14352:2402:186;;;;;:::o;31406:339:188:-;31556:6;31564;31620:36;31626:18;31646:9;31620:5;:36::i;:::-;31586:70;;-1:-1:-1;31586:70:188;-1:-1:-1;31673:65:188;31677:18;31697:9;31586:70;;31673:3;:65::i;:::-;31666:72;;;;31406:339;;;;;;;:::o;10727:8629::-;10877:6;10885;10911:18;10933:1;10911:23;10907:8443;;10957:45;;;;;;;;5827:25:316;;;5868:18;;;5861:34;;;5800:18;;10957:45:188;5599:302:316;10907:8443:188;11023:18;11045:1;11023:23;11019:8331;;-1:-1:-1;1256:1:188;;-1:-1:-1;1256:1:188;11062:67;;11019:8331;11160:24;11198:15;11227:10;11251;11458:39;11467:18;11487:9;11458:8;:39::i;:::-;11417:80;;-1:-1:-1;11417:80:188;-1:-1:-1;11417:80:188;-1:-1:-1;11552:39:188;11561:18;11581:9;11552:8;:39::i;:::-;11511:80;;-1:-1:-1;11511:80:188;-1:-1:-1;11511:80:188;-1:-1:-1;11726:29:188;11758:48;11787:18;11758:28;:48::i;:::-;11726:80;;11820:29;11852:48;11881:18;11852:28;:48::i;:::-;11820:80;-1:-1:-1;11931:4:188;11973:2;12424:29;;;12420:4320;;;12477:5;12473:4129;;;-1:-1:-1;12514:4:188;;-1:-1:-1;12557:2:188;12473:4129;;;12634:4;12610:21;:28;12606:3675;;;12694:4;12670:21;:28;12666:1781;;;12758:4;12734:21;:28;12730:813;;;12826:3;12802:21;:27;12798:321;;;-1:-1:-1;12877:3:188;;-1:-1:-1;12935:1:188;12606:3675;;12798:321;-1:-1:-1;13023:4:188;;-1:-1:-1;13082:2:188;12606:3675;;12730:813;13217:4;13193:21;:28;13189:324;;;-1:-1:-1;13269:4:188;;-1:-1:-1;13328:2:188;12606:3675;;13189:324;-1:-1:-1;13417:4:188;;-1:-1:-1;13476:2:188;12606:3675;;12666:1781;13633:4;13609:21;:28;13605:816;;;13701:4;13677:21;:28;13673:324;;;-1:-1:-1;13753:4:188;;-1:-1:-1;13812:2:188;12606:3675;;13673:324;-1:-1:-1;13901:4:188;;-1:-1:-1;13960:2:188;12606:3675;;13605:816;14095:4;14071:21;:28;14067:324;;;-1:-1:-1;14147:4:188;;-1:-1:-1;14206:2:188;12606:3675;;14067:324;-1:-1:-1;14295:4:188;;-1:-1:-1;14354:2:188;12606:3675;;;14529:4;14505:21;:28;14501:1758;;;14593:4;14569:21;:28;14565:816;;;14661:4;14637:21;:28;14633:324;;;-1:-1:-1;14713:4:188;;-1:-1:-1;14772:2:188;12606:3675;;14633:324;-1:-1:-1;14861:4:188;;-1:-1:-1;14920:2:188;14501:1758;;14565:816;15055:4;15031:21;:28;15027:324;;;-1:-1:-1;15107:4:188;;-1:-1:-1;15166:2:188;12606:3675;;15027:324;-1:-1:-1;15255:4:188;;-1:-1:-1;15314:2:188;14501:1758;;;15471:4;15447:21;:28;15443:790;;;15539:4;15515:21;:28;15511:324;;;-1:-1:-1;15591:4:188;;-1:-1:-1;15650:2:188;15443:790;;15511:324;-1:-1:-1;15739:4:188;;-1:-1:-1;15798:2:188;15443:790;;;15933:4;15909:21;:28;15905:298;;;-1:-1:-1;15985:4:188;;-1:-1:-1;16044:2:188;15905:298;16402:5;16377:21;:30;16370:214;;16484:2;16475:11;;;-1:-1:-1;;;16516:19:188;16370:214;;;16624:5;16619:107;;16660:47;;-1:-1:-1;;;16660:47:188;;;;;5827:25:316;;;5868:18;;;5861:34;;;5800:18;;16660:47:188;5599:302:316;16619:107:188;17208:14;-1:-1:-1;;;17189:33:188;17176:9;:46;17172:623;;17259:14;17246:27;;;;17172:623;;;-1:-1:-1;;;17350:16:188;17320:46;;;;17460:1;17443:18;;17439:338;;;17525:14;-1:-1:-1;;;;;17506:33:188;17493:9;:46;17489:266;;17571:27;;;;17489:266;;;1256:1;1342;17661:67;;;;;;;;;;;;;;17489:266;17823:26;17973:1;17961:9;:13;:30;;;;;17990:1;17978:9;:13;17961:30;17957:222;;;-1:-1:-1;;;18033:28:188;;18105:20;;;:55;;18158:1;18105:55;;;18140:8;18128:9;:20;18105:55;18083:77;;17993:186;17957:222;18242:9;18220:19;18208:9;:31;:43;18197:54;;18302:235;18350:18;18390;18430:59;18437:21;18460:5;18467:21;18430:6;:59::i;:::-;18511:8;18302:26;:235::i;:::-;18270:267;;-1:-1:-1;18270:267:188;-1:-1:-1;18582:1:188;18560:23;;18556:716;;;18633:2;18611:19;:24;18607:308;;;1256:1;1342;18825:67;;;;;;;;;;;;;;;18607:308;19100:19;19086:2;:34;19058:63;;;;;;:::i;:::-;;;;19147:17;19168:1;19147:22;19143:111;;1342:1;19197:34;;19143:111;-1:-1:-1;19297:17:188;;-1:-1:-1;19316:8:188;;-1:-1:-1;19289:36:188;;-1:-1:-1;;;;;;19289:36:188;27242:3681;27392:6;;27658:26;;27686;;27655:58;27732:217;;;;27766:18;27788:1;27766:23;27762:177;;27817:18;27837:9;27809:38;;;;;;;27762:177;27894:18;27914:9;27886:38;;;;;;;27762:177;28186:43;28199:18;28219:9;28186:12;:43::i;:::-;28152:77;;-1:-1:-1;28152:77:188;-1:-1:-1;28273:43:188;28286:18;28306:9;28273:12;:43::i;:::-;28239:77;;-1:-1:-1;28239:77:188;-1:-1:-1;28437:21:188;;;28433:268;;;28540:18;;28652:9;;28487:18;;28433:268;29385:21;;;611:2;29569:45;;29565:122;;;29642:18;29662:9;29634:38;;;;;;;;29565:122;29906:21;29900:2;:27;29871:57;;;;;;:::i;:::-;;;-1:-1:-1;;30021:39:188;;;30279:26;;;30176:4;30269:37;;;30262:45;30355:18;30182:43;;;30172:54;;;30165:62;30339:35;30447:412;;;;30506:9;-1:-1:-1;;;;;30486:29:188;30482:130;;30546:47;;-1:-1:-1;;;30546:47:188;;;;;5827:25:316;;;5868:18;;;5861:34;;;5800:18;;30546:47:188;5599:302:316;30482:130:188;30652:2;30672:24;;;;30630;;;;30743:40;;;30714:11;;;;;;30447:412;;;30843:1;30822:22;;30447:412;-1:-1:-1;30886:18:188;;30906:9;;-1:-1:-1;;;;;;27242:3681:188:o;782:368:37:-;846:4;880:1;866:4;:11;:15;862:33;;;-1:-1:-1;890:5:37;;782:368;-1:-1:-1;782:368:37:o;862:33::-;-1:-1:-1;1072:1:37;1062:12;1056:19;920:16;1052:30;758:18:33;1108:35:37;;782:368::o;3383:242:168:-;3466:12;3604:4;3598;3591;3585:11;3578:4;3572;3568:15;3560:6;3553:5;3540:69;3529:80;3383:242;-1:-1:-1;;;3383:242:168:o;4698:334::-;4829:4;4823:11;4862:16;4847:32;;4932:16;4926:4;4919;4907:17;;4892:57;4997:16;4991:4;4987:27;4979:6;4975:40;4969:4;4962:54;4698:334;:::o;5099:223::-;5203:4;5197:11;5247:16;5241:4;5236:3;5221:43;5289:16;5284:3;5277:29;42436:827:253;42619:16;42637:17;42734:70;42772:23;:31;;;42734:23;:33;;;:37;;:70;;;;:::i;:::-;42721:83;;42829:23;:33;;;42815:47;;42995:46;43009:21;:31;;;42995:10;:13;;:46;;;;:::i;:::-;42991:266;;;43070:21;:31;;;43057:44;;43199:47;43214:23;:31;;;43199:10;:14;;:47;;;;:::i;:::-;43185:61;;42436:827;;;;;:::o;1485:429:176:-;1591:4;1611:6;-1:-1:-1;;;;;1611:18:176;;1633:1;1611:23;1607:301;;1651:17;1670:22;1698:33;1715:4;1721:9;1698:16;:33::i;:::-;-1:-1:-1;1650:81:176;;-1:-1:-1;1650:81:176;-1:-1:-1;1759:26:176;1752:3;:33;;;;;;;;:::i;:::-;;:56;;;;;1802:6;-1:-1:-1;;;;;1789:19:176;:9;-1:-1:-1;;;;;1789:19:176;;1752:56;1745:63;;;;;;1607:301;1846:51;1873:6;1881:4;1887:9;1846:26;:51::i;:::-;1839:58;;;;8561:3045:186;8696:7;8705:4;8828:1;8808:17;:21;8804:2796;;;8852:59;;;;;;;;5827:25:316;;;5868:18;;;5861:34;;;5800:18;;8852:59:186;5599:302:316;8804:2796:186;9010:17;9031:1;9010:22;9006:2594;;-1:-1:-1;9056:1:186;;-1:-1:-1;9059:4:186;9048:16;;9006:2594;9274:17;9555;;;9537:36;;9595:24;;;9591:123;;;9650:45;;-1:-1:-1;;;9650:45:186;;;;;5827:25:316;;;5868:18;;;5861:34;;;5800:18;;9650:45:186;5599:302:316;9591:123:186;9742:13;9769:20;9823:1;9807:13;:17;9803:1787;;;-1:-1:-1;;10085:13:186;:19;10081:91;;;10140:1;10143:5;10132:17;;;;;;;;;;10081:91;10532:13;10531:14;;10517:2;:29;10509:37;;10605:5;10583:19;:27;;;;;:::i;:::-;;;-1:-1:-1;;10868:20:186;;:43;;;;-1:-1:-1;10846:66:186;;-1:-1:-1;10846:66:186;9803:1787;10971:1;10955:13;:17;10951:639;;;11117:28;11131:13;11117:2;:28;:::i;:::-;11109:36;-1:-1:-1;11178:27:186;11109:36;11178:19;:27;:::i;:::-;11163:42;-1:-1:-1;11479:4:186;;-1:-1:-1;11457:27:186;;-1:-1:-1;;;;11457:27:186;10951:639;-1:-1:-1;11549:19:186;;-1:-1:-1;11570:4:186;;-1:-1:-1;;;9006:2594:186;8561:3045;;;;;;:::o;2884:701:188:-;2971:7;3038:1;3018:17;:21;3014:555;;;-1:-1:-1;;;3063:17:188;:37;3059:316;;-1:-1:-1;;;;3131:29:188;2884:701;-1:-1:-1;2884:701:188:o;3059:316::-;-1:-1:-1;3337:18:188;;;2884:701::o;3014:555::-;-1:-1:-1;3536:17:188;2884:701::o;3014:555::-;2884:701;;;:::o;19493:550::-;19554:12;;-1:-1:-1;;19937:1:188;19934;19927:20;19967:9;;;;20015:11;;;20001:12;;;;19997:30;;;;;19493:550;-1:-1:-1;;19493:550:188:o;20206:4048::-;20288:14;20315:13;20330;20347:12;20354:1;20357;20347:6;:12::i;:::-;20314:45;;;;20433:5;20442:1;20433:10;20429:109;;20502:11;20494:5;:19;;;;;:::i;:::-;;20487:26;;;;;;20429:109;20645:11;20636:5;:20;20632:91;;20679:33;;;;;;;;49498:25:316;;;49539:18;;;49532:34;;;49582:18;;;49575:34;;;49471:18;;20679:33:188;49296:319:316;20632:91:188;21015:17;21174:11;21171:1;21168;21161:25;21775:1;21760:12;;:16;;21745:32;;22014:25;;;;;23175:1;23156;:15;;23155:21;;23408;;;23404:25;;23393:36;23477:21;;;23473:25;;23462:36;23547:21;;;23543:25;;23532:36;23617:21;;;23613:25;;23602:36;23687:21;;;23683:25;;23672:36;23758:21;;;23754:25;;;23743:36;21727:15;22624;;;22620:29;;;22616:37;;;21280:20;;;21269:32;;;22742:22;;;;21323:21;;;;22186:19;;;;22733:31;;;;24222:15;;-1:-1:-1;;20206:4048:188;;;;;:::o;3591:1698::-;3741:6;3749;3863:1;3858;3854;:5;3853:11;3849:1434;;;-1:-1:-1;;;;;3884:20:188;:48;3880:830;;;3980:29;-1:-1:-1;;;;;4008:1:188;3980:29;:::i;:::-;3956:20;:53;3952:529;;-1:-1:-1;;;;4151:16:188;-1:-1:-1;4169:8:188;4143:35;;3952:529;4421:25;4444:2;4421:20;:25;:::i;:::-;4413:34;;;:::i;:::-;4449:12;:8;4460:1;4449:12;:::i;:::-;4405:57;;;;;;3880:830;4655:29;4663:20;4655:29;:::i;:::-;4686:8;4647:48;;;;;;3849:1434;-1:-1:-1;;;;;4744:20:188;:48;4740:533;;;4995:25;5018:2;4995:20;:25;:::i;4740:533::-;-1:-1:-1;5226:20:188;;-1:-1:-1;5249:8:188;5211:47;;2337:541;2418:6;2426;-1:-1:-1;;;2544:17:188;:37;2540:271;;-1:-1:-1;;;;;2605:8:188;:28;2601:127;;2664:45;;-1:-1:-1;;;2664:45:188;;;;;5827:25:316;;;5868:18;;;5861:34;;;5800:18;;2664:45:188;5599:302:316;2601:127:188;2766:2;2745:23;;;;2786:10;;;;;2540:271;-1:-1:-1;;2832:18:188;;;;;;2337:541::o;42818:1994::-;42902:6;42910;42918:4;42962:17;42983:1;42962:22;42958:134;;-1:-1:-1;1256:1:188;;-1:-1:-1;1256:1:188;;-1:-1:-1;43072:4:188;43004:73;;42958:134;43231:4;43211:17;:24;43239:1;43211:29;43207:1005;;43284:4;43264:17;:24;:29;:66;;;;-1:-1:-1;43309:21:188;43297:33;;;43264:66;43260:174;;;43375:4;43354:25;;;;43413:2;43401:14;;;;43260:174;43476:4;43456:17;:24;:29;:66;;;;-1:-1:-1;43501:21:188;43489:33;;;43456:66;43452:174;;;43567:4;43546:25;;;;43605:2;43593:14;;;;43452:174;43668:4;43648:17;:24;:29;:66;;;;-1:-1:-1;43693:21:188;43681:33;;;43648:66;43644:174;;;43759:4;43738:25;;;;43797:2;43785:14;;;;43644:174;43863:4;43843:17;:24;:29;:65;;;;-1:-1:-1;43888:20:188;43876:32;;;43843:65;43836:174;;;43953:3;43932:24;;;;43990:1;43978:13;;;;43836:174;;;44052:4;44032:17;:24;:29;:65;;;;-1:-1:-1;44077:20:188;44065:32;;;44032:65;44028:170;;;44142:2;44121:23;;;;44178:1;44166:13;;;;44028:170;44506:2;44486:22;;;;;44547:25;44526:17;:46;:82;;;;-1:-1:-1;44588:20:188;44576:32;;;44526:82;44522:192;;;44648:20;44628:40;;44698:1;44686:13;;;;44522:192;-1:-1:-1;44736:17:188;;-1:-1:-1;44755:8:188;;-1:-1:-1;;44785:4:188;44765:24;;:29;;42818:1994;;;;;;:::o;44818:370::-;44906:6;44914;44933:27;44962:18;44982:9;44995:37;45004:17;45023:8;44995;:37::i;:::-;44932:100;;;;;;45047:4;45042:88;;45074:45;;-1:-1:-1;;;45074:45:188;;;;;5827:25:316;;;5868:18;;;5861:34;;;5800:18;;45074:45:188;5599:302:316;45042:88:188;-1:-1:-1;45147:20:188;;;;-1:-1:-1;44818:370:188;-1:-1:-1;;;44818:370:188:o;2433:778:174:-;2536:17;2555:16;2573:14;2603:9;:16;2623:2;2603:22;2599:606;;2908:4;2893:20;;2887:27;2957:4;2942:20;;2936:27;3014:4;2999:20;;2993:27;2641:9;2985:36;3055:25;3066:4;2985:36;2887:27;2936;3055:10;:25::i;:::-;3048:32;;;;;;;;;;;2599:606;-1:-1:-1;;3176:16:174;;3127:1;;-1:-1:-1;3131:35:174;;3111:83;;2900:986:176;3145:16;;3500:4;3494:11;;3084:34;3518:21;;;3568:4;3559:14;;3552:28;;;3609:4;3600:14;;3593:28;;;;3043:11;;3145:16;3679:4;3667:17;;3145:9;3649:4;3640:14;;3634:51;3770:4;3764;3757;3749:6;3745:17;3740:3;3732:6;3725:5;3714:61;3699:76;;3859:8;3852:4;3846:11;3843:25;3836:4;3818:16;3815:26;3811:58;3802:7;3798:72;3788:82;;;3197:683;;2900:986;;;;;:::o;7142:1551:174:-;7268:17;;;8222:66;8209:79;;8205:164;;;-1:-1:-1;8320:1:174;;-1:-1:-1;8324:30:174;;-1:-1:-1;8356:1:174;8304:54;;8205:164;8480:24;;;8463:14;8480:24;;;;;;;;;50322:25:316;;;50395:4;50383:17;;50363:18;;;50356:45;;;;50417:18;;;50410:34;;;50460:18;;;50453:34;;;8480:24:174;;50294:19:316;;8480:24:174;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;8480:24:174;;-1:-1:-1;;8480:24:174;;;-1:-1:-1;;;;;;;8518:20:174;;8514:113;;-1:-1:-1;8570:1:174;;-1:-1:-1;8574:29:174;;-1:-1:-1;8570:1:174;;-1:-1:-1;8554:62:174;;8514:113;8645:6;-1:-1:-1;8653:20:174;;-1:-1:-1;8653:20:174;;-1:-1:-1;7142:1551:174;;;;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:332:316:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;543:382;621:8;631:6;685:3;678:4;670:6;666:17;662:27;652:55;;703:1;700;693:12;652:55;-1:-1:-1;726:20:316;;769:18;758:30;;755:50;;;801:1;798;791:12;755:50;838:4;830:6;826:17;814:29;;898:3;891:4;881:6;878:1;874:14;866:6;862:27;858:38;855:47;852:67;;;915:1;912;905:12;930:766;1080:6;1088;1096;1149:2;1137:9;1128:7;1124:23;1120:32;1117:52;;;1165:1;1162;1155:12;1117:52;1205:9;1192:23;1234:18;1275:2;1267:6;1264:14;1261:34;;;1291:1;1288;1281:12;1261:34;1314:22;;;;1370:3;1352:16;;;1348:26;1345:46;;;1387:1;1384;1377:12;1345:46;1410:2;;-1:-1:-1;1465:2:316;1450:18;;1437:32;;1481:16;;;1478:36;;;1510:1;1507;1500:12;1478:36;;1549:87;1628:7;1617:8;1606:9;1602:24;1549:87;:::i;:::-;930:766;;1655:8;;-1:-1:-1;1523:113:316;;-1:-1:-1;;;;930:766:316:o;1701:180::-;1760:6;1813:2;1801:9;1792:7;1788:23;1784:32;1781:52;;;1829:1;1826;1819:12;1781:52;-1:-1:-1;1852:23:316;;1701:180;-1:-1:-1;1701:180:316:o;1886:154::-;-1:-1:-1;;;;;1965:5:316;1961:54;1954:5;1951:65;1941:93;;2030:1;2027;2020:12;2045:134;2113:20;;2142:31;2113:20;2142:31;:::i;2184:778::-;2351:6;2359;2367;2375;2383;2436:3;2424:9;2415:7;2411:23;2407:33;2404:53;;;2453:1;2450;2443:12;2404:53;2492:9;2479:23;2511:31;2536:5;2511:31;:::i;:::-;2561:5;-1:-1:-1;2613:2:316;2598:18;;2585:32;;-1:-1:-1;2664:2:316;2649:18;;2636:32;;-1:-1:-1;2719:2:316;2704:18;;2691:32;2746:18;2735:30;;2732:50;;;2778:1;2775;2768:12;2732:50;2817:85;2894:7;2885:6;2874:9;2870:22;2817:85;:::i;:::-;2184:778;;;;-1:-1:-1;2184:778:316;;-1:-1:-1;2921:8:316;;2791:111;2184:778;-1:-1:-1;;;2184:778:316:o;2967:456::-;3044:6;3052;3060;3113:2;3101:9;3092:7;3088:23;3084:32;3081:52;;;3129:1;3126;3119:12;3081:52;3168:9;3155:23;3187:31;3212:5;3187:31;:::i;:::-;3237:5;-1:-1:-1;3294:2:316;3279:18;;3266:32;3307:33;3266:32;3307:33;:::i;:::-;2967:456;;3359:7;;-1:-1:-1;;;3413:2:316;3398:18;;;;3385:32;;2967:456::o;3637:967::-;3765:6;3773;3781;3789;3797;3850:3;3838:9;3829:7;3825:23;3821:33;3818:53;;;3867:1;3864;3857:12;3818:53;3906:9;3893:23;3925:31;3950:5;3925:31;:::i;:::-;3975:5;-1:-1:-1;4032:2:316;4017:18;;4004:32;4045:33;4004:32;4045:33;:::i;:::-;4097:7;-1:-1:-1;4151:2:316;4136:18;;4123:32;;-1:-1:-1;4206:2:316;4191:18;;4178:32;4229:18;4259:14;;;4256:34;;;4286:1;4283;4276:12;4256:34;4324:6;4313:9;4309:22;4299:32;;4369:7;4362:4;4358:2;4354:13;4350:27;4340:55;;4391:1;4388;4381:12;4340:55;4431:2;4418:16;4457:2;4449:6;4446:14;4443:34;;;4473:1;4470;4463:12;4443:34;4518:7;4513:2;4504:6;4500:2;4496:15;4492:24;4489:37;4486:57;;;4539:1;4536;4529:12;4486:57;3637:967;;;;-1:-1:-1;3637:967:316;;-1:-1:-1;4570:2:316;4562:11;;4592:6;3637:967;-1:-1:-1;;;3637:967:316:o;4609:247::-;4668:6;4721:2;4709:9;4700:7;4696:23;4692:32;4689:52;;;4737:1;4734;4727:12;4689:52;4776:9;4763:23;4795:31;4820:5;4795:31;:::i;5043:167::-;5114:5;5159:3;5150:6;5145:3;5141:16;5137:26;5134:46;;;5176:1;5173;5166:12;5134:46;-1:-1:-1;5198:6:316;5043:167;-1:-1:-1;5043:167:316:o;5215:379::-;5313:6;5366:2;5354:9;5345:7;5341:23;5337:32;5334:52;;;5382:1;5379;5372:12;5334:52;5422:9;5409:23;5455:18;5447:6;5444:30;5441:50;;;5487:1;5484;5477:12;5441:50;5510:78;5580:7;5571:6;5560:9;5556:22;5510:78;:::i;:::-;5500:88;5215:379;-1:-1:-1;;;;5215:379:316:o;5906:752::-;6062:6;6070;6078;6131:2;6119:9;6110:7;6106:23;6102:32;6099:52;;;6147:1;6144;6137:12;6099:52;6187:9;6174:23;6216:18;6257:2;6249:6;6246:14;6243:34;;;6273:1;6270;6263:12;6243:34;6296:78;6366:7;6357:6;6346:9;6342:22;6296:78;:::i;:::-;6286:88;;6427:2;6416:9;6412:18;6399:32;6383:48;;6456:2;6446:8;6443:16;6440:36;;;6472:1;6469;6462:12;6663:388;6750:6;6803:2;6791:9;6782:7;6778:23;6774:32;6771:52;;;6819:1;6816;6809:12;6771:52;6859:9;6846:23;6892:18;6884:6;6881:30;6878:50;;;6924:1;6921;6914:12;6878:50;6947:22;;7003:3;6985:16;;;6981:26;6978:46;;;7020:1;7017;7010:12;7444:463;7541:6;7549;7602:2;7590:9;7581:7;7577:23;7573:32;7570:52;;;7618:1;7615;7608:12;7570:52;7658:9;7645:23;7691:18;7683:6;7680:30;7677:50;;;7723:1;7720;7713:12;7677:50;7762:85;7839:7;7830:6;7819:9;7815:22;7762:85;:::i;:::-;7866:8;;7736:111;;-1:-1:-1;7444:463:316;-1:-1:-1;;;;7444:463:316:o;7912:288::-;7953:3;7991:5;7985:12;8018:6;8013:3;8006:19;8074:6;8067:4;8060:5;8056:16;8049:4;8044:3;8040:14;8034:47;8126:1;8119:4;8110:6;8105:3;8101:16;8097:27;8090:38;8189:4;8182:2;8178:7;8173:2;8165:6;8161:15;8157:29;8152:3;8148:39;8144:50;8137:57;;;7912:288;;;;:::o;8205:800::-;8365:4;8394:2;8434;8423:9;8419:18;8464:2;8453:9;8446:21;8487:6;8522;8516:13;8553:6;8545;8538:22;8591:2;8580:9;8576:18;8569:25;;8653:2;8643:6;8640:1;8636:14;8625:9;8621:30;8617:39;8603:53;;8691:2;8683:6;8679:15;8712:1;8722:254;8736:6;8733:1;8730:13;8722:254;;;8829:2;8825:7;8813:9;8805:6;8801:22;8797:36;8792:3;8785:49;8857:39;8889:6;8880;8874:13;8857:39;:::i;:::-;8847:49;-1:-1:-1;8954:12:316;;;;8919:15;;;;8758:1;8751:9;8722:254;;;-1:-1:-1;8993:6:316;;8205:800;-1:-1:-1;;;;;;;8205:800:316:o;9494:315::-;9562:6;9570;9623:2;9611:9;9602:7;9598:23;9594:32;9591:52;;;9639:1;9636;9629:12;9591:52;9678:9;9665:23;9697:31;9722:5;9697:31;:::i;:::-;9747:5;9799:2;9784:18;;;;9771:32;;-1:-1:-1;;;9494:315:316:o;9814:184::-;-1:-1:-1;;;9863:1:316;9856:88;9963:4;9960:1;9953:15;9987:4;9984:1;9977:15;10003:253;10075:2;10069:9;10117:4;10105:17;;10152:18;10137:34;;10173:22;;;10134:62;10131:88;;;10199:18;;:::i;:::-;10235:2;10228:22;10003:253;:::o;10261:257::-;10333:4;10327:11;;;10365:17;;10412:18;10397:34;;10433:22;;;10394:62;10391:88;;;10459:18;;:::i;10523:253::-;10595:2;10589:9;10637:4;10625:17;;10672:18;10657:34;;10693:22;;;10654:62;10651:88;;;10719:18;;:::i;10781:275::-;10852:2;10846:9;10917:2;10898:13;;-1:-1:-1;;10894:27:316;10882:40;;10952:18;10937:34;;10973:22;;;10934:62;10931:88;;;10999:18;;:::i;:::-;11035:2;11028:22;10781:275;;-1:-1:-1;10781:275:316:o;11061:530::-;11103:5;11156:3;11149:4;11141:6;11137:17;11133:27;11123:55;;11174:1;11171;11164:12;11123:55;11210:6;11197:20;11236:18;11232:2;11229:26;11226:52;;;11258:18;;:::i;:::-;11302:55;11345:2;11326:13;;-1:-1:-1;;11322:27:316;11351:4;11318:38;11302:55;:::i;:::-;11382:2;11373:7;11366:19;11428:3;11421:4;11416:2;11408:6;11404:15;11400:26;11397:35;11394:55;;;11445:1;11442;11435:12;11394:55;11510:2;11503:4;11495:6;11491:17;11484:4;11475:7;11471:18;11458:55;11558:1;11533:16;;;11551:4;11529:27;11522:38;;;;11537:7;11061:530;-1:-1:-1;;;11061:530:316:o;11596:624::-;11654:5;11702:4;11690:9;11685:3;11681:19;11677:30;11674:50;;;11720:1;11717;11710:12;11674:50;11742:22;;:::i;:::-;11733:31;;11801:9;11788:23;11820:33;11845:7;11820:33;:::i;:::-;11862:22;;11936:2;11921:18;;11908:32;11949:33;11908:32;11949:33;:::i;:::-;12009:2;11998:14;;11991:31;12073:2;12058:18;;12045:32;12100:18;12089:30;;12086:50;;;12132:1;12129;12122:12;12086:50;12168:45;12209:3;12200:6;12189:9;12185:22;12168:45;:::i;:::-;12163:2;12156:5;12152:14;12145:69;;11596:624;;;;:::o;12225:187::-;12289:4;12322:18;12314:6;12311:30;12308:56;;;12344:18;;:::i;:::-;-1:-1:-1;12389:1:316;12385:14;12401:4;12381:25;;12225:187::o;12417:352::-;12468:5;12516:4;12504:9;12499:3;12495:19;12491:30;12488:50;;;12534:1;12531;12524:12;12488:50;12556:22;;:::i;:::-;12547:31;;12615:9;12602:23;12634:33;12659:7;12634:33;:::i;:::-;12690:7;12683:5;12676:22;;12758:2;12747:9;12743:18;12730:32;12725:2;12718:5;12714:14;12707:56;12417:352;;;;:::o;12774:693::-;12832:5;12885:3;12878:4;12870:6;12866:17;12862:27;12852:55;;12903:1;12900;12893:12;12852:55;12939:6;12926:20;12965:4;12989:64;13005:47;13049:2;13005:47;:::i;:::-;12989:64;:::i;:::-;13075:3;13099:2;13094:3;13087:15;13127:4;13122:3;13118:14;13111:21;;13184:4;13178:2;13175:1;13171:10;13163:6;13159:23;13155:34;13141:48;;13212:3;13204:6;13201:15;13198:35;;;13229:1;13226;13219:12;13198:35;13265:4;13257:6;13253:17;13279:159;13295:6;13290:3;13287:15;13279:159;;;13363:32;13391:3;13386;13363:32;:::i;:::-;13351:45;;13416:12;;;;13321:4;13312:14;13279:159;;;-1:-1:-1;13456:5:316;12774:693;-1:-1:-1;;;;;;12774:693:316:o;13472:912::-;13526:5;13574:4;13562:9;13557:3;13553:19;13549:30;13546:50;;;13592:1;13589;13582:12;13546:50;13614:22;;:::i;:::-;13605:31;;13659:29;13678:9;13659:29;:::i;:::-;13652:5;13645:44;13740:2;13729:9;13725:18;13712:32;13763:18;13804:2;13796:6;13793:14;13790:34;;;13820:1;13817;13810:12;13790:34;13856:58;13910:3;13901:6;13890:9;13886:22;13856:58;:::i;:::-;13851:2;13844:5;13840:14;13833:82;13968:2;13957:9;13953:18;13940:32;13924:48;;13997:2;13987:8;13984:16;13981:36;;;14013:1;14010;14003:12;13981:36;14049:63;14108:3;14097:8;14086:9;14082:24;14049:63;:::i;:::-;14044:2;14037:5;14033:14;14026:87;14166:2;14155:9;14151:18;14138:32;14122:48;;14195:2;14185:8;14182:16;14179:36;;;14211:1;14208;14201:12;14179:36;;14247:63;14306:3;14295:8;14284:9;14280:24;14247:63;:::i;:::-;14242:2;14235:5;14231:14;14224:87;;14372:3;14361:9;14357:19;14344:33;14338:3;14331:5;14327:15;14320:58;13472:912;;;;:::o;14389:2014::-;14483:5;14512:68;14528:51;14572:6;14528:51;:::i;14512:68::-;14614:21;;;14503:77;-1:-1:-1;14654:4:316;14674:14;;;;14707:1;14743:14;;;14731:27;;14770:15;;;14767:35;;;14798:1;14795;14788:12;14767:35;14822:6;14837:1560;14853:6;14848:3;14845:15;14837:1560;;;14939:3;14926:17;14966:18;15016:2;15003:11;15000:19;14997:39;;;15032:1;15029;15022:12;14997:39;15059:24;;;;15117:4;15103:12;;;15099:23;15096:43;;;15135:1;15132;15125:12;15096:43;15165:22;;:::i;:::-;15228:2;15215:16;15244:33;15269:7;15244:33;:::i;:::-;15290:22;;15354:11;;;15341:25;15382:16;;;15379:36;;;15411:1;15408;15401:12;15379:36;15438:17;;15490:4;15482:13;;15478:23;-1:-1:-1;15468:51:316;;15515:1;15512;15505:12;15468:51;15555:2;15542:16;15584:64;15600:47;15644:2;15600:47;:::i;15584:64::-;15692:17;;;15786:11;;;15778:20;;15774:29;;;15731:14;;;;15819:17;;;15816:37;;;15849:1;15846;15839:12;15816:37;15879:11;;;;15903:174;15921:8;15914:5;15911:19;15903:174;;;16003:19;;15989:34;;15942:14;;;;16049;;;;15903:174;;;16097:14;;;16090:29;-1:-1:-1;16142:2:316;;-1:-1:-1;;16186:11:316;;;16173:25;16214:16;;;16211:36;;;16243:1;16240;16233:12;16211:36;16283:40;16319:3;16308:8;16304:2;16300:17;16283:40;:::i;:::-;16267:14;;;16260:64;;;;-1:-1:-1;16337:18:316;;-1:-1:-1;;16375:12:316;;;;14870;;14837:1560;;;14841:3;;;;;14389:2014;;;;;:::o;16408:274::-;16477:5;16530:3;16523:4;16515:6;16511:17;16507:27;16497:55;;16548:1;16545;16538:12;16497:55;16570:106;16672:3;16663:6;16650:20;16643:4;16635:6;16631:17;16570:106;:::i;16687:1288::-;16986:6;16994;17002;17010;17018;17071:3;17059:9;17050:7;17046:23;17042:33;17039:53;;;17088:1;17085;17078:12;17039:53;17128:9;17115:23;17157:18;17198:2;17190:6;17187:14;17184:34;;;17214:1;17211;17204:12;17184:34;17237:58;17287:7;17278:6;17267:9;17263:22;17237:58;:::i;:::-;17227:68;;17348:2;17337:9;17333:18;17320:32;17304:48;;17377:2;17367:8;17364:16;17361:36;;;17393:1;17390;17383:12;17361:36;17416:60;17468:7;17457:8;17446:9;17442:24;17416:60;:::i;:::-;17406:70;;17495:74;17561:7;17556:2;17545:9;17541:18;17495:74;:::i;:::-;17485:84;;17622:3;17611:9;17607:19;17594:33;17578:49;;17652:2;17642:8;17639:16;17636:36;;;17668:1;17665;17658:12;17636:36;17691:78;17761:7;17750:8;17739:9;17735:24;17691:78;:::i;:::-;17681:88;;17822:3;17811:9;17807:19;17794:33;17778:49;;17852:2;17842:8;17839:16;17836:36;;;17868:1;17865;17858:12;17836:36;;17891:78;17961:7;17950:8;17939:9;17935:24;17891:78;:::i;:::-;17881:88;;;16687:1288;;;;;;;;:::o;18312:195::-;18416:9;18453:48;18486:14;18479:5;18453:48;:::i;18512:266::-;18600:6;18595:3;18588:19;18652:6;18645:5;18638:4;18633:3;18629:14;18616:43;-1:-1:-1;18704:1:316;18679:16;;;18697:4;18675:27;;;18668:38;;;;18760:2;18739:15;;;-1:-1:-1;;18735:29:316;18726:39;;;18722:50;;18512:266::o;18783:954::-;18846:3;18892:5;18879:19;18907:33;18932:7;18907:33;:::i;:::-;-1:-1:-1;;;;;19022:16:316;;;19010:29;;19087:4;19076:16;;19063:30;;19102:33;19063:30;19102:33;:::i;:::-;19167:16;19160:4;19151:14;;19144:40;19243:4;19232:16;;19219:30;19300:14;19296:26;;;-1:-1:-1;;19292:40:316;19268:65;;19258:93;;19347:1;19344;19337:12;19258:93;19375:30;;19486:4;19473:18;;;19428:21;19514:18;19503:30;;19500:50;;;19546:1;19543;19536:12;19500:50;19595:6;19579:14;19575:27;19566:7;19562:41;19559:61;;;19616:1;19613;19606:12;19559:61;19652:4;19645;19640:3;19636:14;19629:28;19673:58;19725:4;19720:3;19716:14;19708:6;19699:7;19673:58;:::i;:::-;19666:65;18783:954;-1:-1:-1;;;;;18783:954:316:o;19742:533::-;19825:5;19832:6;19892:3;19879:17;19978:2;19974:7;19963:8;19947:14;19943:29;19939:43;19919:18;19915:68;19905:96;;19997:1;19994;19987:12;19905:96;20025:33;;20129:4;20116:18;;;-1:-1:-1;20077:21:316;;-1:-1:-1;20157:18:316;20146:30;;20143:50;;;20189:1;20186;20179:12;20143:50;20243:6;20240:1;20236:14;20220;20216:35;20209:5;20205:47;20202:67;;;20265:1;20262;20255:12;20280:651;20393:6;20388:3;20381:19;20363:3;20419:4;20448;20443:3;20439:14;20432:21;;20476:5;20499:1;20509:397;20523:6;20520:1;20517:13;20509:397;;;20600:6;20587:20;20620:33;20645:7;20620:33;:::i;:::-;-1:-1:-1;;;;;20678:56:316;20666:69;;20782:15;;;20769:29;20755:12;;;20748:51;20822:4;20846:12;;;;20881:15;;;;20545:1;20538:9;20509:397;;;-1:-1:-1;20922:3:316;;20280:651;-1:-1:-1;;;;;20280:651:316:o;20936:1589::-;21138:4;-1:-1:-1;;;;;21248:2:316;21240:6;21236:15;21225:9;21218:34;21288:6;21283:2;21272:9;21268:18;21261:34;21331:2;21326;21315:9;21311:18;21304:30;21369:6;21356:20;21385:31;21410:5;21385:31;:::i;:::-;21452:14;21447:2;21432:18;;21425:42;21527:2;21515:15;;21502:29;21582:14;21578:27;;;-1:-1:-1;;21574:41:316;21550:66;;21540:94;;21630:1;21627;21620:12;21540:94;21671:4;21665:3;21654:9;21650:19;21643:33;21699:92;21786:3;21775:9;21771:19;21762:6;21742:18;21738:31;21699:92;:::i;:::-;21685:106;;21834:80;21910:2;21902:6;21898:15;21890:6;21834:80;:::i;:::-;21937:2;21933:7;22006:2;21994:9;21986:6;21982:22;21978:31;21971:4;21960:9;21956:20;21949:61;22033:86;22112:6;22098:12;22084;22033:86;:::i;:::-;22019:100;;22166:80;22242:2;22234:6;22230:15;22222:6;22166:80;:::i;:::-;22128:118;;;;22311:2;22299:9;22291:6;22287:22;22283:31;22277:3;22266:9;22262:19;22255:60;;22338:90;22421:6;22405:14;22389;22338:90;:::i;:::-;22324:104;;;;22490:3;22482:6;22478:16;22465:30;22459:3;22448:9;22444:19;22437:59;22513:6;22505:14;;;20936:1589;;;;;;:::o;22530:1387::-;22698:9;22733:68;22749:51;22793:6;22749:51;:::i;22733:68::-;22823:3;22847:6;22842:3;22835:19;22873:4;22902;22897:3;22893:14;22886:21;;22948:6;22945:1;22941:14;22934:5;22930:26;22979:14;22971:6;22968:26;22965:46;;;23007:1;23004;22997:12;22965:46;23031:5;23045:839;23061:6;23056:3;23053:15;23045:839;;;23147:3;23134:17;23174:18;23224:2;23211:11;23208:19;23205:39;;;23240:1;23237;23230:12;23205:39;23278:11;23271:5;23267:23;23257:33;;23335:4;23330:2;23314:14;23310:23;23306:34;23303:54;;;23353:1;23350;23343:12;23303:54;23385:22;;:::i;:::-;23447:2;23434:16;23477:2;23469:6;23466:14;23463:34;;;23493:1;23490;23483:12;23463:34;23526:62;23573:14;23564:6;23560:2;23556:15;23526:62;:::i;:::-;23517:7;23510:79;;23639:2;23635;23631:11;23618:25;23672:2;23662:8;23659:16;23656:36;;;23688:1;23685;23678:12;23656:36;23730:78;23793:14;23782:8;23778:2;23774:17;23730:78;:::i;:::-;23712:16;;;23705:104;-1:-1:-1;23822:20:316;;-1:-1:-1;;23862:12:316;;;;23078;;23045:839;;;-1:-1:-1;23906:5:316;;22530:1387;-1:-1:-1;;;;;;22530:1387:316:o;24800:610::-;25032:4;-1:-1:-1;;;;;25142:2:316;25134:6;25130:15;25119:9;25112:34;25194:2;25186:6;25182:15;25177:2;25166:9;25162:18;25155:43;;25234:6;25229:2;25218:9;25214:18;25207:34;25277:6;25272:2;25261:9;25257:18;25250:34;25321:3;25315;25304:9;25300:19;25293:32;25342:62;25399:3;25388:9;25384:19;25376:6;25368;25342:62;:::i;:::-;25334:70;24800:610;-1:-1:-1;;;;;;;;24800:610:316:o;25415:184::-;25485:6;25538:2;25526:9;25517:7;25513:23;25509:32;25506:52;;;25554:1;25551;25544:12;25506:52;-1:-1:-1;25577:16:316;;25415:184;-1:-1:-1;25415:184:316:o;25786:::-;-1:-1:-1;;;25835:1:316;25828:88;25935:4;25932:1;25925:15;25959:4;25956:1;25949:15;25975:125;26040:9;;;26061:10;;;26058:36;;;26074:18;;:::i;27198:583::-;27329:4;27335:6;27395:11;27382:25;27489:2;27485:7;27474:8;27458:14;27454:29;27450:43;27430:18;27426:68;27416:96;;27508:1;27505;27498:12;27416:96;27535:33;;27587:20;;;-1:-1:-1;27630:18:316;27619:30;;27616:50;;;27662:1;27659;27652:12;27616:50;27695:4;27683:17;;-1:-1:-1;27746:1:316;27742:14;;;27726;27722:35;27712:46;;27709:66;;;27771:1;27768;27761:12;27786:184;-1:-1:-1;;;27835:1:316;27828:88;27935:4;27932:1;27925:15;27959:4;27956:1;27949:15;27975:336;28079:4;28137:11;28124:25;28231:3;28227:8;28216;28200:14;28196:29;28192:44;28172:18;28168:69;28158:97;;28251:1;28248;28241:12;28158:97;28272:33;;;;;27975:336;-1:-1:-1;;27975:336:316:o;28316:326::-;28410:4;28468:11;28455:25;28562:3;28558:8;28547;28531:14;28527:29;28523:44;28503:18;28499:69;28489:97;;28582:1;28579;28572:12;28647:570;28765:4;28771:6;28831:11;28818:25;28925:2;28921:7;28910:8;28894:14;28890:29;28886:43;28866:18;28862:68;28852:96;;28944:1;28941;28934:12;28852:96;28971:33;;29023:20;;;-1:-1:-1;29066:18:316;29055:30;;29052:50;;;29098:1;29095;29088:12;29052:50;29131:4;29119:17;;-1:-1:-1;29182:1:316;29178:14;;;29162;29158:35;29148:46;;29145:66;;;29207:1;29204;29197:12;29222:972;29346:9;29405:4;29397:5;29381:14;29377:26;29373:37;29370:57;;;29423:1;29420;29413:12;29370:57;29456:2;29450:9;29498:4;29490:6;29486:17;29522:18;29590:6;29578:10;29575:22;29570:2;29558:10;29555:18;29552:46;29549:72;;;29601:18;;:::i;:::-;29641:10;29637:2;29630:22;29688:5;29675:19;29661:33;;29717:2;29709:6;29706:14;29703:34;;;29733:1;29730;29723:12;29703:34;29761:61;29807:14;29798:6;29791:5;29787:18;29761:61;:::i;:::-;29753:6;29746:77;29880:2;29873:5;29869:14;29856:28;29851:2;29843:6;29839:15;29832:53;29942:2;29935:5;29931:14;29918:28;29913:2;29905:6;29901:15;29894:53;29996:2;29989:5;29985:14;29972:28;29956:44;;30025:2;30015:8;30012:16;30009:36;;;30041:1;30038;30031:12;30009:36;;30078:81;30144:14;30133:8;30126:5;30122:20;30078:81;:::i;:::-;30073:2;30061:15;;30054:106;-1:-1:-1;30065:6:316;29222:972;-1:-1:-1;;29222:972:316:o;30199:273::-;30255:6;30308:2;30296:9;30287:7;30283:23;30279:32;30276:52;;;30324:1;30321;30314:12;30276:52;30363:9;30350:23;30416:5;30409:13;30402:21;30395:5;30392:32;30382:60;;30438:1;30435;30428:12;30477:579;30534:3;30572:5;30566:12;30599:6;30594:3;30587:19;30625:4;30654;30649:3;30645:14;30638:21;;30693:4;30686:5;30682:16;30716:1;30726:305;30740:6;30737:1;30734:13;30726:305;;;30799:13;;30841:9;;-1:-1:-1;;;;;30837:58:316;30825:71;;30936:11;;30930:18;30916:12;;;30909:40;30978:4;30969:14;;;;31006:15;;;;30762:1;30755:9;30726:305;;31061:990;31111:3;-1:-1:-1;;;;;31220:2:316;31212:5;31206:12;31202:21;31197:3;31190:34;31270:4;31263:5;31259:16;31253:23;31308:4;31301;31296:3;31292:14;31285:28;31370:2;31355:12;31349:19;31345:28;31338:4;31333:3;31329:14;31322:52;31441:2;31433:4;31419:12;31415:23;31409:30;31405:39;31399:3;31394;31390:13;31383:62;31500:4;31486:12;31482:23;31476:30;31454:52;;;31537:4;31531:3;31526;31522:13;31515:27;31564:47;31606:3;31601;31597:13;31581:14;31564:47;:::i;:::-;31551:60;;31659:4;31652:5;31648:16;31642:23;31708:3;31701:5;31697:15;31690:4;31685:3;31681:14;31674:39;31734:55;31783:5;31767:14;31734:55;:::i;:::-;31722:67;;;31837:4;31830:5;31826:16;31820:23;31885:3;31879:4;31875:14;31868:4;31863:3;31859:14;31852:38;31913:54;31962:4;31946:14;31913:54;:::i;:::-;31899:68;;;32016:4;32009:5;32005:16;31999:23;31992:4;31987:3;31983:14;31976:47;32039:6;32032:13;;;31061:990;;;;:::o;32056:439::-;32109:3;32147:5;32141:12;32174:6;32169:3;32162:19;32200:4;32229;32224:3;32220:14;32213:21;;32268:4;32261:5;32257:16;32291:1;32301:169;32315:6;32312:1;32309:13;32301:169;;;32376:13;;32364:26;;32410:12;;;;32445:15;;;;32337:1;32330:9;32301:169;;32500:1951;32802:4;-1:-1:-1;;;;;32912:2:316;32904:6;32900:15;32889:9;32882:34;32935:2;32973:3;32968:2;32957:9;32953:18;32946:31;33012:6;33006:13;33056:3;33050;33039:9;33035:19;33028:32;33083:60;33138:3;33127:9;33123:19;33109:12;33083:60;:::i;:::-;33069:74;;33198:2;33190:6;33186:15;33180:22;33174:3;33163:9;33159:19;33152:51;33222:4;33281;33273:6;33269:17;33263:24;33257:3;33246:9;33242:19;33235:53;33307:4;33360;33352:6;33348:17;33342:24;33435:3;33431:8;33419:9;33411:6;33407:22;33403:37;33397:3;33386:9;33382:19;33375:66;33461:6;33496:14;33490:21;33535:6;33527;33520:22;33570:2;33562:6;33558:15;33551:22;;33629:2;33619:6;33616:1;33612:14;33604:6;33600:27;33596:36;33675:2;33659:14;33655:23;33641:37;;33696:1;33706:626;33720:6;33717:1;33714:13;33706:626;;;33810:2;33806:7;33797:6;33789;33785:19;33781:33;33776:3;33769:46;33844:6;33838:13;33894:2;33889;33883:9;33879:18;33871:6;33864:34;33947:2;33943;33939:11;33933:18;33988:2;33983;33975:6;33971:15;33964:27;34018:61;34075:2;34067:6;34063:15;34047:14;34018:61;:::i;:::-;34120:11;;;34114:18;34169:19;;;34152:15;;;34145:44;34114:18;34004:75;-1:-1:-1;34212:40:316;34004:75;34114:18;34212:40;:::i;:::-;34275:15;;;;34310:12;;;;34202:50;-1:-1:-1;;;33742:1:316;33735:9;33706:626;;;33710:3;34349:6;34341:14;;;;;;;;;;;34393:6;34386:4;34375:9;34371:20;34364:36;34438:6;34431:4;34420:9;34416:20;34409:36;32500:1951;;;;;;;:::o;34456:521::-;34533:4;34539:6;34599:11;34586:25;34693:2;34689:7;34678:8;34662:14;34658:29;34654:43;34634:18;34630:68;34620:96;;34712:1;34709;34702:12;34620:96;34739:33;;34791:20;;;-1:-1:-1;34834:18:316;34823:30;;34820:50;;;34866:1;34863;34856:12;34820:50;34899:4;34887:17;;-1:-1:-1;34930:14:316;34926:27;;;34916:38;;34913:58;;;34967:1;34964;34957:12;35651:329;35749:4;35807:11;35794:25;35901:2;35897:7;35886:8;35870:14;35866:29;35862:43;35842:18;35838:68;35828:96;;35920:1;35917;35910:12;35985:207;36097:9;36134:52;36171:14;36164:5;36134:52;:::i;36197:222::-;36279:6;36332:2;36320:9;36311:7;36307:23;36303:32;36300:52;;;36348:1;36345;36338:12;36300:52;36371:42;36405:7;36394:9;36371:42;:::i;36424:451::-;-1:-1:-1;;;;;36665:6:316;36661:55;36650:9;36643:74;36753:6;36748:2;36737:9;36733:18;36726:34;36796:2;36791;36780:9;36776:18;36769:30;36624:4;36816:53;36865:2;36854:9;36850:18;36842:6;36816:53;:::i;36880:435::-;-1:-1:-1;;;;;37097:6:316;37093:55;37082:9;37075:74;37185:6;37180:2;37169:9;37165:18;37158:34;37228:2;37223;37212:9;37208:18;37201:30;37056:4;37248:61;37305:2;37294:9;37290:18;37282:6;37274;37248:61;:::i;:::-;37240:69;36880:435;-1:-1:-1;;;;;;36880:435:316:o;37906:320::-;38092:9;38129:91;38205:14;38197:6;38190:5;38129:91;:::i;38700:454::-;38929:6;38921;38916:3;38903:33;38885:3;38964:6;38959:3;38955:16;38991:1;38987:2;38980:13;39022:6;39016:13;39067:6;39060:4;39052:6;39048:17;39044:2;39038:36;39128:1;39093:15;;39117:13;;;39093:15;38700:454;-1:-1:-1;;;;;38700:454:316:o;39159:1093::-;39505:4;39534:3;-1:-1:-1;;;;;39568:6:316;39564:55;39553:9;39546:74;39656:2;39651;39640:9;39636:18;39629:30;39682:53;39731:2;39720:9;39716:18;39708:6;39682:53;:::i;:::-;39668:67;;39783:9;39775:6;39771:22;39766:2;39755:9;39751:18;39744:50;39811:41;39845:6;39837;39811:41;:::i;:::-;39803:49;;;39901:6;39888:20;39883:2;39872:9;39868:18;39861:48;39971:2;39963:6;39959:15;39946:29;39940:3;39929:9;39925:19;39918:58;40038:2;40030:6;40026:15;40013:29;40007:3;39996:9;39992:19;39985:58;40105:2;40097:6;40093:15;40080:29;40074:3;40063:9;40059:19;40052:58;40172:3;40164:6;40160:16;40147:30;40141:3;40130:9;40126:19;40119:59;40240:3;40232:6;40228:16;40215:30;40209:3;40198:9;40194:19;40187:59;39159:1093;;;;;;;:::o;40819:260::-;41000:2;40989:9;40982:21;40963:4;41020:53;41069:2;41058:9;41054:18;41046:6;41020:53;:::i;41084:620::-;41147:3;41178;41210:5;41204:12;41237:6;41232:3;41225:19;41263:4;41292;41287:3;41283:14;41276:21;;41350:4;41340:6;41337:1;41333:14;41326:5;41322:26;41318:37;41389:4;41382:5;41378:16;41412:1;41422:256;41436:6;41433:1;41430:13;41422:256;;;41523:2;41519:7;41511:5;41505:4;41501:16;41497:30;41492:3;41485:43;41549:49;41593:4;41584:6;41578:13;41549:49;:::i;:::-;41656:12;;;;41541:57;-1:-1:-1;41621:15:316;;;;41458:1;41451:9;41422:256;;;-1:-1:-1;41694:4:316;;41084:620;-1:-1:-1;;;;;;;41084:620:316:o;41709:1197::-;41888:2;41877:9;41870:21;-1:-1:-1;;;;;41937:6:316;41931:13;41927:62;41922:2;41911:9;41907:18;41900:90;42044:2;42036:6;42032:15;42026:22;42021:2;42010:9;42006:18;41999:50;41851:4;42096:2;42088:6;42084:15;42078:22;42136:4;42131:2;42120:9;42116:18;42109:32;42164:51;42210:3;42199:9;42195:19;42181:12;42164:51;:::i;:::-;42150:65;;42270:2;42262:6;42258:15;42252:22;42246:3;42235:9;42231:19;42224:51;42324:3;42316:6;42312:16;42306:23;42352:2;42348:7;42420:2;42408:9;42400:6;42396:22;42392:31;42386:3;42375:9;42371:19;42364:60;42447:62;42502:6;42486:14;42447:62;:::i;:::-;42433:76;;42558:3;42550:6;42546:16;42540:23;42518:45;;42628:2;42616:9;42608:6;42604:22;42600:31;42594:3;42583:9;42579:19;42572:60;42655:52;42700:6;42684:14;42655:52;:::i;:::-;42641:66;;42756:3;42748:6;42744:16;42738:23;42716:45;;42827:2;42815:9;42807:6;42803:22;42799:31;42792:4;42781:9;42777:20;42770:61;;42848:52;42893:6;42877:14;42848:52;:::i;42911:669::-;42976:5;43029:3;43022:4;43014:6;43010:17;43006:27;42996:55;;43047:1;43044;43037:12;42996:55;43076:6;43070:13;43102:4;43126:64;43142:47;43186:2;43142:47;:::i;43126:64::-;43212:3;43236:2;43231:3;43224:15;43264:4;43259:3;43255:14;43248:21;;43321:4;43315:2;43312:1;43308:10;43300:6;43296:23;43292:34;43278:48;;43349:3;43341:6;43338:15;43335:35;;;43366:1;43363;43356:12;43335:35;43402:4;43394:6;43390:17;43416:135;43432:6;43427:3;43424:15;43416:135;;;43498:10;;43486:23;;43529:12;;;;43449;;43416:135;;43585:1169;43745:6;43753;43806:2;43794:9;43785:7;43781:23;43777:32;43774:52;;;43822:1;43819;43812:12;43774:52;43855:9;43849:16;43884:18;43925:2;43917:6;43914:14;43911:34;;;43941:1;43938;43931:12;43911:34;43979:6;43968:9;43964:22;43954:32;;44024:7;44017:4;44013:2;44009:13;44005:27;43995:55;;44046:1;44043;44036:12;43995:55;44075:2;44069:9;44097:4;44121:64;44137:47;44181:2;44137:47;:::i;44121:64::-;44219:15;;;44301:1;44297:10;;;;44289:19;;44285:28;;;44250:12;;;;44325:19;;;44322:39;;;44357:1;44354;44347:12;44322:39;44381:11;;;;44401:135;44417:6;44412:3;44409:15;44401:135;;;44483:10;;44471:23;;44434:12;;;;44514;;;;44401:135;;;44591:18;;;44585:25;44555:5;;-1:-1:-1;44585:25:316;;-1:-1:-1;;;44622:16:316;;;44619:36;;;44651:1;44648;44641:12;44619:36;;44674:74;44740:7;44729:8;44718:9;44714:24;44674:74;:::i;:::-;44664:84;;;43585:1169;;;;;:::o;44759:368::-;45002:6;44991:9;44984:25;45045:2;45040;45029:9;45025:18;45018:30;44965:4;45065:56;45117:2;45106:9;45102:18;45094:6;45065:56;:::i;45132:184::-;-1:-1:-1;;;45181:1:316;45174:88;45281:4;45278:1;45271:15;45305:4;45302:1;45295:15;45321:522;-1:-1:-1;;;;;45528:55:316;;45510:74;;45498:2;45483:18;;45614:1;45603:13;;45593:201;;-1:-1:-1;;;45647:1:316;45640:88;45751:4;45748:1;45741:15;45779:4;45776:1;45769:15;45593:201;45830:6;45825:2;45814:9;45810:18;45803:34;45321:522;;;;;:::o;45848:135::-;45887:3;45908:17;;;45905:43;;45928:18;;:::i;:::-;-1:-1:-1;45975:1:316;45964:13;;45848:135::o;45988:441::-;-1:-1:-1;;;;;46249:6:316;46245:55;46234:9;46227:74;46337:2;46332;46321:9;46317:18;46310:30;46208:4;46357:66;46419:2;46408:9;46404:18;46396:6;46357:66;:::i;46434:217::-;46581:2;46570:9;46563:21;46544:4;46601:44;46641:2;46630:9;46626:18;46618:6;46601:44;:::i;46656:184::-;-1:-1:-1;;;46705:1:316;46698:88;46805:4;46802:1;46795:15;46829:4;46826:1;46819:15;46845:435;46939:6;46947;47000:2;46988:9;46979:7;46975:23;46971:32;46968:52;;;47016:1;47013;47006:12;46968:52;47048:9;47042:16;47087:1;47080:5;47077:12;47067:40;;47103:1;47100;47093:12;47067:40;47176:2;47161:18;;47155:25;47126:5;;-1:-1:-1;47224:4:316;47211:18;;47199:31;;47189:59;;47244:1;47241;47234:12;47189:59;47267:7;47257:17;;;46845:435;;;;;:::o;47285:216::-;47349:9;;;47377:11;;;47324:3;47407:9;;47435:10;;47431:19;;47460:10;;47452:19;;47428:44;47425:70;;;47475:18;;:::i;47506:416::-;47595:1;47632:5;47595:1;47646:270;47667:7;47657:8;47654:21;47646:270;;;47726:4;47722:1;47718:6;47714:17;47708:4;47705:27;47702:53;;;47735:18;;:::i;:::-;47785:7;47775:8;47771:22;47768:55;;;47805:16;;;;47768:55;47884:22;;;;47844:15;;;;47646:270;;;47650:3;47506:416;;;;;:::o;47927:806::-;47976:5;48006:8;47996:80;;-1:-1:-1;48047:1:316;48061:5;;47996:80;48095:4;48085:76;;-1:-1:-1;48132:1:316;48146:5;;48085:76;48177:4;48195:1;48190:59;;;;48263:1;48258:130;;;;48170:218;;48190:59;48220:1;48211:10;;48234:5;;;48258:130;48295:3;48285:8;48282:17;48279:43;;;48302:18;;:::i;:::-;-1:-1:-1;;48358:1:316;48344:16;;48373:5;;48170:218;;48472:2;48462:8;48459:16;48453:3;48447:4;48444:13;48440:36;48434:2;48424:8;48421:16;48416:2;48410:4;48407:12;48403:35;48400:77;48397:159;;;-1:-1:-1;48509:19:316;;;48541:5;;48397:159;48588:34;48613:8;48607:4;48588:34;:::i;:::-;48658:6;48654:1;48650:6;48646:19;48637:7;48634:32;48631:58;;;48669:18;;:::i;:::-;48707:20;;47927:806;-1:-1:-1;;;47927:806:316:o;48738:131::-;48798:5;48827:36;48854:8;48848:4;48827:36;:::i;49123:168::-;49196:9;;;49227;;49244:15;;;49238:22;;49224:37;49214:71;;49265:18;;:::i;49620:274::-;49660:1;49686;49676:189;;-1:-1:-1;;;49718:1:316;49711:88;49822:4;49819:1;49812:15;49850:4;49847:1;49840:15;49676:189;-1:-1:-1;49879:9:316;;49620:274::o;49899:191::-;49934:3;-1:-1:-1;;;49958:5:316;49955:77;49952:103;;50035:18;;:::i","linkReferences":{}},"methodIdentifiers":{"addOrder4(((address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32,bytes32,bytes),((address,address,bytes),(address,bytes32[],bytes)[])[])":"709fb8a5","clear3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(uint256,uint256,uint256,uint256,bytes32,bytes32),(address,bytes32[],bytes)[],(address,bytes32[],bytes)[])":"fa501182","deposit4(address,bytes32,bytes32,((address,address,bytes),(address,bytes32[],bytes)[])[])":"2fbc4ba0","entask2(((address,address,bytes),(address,bytes32[],bytes)[])[])":"d7e442ec","flashFee(address,uint256)":"d9d98ce4","flashLoan(address,address,uint256,bytes)":"5cffe9de","maxFlashLoan(address)":"613255ab","multicall(bytes[])":"ac9650d8","orderExists(bytes32)":"2cb77e9f","quote2(((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[]))":"9235084d","removeOrder3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),((address,address,bytes),(address,bytes32[],bytes)[])[])":"1f69cb75","supportsInterface(bytes4)":"01ffc9a7","takeOrders4((bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes))":"69c72856","vaultBalance2(address,address,bytes32)":"41d1514f","withdraw4(address,bytes32,bytes32,((address,address,bytes),(address,bytes32[],bytes)[])[])":"60746119"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClearZeroAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"signedCoefficient\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"exponent\",\"type\":\"int256\"}],\"name\":\"DivisionByZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"signedCoefficient\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"exponent\",\"type\":\"int256\"}],\"name\":\"ExponentOverflow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"result\",\"type\":\"bytes32\"}],\"name\":\"FlashLenderCallbackFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"signedCoefficient\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"exponent\",\"type\":\"int256\"}],\"name\":\"MaximizeOverflow\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"Float\",\"name\":\"minimumIO\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"actualIO\",\"type\":\"bytes32\"}],\"name\":\"MinimumIO\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"denominator\",\"type\":\"uint256\"}],\"name\":\"MulDivOverflow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NegativeBounty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"signedCoefficient\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"exponent\",\"type\":\"int256\"}],\"name\":\"NegativeFixedDecimalConversion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NegativePull\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NegativePush\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"Float\",\"name\":\"vaultBalance\",\"type\":\"bytes32\"}],\"name\":\"NegativeVaultBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"Float\",\"name\":\"amount\",\"type\":\"bytes32\"}],\"name\":\"NegativeVaultBalanceChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoOrders\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NotOrderOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"unmeta\",\"type\":\"bytes\"}],\"name\":\"NotRainMetaV1\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OrderNoHandleIO\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OrderNoInputs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OrderNoOutputs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OrderNoSources\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SameOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"enum TOFUOutcome\",\"name\":\"tofuOutcome\",\"type\":\"uint8\"}],\"name\":\"TokenDecimalsReadFailure\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenSelfTrade\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"outputs\",\"type\":\"uint256\"}],\"name\":\"UnsupportedCalculateOutputs\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"name\":\"ZeroDepositAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroMaximumIO\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"ZeroVaultId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"name\":\"ZeroWithdrawTargetAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"orderHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"struct OrderV4\",\"name\":\"order\",\"type\":\"tuple\"}],\"name\":\"AddOrderV3\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"Float\",\"name\":\"aliceOutput\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"bobOutput\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"aliceInput\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"bobInput\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"struct ClearStateChangeV2\",\"name\":\"clearStateChange\",\"type\":\"tuple\"}],\"name\":\"AfterClearV2\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"struct OrderV4\",\"name\":\"alice\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"struct OrderV4\",\"name\":\"bob\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"aliceInputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"aliceOutputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"bobInputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"bobOutputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"aliceBountyVaultId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"bobBountyVaultId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"struct ClearConfigV2\",\"name\":\"clearConfig\",\"type\":\"tuple\"}],\"name\":\"ClearV3\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32[][]\",\"name\":\"context\",\"type\":\"bytes32[][]\"}],\"name\":\"ContextV2\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositAmountUint256\",\"type\":\"uint256\"}],\"name\":\"DepositV2\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"subject\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"meta\",\"type\":\"bytes\"}],\"name\":\"MetaV1_2\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"orderHash\",\"type\":\"bytes32\"}],\"name\":\"OrderExceedsMaxRatio\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"orderHash\",\"type\":\"bytes32\"}],\"name\":\"OrderNotFound\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"orderHash\",\"type\":\"bytes32\"}],\"name\":\"OrderZeroAmount\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"orderHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"struct OrderV4\",\"name\":\"order\",\"type\":\"tuple\"}],\"name\":\"RemoveOrderV3\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OrderV4\",\"name\":\"order\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"inputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outputIOIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"struct TakeOrderConfigV4\",\"name\":\"config\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"Float\",\"name\":\"input\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"Float\",\"name\":\"output\",\"type\":\"bytes32\"}],\"name\":\"TakeOrderV3\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"Float\",\"name\":\"targetAmount\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"Float\",\"name\":\"withdrawAmount\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawAmountUint256\",\"type\":\"uint256\"}],\"name\":\"WithdrawV2\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"meta\",\"type\":\"bytes\"}],\"internalType\":\"struct OrderConfigV4\",\"name\":\"orderConfig\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV2[]\",\"name\":\"post\",\"type\":\"tuple[]\"}],\"name\":\"addOrder4\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OrderV4\",\"name\":\"aliceOrder\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OrderV4\",\"name\":\"bobOrder\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"aliceInputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"aliceOutputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"bobInputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"bobOutputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"aliceBountyVaultId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"bobBountyVaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct ClearConfigV2\",\"name\":\"clearConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"aliceSignedContext\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"bobSignedContext\",\"type\":\"tuple[]\"}],\"name\":\"clear3\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"depositAmount\",\"type\":\"bytes32\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV2[]\",\"name\":\"post\",\"type\":\"tuple[]\"}],\"name\":\"deposit4\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV2[]\",\"name\":\"post\",\"type\":\"tuple[]\"}],\"name\":\"entask2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"flashFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC3156FlashBorrower\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"flashLoan\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"maxFlashLoan\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"multicall\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"results\",\"type\":\"bytes[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"orderHash\",\"type\":\"bytes32\"}],\"name\":\"orderExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OrderV4\",\"name\":\"order\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"inputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outputIOIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct QuoteV2\",\"name\":\"quoteConfig\",\"type\":\"tuple\"}],\"name\":\"quote2\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"Float\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OrderV4\",\"name\":\"order\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV2[]\",\"name\":\"post\",\"type\":\"tuple[]\"}],\"name\":\"removeOrder3\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"stateChanged\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"Float\",\"name\":\"minimumIO\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"maximumIO\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"maximumIORatio\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"IOIsInput\",\"type\":\"bool\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OrderV4\",\"name\":\"order\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"inputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outputIOIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TakeOrderConfigV4[]\",\"name\":\"orders\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct TakeOrdersConfigV5\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"takeOrders4\",\"outputs\":[{\"internalType\":\"Float\",\"name\":\"totalTakerInput\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"totalTakerOutput\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"name\":\"vaultBalance2\",\"outputs\":[{\"internalType\":\"Float\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"targetAmount\",\"type\":\"bytes32\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV2[]\",\"name\":\"post\",\"type\":\"tuple[]\"}],\"name\":\"withdraw4\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AddressEmptyCode(address)\":[{\"details\":\"There's no code at `target` (it is not a contract).\"}],\"DivisionByZero(int256,int256)\":[{\"details\":\"Thrown when dividing by zero.\",\"params\":{\"exponent\":\"The exponent of the numerator.\",\"signedCoefficient\":\"The signed coefficient of the numerator.\"}}],\"ExponentOverflow(int256,int256)\":[{\"details\":\"Thrown when an exponent overflows.\"}],\"FailedCall()\":[{\"details\":\"A call to an address target failed. The target may have reverted.\"}],\"FlashLenderCallbackFailed(bytes32)\":[{\"params\":{\"result\":\"The value that was returned by `onFlashLoan`.\"}}],\"MaximizeOverflow(int256,int256)\":[{\"details\":\"Thrown when a maximize overflows where it is not appropriate.\"}],\"MinimumIO(bytes32,bytes32)\":[{\"params\":{\"actualIO\":\"The io that was achieved.\",\"minimumIO\":\"The minimum io required.\"}}],\"MulDivOverflow(uint256,uint256,uint256)\":[{\"details\":\"Thrown when mulDiv internal to division overflows.\"}],\"NegativeFixedDecimalConversion(int256,int256)\":[{\"details\":\"Thrown when attempting to convert a negative number to an unsigned fixed-point number.\"}],\"NegativeVaultBalance(bytes32)\":[{\"params\":{\"vaultBalance\":\"The negative vault balance being recorded.\"}}],\"NegativeVaultBalanceChange(bytes32)\":[{\"params\":{\"amount\":\"The negative amount being applied.\"}}],\"NotOrderOwner(address,address)\":[{\"params\":{\"owner\":\"The owner of the order.\",\"sender\":\"`msg.sender` attempting to modify the order.\"}}],\"NotRainMetaV1(bytes)\":[{\"params\":{\"unmeta\":\"the bytes that are not meta.\"}}],\"ReentrancyGuardReentrantCall()\":[{\"details\":\"Unauthorized reentrant call.\"}],\"SafeERC20FailedOperation(address)\":[{\"details\":\"An operation with an ERC-20 token failed.\"}],\"TokenDecimalsReadFailure(address,uint8)\":[{\"params\":{\"tofuOutcome\":\"The outcome of the TOFU read.\",\"token\":\"The token that failed to read decimals.\"}}],\"UnsupportedCalculateOutputs(uint256)\":[{\"params\":{\"outputs\":\"The outputs the expression offers.\"}}],\"ZeroDepositAmount(address,address,bytes32)\":[{\"params\":{\"sender\":\"`msg.sender` depositing tokens.\",\"token\":\"The token being deposited.\",\"vaultId\":\"The vault ID the tokens are being deposited under.\"}}],\"ZeroVaultId(address,address)\":[{\"params\":{\"sender\":\"`msg.sender` depositing or withdrawing tokens.\",\"token\":\"The token being deposited or withdrawn.\"}}],\"ZeroWithdrawTargetAmount(address,address,bytes32)\":[{\"params\":{\"sender\":\"`msg.sender` withdrawing tokens.\",\"token\":\"The token being withdrawn.\",\"vaultId\":\"The vault ID the tokens are being withdrawn from.\"}}]},\"events\":{\"AddOrderV3(address,bytes32,(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32))\":{\"params\":{\"order\":\"The newly added order. MUST be handed back as-is when clearing orders and contains derived information in addition to the order config that was provided by the order owner.\",\"orderHash\":\"The hash of the order as it is recorded onchain. Only the hash is stored in Orderbook storage to avoid paying gas to store the entire order.\",\"sender\":\"`msg.sender` adding the order and is owner of the order.\"}},\"AfterClearV2(address,(bytes32,bytes32,bytes32,bytes32))\":{\"params\":{\"clearStateChange\":\"The final vault state changes from the clearance.\",\"sender\":\"`msg.sender` clearing the order.\"}},\"ClearV3(address,(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(uint256,uint256,uint256,uint256,bytes32,bytes32))\":{\"params\":{\"alice\":\"One of the orders.\",\"bob\":\"The other order.\",\"clearConfig\":\"Additional config required to process the clearance.\",\"sender\":\"`msg.sender` clearing both orders.\"}},\"ContextV2(address,bytes32[][])\":{\"params\":{\"context\":\"The context that was built.\",\"sender\":\"`msg.sender` building the context.\"}},\"DepositV2(address,address,bytes32,uint256)\":{\"params\":{\"depositAmountUint256\":\"The amount of tokens deposited.\",\"sender\":\"`msg.sender` depositing tokens. Delegated deposits are NOT supported.\",\"token\":\"The token being deposited.\",\"vaultId\":\"The vault ID the tokens are being deposited under.\"}},\"MetaV1_2(address,bytes32,bytes)\":{\"params\":{\"meta\":\"Rain metadata V1 compliant metadata bytes. https://github.com/rainprotocol/specs/blob/main/metadata-v1.md\",\"sender\":\"The msg.sender.\",\"subject\":\"The entity that the metadata is about. MAY be the address of the emitting contract (as `bytes32`) OR anything else. The interpretation of the subject is context specific, so will often be a hash of some data/thing that this metadata is about.\"}},\"OrderExceedsMaxRatio(address,address,bytes32)\":{\"params\":{\"orderHash\":\"Hash of the order that had an excess ratio.\",\"owner\":\"Owner of the order that had an excess ratio.\",\"sender\":\"`msg.sender` clearing the order that had an excess ratio.\"}},\"OrderNotFound(address,address,bytes32)\":{\"params\":{\"orderHash\":\"Hash of the order that was not found.\",\"owner\":\"Owner of the order that was not found.\",\"sender\":\"`msg.sender` clearing the order that wasn't found.\"}},\"OrderZeroAmount(address,address,bytes32)\":{\"params\":{\"orderHash\":\"Hash of the order that evaluated to a 0 amount.\",\"owner\":\"Owner of the order that evaluated to a 0 amount.\",\"sender\":\"`msg.sender` clearing the order that had a 0 amount.\"}},\"RemoveOrderV3(address,bytes32,(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32))\":{\"params\":{\"order\":\"The removed order.\",\"orderHash\":\"The hash of the removed order.\",\"sender\":\"`msg.sender` removing the order and is owner of the order.\"}},\"TakeOrderV3(address,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[]),bytes32,bytes32)\":{\"params\":{\"config\":\"All config defining the orders to attempt to take.\",\"input\":\"The input amount from the perspective of sender.\",\"output\":\"The output amount from the perspective of sender.\",\"sender\":\"`msg.sender` taking the orders.\"}},\"WithdrawV2(address,address,bytes32,bytes32,bytes32,uint256)\":{\"params\":{\"sender\":\"`msg.sender` withdrawing tokens. Delegated withdrawals are NOT supported.\",\"targetAmount\":\"The amount of tokens requested to withdraw.\",\"token\":\"The token being withdrawn.\",\"vaultId\":\"The vault ID the tokens are being withdrawn from.\",\"withdrawAmount\":\"The amount of tokens withdrawn, can be less than the target amount if the vault does not have the funds available to cover the target amount. For example an active order might move tokens before the withdraw completes.\",\"withdrawAmountUint256\":\"The amount of tokens withdrawn, as the uint256 of tokens that actually move onchain.\"}}},\"kind\":\"dev\",\"methods\":{\"addOrder4(((address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32,bytes32,bytes),((address,address,bytes),(address,bytes32[],bytes)[])[])\":{\"params\":{\"config\":\"All config required to build an `Order`.\",\"tasks\":\"Additional tasks to run after the order is added. Order information SHOULD be made available during evaluation in context. If ANY of the tasks revert, the order MUST NOT be added.\"},\"returns\":{\"_0\":\"True if the order was added, false if it already existed.\"}},\"clear3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(uint256,uint256,uint256,uint256,bytes32,bytes32),(address,bytes32[],bytes)[],(address,bytes32[],bytes)[])\":{\"params\":{\"alice\":\"Some order to clear.\",\"aliceSignedContext\":\"Optional signed context that is relevant to A.\",\"bob\":\"Another order to clear.\",\"bobSignedContext\":\"Optional signed context that is relevant to B.\",\"clearConfig\":\"Additional configuration for the clearance such as how to handle the bounty payment for the `msg.sender`.\"}},\"deposit4(address,bytes32,bytes32,((address,address,bytes),(address,bytes32[],bytes)[])[])\":{\"params\":{\"depositAmount\":\"The amount of tokens to deposit.\",\"tasks\":\"Additional tasks to run after the deposit. Deposit information SHOULD be made available during evaluation in context. If ANY of the post tasks revert, the deposit MUST be reverted.\",\"token\":\"The token to deposit.\",\"vaultId\":\"The vault ID to deposit under.\"}},\"flashFee(address,uint256)\":{\"details\":\"The fee to be charged for a given loan.\",\"params\":{\"amount\":\"The amount of tokens lent.\",\"token\":\"The loan currency.\"},\"returns\":{\"_0\":\"The amount of `token` to be charged for the loan, on top of the returned principal.\"}},\"flashLoan(address,address,uint256,bytes)\":{\"details\":\"Initiate a flash loan.\",\"params\":{\"amount\":\"The amount of tokens lent.\",\"data\":\"Arbitrary data structure, intended to contain user-defined parameters.\",\"receiver\":\"The receiver of the tokens in the loan, and the receiver of the callback.\",\"token\":\"The loan currency.\"}},\"maxFlashLoan(address)\":{\"details\":\"The amount of currency available to be lent.\",\"params\":{\"token\":\"The loan currency.\"},\"returns\":{\"_0\":\"The amount of `token` that can be borrowed.\"}},\"multicall(bytes[])\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Receives and executes a batch of function calls on this contract.\"},\"orderExists(bytes32)\":{\"params\":{\"orderHash\":\"The hash of the order to check.\"},\"returns\":{\"_0\":\"True if the order exists, false otherwise.\"}},\"quote2(((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[]))\":{\"params\":{\"quoteConfig\":\"The configuration for the quote.\"},\"returns\":{\"_0\":\"True if the order exists, false otherwise.\",\"_1\":\"The maximum output amount that the order could send. Is `0` if the order does not exist.\",\"_2\":\"The input:output ratio of the order. Is `0` if the order does not exist.\"}},\"removeOrder3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),((address,address,bytes),(address,bytes32[],bytes)[])[])\":{\"params\":{\"order\":\"The `Order` data exactly as it was added.\",\"tasks\":\"Additional tasks to run after the order is removed. Order information SHOULD be made available during evaluation in context. If ANY of the tasks revert, the order MUST NOT be removed.\"},\"returns\":{\"stateChanged\":\"True if the order was removed, false if it did not exist.\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"takeOrders4((bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes))\":{\"params\":{\"config\":\"The constraints and list of orders to take, orders are processed sequentially in order as provided, there is NO ATTEMPT onchain to predict/filter/sort these orders other than evaluating them as provided. Inputs and outputs are from the perspective of `msg.sender` except for values specified by the orders themselves which are the from the perspective of that order.\"},\"returns\":{\"totalTakerInput\":\"Total tokens sent to `msg.sender`, taken from order vaults processed.\",\"totalTakerOutput\":\"Total tokens taken from `msg.sender` and distributed between vaults.\"}},\"vaultBalance2(address,address,bytes32)\":{\"params\":{\"owner\":\"The owner of the vault.\",\"token\":\"The token the vault is for.\",\"vaultId\":\"The vault ID to read.\"},\"returns\":{\"_0\":\"The current balance of the vault.\"}},\"withdraw4(address,bytes32,bytes32,((address,address,bytes),(address,bytes32[],bytes)[])[])\":{\"params\":{\"targetAmount\":\"The amount of tokens to attempt to withdraw. MAY result in fewer tokens withdrawn if the vault balance is lower than the target amount. MAY NOT be zero, the order book MUST revert with `ZeroWithdrawTargetAmount` if the amount is zero.\",\"tasks\":\"Additional tasks to run after the withdraw. Withdraw information SHOULD be made available during evaluation in context. If ANY of the tasks revert, the withdraw MUST be reverted.\",\"token\":\"The token to withdraw.\",\"vaultId\":\"The vault ID to withdraw from.\"}}},\"stateVariables\":{\"sVaultBalances\":{\"details\":\"Vault balances are stored in a mapping of owner => token => vault ID This gives 1:1 parity with the `IOrderBookV1` interface but keeping the `sFoo` naming convention for storage variables.\"}},\"title\":\"OrderBookV6 See `IOrderBookV6` for more documentation.\",\"version\":1},\"userdoc\":{\"errors\":{\"ClearZeroAmount()\":[{\"notice\":\"Thrown when clear output amounts are both zero.\"}],\"FlashLenderCallbackFailed(bytes32)\":[{\"notice\":\"Thrown when the `onFlashLoan` callback returns anything other than ON_FLASH_LOAN_CALLBACK_SUCCESS.\"}],\"InvalidSignature(uint256)\":[{\"notice\":\"Thrown when the ith signature from a list of signed contexts is invalid.\"}],\"MinimumIO(bytes32,bytes32)\":[{\"notice\":\"Thrown when the minimum input is not met.\"}],\"NegativeBounty()\":[{\"notice\":\"Throws when a negative bounty is calculated.\"}],\"NegativePull()\":[{\"notice\":\"Thrown when a negative pull is attempted.\"}],\"NegativePush()\":[{\"notice\":\"Thrown when a negative push is attempted.\"}],\"NegativeVaultBalance(bytes32)\":[{\"notice\":\"Thrown when a negative vault balance is being recorded.\"}],\"NegativeVaultBalanceChange(bytes32)\":[{\"notice\":\"Thrown when a negative amount is being applied to a vault balance.\"}],\"NoOrders()\":[{\"notice\":\"MUST be thrown when take orders is called with no orders.\"}],\"NotOrderOwner(address,address)\":[{\"notice\":\"Thrown when the `msg.sender` modifying an order is not its owner.\"}],\"NotRainMetaV1(bytes)\":[{\"notice\":\"Thrown when some bytes are expected to be rain meta and are not.\"}],\"OrderNoHandleIO()\":[{\"notice\":\"MUST be thrown by `addOrder` if the order has no associated handle IO.\"}],\"OrderNoInputs()\":[{\"notice\":\"MUST be thrown by `addOrder` if the order has no inputs.\"}],\"OrderNoOutputs()\":[{\"notice\":\"MUST be thrown by `addOrder` if the order has no outputs.\"}],\"OrderNoSources()\":[{\"notice\":\"MUST be thrown by `addOrder` if the order has no associated calculation.\"}],\"SameOwner()\":[{\"notice\":\"Thrown when two orders have the same owner during clear.\"}],\"TokenDecimalsReadFailure(address,uint8)\":[{\"notice\":\"Thrown when a TOFU decimals safe read fails.\"}],\"TokenMismatch()\":[{\"notice\":\"Thrown when the input and output tokens don't match, in either direction.\"}],\"TokenSelfTrade()\":[{\"notice\":\"Thrown when the input token is the output token.\"}],\"UnsupportedCalculateOutputs(uint256)\":[{\"notice\":\"Thrown when calculate order expression offers too few outputs.\"}],\"ZeroDepositAmount(address,address,bytes32)\":[{\"notice\":\"MUST be thrown by `deposit` if the amount is zero.\"}],\"ZeroMaximumIO()\":[{\"notice\":\"MUST be thrown by `takeOrders` if the maximum input/output is zero.\"}],\"ZeroVaultId(address,address)\":[{\"notice\":\"MUST be thrown by `deposit` and `withdraw` if the vault ID is zero.\"}],\"ZeroWithdrawTargetAmount(address,address,bytes32)\":[{\"notice\":\"MUST be thrown by `withdraw` if the amount _requested_ to withdraw is zero. The withdrawal MAY still not move any tokens if the vault balance is zero, or the withdrawal is used to repay a flash loan.\"}]},\"events\":{\"AddOrderV3(address,bytes32,(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32))\":{\"notice\":\"An order has been added to the orderbook. The order is permanently and always active according to its expression until/unless it is removed.\"},\"AfterClearV2(address,(bytes32,bytes32,bytes32,bytes32))\":{\"notice\":\"Emitted after two orders clear. Includes all final state changes in the vault balances, including the clearer's vaults.\"},\"ClearV3(address,(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(uint256,uint256,uint256,uint256,bytes32,bytes32))\":{\"notice\":\"Emitted before two orders clear. Covers both orders and includes all the state before anything is calculated.\"},\"ContextV2(address,bytes32[][])\":{\"notice\":\"Calling contracts SHOULD emit `Context` before calling `eval4` if they are able. Notably `eval4` MAY be called within a static call which means that events cannot be emitted, in which case this does not apply. It MAY NOT be useful to emit this multiple times for several eval calls if they all share a common context, in which case a single emit is sufficient.\"},\"DepositV2(address,address,bytes32,uint256)\":{\"notice\":\"Some tokens have been deposited to a vault.\"},\"MetaV1_2(address,bytes32,bytes)\":{\"notice\":\"An onchain wrapper to carry arbitrary Rain metadata. Assigns the sender to the metadata so that tooling can easily drop/ignore data from unknown sources. As metadata is about something, the subject MUST be provided.\"},\"OrderExceedsMaxRatio(address,address,bytes32)\":{\"notice\":\"Emitted when an order evaluates to a ratio exceeding the counterparty's maximum limit. An event rather than an error so that we allow attempting many orders in a loop and NOT rollback on a \\\"best effort\\\" basis to clear.\"},\"OrderNotFound(address,address,bytes32)\":{\"notice\":\"Emitted when attempting to match an order that either never existed or was removed. An event rather than an error so that we allow attempting many orders in a loop and NOT rollback on \\\"best effort\\\" basis to clear.\"},\"OrderZeroAmount(address,address,bytes32)\":{\"notice\":\"Emitted when an order evaluates to a zero amount. An event rather than an error so that we allow attempting many orders in a loop and NOT rollback on a \\\"best effort\\\" basis to clear.\"},\"RemoveOrderV3(address,bytes32,(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32))\":{\"notice\":\"An order has been removed from the orderbook. This effectively deactivates it. Orders can be added again after removal.\"},\"TakeOrderV3(address,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[]),bytes32,bytes32)\":{\"notice\":\"Some order has been taken by `msg.sender`. This is the same as them placing inverse orders then immediately clearing them all, but costs less gas and is more convenient and reliable. Analogous to a market buy against the specified orders. Each order that is matched within a the `takeOrders` loop emits its own individual event.\"},\"WithdrawV2(address,address,bytes32,bytes32,bytes32,uint256)\":{\"notice\":\"Some tokens have been withdrawn from a vault.\"}},\"kind\":\"user\",\"methods\":{\"addOrder4(((address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32,bytes32,bytes),((address,address,bytes),(address,bytes32[],bytes)[])[])\":{\"notice\":\"Given an order config, deploys the expression and builds the full `Order` for the config, then records it as an active order. Delegated adding an order is NOT supported. The `msg.sender` that adds an order is ALWAYS the owner and all resulting vault movements are their own. MUST revert with `OrderNoSources` if the order has no associated calculation and `OrderNoHandleIO` if the order has no handle IO entrypoint. The calculation MUST return at least two values from evaluation, the maximum amount and the IO ratio. The handle IO entrypoint SHOULD return zero values from evaluation. Either MAY revert during evaluation on the interpreter, which MUST prevent the order from clearing. MUST revert with `OrderNoInputs` if the order has no inputs. MUST revert with `OrderNoOutputs` if the order has no outputs. If the order already exists, the order book MUST NOT change state, which includes not emitting an event. Instead it MUST return false. If the order book modifies state it MUST emit an `AddOrder` event and return true. If vault ID is `0` for any input or output, this indicates a vaultless order for that token. Vaultless orders draw from or pay to the order's owner's wallet directly rather than any internal vault.\"},\"clear3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(uint256,uint256,uint256,uint256,bytes32,bytes32),(address,bytes32[],bytes)[],(address,bytes32[],bytes)[])\":{\"notice\":\"Allows `msg.sender` to match two live orders placed earlier by non-interactive parties and claim a bounty in the process. The clearer is free to select any two live orders on the order book for matching and as long as they have compatible tokens, ratios and amounts, the orders will clear. Clearing the orders DOES NOT remove them from the orderbook, they remain live until explicitly removed by their owner. Even if the input vault balances are completely emptied, the orders remain live until removed. This allows order owners to deploy a strategy over a long period of time and periodically top up the input vaults. Clearing two orders from the same owner is disallowed. Any mismatch in the ratios between the two orders will cause either more inputs than there are available outputs (transaction will revert) or less inputs than there are available outputs. In the latter case the excess outputs are given to the `msg.sender` of clear, to the vaults they specify in the clear config. This not only incentivises \\\"automatic\\\" clear calls for both alice and bob, but incentivises _prioritising greater ratio differences_ with a larger bounty. The second point is important because it implicitly prioritises orders that are further from the current market price, thus putting constant increasing pressure on the entire system the further it drifts from the norm, no matter how esoteric the individual order expressions and sizings might be. All else equal there are several factors that would impact how reliably some order clears relative to the wider market, such as: - Bounties are effectively percentages of cleared amounts so larger orders have larger bounties and cover gas costs more easily - High gas on the network means that orders are harder to clear profitably so the negative spread of the ratios will need to be larger - Complex and stateful expressions cost more gas to evalulate so the negative spread will need to be larger - Erratic behavior of the order owner could reduce the willingness of third parties to interact if it could result in wasted gas due to orders suddently being removed before clearance etc. - Dynamic and highly volatile words used in the expression could be ignored or low priority by clearers who want to be sure that they can accurately predict the ratios that they include in their clearance - Geopolitical issues such as sanctions and regulatory restrictions could cause issues for certain owners and clearers\"},\"deposit4(address,bytes32,bytes32,((address,address,bytes),(address,bytes32[],bytes)[])[])\":{\"notice\":\"`msg.sender` deposits tokens according to config. The config specifies the vault to deposit tokens under. Delegated depositing is NOT supported. Depositing DOES NOT mint shares (unlike ERC4626) so the overall vaulted experience is much simpler as there is always a 1:1 relationship between deposited assets and vault balances globally and individually. This mitigates rounding/dust issues, speculative behaviour on derived assets, possible regulatory issues re: whether a vault share is a security, code bloat on the vault, complex mint/deposit/withdraw/redeem 4-way logic, the need for preview functions, etc. etc. At the same time, allowing vault IDs to be specified by the depositor allows much more granular and direct control over token movements within Orderbook than either ERC4626 vault shares or mere contract-level ERC20 allowances can facilitate. Vault IDs are namespaced by the token address so there is no risk of collision between tokens. For example, vault ID 1 for token A is completely different to vault ID 1 for token B. `0` amount deposits are unsupported as underlying token contracts handle `0` value transfers differently and this would be a source of confusion. The order book MUST revert with `ZeroDepositAmount` if the amount is zero. Vault ID `0` is disallowed for deposits to avoid collision with vaultless orders.\"},\"entask2(((address,address,bytes),(address,bytes32[],bytes)[])[])\":{\"notice\":\"`msg.sender` entasks the provided tasks. This DOES NOT return any values, and MUST NOT modify any vault balances. Presumably the expressions will modify some internal state associated with active orders. If ANY of the expressions revert, the entire transaction MUST revert.\"},\"maxFlashLoan(address)\":{\"notice\":\"There's no limit to the size of a flash loan from `Orderbook` other than the current tokens deposited in `Orderbook`. If there is an active debt then loans are disabled so the max becomes `0` until after repayment.\"},\"orderExists(bytes32)\":{\"notice\":\"Returns true if the order exists, false otherwise.\"},\"quote2(((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[]))\":{\"notice\":\"Quotes the provided order for the caller. The caller is considered to be the counterparty to the order, for the purposes of evaluating the quote. However, the caller's vault balances and/or tokens in wallet are not considered in the quote. This means the output max can exceed what the caller could actually pay for. Both the output max and io ratio are returned as rain floating point values, ignoring any token decimals, so are not the literal amounts that would be moved in the order were it to clear.\"},\"removeOrder3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),((address,address,bytes),(address,bytes32[],bytes)[])[])\":{\"notice\":\"Order owner can remove their own orders. Delegated order removal is NOT supported and will revert. Removing an order multiple times or removing an order that never existed are valid, the event will be emitted and the transaction will complete with that order hash definitely, redundantly not live.\"},\"takeOrders4((bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes))\":{\"notice\":\"Allows `msg.sender` to attempt to fill a list of orders in sequence without needing to place their own order and clear them. This works like a market buy but against a specific set of orders. Every order will looped over and calculated individually then filled maximally until the request input is reached for the `msg.sender`. The `msg.sender` is responsible for selecting the best orders at the time according to their criteria and MAY specify a maximum IO ratio to guard against an order spiking the ratio beyond what the `msg.sender` expected and is comfortable with. As orders may be removed and calculate their ratios dynamically, all issues fulfilling an order other than misconfiguration by the `msg.sender` are no-ops and DO NOT revert the transaction. This allows the `msg.sender` to optimistically provide a list of orders that they aren't sure will completely fill at a good price, and fallback to more reliable orders further down their list. Misconfiguration such as token mismatches are errors that revert as this is known and static at all times to the `msg.sender` so MUST be provided correctly. `msg.sender` MAY specify a minimum input that MUST be reached across all orders in the list, otherwise the transaction will revert, this MAY be set to zero. Exactly like withdraw, if there is an active flash loan for `msg.sender` they will have their outstanding loan reduced by the final input amount preferentially before sending any tokens. Notably this allows arb bots implemented as flash loan borrowers to connect orders against external liquidity directly by paying back the loan with a `takeOrders` call and outputting the result of the external trade. Rounding errors always favour the order never the `msg.sender`.\"},\"vaultBalance2(address,address,bytes32)\":{\"notice\":\"Get the current balance of a vault for a given owner, token and vault ID.\"},\"withdraw4(address,bytes32,bytes32,((address,address,bytes),(address,bytes32[],bytes)[])[])\":{\"notice\":\"Allows the sender to withdraw any tokens from their own vaults. If the withdrawer has an active flash loan debt denominated in the same token being withdrawn then Orderbook will merely reduce the debt and NOT send the amount of tokens repaid to the flashloan debt. MUST revert if the amount _requested_ to withdraw is zero. The withdrawal MAY still not move any tokens (without revert) if the vault balance is zero, or the withdrawal is used to repay a flash loan, or due to any other internal accounting. Vault ID `0` is NOT supported due to collision with vaultless orders.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/concrete/ob/OrderBookV6.sol\":\"OrderBookV6\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"appendCBOR\":false,\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[\":@openzeppelin/contracts/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/contracts/\",\":axelar-gmp-sdk-solidity/=lib/sushixswap-v2/lib/axelar-gmp-sdk-solidity/\",\":bytecode/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/bytecode/\",\":caller/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/caller/\",\":codegen/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/codegen/\",\":constants/=lib/rain.interpreter/src/lib/constants/\",\":deprecated/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/\",\":ds-test/=lib/sushixswap-v2/lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/lib/erc4626-tests/\",\":eval/=lib/rain.interpreter/src/lib/eval/\",\":extern/=lib/rain.interpreter/src/lib/extern/\",\":forge-gas-snapshot/=lib/sushixswap-v2/lib/forge-gas-snapshot/src/\",\":forge-std/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/forge-std/src/\",\":halmos-cheatcodes/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\",\":integrity/=lib/rain.interpreter/src/lib/integrity/\",\":mut/=lib/rain.interpreter/lib/rain.string/src/lib/mut/\",\":ns/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/ns/\",\":op/=lib/rain.interpreter/src/lib/op/\",\":openzeppelin-contracts/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/\",\":parse/=lib/rain.interpreter/src/lib/parse/\",\":rain.datacontract/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.datacontract/src/\",\":rain.interpreter.interface/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/\",\":rain.interpreter/=lib/rain.interpreter/src/\",\":rain.intorastring/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.intorastring/src/\",\":rain.lib.hash/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.hash/src/\",\":rain.lib.memkv/=lib/rain.interpreter/lib/rain.lib.memkv/src/\",\":rain.lib.typecast/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.typecast/src/\",\":rain.math.binary/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.binary/src/\",\":rain.math.fixedpoint/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.math.fixedpoint/src/\",\":rain.math.float/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/\",\":rain.math.saturating/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.math.fixedpoint/lib/rain.math.saturating/src/\",\":rain.metadata/=lib/rain.interpreter/lib/rain.metadata/src/\",\":rain.orderbook.interface/=lib/rain.orderbook.interface/src/\",\":rain.sol.codegen/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.sol.codegen/src/\",\":rain.solmem/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/\",\":rain.string/=lib/rain.interpreter/lib/rain.string/src/\",\":rain.tofu.erc20-decimals/=lib/rain.tofu.erc20-decimals/src/\",\":sol.lib.binmaskflag/=lib/rain.interpreter/lib/sol.lib.binmaskflag/src/\",\":state/=lib/rain.interpreter/src/lib/state/\",\":sushixswap-v2/=lib/sushixswap-v2/\"]},\"sources\":{\"lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.hash/src/LibHashNoAlloc.sol\":{\"keccak256\":\"0x1153c2d2ec53adca83c81c37ac958aab8b4d31e0e01f64f5189b1783375c0347\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://79d10d5165cf0d5cc8b28b76613fc114e74c33fcc2d5632f7e284dace2247927\",\"dweb:/ipfs/QmZEt4BQ6xsfiFNBQ55GoQq8Ats3Hb1v2hPFEWPDeqKrTv\"]},\"lib/rain.interpreter/lib/rain.metadata/src/interface/deprecated/IMetaV1.sol\":{\"keccak256\":\"0x8ba40db7da4859ce5c42510e7bd70bb9d02a33609938b7137b51187ba6c120ba\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://8885892b317e0c798e11f88e4e23198e940d43c73b4613449a0199d41bf02d3e\",\"dweb:/ipfs/Qmb6AEittgihpJnL2aZeG9XA3PSjBSaKa9ewk6dZR9WhL1\"]},\"lib/rain.interpreter/lib/rain.metadata/src/interface/unstable/IMetaV1_2.sol\":{\"keccak256\":\"0x968d077369f63608da1d8d69c5832cd1561133a3b32f6dfce84adf4eab9d22b6\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://162291396bb979dc92dda61cd705d86fdb6378e58c556bb0a33e45fe60216c27\",\"dweb:/ipfs/QmcdzNthSLZsW8Qg1bU72jXG7KvhycppH6phzRo4awxJxD\"]},\"lib/rain.interpreter/lib/rain.metadata/src/lib/LibMeta.sol\":{\"keccak256\":\"0xb924ea27ba17f3c5582475a854b572d7149a0088e06646663b15b3e4c1577d31\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://94d7f0a3e4704d25904e4e3d9df064a5fa5d0fecf96128fc3ab44d41a44e92ad\",\"dweb:/ipfs/QmYPR15FL8dXmbKjZK7Bq2qXbnno6eoj3SiXuuayLpB7Yh\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol\":{\"keccak256\":\"0x66c7ec42c6c43712be2107a50ab4529379bc76a632b425babec698d9da921ac6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://dce2778f0b638adfc5ba29c2c618c855fe725fa74a16846386aa1d56a834aa04\",\"dweb:/ipfs/QmPV9oWnzQdi58od266j62xvviavLNHqKLZfm6k2K1qy9E\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol\":{\"keccak256\":\"0xd5ea07362ab630a6a3dee4285a74cf2377044ca2e4be472755ad64d7c5d4b69d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://da5e832b40fc5c3145d3781e2e5fa60ac2052c9d08af7e300dc8ab80c4343100\",\"dweb:/ipfs/QmTzf7N5ZUdh5raqtzbM11yexiUoLC9z3Ws632MCuycq1d\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol\":{\"keccak256\":\"0x0afcb7e740d1537b252cb2676f600465ce6938398569f09ba1b9ca240dde2dfc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1c299900ac4ec268d4570ecef0d697a3013cd11a6eb74e295ee3fbc945056037\",\"dweb:/ipfs/Qmab9owJoxcA7vJT5XNayCMaUR1qxqj1NDzzisduwaJMcZ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol\":{\"keccak256\":\"0x1a6221315ce0307746c2c4827c125d821ee796c74a676787762f4778671d4f44\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1bb2332a7ee26dd0b0de9b7fe266749f54820c99ab6a3bcb6f7e6b751d47ee2d\",\"dweb:/ipfs/QmcRWpaBeCYkhy68PR3B4AgD7asuQk7PwkWxrvJbZcikLF\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC7913.sol\":{\"keccak256\":\"0xe5a126930df1d54e4a6dd5fea09010c4a7db0ea974c6c17a1e6082879f5a032b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2f58f5a90328536a6c68289916bfa4ed653d871319c7b2a416ab3f6263c4f2f5\",\"dweb:/ipfs/Qmaa9DmgUA16Urz5fuF4RbFz2NaVpNLV41ddwykSdasFUd\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303\",\"dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0xd6fa4088198f04eef10c5bce8a2f4d60554b7ec4b987f684393c01bf79b94d9f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f95ee0bbd4dd3ac730d066ba3e785ded4565e890dbec2fa7d3b9fe3bad9d0d6e\",\"dweb:/ipfs/QmSLr6bHkPFWT7ntj34jmwfyskpwo97T9jZUrk5sz3sdtR\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x304d732678032a9781ae85c8f204c8fba3d3a5e31c02616964e75cfdc5049098\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://299ced486011781dc98f638059678323c03079fefae1482abaa2135b22fa92d0\",\"dweb:/ipfs/QmbZNbcPTBxNvwChavN2kkZZs7xHhYL7mv51KrxMhsMs3j\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x0fa9e0d3a859900b5a46f70a03c73adf259603d5e05027a37fe0b45529d85346\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c2add4da0240c9f2ce47649c8bb6b11b40e98cf6f88b8bdc76b2704e89391710\",\"dweb:/ipfs/QmNQTwF2uVzu4CRtNxr8bxyP9XuW6VsZuo2Nr4KR2bZr3d\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Bytes.sol\":{\"keccak256\":\"0x8140d608316521b1fd71167c3b708ebb8659da070723fc8807609553b296ee33\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a7bf7db66869ba1e945a0390b85da2f6afc7e42a4735ca918d0d56ac90c50147\",\"dweb:/ipfs/QmRmNyhpBpgzSdQqLtrQCYE7H7eLnVVxh2Yy4YMrySR8AR\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12\",\"dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Errors.sol\":{\"keccak256\":\"0x6afa713bfd42cf0f7656efa91201007ac465e42049d7de1d50753a373648c123\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ba1d02f4847670a1b83dec9f7d37f0b0418d6043447b69f3a29a5f9efc547fcf\",\"dweb:/ipfs/QmQ7iH2keLNUKgq2xSWcRmuBE5eZ3F5whYAkAGzCNNoEWB\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol\":{\"keccak256\":\"0x5b4802a4352474792df3107e961d1cc593e47b820c14f69d3505cb28f5a6a583\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a6f86fd01f829499fe0545ff5dda07d4521988e88bfe0bf801fc15650921ed56\",\"dweb:/ipfs/QmUUKu4ZDffHAmfkf3asuQfmLTyfpuy2Amdncc3SqfzKPG\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Multicall.sol\":{\"keccak256\":\"0x72a5499dfae7676e4298a7299bccd3b27438ba1a4c72df5cd69c1c343c7ea20d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://de0fb51ccae3a0ff377ed185d187440fc612a71bf8e42fdb0e032ce747fa3eef\",\"dweb:/ipfs/QmPNBaiVsAiUhz8qfXcSy27S7CqBbtSd8rPqmaykKBhw7Q\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Panic.sol\":{\"keccak256\":\"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a\",\"dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol\":{\"keccak256\":\"0xa516cbf1c7d15d3517c2d668601ce016c54395bf5171918a14e2686977465f53\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1e1d079e8edfb58efd23a311e315a4807b01b5d1cf153f8fa2d0608b9dec3e99\",\"dweb:/ipfs/QmTBExeX2SDTkn5xbk5ssbYSx7VqRp9H4Ux1CY4uQM4b9N\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol\":{\"keccak256\":\"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b\",\"dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x36d1750bf1aa5fee9c52adb2f7857ab652daca722fc05dff533b364f67a1139a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2e5e7052539b7849d02f3ce25acc1dce29373c11cfae9f0bc918c54b780c549a\",\"dweb:/ipfs/QmRGE32xNkMTo6i4pHHMxjpiu77yPwnTA25SFngw2NXJys\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0x360cf86214a764694dae1522a38200b1737fe90e46dcf56a0f89de143071cc20\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2e393290a46ca6d1fa1addb40709d26e1d250638ab6acdd103b5af21768ebc7b\",\"dweb:/ipfs/QmPwT3tXwQ9NbGtZ99XRq7sr8LCQP8XaCrzw49JdXGn7us\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol\":{\"keccak256\":\"0x6abeed5940e1da7bb329e458db9a1c5c4ea6f86d651b952af99c6bddcd6bbb94\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5fe75e9a6b759c5d7fd82fb59bd4f58c672b36f0a69b84f4789b7c7895d3e61c\",\"dweb:/ipfs/QmX28wsir8w5sS3acfJMNHcBwoPsDpqCu7WDkPnUWLMNiZ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol\":{\"keccak256\":\"0x445455b8be33e09cf1db14e59c0d1c5aa5d312b5e754e8ae751e42313a0cae88\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d6939df526d1c3f1d773448f6451eebb8de344113744e0da121b6349658b1298\",\"dweb:/ipfs/QmPffovzJ8qGRuUh57qrnWajHqYPPrntb1EA1VRh8p5TLP\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0x2d9dc2fe26180f74c11c13663647d38e259e45f95eb88f57b61d2160b0109d3e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://81233d1f98060113d9922180bb0f14f8335856fe9f339134b09335e9f678c377\",\"dweb:/ipfs/QmWh6R35SarhAn4z2wH8SU456jJSYL2FgucfTFgbHJJN4E\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\",\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0x09e3f1c72d4c5cbe8e2644ab7313f8f7177533ae2f4c24cdcbbeaf520a73734c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://93208401215d539fa2d81626b207c1f611def7883d0e447b3b5969ebaa7b3c2c\",\"dweb:/ipfs/QmXPxDnQPx8LAweX5ZJqEcwkvs59kP4c64VVDG1Jjq1mef\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0x195533c86d0ef72bcc06456a4f66a9b941f38eb403739b00f21fd7c1abd1ae54\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b1d578337048cad08c1c03041cca5978eff5428aa130c781b271ad9e5566e1f8\",\"dweb:/ipfs/QmPFKL2r9CBsMwmUqqdcFPfHZB2qcs9g1HDrPxzWSxomvy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb1970fac7b64e6c09611e6691791e848d5e3fe410fa5899e7df2e0afd77a99e3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://db5fbb3dddd8b7047465b62575d96231ba8a2774d37fb4737fbf23340fabbb03\",\"dweb:/ipfs/QmVUSvooZKEdEdap619tcJjTLcAuH6QBdZqAzWwnAXZAWJ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/error/ErrDecimalFloat.sol\":{\"keccak256\":\"0x3c9e3f5e6b78877add52f397e2cf452e8a1afe6b9e630fc7bbc7c2d6704d07d9\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://9840b88bf5143a94f8e7779390b025dda83530090be3503e110aa2584250c6e4\",\"dweb:/ipfs/QmemaALnbRKFChq5Ec1p4xdar5rDqEvdbQwGb2vzMVWhK9\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/LibDecimalFloat.sol\":{\"keccak256\":\"0x5c8820a79da0ac3c8558ae65c8b3b2b4579326755a4914a243f2475c1159b2aa\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://edc7ddd33798964f19aa9183fa0366321f93ab03171ba334192f65bd71a1a53d\",\"dweb:/ipfs/QmYKAKopDLGMWCfTVhwhF3vCGw6wXveKX1uTtxCyvycNkL\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/implementation/LibDecimalFloatImplementation.sol\":{\"keccak256\":\"0x182d010eee786cfa19ad44e215332c4e6fd4e9310da3e61ebd17a0309307d6b6\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1206a9557d6410c30ec82f02d44d3e857d7aabf46d607ee08bf415af14f8a799\",\"dweb:/ipfs/Qmbygfmw9K8YVQdEsNEkkHxTbTiuuDgWt7yB6gMwoYGBcp\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/table/LibLogTable.sol\":{\"keccak256\":\"0x412629a161febf0dc9c3bae0cc9fe0b8de8774d37c5f3afde2e2312478d96a98\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://c8da5302117961caad328e80cb28296ea71aadbc291312e37d3db079d84a9777\",\"dweb:/ipfs/QmWYzpex1Xrnjf3QM68n6mGFQ4KxE53fUUyDjwE3zNrtok\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrBytes.sol\":{\"keccak256\":\"0xdec97437eeba42f5950dc52f89caac433bc11a56a4e14a0f67a521821600c4b6\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://72b96a4ed0d34dab653df0e6eb19d77b3e1c691b8e35543f6f32ae6a44c6312e\",\"dweb:/ipfs/QmNrwwf3La4D25DudigRedu2c7xfx8k7bEzHFVZfpRu3se\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol\":{\"keccak256\":\"0x57b7a7a5cbc2fc97200130e84fde3a8afc14e0729040b14670dacc7f63c3ac5f\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://4e7c7ce525e882db437b488b590fae6a817b282f88d76eb4f56986b549815e57\",\"dweb:/ipfs/QmajzM26fsaFtaAnm5cg1FZrD6N2wkLJHCxa7Atx5x6iAB\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes.sol\":{\"keccak256\":\"0x6497d17390179a62820805d18a2cf2cdfddbe4990df783bde11cbf82e414fd0e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://54e8ed63c566d374ca2d89e8109c41267f7ca661e85570c6c7d51193aaca128b\",\"dweb:/ipfs/Qmd6LoUZqg7TbeAx2auk5UkimyMiK4a9GsVMvDeqDRZF3M\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes32Array.sol\":{\"keccak256\":\"0x93a9a12fa9161523c8580196daf8e2bf59c48003166ef718f5fc07d47752aabe\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://f1d24979b4b1f94621f0bc0505f8aafbb845ac86f72323454b6e96b4e57fb367\",\"dweb:/ipfs/QmUD7hAfaNPPHUu9DjLaJrwrUrei8vfbyUoJcymbQeSsXE\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes32Matrix.sol\":{\"keccak256\":\"0xffd4769d4d0f89d0de792c6d100384ec0262c55c5cf6b33432739e8c4c0edcf6\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1c73e871d16e3b2f3498efb6b3235db19156e07cc71e9f0fbc3c6b0b4efe633a\",\"dweb:/ipfs/Qmeu91h2q8EdtAoPdRtKUsKL48VD16AUAU1ZXmt89iiuck\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibMemCpy.sol\":{\"keccak256\":\"0x3f0a1962829eed7af79d21ab1f84b1a3b4044d90114812871c9dde7ae6f5cf0a\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://4b777f051eef0b83c1b1b6e3927faf683609522acbac9c5bba412cd482be3fef\",\"dweb:/ipfs/QmZrMNaEQBGeCM2L6bg5d8WBxPCSG1cwFD95AUQFVXzQXL\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol\":{\"keccak256\":\"0x3fc6ff807b57b681e32229380e3eda57107a1ada8dc2c1270daa84c9fca5addc\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://a82b17ddc1db163ec548648c83dd5bb2f9f4441559452933f424e0a8dff48e57\",\"dweb:/ipfs/QmdKoRbEAPxBRHJWWRwjh9Yrps1QXcJuX5mJmua8nvnq7B\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol\":{\"keccak256\":\"0xf51dffaeb88063748495e3184e335d9bb46f22881c2e8c930f2b68a32bdb39c2\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://4a66ae9e4e9b9bf83b68c4d1d609fda02f8584387740354318d4eca1e2639047\",\"dweb:/ipfs/QmXTS3azQ3ebBpJzj15HJRjTLV8zHfrFPQ7qPiic6eE3Pa\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Matrix.sol\":{\"keccak256\":\"0xf58526ebebc0e51a84369ebe6fb1173930cea3a61a488b6b5a597406fc1216e0\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://75940e084457b62a7a38a2cfe920b0838c7c7517c914de64a5073fd01bdcedd8\",\"dweb:/ipfs/QmUZ1sm2EQMhiR2UzB4cY868t6XYpgAi62tr6xvwMtYDnQ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/error/ErrBytecode.sol\":{\"keccak256\":\"0x4d740b62c6e81ffdb25a42c72a5bd5ea945659df1bc38510b4e95a9cd3bfe8bb\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://aa05c6e63a9bd9dd722d3824b2ae376d5237c81a189e0e42bf9a1ba33da919d3\",\"dweb:/ipfs/QmPLZtsKPrC9nLwk1jqw7LwwvsXAkxomrtUQLrhiQNWubC\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterCallerV3.sol\":{\"keccak256\":\"0xdd13be6b4942424143613a301d020f44f67dfe6bc81550d7726cbad8d735ccdc\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://deb8adb379085983857f311d937d09f8ea1c1ecac8864f6a63f5391ba93e0929\",\"dweb:/ipfs/QmcFsrfhXyjwT8yF8UkwaCW8LMbQr4uTj3Lhcju2yeQpZZ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol\":{\"keccak256\":\"0x15796750d51d5498986438ce9546cbb1ec66dd73531f2b12f155459c97ea24c5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e73668fe127eb60cb27794da3398d7d6e8f1f9f41d71081af7016dd114c81904\",\"dweb:/ipfs/QmUe8ge3U3Fz3FzEQyXaPS2oLm9bAV2QZttP77WPrsckcK\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterV3.sol\":{\"keccak256\":\"0xe546b8a716e632ce6db719b6eb63e6ec86d530ac80ad619c47bedd470270e85a\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1359938d87ab63d170aecfbc28336db3a5598d1aacffc35f2ed1bb786ee17755\",\"dweb:/ipfs/QmbtR2wot29rpuxu1kBVvqtHBe7NVb6c2B3sXpyhj1ERkU\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IParserV2.sol\":{\"keccak256\":\"0x29935383d2b114fd0a145977340552fcbc4b674ba89949b7b40ba23c56e3586a\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://aefa76e1dd78f206cf93b9522c545e665e73e44585b3dddb70e03c6aefdf443e\",\"dweb:/ipfs/QmePBeLhR1Z7DYzhmbVkm4aUKTwDHnhJCpFXniLBuN8ryK\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV1.sol\":{\"keccak256\":\"0xc0afd50701cd68eef984a63862bd6a10552d704cca6e10f06d19d920b0777c98\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://cd3cbfa9159ceed8871f46f62c7ea235ad8537d3c6c1c004152ebf5d2d597346\",\"dweb:/ipfs/QmPSAJXAcmDeK9Qy6s2dXdeu4GJ62FKWa69VBo4ioCPcJ9\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV2.sol\":{\"keccak256\":\"0x368ace8d0f82832f08caf264e4194647b9777c0d4a0f22d88236b30c1e4c8a63\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://9c8a2141fcd76d6308156777b0a9e5a4f7f07fb3693461e2c12f07e4d8c87130\",\"dweb:/ipfs/QmPnhPz6sXzh5xBGZobAPY2WJTgvQDiYWRFKavscSPu7T5\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV3.sol\":{\"keccak256\":\"0x6f6b03c0f8e37ebe4275e0d27242754c7be815ff091ad0931a7be21ab11de628\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1f200079a3689e0d0c8efb97040737a2b4113a82f0df5d8319af36d9ad5d8b97\",\"dweb:/ipfs/QmXFzXZasmD9D7pAYC5wBtB748TZajy69V5tmSEXRd1VZk\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV1.sol\":{\"keccak256\":\"0xc01bc48e2479cab07fc799e26c3790c8cf97acc1f0f490c8f456f554d239a505\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://2981aa2eae0d414bc8ad4105bedb05026cfdad7e6af8f23805dba4835ae9fd8a\",\"dweb:/ipfs/QmQRKi5nmatC1UM2sNta9giuJX3xvvLAD5pmCeAsVWF4hF\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV2.sol\":{\"keccak256\":\"0x62c7149e3d28cd9b67d7eed183c4e59cf300689dd5cc363b011cb2cf32c1200d\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://52cf991b2dc9581222520c32cac224f6936c75183e4c6c16fafa4450a05c0de0\",\"dweb:/ipfs/QmZ7fiZYjnDhNnFXYCXC9iSYs8WAAwmsVxBd5XDA1tPPah\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol\":{\"keccak256\":\"0x7d2bc86fefbe372fc64381b320244fe9dbda1816867f3040c5bb3951869fe6a7\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://90c371494080129d5acd2bc52d092fc5cfe559147f7fc855ed01e62a7837f21e\",\"dweb:/ipfs/QmcNtPDuTxic8zqRFXf1ba6FJKmQXguxiDUY4E7wjyVwU5\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol\":{\"keccak256\":\"0xe0b94c771a7b6aa05388b4db6e238e36a4653cbfdbd3e54bbcaa7a97fc9491f4\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://59887a7f2ef60669906c5e70831ac0c9a7345313b04efb306235280f85e1db73\",\"dweb:/ipfs/QmP6Ny9m3sPCP65UmgGGpucSMgVAoDv6qURqyxUE95VU5Q\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV2.sol\":{\"keccak256\":\"0x0ae0d1b0ca245779f33ea3e5ffbfcc234533d5c75f4ec2a6f3042cf841bcc219\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0fd476c34670477ece5a217d2372637c279287af883c132f1b98db4b3ccb80bf\",\"dweb:/ipfs/QmVBfaGYovi93pDr9HosQkacCmeXQAfgM6haTQZFJsGnoE\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IParserV1.sol\":{\"keccak256\":\"0x4f6a9e028942cebebfc84328193f1d31807aac292d9b82e2df489064aa913070\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://54073f63db1f652571472cb2d07de297772c2420e1571a0cb9e0a805ee4347e7\",\"dweb:/ipfs/QmXRqBreJvC8MQd5zLNgmPUdfFa4WD6gSoxvD8hecycux4\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterCallerV4.sol\":{\"keccak256\":\"0xae8309d29bcc770df07bf5f5b463e80a6c20456d9fc9dcae203975328b257423\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://196dbc14f46e90344ed1bac0efbf87dd3dba15aeaed57678673e03f1362eb487\",\"dweb:/ipfs/QmejhzZx6G8gw76vPKvDEfVQQ9mF1kJvx5wj9qdeDoVrPH\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterStoreV3.sol\":{\"keccak256\":\"0xda4e6583c7a6cefb7d32593d0e069fb26b4822fb07d916bef68a4b4be857078e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://970ae6a0f2dcfaaea8b79fc30af89043282e159910b8c375a8027ad738e4e736\",\"dweb:/ipfs/QmQk5fhi61BcvEAUcBVFivUTzd7SZxULG5UdsNkrykjVPF\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterV4.sol\":{\"keccak256\":\"0x1617c780008c8f724516b1af0844f97c2c8c17ee87f515e3be3cce2d2731085f\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://b4d206e14a81549771cc8c62f54006b545c8acb546074e2cf66213211f3363a9\",\"dweb:/ipfs/QmNtpyVpL9riAxB8ZjHP1tp9GkdX9YVfXKVQ7an8ZL9rJD\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/bytecode/LibBytecode.sol\":{\"keccak256\":\"0xaf78f1b85b0fd4df30da5f6515604fdc2792d34c14ad8d2fd633afb7777f0162\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e5b2fad52a1f8ed91dc5ba72454d95cd7642825b165f4db75a402d16279d65bb\",\"dweb:/ipfs/QmTAkJmLMj45NkvvEtoSGFbuiHmkDEMHHzKfTTfd7PKHZH\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibContext.sol\":{\"keccak256\":\"0xaeb62b79fa753d8327c6d6af457d4b00937db798b51ba7e51d4a367176f8d8ba\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1c91eb4f6bb61ef79c217e15ec8cb88be4cca841d4efe70bfeb4858319032a2b\",\"dweb:/ipfs/QmVCfM2pufm269ExXDXPTwK8EcWA5ksT8Z1XAG6YTLX34Y\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibEvaluable.sol\":{\"keccak256\":\"0xd2b8ff7feb5fdfefa6c0068ae33bd0723f1a58a066a8ee1da46608bd3ae63da3\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://7290ceebbd842f88d4ecadc3847a555afbc8a4b4458b7def1c0cba4e28eb80bb\",\"dweb:/ipfs/QmR28Pst8QTLUSmRUDGK8f8prA5zutCeTG3F7RYXmNJ7WH\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/deprecated/caller/LibEncodedDispatch.sol\":{\"keccak256\":\"0xf026da6a07f43d8345f41946c257f872172f33732a01dcb56c954c444467e9cb\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://424d8f53931425c56e18e5355e0875333b4864e04dcbab424d29ec2dd624e35b\",\"dweb:/ipfs/QmePkJjv1XvXEjjHBq9NeEdb6WTKTj8uTcCbxANM9P3DGw\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/ns/LibNamespace.sol\":{\"keccak256\":\"0xd621d3e5f8b404309ad5d841a3658248e979c1bd59876be3afa7aa0595b4c0e6\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://801fa302f49f3734dd5cc6221dd25f73591ac8feae47351c18e30a98a4ae0ce1\",\"dweb:/ipfs/QmbwXbTSMZ4u6ZsyfseBx79PeHNAWocNHXpgnaPVmLZM38\"]},\"lib/rain.orderbook.interface/src/interface/IOrderBookV5.sol\":{\"keccak256\":\"0x81531ce21b2cf824be60f70e14b97e8d6f5df7e09a454a690f4ed8c7d41a0dc1\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e8a203d32f5e423f0f5fd47f1a7be70d0cad3b69c3d1469d19a8d85e1f14c303\",\"dweb:/ipfs/QmZH6v3Hc41SXiiuruUpntcUAXMcHqEhhpDATSArHQfe99\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v2/IOrderBookV2.sol\":{\"keccak256\":\"0x6df5dd48103f06c7a41b49e9497f9f28baa4940eb5eba4113c71b323da66e5a4\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e295c8ce419a26e44d1f5be80c1bfa8a852a0b47e0e332be9323a670806344aa\",\"dweb:/ipfs/QmbAJ1j8WTdwCBLF6mjiHihfvUZFAeiv3uTXntMWPLKTt7\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v3/IOrderBookV3.sol\":{\"keccak256\":\"0x0f90c4db32d78d1c15f6230b1f0cc1e16cca908e3981f417039816e820fe0c24\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://693ae8187a8012410ff5774e73ed11ca5279c296cfafecd75613e804197ec43f\",\"dweb:/ipfs/QmQLPSZwcPfc8MJDnaJiUT5ktsodQ48erR1uoTtF3Fa1ju\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v4/IOrderBookV4.sol\":{\"keccak256\":\"0xc94415fcd366693e78116a72df9c6b29408ad4bdb745846c5929561a5ce2a226\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://48f92b2281195b90bb5ee6a6b3866e27f25b9268729765eb6681de4c48b86d82\",\"dweb:/ipfs/QmUjiXwgsYzsRRj1o3uxo2aeboAT2VZxV5RWYbkinT9jUt\"]},\"lib/rain.orderbook.interface/src/interface/ierc3156/IERC3156FlashBorrower.sol\":{\"keccak256\":\"0xdcd81b1110e9c3c91715ac90aef1da70066bcaba8aeb3dc23df979f7f87644f9\",\"license\":\"CC0-1.0\",\"urls\":[\"bzz-raw://4572efaeb9eb30ad9b766b80cb2a8101a2cec0c9e8c78c7696f4aae710c8e2c9\",\"dweb:/ipfs/QmVsz1gtqWfxTAbsoLPvZBe6PBVXqaWNx6nu7RHr2ghLuK\"]},\"lib/rain.orderbook.interface/src/interface/ierc3156/IERC3156FlashLender.sol\":{\"keccak256\":\"0x119c477281a6ec109e9c729a254b39d7ccc9a9f5baa82fa28d0fa1e3bd2b6ae8\",\"license\":\"CC0-1.0\",\"urls\":[\"bzz-raw://19ec8289a123459659dca0389a650ca6bf6bc12d925ad7a3e61f0b1bfe68d1b6\",\"dweb:/ipfs/QmRZ9U5ECovPFmbRaBTauFjjVQcvPA7VQL7S1zJVEBTMD5\"]},\"lib/rain.orderbook.interface/src/interface/unstable/IOrderBookV6.sol\":{\"keccak256\":\"0xabb3b41a1e11614ce9638fece01c78e5b8aff3598263ef38c80367b09233b801\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://03108d4f4c13316863257e21c9be2788cd780b19ad55d4a0d3d9306d53c3f7a4\",\"dweb:/ipfs/QmNt9vWhgj4VGHq8SVMX9HWFed5LUZNEpWMxaW3SLojPsL\"]},\"lib/rain.orderbook.interface/src/interface/unstable/IOrderBookV6OrderTaker.sol\":{\"keccak256\":\"0xc74b50c77d37fe78e350e9d2e2a09fe603661c25eccd28961abfd17a903b7283\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://dff51045b7d2b291880d130e6c3a8286f0face2ff1c6bbe3d6a6e70f3506f2c2\",\"dweb:/ipfs/QmSFh54NcMv62KK7w8YwMtLciKeLbRSUbdK3EE6tMkK35P\"]},\"lib/rain.tofu.erc20-decimals/src/interface/ITOFUTokenDecimals.sol\":{\"keccak256\":\"0xff728b82d787191dc32f7dac385baa1e194d313c84979b90934e6b8fd06ddbc5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e789fb5fcb3396d81fa487c907486b9ba7d33312502b676e43816f777e0379fd\",\"dweb:/ipfs/Qme1evJCUVHVpPteVvgwW84fNAJwLKfVi5xmJjNrhKEziR\"]},\"lib/rain.tofu.erc20-decimals/src/lib/LibTOFUTokenDecimals.sol\":{\"keccak256\":\"0x50c11116ed9fab852afd4cdc010751e93485d7c08a6fc318a8582c96ab26a068\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://f1d781fe347ab40ed0169d8ffa41f0311cceb9c7f4a31205ef118a280ecfa455\",\"dweb:/ipfs/QmecF2QZ92oh9qEzD9BRN2r9H8VwEXZQfJZRtrbUcsESQV\"]},\"src/abstract/OrderBookV6FlashLender.sol\":{\"keccak256\":\"0x2cf18ae141f9b7c4f93817985b11633daf667ad0feb45111e99865012a6661fe\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://6cc1280407c8ef53df2c97df0bda506a90e8a728b697669eec9d25015df811db\",\"dweb:/ipfs/QmenGASd6vBn3KCrtjKdsq9c1g5f6XzidxWD6sav7dRBXM\"]},\"src/concrete/ob/OrderBookV6.sol\":{\"keccak256\":\"0x7fc33c619f1ac871a2887ca1b3c8c9b04e8797966978801a2e6e4861b38f563e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://851e8297499dfea38b2b9acdf60d3540612232c93ab9737ece66e020aeee938b\",\"dweb:/ipfs/Qmdzm6iZc9YVSuPAJbRYZPUU7rXigVYYPZ5JR7kuVV241X\"]},\"src/lib/LibOrder.sol\":{\"keccak256\":\"0x1a458a49c08e02df1e7981e64f26647f5912554280697b3ae1a984e1a863dae9\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0aaab364d64cbb8ab37cd0f5344f14bfffcc6f426a4e993b28dc70e8fae6327e\",\"dweb:/ipfs/QmWoqhqNtYd22a3jnFmFzvqGatY8RCVxLvoPonxKELFD9J\"]},\"src/lib/LibOrderBook.sol\":{\"keccak256\":\"0x77b9b1fa35a044f652da6f6e9c91ee33699b3412ed651d517fbce9d180b60eb1\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://b275a56b1f85b4cee2e6e2fffb1060590978ad5b0fc5cd4f3cedf2e67287cbcb\",\"dweb:/ipfs/QmeaB2XNZsXJvLWRgNahJZCQMmmwpmLQ2txjbupEbNbYwE\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.25+commit.b61c2a91"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"target","type":"address"}],"type":"error","name":"AddressEmptyCode"},{"inputs":[],"type":"error","name":"ClearZeroAmount"},{"inputs":[{"internalType":"int256","name":"signedCoefficient","type":"int256"},{"internalType":"int256","name":"exponent","type":"int256"}],"type":"error","name":"DivisionByZero"},{"inputs":[{"internalType":"int256","name":"signedCoefficient","type":"int256"},{"internalType":"int256","name":"exponent","type":"int256"}],"type":"error","name":"ExponentOverflow"},{"inputs":[],"type":"error","name":"FailedCall"},{"inputs":[{"internalType":"bytes32","name":"result","type":"bytes32"}],"type":"error","name":"FlashLenderCallbackFailed"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"type":"error","name":"InvalidSignature"},{"inputs":[{"internalType":"int256","name":"signedCoefficient","type":"int256"},{"internalType":"int256","name":"exponent","type":"int256"}],"type":"error","name":"MaximizeOverflow"},{"inputs":[{"internalType":"Float","name":"minimumIO","type":"bytes32"},{"internalType":"Float","name":"actualIO","type":"bytes32"}],"type":"error","name":"MinimumIO"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"type":"error","name":"MulDivOverflow"},{"inputs":[],"type":"error","name":"NegativeBounty"},{"inputs":[{"internalType":"int256","name":"signedCoefficient","type":"int256"},{"internalType":"int256","name":"exponent","type":"int256"}],"type":"error","name":"NegativeFixedDecimalConversion"},{"inputs":[],"type":"error","name":"NegativePull"},{"inputs":[],"type":"error","name":"NegativePush"},{"inputs":[{"internalType":"Float","name":"vaultBalance","type":"bytes32"}],"type":"error","name":"NegativeVaultBalance"},{"inputs":[{"internalType":"Float","name":"amount","type":"bytes32"}],"type":"error","name":"NegativeVaultBalanceChange"},{"inputs":[],"type":"error","name":"NoOrders"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"type":"error","name":"NotOrderOwner"},{"inputs":[{"internalType":"bytes","name":"unmeta","type":"bytes"}],"type":"error","name":"NotRainMetaV1"},{"inputs":[],"type":"error","name":"OrderNoHandleIO"},{"inputs":[],"type":"error","name":"OrderNoInputs"},{"inputs":[],"type":"error","name":"OrderNoOutputs"},{"inputs":[],"type":"error","name":"OrderNoSources"},{"inputs":[],"type":"error","name":"ReentrancyGuardReentrantCall"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"type":"error","name":"SafeERC20FailedOperation"},{"inputs":[],"type":"error","name":"SameOwner"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"enum TOFUOutcome","name":"tofuOutcome","type":"uint8"}],"type":"error","name":"TokenDecimalsReadFailure"},{"inputs":[],"type":"error","name":"TokenMismatch"},{"inputs":[],"type":"error","name":"TokenSelfTrade"},{"inputs":[{"internalType":"uint256","name":"outputs","type":"uint256"}],"type":"error","name":"UnsupportedCalculateOutputs"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}],"type":"error","name":"ZeroDepositAmount"},{"inputs":[],"type":"error","name":"ZeroMaximumIO"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"token","type":"address"}],"type":"error","name":"ZeroVaultId"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}],"type":"error","name":"ZeroWithdrawTargetAmount"},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"bytes32","name":"orderHash","type":"bytes32","indexed":false},{"internalType":"struct OrderV4","name":"order","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"indexed":false}],"type":"event","name":"AddOrderV3","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"struct ClearStateChangeV2","name":"clearStateChange","type":"tuple","components":[{"internalType":"Float","name":"aliceOutput","type":"bytes32"},{"internalType":"Float","name":"bobOutput","type":"bytes32"},{"internalType":"Float","name":"aliceInput","type":"bytes32"},{"internalType":"Float","name":"bobInput","type":"bytes32"}],"indexed":false}],"type":"event","name":"AfterClearV2","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"struct OrderV4","name":"alice","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"indexed":false},{"internalType":"struct OrderV4","name":"bob","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"indexed":false},{"internalType":"struct ClearConfigV2","name":"clearConfig","type":"tuple","components":[{"internalType":"uint256","name":"aliceInputIOIndex","type":"uint256"},{"internalType":"uint256","name":"aliceOutputIOIndex","type":"uint256"},{"internalType":"uint256","name":"bobInputIOIndex","type":"uint256"},{"internalType":"uint256","name":"bobOutputIOIndex","type":"uint256"},{"internalType":"bytes32","name":"aliceBountyVaultId","type":"bytes32"},{"internalType":"bytes32","name":"bobBountyVaultId","type":"bytes32"}],"indexed":false}],"type":"event","name":"ClearV3","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"bytes32[][]","name":"context","type":"bytes32[][]","indexed":false}],"type":"event","name":"ContextV2","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"address","name":"token","type":"address","indexed":false},{"internalType":"bytes32","name":"vaultId","type":"bytes32","indexed":false},{"internalType":"uint256","name":"depositAmountUint256","type":"uint256","indexed":false}],"type":"event","name":"DepositV2","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"bytes32","name":"subject","type":"bytes32","indexed":false},{"internalType":"bytes","name":"meta","type":"bytes","indexed":false}],"type":"event","name":"MetaV1_2","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"address","name":"owner","type":"address","indexed":false},{"internalType":"bytes32","name":"orderHash","type":"bytes32","indexed":false}],"type":"event","name":"OrderExceedsMaxRatio","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"address","name":"owner","type":"address","indexed":false},{"internalType":"bytes32","name":"orderHash","type":"bytes32","indexed":false}],"type":"event","name":"OrderNotFound","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"address","name":"owner","type":"address","indexed":false},{"internalType":"bytes32","name":"orderHash","type":"bytes32","indexed":false}],"type":"event","name":"OrderZeroAmount","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"bytes32","name":"orderHash","type":"bytes32","indexed":false},{"internalType":"struct OrderV4","name":"order","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"indexed":false}],"type":"event","name":"RemoveOrderV3","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"struct TakeOrderConfigV4","name":"config","type":"tuple","components":[{"internalType":"struct OrderV4","name":"order","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}]},{"internalType":"uint256","name":"inputIOIndex","type":"uint256"},{"internalType":"uint256","name":"outputIOIndex","type":"uint256"},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}],"indexed":false},{"internalType":"Float","name":"input","type":"bytes32","indexed":false},{"internalType":"Float","name":"output","type":"bytes32","indexed":false}],"type":"event","name":"TakeOrderV3","anonymous":false},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"address","name":"token","type":"address","indexed":false},{"internalType":"bytes32","name":"vaultId","type":"bytes32","indexed":false},{"internalType":"Float","name":"targetAmount","type":"bytes32","indexed":false},{"internalType":"Float","name":"withdrawAmount","type":"bytes32","indexed":false},{"internalType":"uint256","name":"withdrawAmountUint256","type":"uint256","indexed":false}],"type":"event","name":"WithdrawV2","anonymous":false},{"inputs":[{"internalType":"struct OrderConfigV4","name":"orderConfig","type":"tuple","components":[{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes32","name":"secret","type":"bytes32"},{"internalType":"bytes","name":"meta","type":"bytes"}]},{"internalType":"struct TaskV2[]","name":"post","type":"tuple[]","components":[{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]}],"stateMutability":"nonpayable","type":"function","name":"addOrder4","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"struct OrderV4","name":"aliceOrder","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}]},{"internalType":"struct OrderV4","name":"bobOrder","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}]},{"internalType":"struct ClearConfigV2","name":"clearConfig","type":"tuple","components":[{"internalType":"uint256","name":"aliceInputIOIndex","type":"uint256"},{"internalType":"uint256","name":"aliceOutputIOIndex","type":"uint256"},{"internalType":"uint256","name":"bobInputIOIndex","type":"uint256"},{"internalType":"uint256","name":"bobOutputIOIndex","type":"uint256"},{"internalType":"bytes32","name":"aliceBountyVaultId","type":"bytes32"},{"internalType":"bytes32","name":"bobBountyVaultId","type":"bytes32"}]},{"internalType":"struct SignedContextV1[]","name":"aliceSignedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]},{"internalType":"struct SignedContextV1[]","name":"bobSignedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}],"stateMutability":"nonpayable","type":"function","name":"clear3"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"},{"internalType":"Float","name":"depositAmount","type":"bytes32"},{"internalType":"struct TaskV2[]","name":"post","type":"tuple[]","components":[{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]}],"stateMutability":"nonpayable","type":"function","name":"deposit4"},{"inputs":[{"internalType":"struct TaskV2[]","name":"post","type":"tuple[]","components":[{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]}],"stateMutability":"nonpayable","type":"function","name":"entask2"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function","name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"stateMutability":"view","type":"function","name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function","name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}]},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"stateMutability":"view","type":"function","name":"orderExists","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"struct QuoteV2","name":"quoteConfig","type":"tuple","components":[{"internalType":"struct OrderV4","name":"order","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}]},{"internalType":"uint256","name":"inputIOIndex","type":"uint256"},{"internalType":"uint256","name":"outputIOIndex","type":"uint256"},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]}],"stateMutability":"view","type":"function","name":"quote2","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"Float","name":"","type":"bytes32"},{"internalType":"Float","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"struct OrderV4","name":"order","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}]},{"internalType":"struct TaskV2[]","name":"post","type":"tuple[]","components":[{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]}],"stateMutability":"nonpayable","type":"function","name":"removeOrder3","outputs":[{"internalType":"bool","name":"stateChanged","type":"bool"}]},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"stateMutability":"view","type":"function","name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"struct TakeOrdersConfigV5","name":"config","type":"tuple","components":[{"internalType":"Float","name":"minimumIO","type":"bytes32"},{"internalType":"Float","name":"maximumIO","type":"bytes32"},{"internalType":"Float","name":"maximumIORatio","type":"bytes32"},{"internalType":"bool","name":"IOIsInput","type":"bool"},{"internalType":"struct TakeOrderConfigV4[]","name":"orders","type":"tuple[]","components":[{"internalType":"struct OrderV4","name":"order","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}]},{"internalType":"uint256","name":"inputIOIndex","type":"uint256"},{"internalType":"uint256","name":"outputIOIndex","type":"uint256"},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]},{"internalType":"bytes","name":"data","type":"bytes"}]}],"stateMutability":"nonpayable","type":"function","name":"takeOrders4","outputs":[{"internalType":"Float","name":"totalTakerInput","type":"bytes32"},{"internalType":"Float","name":"totalTakerOutput","type":"bytes32"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}],"stateMutability":"view","type":"function","name":"vaultBalance2","outputs":[{"internalType":"Float","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"},{"internalType":"Float","name":"targetAmount","type":"bytes32"},{"internalType":"struct TaskV2[]","name":"post","type":"tuple[]","components":[{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]}],"stateMutability":"nonpayable","type":"function","name":"withdraw4"}],"devdoc":{"kind":"dev","methods":{"addOrder4(((address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32,bytes32,bytes),((address,address,bytes),(address,bytes32[],bytes)[])[])":{"params":{"config":"All config required to build an `Order`.","tasks":"Additional tasks to run after the order is added. Order information SHOULD be made available during evaluation in context. If ANY of the tasks revert, the order MUST NOT be added."},"returns":{"_0":"True if the order was added, false if it already existed."}},"clear3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(uint256,uint256,uint256,uint256,bytes32,bytes32),(address,bytes32[],bytes)[],(address,bytes32[],bytes)[])":{"params":{"alice":"Some order to clear.","aliceSignedContext":"Optional signed context that is relevant to A.","bob":"Another order to clear.","bobSignedContext":"Optional signed context that is relevant to B.","clearConfig":"Additional configuration for the clearance such as how to handle the bounty payment for the `msg.sender`."}},"deposit4(address,bytes32,bytes32,((address,address,bytes),(address,bytes32[],bytes)[])[])":{"params":{"depositAmount":"The amount of tokens to deposit.","tasks":"Additional tasks to run after the deposit. Deposit information SHOULD be made available during evaluation in context. If ANY of the post tasks revert, the deposit MUST be reverted.","token":"The token to deposit.","vaultId":"The vault ID to deposit under."}},"flashFee(address,uint256)":{"details":"The fee to be charged for a given loan.","params":{"amount":"The amount of tokens lent.","token":"The loan currency."},"returns":{"_0":"The amount of `token` to be charged for the loan, on top of the returned principal."}},"flashLoan(address,address,uint256,bytes)":{"details":"Initiate a flash loan.","params":{"amount":"The amount of tokens lent.","data":"Arbitrary data structure, intended to contain user-defined parameters.","receiver":"The receiver of the tokens in the loan, and the receiver of the callback.","token":"The loan currency."}},"maxFlashLoan(address)":{"details":"The amount of currency available to be lent.","params":{"token":"The loan currency."},"returns":{"_0":"The amount of `token` that can be borrowed."}},"multicall(bytes[])":{"custom:oz-upgrades-unsafe-allow-reachable":"delegatecall","details":"Receives and executes a batch of function calls on this contract."},"orderExists(bytes32)":{"params":{"orderHash":"The hash of the order to check."},"returns":{"_0":"True if the order exists, false otherwise."}},"quote2(((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[]))":{"params":{"quoteConfig":"The configuration for the quote."},"returns":{"_0":"True if the order exists, false otherwise.","_1":"The maximum output amount that the order could send. Is `0` if the order does not exist.","_2":"The input:output ratio of the order. Is `0` if the order does not exist."}},"removeOrder3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),((address,address,bytes),(address,bytes32[],bytes)[])[])":{"params":{"order":"The `Order` data exactly as it was added.","tasks":"Additional tasks to run after the order is removed. Order information SHOULD be made available during evaluation in context. If ANY of the tasks revert, the order MUST NOT be removed."},"returns":{"stateChanged":"True if the order was removed, false if it did not exist."}},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas."},"takeOrders4((bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes))":{"params":{"config":"The constraints and list of orders to take, orders are processed sequentially in order as provided, there is NO ATTEMPT onchain to predict/filter/sort these orders other than evaluating them as provided. Inputs and outputs are from the perspective of `msg.sender` except for values specified by the orders themselves which are the from the perspective of that order."},"returns":{"totalTakerInput":"Total tokens sent to `msg.sender`, taken from order vaults processed.","totalTakerOutput":"Total tokens taken from `msg.sender` and distributed between vaults."}},"vaultBalance2(address,address,bytes32)":{"params":{"owner":"The owner of the vault.","token":"The token the vault is for.","vaultId":"The vault ID to read."},"returns":{"_0":"The current balance of the vault."}},"withdraw4(address,bytes32,bytes32,((address,address,bytes),(address,bytes32[],bytes)[])[])":{"params":{"targetAmount":"The amount of tokens to attempt to withdraw. MAY result in fewer tokens withdrawn if the vault balance is lower than the target amount. MAY NOT be zero, the order book MUST revert with `ZeroWithdrawTargetAmount` if the amount is zero.","tasks":"Additional tasks to run after the withdraw. Withdraw information SHOULD be made available during evaluation in context. If ANY of the tasks revert, the withdraw MUST be reverted.","token":"The token to withdraw.","vaultId":"The vault ID to withdraw from."}}},"version":1},"userdoc":{"kind":"user","methods":{"addOrder4(((address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32,bytes32,bytes),((address,address,bytes),(address,bytes32[],bytes)[])[])":{"notice":"Given an order config, deploys the expression and builds the full `Order` for the config, then records it as an active order. Delegated adding an order is NOT supported. The `msg.sender` that adds an order is ALWAYS the owner and all resulting vault movements are their own. MUST revert with `OrderNoSources` if the order has no associated calculation and `OrderNoHandleIO` if the order has no handle IO entrypoint. The calculation MUST return at least two values from evaluation, the maximum amount and the IO ratio. The handle IO entrypoint SHOULD return zero values from evaluation. Either MAY revert during evaluation on the interpreter, which MUST prevent the order from clearing. MUST revert with `OrderNoInputs` if the order has no inputs. MUST revert with `OrderNoOutputs` if the order has no outputs. If the order already exists, the order book MUST NOT change state, which includes not emitting an event. Instead it MUST return false. If the order book modifies state it MUST emit an `AddOrder` event and return true. If vault ID is `0` for any input or output, this indicates a vaultless order for that token. Vaultless orders draw from or pay to the order's owner's wallet directly rather than any internal vault."},"clear3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),(uint256,uint256,uint256,uint256,bytes32,bytes32),(address,bytes32[],bytes)[],(address,bytes32[],bytes)[])":{"notice":"Allows `msg.sender` to match two live orders placed earlier by non-interactive parties and claim a bounty in the process. The clearer is free to select any two live orders on the order book for matching and as long as they have compatible tokens, ratios and amounts, the orders will clear. Clearing the orders DOES NOT remove them from the orderbook, they remain live until explicitly removed by their owner. Even if the input vault balances are completely emptied, the orders remain live until removed. This allows order owners to deploy a strategy over a long period of time and periodically top up the input vaults. Clearing two orders from the same owner is disallowed. Any mismatch in the ratios between the two orders will cause either more inputs than there are available outputs (transaction will revert) or less inputs than there are available outputs. In the latter case the excess outputs are given to the `msg.sender` of clear, to the vaults they specify in the clear config. This not only incentivises \"automatic\" clear calls for both alice and bob, but incentivises _prioritising greater ratio differences_ with a larger bounty. The second point is important because it implicitly prioritises orders that are further from the current market price, thus putting constant increasing pressure on the entire system the further it drifts from the norm, no matter how esoteric the individual order expressions and sizings might be. All else equal there are several factors that would impact how reliably some order clears relative to the wider market, such as: - Bounties are effectively percentages of cleared amounts so larger orders have larger bounties and cover gas costs more easily - High gas on the network means that orders are harder to clear profitably so the negative spread of the ratios will need to be larger - Complex and stateful expressions cost more gas to evalulate so the negative spread will need to be larger - Erratic behavior of the order owner could reduce the willingness of third parties to interact if it could result in wasted gas due to orders suddently being removed before clearance etc. - Dynamic and highly volatile words used in the expression could be ignored or low priority by clearers who want to be sure that they can accurately predict the ratios that they include in their clearance - Geopolitical issues such as sanctions and regulatory restrictions could cause issues for certain owners and clearers"},"deposit4(address,bytes32,bytes32,((address,address,bytes),(address,bytes32[],bytes)[])[])":{"notice":"`msg.sender` deposits tokens according to config. The config specifies the vault to deposit tokens under. Delegated depositing is NOT supported. Depositing DOES NOT mint shares (unlike ERC4626) so the overall vaulted experience is much simpler as there is always a 1:1 relationship between deposited assets and vault balances globally and individually. This mitigates rounding/dust issues, speculative behaviour on derived assets, possible regulatory issues re: whether a vault share is a security, code bloat on the vault, complex mint/deposit/withdraw/redeem 4-way logic, the need for preview functions, etc. etc. At the same time, allowing vault IDs to be specified by the depositor allows much more granular and direct control over token movements within Orderbook than either ERC4626 vault shares or mere contract-level ERC20 allowances can facilitate. Vault IDs are namespaced by the token address so there is no risk of collision between tokens. For example, vault ID 1 for token A is completely different to vault ID 1 for token B. `0` amount deposits are unsupported as underlying token contracts handle `0` value transfers differently and this would be a source of confusion. The order book MUST revert with `ZeroDepositAmount` if the amount is zero. Vault ID `0` is disallowed for deposits to avoid collision with vaultless orders."},"entask2(((address,address,bytes),(address,bytes32[],bytes)[])[])":{"notice":"`msg.sender` entasks the provided tasks. This DOES NOT return any values, and MUST NOT modify any vault balances. Presumably the expressions will modify some internal state associated with active orders. If ANY of the expressions revert, the entire transaction MUST revert."},"maxFlashLoan(address)":{"notice":"There's no limit to the size of a flash loan from `Orderbook` other than the current tokens deposited in `Orderbook`. If there is an active debt then loans are disabled so the max becomes `0` until after repayment."},"orderExists(bytes32)":{"notice":"Returns true if the order exists, false otherwise."},"quote2(((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[]))":{"notice":"Quotes the provided order for the caller. The caller is considered to be the counterparty to the order, for the purposes of evaluating the quote. However, the caller's vault balances and/or tokens in wallet are not considered in the quote. This means the output max can exceed what the caller could actually pay for. Both the output max and io ratio are returned as rain floating point values, ignoring any token decimals, so are not the literal amounts that would be moved in the order were it to clear."},"removeOrder3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),((address,address,bytes),(address,bytes32[],bytes)[])[])":{"notice":"Order owner can remove their own orders. Delegated order removal is NOT supported and will revert. Removing an order multiple times or removing an order that never existed are valid, the event will be emitted and the transaction will complete with that order hash definitely, redundantly not live."},"takeOrders4((bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes))":{"notice":"Allows `msg.sender` to attempt to fill a list of orders in sequence without needing to place their own order and clear them. This works like a market buy but against a specific set of orders. Every order will looped over and calculated individually then filled maximally until the request input is reached for the `msg.sender`. The `msg.sender` is responsible for selecting the best orders at the time according to their criteria and MAY specify a maximum IO ratio to guard against an order spiking the ratio beyond what the `msg.sender` expected and is comfortable with. As orders may be removed and calculate their ratios dynamically, all issues fulfilling an order other than misconfiguration by the `msg.sender` are no-ops and DO NOT revert the transaction. This allows the `msg.sender` to optimistically provide a list of orders that they aren't sure will completely fill at a good price, and fallback to more reliable orders further down their list. Misconfiguration such as token mismatches are errors that revert as this is known and static at all times to the `msg.sender` so MUST be provided correctly. `msg.sender` MAY specify a minimum input that MUST be reached across all orders in the list, otherwise the transaction will revert, this MAY be set to zero. Exactly like withdraw, if there is an active flash loan for `msg.sender` they will have their outstanding loan reduced by the final input amount preferentially before sending any tokens. Notably this allows arb bots implemented as flash loan borrowers to connect orders against external liquidity directly by paying back the loan with a `takeOrders` call and outputting the result of the external trade. Rounding errors always favour the order never the `msg.sender`."},"vaultBalance2(address,address,bytes32)":{"notice":"Get the current balance of a vault for a given owner, token and vault ID."},"withdraw4(address,bytes32,bytes32,((address,address,bytes),(address,bytes32[],bytes)[])[])":{"notice":"Allows the sender to withdraw any tokens from their own vaults. If the withdrawer has an active flash loan debt denominated in the same token being withdrawn then Orderbook will merely reduce the debt and NOT send the amount of tokens repaid to the flashloan debt. MUST revert if the amount _requested_ to withdraw is zero. The withdrawal MAY still not move any tokens (without revert) if the vault balance is zero, or the withdrawal is used to repay a flash loan, or due to any other internal accounting. Vault ID `0` is NOT supported due to collision with vaultless orders."}},"version":1}},"settings":{"remappings":["@openzeppelin/contracts/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/contracts/","axelar-gmp-sdk-solidity/=lib/sushixswap-v2/lib/axelar-gmp-sdk-solidity/","bytecode/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/bytecode/","caller/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/caller/","codegen/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/codegen/","constants/=lib/rain.interpreter/src/lib/constants/","deprecated/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/","ds-test/=lib/sushixswap-v2/lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/lib/erc4626-tests/","eval/=lib/rain.interpreter/src/lib/eval/","extern/=lib/rain.interpreter/src/lib/extern/","forge-gas-snapshot/=lib/sushixswap-v2/lib/forge-gas-snapshot/src/","forge-std/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/forge-std/src/","halmos-cheatcodes/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","integrity/=lib/rain.interpreter/src/lib/integrity/","mut/=lib/rain.interpreter/lib/rain.string/src/lib/mut/","ns/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/ns/","op/=lib/rain.interpreter/src/lib/op/","openzeppelin-contracts/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/","parse/=lib/rain.interpreter/src/lib/parse/","rain.datacontract/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.datacontract/src/","rain.interpreter.interface/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/","rain.interpreter/=lib/rain.interpreter/src/","rain.intorastring/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.intorastring/src/","rain.lib.hash/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.hash/src/","rain.lib.memkv/=lib/rain.interpreter/lib/rain.lib.memkv/src/","rain.lib.typecast/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.typecast/src/","rain.math.binary/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.binary/src/","rain.math.fixedpoint/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.math.fixedpoint/src/","rain.math.float/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/","rain.math.saturating/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.math.fixedpoint/lib/rain.math.saturating/src/","rain.metadata/=lib/rain.interpreter/lib/rain.metadata/src/","rain.orderbook.interface/=lib/rain.orderbook.interface/src/","rain.sol.codegen/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.sol.codegen/src/","rain.solmem/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/","rain.string/=lib/rain.interpreter/lib/rain.string/src/","rain.tofu.erc20-decimals/=lib/rain.tofu.erc20-decimals/src/","sol.lib.binmaskflag/=lib/rain.interpreter/lib/sol.lib.binmaskflag/src/","state/=lib/rain.interpreter/src/lib/state/","sushixswap-v2/=lib/sushixswap-v2/"],"optimizer":{"enabled":true,"runs":1000},"metadata":{"bytecodeHash":"none","appendCBOR":false},"compilationTarget":{"src/concrete/ob/OrderBookV6.sol":"OrderBookV6"},"evmVersion":"cancun","libraries":{}},"sources":{"lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.hash/src/LibHashNoAlloc.sol":{"keccak256":"0x1153c2d2ec53adca83c81c37ac958aab8b4d31e0e01f64f5189b1783375c0347","urls":["bzz-raw://79d10d5165cf0d5cc8b28b76613fc114e74c33fcc2d5632f7e284dace2247927","dweb:/ipfs/QmZEt4BQ6xsfiFNBQ55GoQq8Ats3Hb1v2hPFEWPDeqKrTv"],"license":"LicenseRef-DCL-1.0"},"lib/rain.interpreter/lib/rain.metadata/src/interface/deprecated/IMetaV1.sol":{"keccak256":"0x8ba40db7da4859ce5c42510e7bd70bb9d02a33609938b7137b51187ba6c120ba","urls":["bzz-raw://8885892b317e0c798e11f88e4e23198e940d43c73b4613449a0199d41bf02d3e","dweb:/ipfs/Qmb6AEittgihpJnL2aZeG9XA3PSjBSaKa9ewk6dZR9WhL1"],"license":"LicenseRef-DCL-1.0"},"lib/rain.interpreter/lib/rain.metadata/src/interface/unstable/IMetaV1_2.sol":{"keccak256":"0x968d077369f63608da1d8d69c5832cd1561133a3b32f6dfce84adf4eab9d22b6","urls":["bzz-raw://162291396bb979dc92dda61cd705d86fdb6378e58c556bb0a33e45fe60216c27","dweb:/ipfs/QmcdzNthSLZsW8Qg1bU72jXG7KvhycppH6phzRo4awxJxD"],"license":"LicenseRef-DCL-1.0"},"lib/rain.interpreter/lib/rain.metadata/src/lib/LibMeta.sol":{"keccak256":"0xb924ea27ba17f3c5582475a854b572d7149a0088e06646663b15b3e4c1577d31","urls":["bzz-raw://94d7f0a3e4704d25904e4e3d9df064a5fa5d0fecf96128fc3ab44d41a44e92ad","dweb:/ipfs/QmYPR15FL8dXmbKjZK7Bq2qXbnno6eoj3SiXuuayLpB7Yh"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol":{"keccak256":"0x66c7ec42c6c43712be2107a50ab4529379bc76a632b425babec698d9da921ac6","urls":["bzz-raw://dce2778f0b638adfc5ba29c2c618c855fe725fa74a16846386aa1d56a834aa04","dweb:/ipfs/QmPV9oWnzQdi58od266j62xvviavLNHqKLZfm6k2K1qy9E"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol":{"keccak256":"0xd5ea07362ab630a6a3dee4285a74cf2377044ca2e4be472755ad64d7c5d4b69d","urls":["bzz-raw://da5e832b40fc5c3145d3781e2e5fa60ac2052c9d08af7e300dc8ab80c4343100","dweb:/ipfs/QmTzf7N5ZUdh5raqtzbM11yexiUoLC9z3Ws632MCuycq1d"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol":{"keccak256":"0x0afcb7e740d1537b252cb2676f600465ce6938398569f09ba1b9ca240dde2dfc","urls":["bzz-raw://1c299900ac4ec268d4570ecef0d697a3013cd11a6eb74e295ee3fbc945056037","dweb:/ipfs/Qmab9owJoxcA7vJT5XNayCMaUR1qxqj1NDzzisduwaJMcZ"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"keccak256":"0x1a6221315ce0307746c2c4827c125d821ee796c74a676787762f4778671d4f44","urls":["bzz-raw://1bb2332a7ee26dd0b0de9b7fe266749f54820c99ab6a3bcb6f7e6b751d47ee2d","dweb:/ipfs/QmcRWpaBeCYkhy68PR3B4AgD7asuQk7PwkWxrvJbZcikLF"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC7913.sol":{"keccak256":"0xe5a126930df1d54e4a6dd5fea09010c4a7db0ea974c6c17a1e6082879f5a032b","urls":["bzz-raw://2f58f5a90328536a6c68289916bfa4ed653d871319c7b2a416ab3f6263c4f2f5","dweb:/ipfs/Qmaa9DmgUA16Urz5fuF4RbFz2NaVpNLV41ddwykSdasFUd"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2","urls":["bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303","dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0xd6fa4088198f04eef10c5bce8a2f4d60554b7ec4b987f684393c01bf79b94d9f","urls":["bzz-raw://f95ee0bbd4dd3ac730d066ba3e785ded4565e890dbec2fa7d3b9fe3bad9d0d6e","dweb:/ipfs/QmSLr6bHkPFWT7ntj34jmwfyskpwo97T9jZUrk5sz3sdtR"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0x304d732678032a9781ae85c8f204c8fba3d3a5e31c02616964e75cfdc5049098","urls":["bzz-raw://299ced486011781dc98f638059678323c03079fefae1482abaa2135b22fa92d0","dweb:/ipfs/QmbZNbcPTBxNvwChavN2kkZZs7xHhYL7mv51KrxMhsMs3j"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x0fa9e0d3a859900b5a46f70a03c73adf259603d5e05027a37fe0b45529d85346","urls":["bzz-raw://c2add4da0240c9f2ce47649c8bb6b11b40e98cf6f88b8bdc76b2704e89391710","dweb:/ipfs/QmNQTwF2uVzu4CRtNxr8bxyP9XuW6VsZuo2Nr4KR2bZr3d"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Bytes.sol":{"keccak256":"0x8140d608316521b1fd71167c3b708ebb8659da070723fc8807609553b296ee33","urls":["bzz-raw://a7bf7db66869ba1e945a0390b85da2f6afc7e42a4735ca918d0d56ac90c50147","dweb:/ipfs/QmRmNyhpBpgzSdQqLtrQCYE7H7eLnVVxh2Yy4YMrySR8AR"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2","urls":["bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12","dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Errors.sol":{"keccak256":"0x6afa713bfd42cf0f7656efa91201007ac465e42049d7de1d50753a373648c123","urls":["bzz-raw://ba1d02f4847670a1b83dec9f7d37f0b0418d6043447b69f3a29a5f9efc547fcf","dweb:/ipfs/QmQ7iH2keLNUKgq2xSWcRmuBE5eZ3F5whYAkAGzCNNoEWB"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol":{"keccak256":"0x5b4802a4352474792df3107e961d1cc593e47b820c14f69d3505cb28f5a6a583","urls":["bzz-raw://a6f86fd01f829499fe0545ff5dda07d4521988e88bfe0bf801fc15650921ed56","dweb:/ipfs/QmUUKu4ZDffHAmfkf3asuQfmLTyfpuy2Amdncc3SqfzKPG"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Multicall.sol":{"keccak256":"0x72a5499dfae7676e4298a7299bccd3b27438ba1a4c72df5cd69c1c343c7ea20d","urls":["bzz-raw://de0fb51ccae3a0ff377ed185d187440fc612a71bf8e42fdb0e032ce747fa3eef","dweb:/ipfs/QmPNBaiVsAiUhz8qfXcSy27S7CqBbtSd8rPqmaykKBhw7Q"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Panic.sol":{"keccak256":"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a","urls":["bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a","dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"keccak256":"0xa516cbf1c7d15d3517c2d668601ce016c54395bf5171918a14e2686977465f53","urls":["bzz-raw://1e1d079e8edfb58efd23a311e315a4807b01b5d1cf153f8fa2d0608b9dec3e99","dweb:/ipfs/QmTBExeX2SDTkn5xbk5ssbYSx7VqRp9H4Ux1CY4uQM4b9N"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol":{"keccak256":"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97","urls":["bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b","dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x36d1750bf1aa5fee9c52adb2f7857ab652daca722fc05dff533b364f67a1139a","urls":["bzz-raw://2e5e7052539b7849d02f3ce25acc1dce29373c11cfae9f0bc918c54b780c549a","dweb:/ipfs/QmRGE32xNkMTo6i4pHHMxjpiu77yPwnTA25SFngw2NXJys"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"keccak256":"0x360cf86214a764694dae1522a38200b1737fe90e46dcf56a0f89de143071cc20","urls":["bzz-raw://2e393290a46ca6d1fa1addb40709d26e1d250638ab6acdd103b5af21768ebc7b","dweb:/ipfs/QmPwT3tXwQ9NbGtZ99XRq7sr8LCQP8XaCrzw49JdXGn7us"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol":{"keccak256":"0x6abeed5940e1da7bb329e458db9a1c5c4ea6f86d651b952af99c6bddcd6bbb94","urls":["bzz-raw://5fe75e9a6b759c5d7fd82fb59bd4f58c672b36f0a69b84f4789b7c7895d3e61c","dweb:/ipfs/QmX28wsir8w5sS3acfJMNHcBwoPsDpqCu7WDkPnUWLMNiZ"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol":{"keccak256":"0x445455b8be33e09cf1db14e59c0d1c5aa5d312b5e754e8ae751e42313a0cae88","urls":["bzz-raw://d6939df526d1c3f1d773448f6451eebb8de344113744e0da121b6349658b1298","dweb:/ipfs/QmPffovzJ8qGRuUh57qrnWajHqYPPrntb1EA1VRh8p5TLP"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0x2d9dc2fe26180f74c11c13663647d38e259e45f95eb88f57b61d2160b0109d3e","urls":["bzz-raw://81233d1f98060113d9922180bb0f14f8335856fe9f339134b09335e9f678c377","dweb:/ipfs/QmWh6R35SarhAn4z2wH8SU456jJSYL2FgucfTFgbHJJN4E"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c","urls":["bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617","dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0x09e3f1c72d4c5cbe8e2644ab7313f8f7177533ae2f4c24cdcbbeaf520a73734c","urls":["bzz-raw://93208401215d539fa2d81626b207c1f611def7883d0e447b3b5969ebaa7b3c2c","dweb:/ipfs/QmXPxDnQPx8LAweX5ZJqEcwkvs59kP4c64VVDG1Jjq1mef"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"keccak256":"0x195533c86d0ef72bcc06456a4f66a9b941f38eb403739b00f21fd7c1abd1ae54","urls":["bzz-raw://b1d578337048cad08c1c03041cca5978eff5428aa130c781b271ad9e5566e1f8","dweb:/ipfs/QmPFKL2r9CBsMwmUqqdcFPfHZB2qcs9g1HDrPxzWSxomvy"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xb1970fac7b64e6c09611e6691791e848d5e3fe410fa5899e7df2e0afd77a99e3","urls":["bzz-raw://db5fbb3dddd8b7047465b62575d96231ba8a2774d37fb4737fbf23340fabbb03","dweb:/ipfs/QmVUSvooZKEdEdap619tcJjTLcAuH6QBdZqAzWwnAXZAWJ"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/error/ErrDecimalFloat.sol":{"keccak256":"0x3c9e3f5e6b78877add52f397e2cf452e8a1afe6b9e630fc7bbc7c2d6704d07d9","urls":["bzz-raw://9840b88bf5143a94f8e7779390b025dda83530090be3503e110aa2584250c6e4","dweb:/ipfs/QmemaALnbRKFChq5Ec1p4xdar5rDqEvdbQwGb2vzMVWhK9"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/LibDecimalFloat.sol":{"keccak256":"0x5c8820a79da0ac3c8558ae65c8b3b2b4579326755a4914a243f2475c1159b2aa","urls":["bzz-raw://edc7ddd33798964f19aa9183fa0366321f93ab03171ba334192f65bd71a1a53d","dweb:/ipfs/QmYKAKopDLGMWCfTVhwhF3vCGw6wXveKX1uTtxCyvycNkL"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/implementation/LibDecimalFloatImplementation.sol":{"keccak256":"0x182d010eee786cfa19ad44e215332c4e6fd4e9310da3e61ebd17a0309307d6b6","urls":["bzz-raw://1206a9557d6410c30ec82f02d44d3e857d7aabf46d607ee08bf415af14f8a799","dweb:/ipfs/Qmbygfmw9K8YVQdEsNEkkHxTbTiuuDgWt7yB6gMwoYGBcp"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/table/LibLogTable.sol":{"keccak256":"0x412629a161febf0dc9c3bae0cc9fe0b8de8774d37c5f3afde2e2312478d96a98","urls":["bzz-raw://c8da5302117961caad328e80cb28296ea71aadbc291312e37d3db079d84a9777","dweb:/ipfs/QmWYzpex1Xrnjf3QM68n6mGFQ4KxE53fUUyDjwE3zNrtok"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrBytes.sol":{"keccak256":"0xdec97437eeba42f5950dc52f89caac433bc11a56a4e14a0f67a521821600c4b6","urls":["bzz-raw://72b96a4ed0d34dab653df0e6eb19d77b3e1c691b8e35543f6f32ae6a44c6312e","dweb:/ipfs/QmNrwwf3La4D25DudigRedu2c7xfx8k7bEzHFVZfpRu3se"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol":{"keccak256":"0x57b7a7a5cbc2fc97200130e84fde3a8afc14e0729040b14670dacc7f63c3ac5f","urls":["bzz-raw://4e7c7ce525e882db437b488b590fae6a817b282f88d76eb4f56986b549815e57","dweb:/ipfs/QmajzM26fsaFtaAnm5cg1FZrD6N2wkLJHCxa7Atx5x6iAB"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes.sol":{"keccak256":"0x6497d17390179a62820805d18a2cf2cdfddbe4990df783bde11cbf82e414fd0e","urls":["bzz-raw://54e8ed63c566d374ca2d89e8109c41267f7ca661e85570c6c7d51193aaca128b","dweb:/ipfs/Qmd6LoUZqg7TbeAx2auk5UkimyMiK4a9GsVMvDeqDRZF3M"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes32Array.sol":{"keccak256":"0x93a9a12fa9161523c8580196daf8e2bf59c48003166ef718f5fc07d47752aabe","urls":["bzz-raw://f1d24979b4b1f94621f0bc0505f8aafbb845ac86f72323454b6e96b4e57fb367","dweb:/ipfs/QmUD7hAfaNPPHUu9DjLaJrwrUrei8vfbyUoJcymbQeSsXE"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes32Matrix.sol":{"keccak256":"0xffd4769d4d0f89d0de792c6d100384ec0262c55c5cf6b33432739e8c4c0edcf6","urls":["bzz-raw://1c73e871d16e3b2f3498efb6b3235db19156e07cc71e9f0fbc3c6b0b4efe633a","dweb:/ipfs/Qmeu91h2q8EdtAoPdRtKUsKL48VD16AUAU1ZXmt89iiuck"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibMemCpy.sol":{"keccak256":"0x3f0a1962829eed7af79d21ab1f84b1a3b4044d90114812871c9dde7ae6f5cf0a","urls":["bzz-raw://4b777f051eef0b83c1b1b6e3927faf683609522acbac9c5bba412cd482be3fef","dweb:/ipfs/QmZrMNaEQBGeCM2L6bg5d8WBxPCSG1cwFD95AUQFVXzQXL"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol":{"keccak256":"0x3fc6ff807b57b681e32229380e3eda57107a1ada8dc2c1270daa84c9fca5addc","urls":["bzz-raw://a82b17ddc1db163ec548648c83dd5bb2f9f4441559452933f424e0a8dff48e57","dweb:/ipfs/QmdKoRbEAPxBRHJWWRwjh9Yrps1QXcJuX5mJmua8nvnq7B"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol":{"keccak256":"0xf51dffaeb88063748495e3184e335d9bb46f22881c2e8c930f2b68a32bdb39c2","urls":["bzz-raw://4a66ae9e4e9b9bf83b68c4d1d609fda02f8584387740354318d4eca1e2639047","dweb:/ipfs/QmXTS3azQ3ebBpJzj15HJRjTLV8zHfrFPQ7qPiic6eE3Pa"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Matrix.sol":{"keccak256":"0xf58526ebebc0e51a84369ebe6fb1173930cea3a61a488b6b5a597406fc1216e0","urls":["bzz-raw://75940e084457b62a7a38a2cfe920b0838c7c7517c914de64a5073fd01bdcedd8","dweb:/ipfs/QmUZ1sm2EQMhiR2UzB4cY868t6XYpgAi62tr6xvwMtYDnQ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/error/ErrBytecode.sol":{"keccak256":"0x4d740b62c6e81ffdb25a42c72a5bd5ea945659df1bc38510b4e95a9cd3bfe8bb","urls":["bzz-raw://aa05c6e63a9bd9dd722d3824b2ae376d5237c81a189e0e42bf9a1ba33da919d3","dweb:/ipfs/QmPLZtsKPrC9nLwk1jqw7LwwvsXAkxomrtUQLrhiQNWubC"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterCallerV3.sol":{"keccak256":"0xdd13be6b4942424143613a301d020f44f67dfe6bc81550d7726cbad8d735ccdc","urls":["bzz-raw://deb8adb379085983857f311d937d09f8ea1c1ecac8864f6a63f5391ba93e0929","dweb:/ipfs/QmcFsrfhXyjwT8yF8UkwaCW8LMbQr4uTj3Lhcju2yeQpZZ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol":{"keccak256":"0x15796750d51d5498986438ce9546cbb1ec66dd73531f2b12f155459c97ea24c5","urls":["bzz-raw://e73668fe127eb60cb27794da3398d7d6e8f1f9f41d71081af7016dd114c81904","dweb:/ipfs/QmUe8ge3U3Fz3FzEQyXaPS2oLm9bAV2QZttP77WPrsckcK"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterV3.sol":{"keccak256":"0xe546b8a716e632ce6db719b6eb63e6ec86d530ac80ad619c47bedd470270e85a","urls":["bzz-raw://1359938d87ab63d170aecfbc28336db3a5598d1aacffc35f2ed1bb786ee17755","dweb:/ipfs/QmbtR2wot29rpuxu1kBVvqtHBe7NVb6c2B3sXpyhj1ERkU"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IParserV2.sol":{"keccak256":"0x29935383d2b114fd0a145977340552fcbc4b674ba89949b7b40ba23c56e3586a","urls":["bzz-raw://aefa76e1dd78f206cf93b9522c545e665e73e44585b3dddb70e03c6aefdf443e","dweb:/ipfs/QmePBeLhR1Z7DYzhmbVkm4aUKTwDHnhJCpFXniLBuN8ryK"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV1.sol":{"keccak256":"0xc0afd50701cd68eef984a63862bd6a10552d704cca6e10f06d19d920b0777c98","urls":["bzz-raw://cd3cbfa9159ceed8871f46f62c7ea235ad8537d3c6c1c004152ebf5d2d597346","dweb:/ipfs/QmPSAJXAcmDeK9Qy6s2dXdeu4GJ62FKWa69VBo4ioCPcJ9"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV2.sol":{"keccak256":"0x368ace8d0f82832f08caf264e4194647b9777c0d4a0f22d88236b30c1e4c8a63","urls":["bzz-raw://9c8a2141fcd76d6308156777b0a9e5a4f7f07fb3693461e2c12f07e4d8c87130","dweb:/ipfs/QmPnhPz6sXzh5xBGZobAPY2WJTgvQDiYWRFKavscSPu7T5"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV3.sol":{"keccak256":"0x6f6b03c0f8e37ebe4275e0d27242754c7be815ff091ad0931a7be21ab11de628","urls":["bzz-raw://1f200079a3689e0d0c8efb97040737a2b4113a82f0df5d8319af36d9ad5d8b97","dweb:/ipfs/QmXFzXZasmD9D7pAYC5wBtB748TZajy69V5tmSEXRd1VZk"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV1.sol":{"keccak256":"0xc01bc48e2479cab07fc799e26c3790c8cf97acc1f0f490c8f456f554d239a505","urls":["bzz-raw://2981aa2eae0d414bc8ad4105bedb05026cfdad7e6af8f23805dba4835ae9fd8a","dweb:/ipfs/QmQRKi5nmatC1UM2sNta9giuJX3xvvLAD5pmCeAsVWF4hF"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV2.sol":{"keccak256":"0x62c7149e3d28cd9b67d7eed183c4e59cf300689dd5cc363b011cb2cf32c1200d","urls":["bzz-raw://52cf991b2dc9581222520c32cac224f6936c75183e4c6c16fafa4450a05c0de0","dweb:/ipfs/QmZ7fiZYjnDhNnFXYCXC9iSYs8WAAwmsVxBd5XDA1tPPah"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol":{"keccak256":"0x7d2bc86fefbe372fc64381b320244fe9dbda1816867f3040c5bb3951869fe6a7","urls":["bzz-raw://90c371494080129d5acd2bc52d092fc5cfe559147f7fc855ed01e62a7837f21e","dweb:/ipfs/QmcNtPDuTxic8zqRFXf1ba6FJKmQXguxiDUY4E7wjyVwU5"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol":{"keccak256":"0xe0b94c771a7b6aa05388b4db6e238e36a4653cbfdbd3e54bbcaa7a97fc9491f4","urls":["bzz-raw://59887a7f2ef60669906c5e70831ac0c9a7345313b04efb306235280f85e1db73","dweb:/ipfs/QmP6Ny9m3sPCP65UmgGGpucSMgVAoDv6qURqyxUE95VU5Q"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV2.sol":{"keccak256":"0x0ae0d1b0ca245779f33ea3e5ffbfcc234533d5c75f4ec2a6f3042cf841bcc219","urls":["bzz-raw://0fd476c34670477ece5a217d2372637c279287af883c132f1b98db4b3ccb80bf","dweb:/ipfs/QmVBfaGYovi93pDr9HosQkacCmeXQAfgM6haTQZFJsGnoE"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IParserV1.sol":{"keccak256":"0x4f6a9e028942cebebfc84328193f1d31807aac292d9b82e2df489064aa913070","urls":["bzz-raw://54073f63db1f652571472cb2d07de297772c2420e1571a0cb9e0a805ee4347e7","dweb:/ipfs/QmXRqBreJvC8MQd5zLNgmPUdfFa4WD6gSoxvD8hecycux4"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterCallerV4.sol":{"keccak256":"0xae8309d29bcc770df07bf5f5b463e80a6c20456d9fc9dcae203975328b257423","urls":["bzz-raw://196dbc14f46e90344ed1bac0efbf87dd3dba15aeaed57678673e03f1362eb487","dweb:/ipfs/QmejhzZx6G8gw76vPKvDEfVQQ9mF1kJvx5wj9qdeDoVrPH"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterStoreV3.sol":{"keccak256":"0xda4e6583c7a6cefb7d32593d0e069fb26b4822fb07d916bef68a4b4be857078e","urls":["bzz-raw://970ae6a0f2dcfaaea8b79fc30af89043282e159910b8c375a8027ad738e4e736","dweb:/ipfs/QmQk5fhi61BcvEAUcBVFivUTzd7SZxULG5UdsNkrykjVPF"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterV4.sol":{"keccak256":"0x1617c780008c8f724516b1af0844f97c2c8c17ee87f515e3be3cce2d2731085f","urls":["bzz-raw://b4d206e14a81549771cc8c62f54006b545c8acb546074e2cf66213211f3363a9","dweb:/ipfs/QmNtpyVpL9riAxB8ZjHP1tp9GkdX9YVfXKVQ7an8ZL9rJD"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/bytecode/LibBytecode.sol":{"keccak256":"0xaf78f1b85b0fd4df30da5f6515604fdc2792d34c14ad8d2fd633afb7777f0162","urls":["bzz-raw://e5b2fad52a1f8ed91dc5ba72454d95cd7642825b165f4db75a402d16279d65bb","dweb:/ipfs/QmTAkJmLMj45NkvvEtoSGFbuiHmkDEMHHzKfTTfd7PKHZH"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibContext.sol":{"keccak256":"0xaeb62b79fa753d8327c6d6af457d4b00937db798b51ba7e51d4a367176f8d8ba","urls":["bzz-raw://1c91eb4f6bb61ef79c217e15ec8cb88be4cca841d4efe70bfeb4858319032a2b","dweb:/ipfs/QmVCfM2pufm269ExXDXPTwK8EcWA5ksT8Z1XAG6YTLX34Y"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibEvaluable.sol":{"keccak256":"0xd2b8ff7feb5fdfefa6c0068ae33bd0723f1a58a066a8ee1da46608bd3ae63da3","urls":["bzz-raw://7290ceebbd842f88d4ecadc3847a555afbc8a4b4458b7def1c0cba4e28eb80bb","dweb:/ipfs/QmR28Pst8QTLUSmRUDGK8f8prA5zutCeTG3F7RYXmNJ7WH"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/deprecated/caller/LibEncodedDispatch.sol":{"keccak256":"0xf026da6a07f43d8345f41946c257f872172f33732a01dcb56c954c444467e9cb","urls":["bzz-raw://424d8f53931425c56e18e5355e0875333b4864e04dcbab424d29ec2dd624e35b","dweb:/ipfs/QmePkJjv1XvXEjjHBq9NeEdb6WTKTj8uTcCbxANM9P3DGw"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/ns/LibNamespace.sol":{"keccak256":"0xd621d3e5f8b404309ad5d841a3658248e979c1bd59876be3afa7aa0595b4c0e6","urls":["bzz-raw://801fa302f49f3734dd5cc6221dd25f73591ac8feae47351c18e30a98a4ae0ce1","dweb:/ipfs/QmbwXbTSMZ4u6ZsyfseBx79PeHNAWocNHXpgnaPVmLZM38"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/IOrderBookV5.sol":{"keccak256":"0x81531ce21b2cf824be60f70e14b97e8d6f5df7e09a454a690f4ed8c7d41a0dc1","urls":["bzz-raw://e8a203d32f5e423f0f5fd47f1a7be70d0cad3b69c3d1469d19a8d85e1f14c303","dweb:/ipfs/QmZH6v3Hc41SXiiuruUpntcUAXMcHqEhhpDATSArHQfe99"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v2/IOrderBookV2.sol":{"keccak256":"0x6df5dd48103f06c7a41b49e9497f9f28baa4940eb5eba4113c71b323da66e5a4","urls":["bzz-raw://e295c8ce419a26e44d1f5be80c1bfa8a852a0b47e0e332be9323a670806344aa","dweb:/ipfs/QmbAJ1j8WTdwCBLF6mjiHihfvUZFAeiv3uTXntMWPLKTt7"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v3/IOrderBookV3.sol":{"keccak256":"0x0f90c4db32d78d1c15f6230b1f0cc1e16cca908e3981f417039816e820fe0c24","urls":["bzz-raw://693ae8187a8012410ff5774e73ed11ca5279c296cfafecd75613e804197ec43f","dweb:/ipfs/QmQLPSZwcPfc8MJDnaJiUT5ktsodQ48erR1uoTtF3Fa1ju"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v4/IOrderBookV4.sol":{"keccak256":"0xc94415fcd366693e78116a72df9c6b29408ad4bdb745846c5929561a5ce2a226","urls":["bzz-raw://48f92b2281195b90bb5ee6a6b3866e27f25b9268729765eb6681de4c48b86d82","dweb:/ipfs/QmUjiXwgsYzsRRj1o3uxo2aeboAT2VZxV5RWYbkinT9jUt"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/ierc3156/IERC3156FlashBorrower.sol":{"keccak256":"0xdcd81b1110e9c3c91715ac90aef1da70066bcaba8aeb3dc23df979f7f87644f9","urls":["bzz-raw://4572efaeb9eb30ad9b766b80cb2a8101a2cec0c9e8c78c7696f4aae710c8e2c9","dweb:/ipfs/QmVsz1gtqWfxTAbsoLPvZBe6PBVXqaWNx6nu7RHr2ghLuK"],"license":"CC0-1.0"},"lib/rain.orderbook.interface/src/interface/ierc3156/IERC3156FlashLender.sol":{"keccak256":"0x119c477281a6ec109e9c729a254b39d7ccc9a9f5baa82fa28d0fa1e3bd2b6ae8","urls":["bzz-raw://19ec8289a123459659dca0389a650ca6bf6bc12d925ad7a3e61f0b1bfe68d1b6","dweb:/ipfs/QmRZ9U5ECovPFmbRaBTauFjjVQcvPA7VQL7S1zJVEBTMD5"],"license":"CC0-1.0"},"lib/rain.orderbook.interface/src/interface/unstable/IOrderBookV6.sol":{"keccak256":"0xabb3b41a1e11614ce9638fece01c78e5b8aff3598263ef38c80367b09233b801","urls":["bzz-raw://03108d4f4c13316863257e21c9be2788cd780b19ad55d4a0d3d9306d53c3f7a4","dweb:/ipfs/QmNt9vWhgj4VGHq8SVMX9HWFed5LUZNEpWMxaW3SLojPsL"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/unstable/IOrderBookV6OrderTaker.sol":{"keccak256":"0xc74b50c77d37fe78e350e9d2e2a09fe603661c25eccd28961abfd17a903b7283","urls":["bzz-raw://dff51045b7d2b291880d130e6c3a8286f0face2ff1c6bbe3d6a6e70f3506f2c2","dweb:/ipfs/QmSFh54NcMv62KK7w8YwMtLciKeLbRSUbdK3EE6tMkK35P"],"license":"LicenseRef-DCL-1.0"},"lib/rain.tofu.erc20-decimals/src/interface/ITOFUTokenDecimals.sol":{"keccak256":"0xff728b82d787191dc32f7dac385baa1e194d313c84979b90934e6b8fd06ddbc5","urls":["bzz-raw://e789fb5fcb3396d81fa487c907486b9ba7d33312502b676e43816f777e0379fd","dweb:/ipfs/Qme1evJCUVHVpPteVvgwW84fNAJwLKfVi5xmJjNrhKEziR"],"license":"LicenseRef-DCL-1.0"},"lib/rain.tofu.erc20-decimals/src/lib/LibTOFUTokenDecimals.sol":{"keccak256":"0x50c11116ed9fab852afd4cdc010751e93485d7c08a6fc318a8582c96ab26a068","urls":["bzz-raw://f1d781fe347ab40ed0169d8ffa41f0311cceb9c7f4a31205ef118a280ecfa455","dweb:/ipfs/QmecF2QZ92oh9qEzD9BRN2r9H8VwEXZQfJZRtrbUcsESQV"],"license":"LicenseRef-DCL-1.0"},"src/abstract/OrderBookV6FlashLender.sol":{"keccak256":"0x2cf18ae141f9b7c4f93817985b11633daf667ad0feb45111e99865012a6661fe","urls":["bzz-raw://6cc1280407c8ef53df2c97df0bda506a90e8a728b697669eec9d25015df811db","dweb:/ipfs/QmenGASd6vBn3KCrtjKdsq9c1g5f6XzidxWD6sav7dRBXM"],"license":"LicenseRef-DCL-1.0"},"src/concrete/ob/OrderBookV6.sol":{"keccak256":"0x7fc33c619f1ac871a2887ca1b3c8c9b04e8797966978801a2e6e4861b38f563e","urls":["bzz-raw://851e8297499dfea38b2b9acdf60d3540612232c93ab9737ece66e020aeee938b","dweb:/ipfs/Qmdzm6iZc9YVSuPAJbRYZPUU7rXigVYYPZ5JR7kuVV241X"],"license":"LicenseRef-DCL-1.0"},"src/lib/LibOrder.sol":{"keccak256":"0x1a458a49c08e02df1e7981e64f26647f5912554280697b3ae1a984e1a863dae9","urls":["bzz-raw://0aaab364d64cbb8ab37cd0f5344f14bfffcc6f426a4e993b28dc70e8fae6327e","dweb:/ipfs/QmWoqhqNtYd22a3jnFmFzvqGatY8RCVxLvoPonxKELFD9J"],"license":"LicenseRef-DCL-1.0"},"src/lib/LibOrderBook.sol":{"keccak256":"0x77b9b1fa35a044f652da6f6e9c91ee33699b3412ed651d517fbce9d180b60eb1","urls":["bzz-raw://b275a56b1f85b4cee2e6e2fffb1060590978ad5b0fc5cd4f3cedf2e67287cbcb","dweb:/ipfs/QmeaB2XNZsXJvLWRgNahJZCQMmmwpmLQ2txjbupEbNbYwE"],"license":"LicenseRef-DCL-1.0"}},"version":1},"id":253} \ No newline at end of file diff --git a/test/abis/RaindexRouterOrderBookV6Arb.json b/test/abis/RaindexRouterOrderBookV6Arb.json new file mode 100644 index 00000000..b6b2cd5f --- /dev/null +++ b/test/abis/RaindexRouterOrderBookV6Arb.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[{"name":"config","type":"tuple","internalType":"struct OrderBookV6ArbConfig","components":[{"name":"orderBook","type":"address","internalType":"address"},{"name":"task","type":"tuple","internalType":"struct TaskV2","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"implementationData","type":"bytes","internalType":"bytes"}]}],"stateMutability":"nonpayable"},{"type":"fallback","stateMutability":"nonpayable"},{"type":"function","name":"arb4","inputs":[{"name":"orderBook","type":"address","internalType":"contract IOrderBookV6"},{"name":"takeOrders","type":"tuple[]","internalType":"struct TakeOrdersConfigV5[]","components":[{"name":"minimumIO","type":"bytes32","internalType":"Float"},{"name":"maximumIO","type":"bytes32","internalType":"Float"},{"name":"maximumIORatio","type":"bytes32","internalType":"Float"},{"name":"IOIsInput","type":"bool","internalType":"bool"},{"name":"orders","type":"tuple[]","internalType":"struct TakeOrderConfigV4[]","components":[{"name":"order","type":"tuple","internalType":"struct OrderV4","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IOV2[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"vaultId","type":"bytes32","internalType":"bytes32"}]},{"name":"nonce","type":"bytes32","internalType":"bytes32"}]},{"name":"inputIOIndex","type":"uint256","internalType":"uint256"},{"name":"outputIOIndex","type":"uint256","internalType":"uint256"},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"data","type":"bytes","internalType":"bytes"}]},{"name":"exchangeData","type":"bytes","internalType":"bytes"},{"name":"task","type":"tuple","internalType":"struct TaskV2","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"iTaskHash","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"onFlashLoan","inputs":[{"name":"initiator","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"event","name":"Construct","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"config","type":"tuple","indexed":false,"internalType":"struct OrderBookV6ArbConfig","components":[{"name":"orderBook","type":"address","internalType":"address"},{"name":"task","type":"tuple","internalType":"struct TaskV2","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV4","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV4"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV3"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"bytes32[]","internalType":"bytes32[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"implementationData","type":"bytes","internalType":"bytes"}]}],"anonymous":false},{"type":"error","name":"BadInitiator","inputs":[{"name":"badInitiator","type":"address","internalType":"address"}]},{"type":"error","name":"CoefficientOverflow","inputs":[{"name":"signedCoefficient","type":"int256","internalType":"int256"},{"name":"exponent","type":"int256","internalType":"int256"}]},{"type":"error","name":"ExponentOverflow","inputs":[{"name":"signedCoefficient","type":"int256","internalType":"int256"},{"name":"exponent","type":"int256","internalType":"int256"}]},{"type":"error","name":"FailedCall","inputs":[]},{"type":"error","name":"FlashLoanFailed","inputs":[]},{"type":"error","name":"InsufficientBalance","inputs":[{"name":"balance","type":"uint256","internalType":"uint256"},{"name":"needed","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidSignature","inputs":[{"name":"i","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"LossyConversionToFloat","inputs":[{"name":"signedCoefficient","type":"int256","internalType":"int256"},{"name":"exponent","type":"int256","internalType":"int256"}]},{"type":"error","name":"NegativeFixedDecimalConversion","inputs":[{"name":"signedCoefficient","type":"int256","internalType":"int256"},{"name":"exponent","type":"int256","internalType":"int256"}]},{"type":"error","name":"NoOrders","inputs":[]},{"type":"error","name":"ReentrancyGuardReentrantCall","inputs":[]},{"type":"error","name":"SafeERC20FailedOperation","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"type":"error","name":"WrongTask","inputs":[]}],"bytecode":{"object":"0x60a06040525f608052348015610013575f80fd5b50604051613ae3380380613ae383398101604081905261003291610353565b808060017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556040517f3a5f92e1700a303557ddae1bed800da2d50036e5b24950a948611540f0928e799061008a90339084906105c1565b60405180910390a16020810151516040015151156100d1576020808201516040516100b59201610620565b60408051601f1981840301815291905280516020909101206080525b505050610639565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b038111828210171561010f5761010f6100d9565b60405290565b604080519081016001600160401b038111828210171561010f5761010f6100d9565b604051601f8201601f191681016001600160401b038111828210171561015f5761015f6100d9565b604052919050565b6001600160a01b038116811461017b575f80fd5b50565b5f82601f83011261018d575f80fd5b81516001600160401b038111156101a6576101a66100d9565b6101b9601f8201601f1916602001610137565b8181528460208386010111156101cd575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f6001600160401b03821115610201576102016100d9565b5060051b60200190565b5f82601f83011261021a575f80fd5b8151602061022f61022a836101e9565b610137565b82815260059290921b8401810191818101908684111561024d575f80fd5b8286015b848110156103485780516001600160401b038082111561026f575f80fd5b908801906060828b03601f19011215610286575f80fd5b61028e6100ed565b8683015161029b81610167565b8152604083810151838111156102af575f80fd5b8401603f81018d136102bf575f80fd5b888101516102cf61022a826101e9565b81815260059190911b82018301908a8101908f8311156102ed575f80fd5b928401925b8284101561030b5783518252928b0192908b01906102f2565b858c0152505050606084015183811115610323575f80fd5b6103318d8a8388010161017e565b918301919091525085525050918301918301610251565b509695505050505050565b5f6020808385031215610364575f80fd5b82516001600160401b038082111561037a575f80fd5b908401906060828703121561038d575f80fd5b6103956100ed565b82516103a081610167565b815282840151828111156103b2575f80fd5b8301604081890312156103c3575f80fd5b6103cb610115565b8151848111156103d9575f80fd5b82016060818b0312156103ea575f80fd5b6103f26100ed565b81516103fd81610167565b81528188015161040c81610167565b81890152604082015186811115610421575f80fd5b61042d8c82850161017e565b6040830152508252508186015184811115610446575f80fd5b6104528a82850161020b565b8783015250808684015250506040830151935081841115610471575f80fd5b61047d8785850161017e565b60408201529695505050505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f604082516040855260018060a01b03808251166040870152602080830151606083821660608a01526040850151945060809150606060808a015261050260a08a018661048c565b888401518a82038b860152805180835291965084019084870190600581901b880186015f5b828110156105b057898203601f19018452845180518a168352888101518984018890528051888501819052908a01905f908a8601905b8083101561057d5783518252928c019260019290920191908c019061055d565b508e84015193508581038f870152610595818561048c565b95505050505087850194508784019350600181019050610527565b509c9b505050505050505050505050565b6001600160a01b038381168252604060208084018290528451909216908301528201516060808301525f906105f960a08401826104ba565b90506040840151603f19848303016080850152610616828261048c565b9695505050505050565b602081525f61063260208301846104ba565b9392505050565b60805161348561065e5f395f818160bd0152818161023a015261028b01526134855ff3fe60806040526004361061003e575f3560e01c806301ffc9a71461004b57806323e30c8b1461007f57806393be095e146100ac578063c55377d6146100df575b348015610049575f80fd5b005b348015610056575f80fd5b5061006a6100653660046121ab565b6100f2565b60405190151581526020015b60405180910390f35b34801561008a575f80fd5b5061009e61009936600461224f565b61018a565b604051908152602001610076565b3480156100b7575f80fd5b5061009e7f000000000000000000000000000000000000000000000000000000000000000081565b6100496100ed366004612929565b610227565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f23e30c8b00000000000000000000000000000000000000000000000000000000148061018457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f6001600160a01b03871630146101dd576040517f8b1f7c640000000000000000000000000000000000000000000000000000000081526001600160a01b03881660048201526024015b60405180910390fd5b5f806101eb848601866129c9565b915091506101f982826108b1565b507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd998975050505050505050565b61022f610dc7565b61023881612a29565b7f0000000000000000000000000000000000000000000000000000000000000000158015906102ad5750806040516020016102739190612bc7565b604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000014155b156102e4576040517f8812562900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845f815181106102f6576102f6612bff565b602002602001015160800151515f148061032e57508460018151811061031e5761031e612bff565b602002602001015160800151515f145b15610365576040517f9c95219f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516002146103db5760405162461bcd60e51b8152602060048201526024808201527f556e65787065637465642074616b65206f726465727320636f6e666967206c6560448201527f6e6774680000000000000000000000000000000000000000000000000000000060648201526084016101d4565b5f855f815181106103ee576103ee612bff565b6020026020010151608001515f8151811061040b5761040b612bff565b60200260200101515f015160400151865f8151811061042c5761042c612bff565b6020026020010151608001515f8151811061044957610449612bff565b6020026020010151602001518151811061046557610465612bff565b60200260200101515f015190505f8660018151811061048657610486612bff565b6020026020010151608001515f815181106104a3576104a3612bff565b60200260200101515f015160400151876001815181106104c5576104c5612bff565b6020026020010151608001515f815181106104e2576104e2612bff565b602002602001015160200151815181106104fe576104fe612bff565b60200260200101515f015190508660018151811061051e5761051e612bff565b6020026020010151608001515f8151811061053b5761053b612bff565b60200260200101515f0151606001518760018151811061055d5761055d612bff565b6020026020010151608001515f8151811061057a5761057a612bff565b6020026020010151604001518151811061059657610596612bff565b60200260200101515f01516001600160a01b0316826001600160a01b0316146106275760405162461bcd60e51b815260206004820152603660248201527f737461727420616e6420656e64206f726465727320494f20646f204e4f54206360448201527f6c6f73652074686520726f75746520636972637569740000000000000000000060648201526084016101d4565b5f61063183610df5565b90505f61063d83610df5565b6040516370a0823160e01b81526001600160a01b038c811660048301529192505f91600291908716906370a0823190602401602060405180830381865afa15801561068a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106ae9190612c13565b6106b89190612c52565b90505f6106c58285610e8b565b90506106db6001600160a01b0387168d5f610eaf565b6106f06001600160a01b0387168d5f19610eaf565b6107178b5f8151811061070557610705612bff565b60200260200101516020015182610f2e565b1561074057808b5f8151811061072f5761072f612bff565b602002602001015160200181815250505b5f8b5f8151811061075357610753612bff565b602002602001015160600190151590811515815250505f8b8b8b60405160200161077f93929190612dfb565b60408051601f19818403018152908290527f5cffe9de00000000000000000000000000000000000000000000000000000000825291506001600160a01b038e1690635cffe9de906107da9030908b9088908790600401612e82565b6020604051808303815f875af11580156107f6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061081a9190612ebd565b610850576040517f92111eb200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108646001600160a01b0388168e5f610eaf565b6108796108708a612a29565b88878988610f68565b50505050505050506108aa60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050505050565b5f825f815181106108c4576108c4612bff565b6020026020010151608001515f815181106108e1576108e1612bff565b60200260200101515f015160600151835f8151811061090257610902612bff565b6020026020010151608001515f8151811061091f5761091f612bff565b6020026020010151604001518151811061093b5761093b612bff565b60200260200101515f015190505f80336001600160a01b03166369c72856865f8151811061096b5761096b612bff565b60200260200101516040518263ffffffff1660e01b815260040161098f9190612ed8565b60408051808303815f875af11580156109aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ce9190612eea565b85519193509150829015610bdd575f858060200190518101906109f19190612f59565b90505f5b8151811015610bda575f828281518110610a1157610a11612bff565b6020026020010151905060016003811115610a2e57610a2e61305c565b81516003811115610a4157610a4161305c565b03610a5a57610a51818589611203565b97509350610bd1565b5f81516003811115610a6e57610a6e61305c565b03610ad15760405162461bcd60e51b815260206004820152602d60248201527f7261696e64657820726f757465206c65672074797065206973206e6f7420796560448201526c1d081a5b5c1b195b595b9d1959609a1b60648201526084016101d4565b600281516003811115610ae657610ae661305c565b03610b595760405162461bcd60e51b815260206004820152602e60248201527f62616c616e63657220726f757465206c65672074797065206973206e6f74207960448201527f657420696d706c656d656e74656400000000000000000000000000000000000060648201526084016101d4565b600381516003811115610b6e57610b6e61305c565b03610bd15760405162461bcd60e51b815260206004820152602d60248201527f73746162756c6c20726f757465206c65672074797065206973206e6f7420796560448201526c1d081a5b5c1b195b595b9d1959609a1b60648201526084016101d4565b506001016109f5565b50505b5f86600181518110610bf157610bf1612bff565b6020026020010151608001515f81518110610c0e57610c0e612bff565b60200260200101515f01516040015187600181518110610c3057610c30612bff565b6020026020010151608001515f81518110610c4d57610c4d612bff565b60200260200101516020015181518110610c6957610c69612bff565b6020908102919091010151519050610c8b6001600160a01b038216335f610eaf565b610ca06001600160a01b038216335f19610eaf565b610cc887600181518110610cb657610cb6612bff565b60200260200101516020015183610f2e565b15610cf2578187600181518110610ce157610ce1612bff565b602002602001015160200181815250505b5f87600181518110610d0657610d06612bff565b602002602001015160600190151590811515815250505f80336001600160a01b03166369c728568a600181518110610d4057610d40612bff565b60200260200101516040518263ffffffff1660e01b8152600401610d649190612ed8565b60408051808303815f875af1158015610d7f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da39190612eea565b9092509050610dbc6001600160a01b038416335f610eaf565b505050505050505050565b610dcf611485565b60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b6040517f54636d2b0000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201525f9073f66761f6b5f58202998d6cd944c81b22dc6d4f1e906354636d2b906024016020604051808303815f875af1158015610e67573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101849190613070565b5f805f610e9885856114e2565b91509150610ea68282611546565b95945050505050565b610ebb8383835f6115a0565b610f2957610ecc83835f60016115a0565b610ef457604051635274afe760e01b81526001600160a01b03841660048201526024016101d4565b610f0183838360016115a0565b610f2957604051635274afe760e01b81526001600160a01b03841660048201526024016101d4565b505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d610f5c8484848461161b565b12979650505050505050565b6040805160018082528183019092525f91816020015b6060815260200190600190039081610f7e575050604080516003808252608082019092529192505f919060208201606080368337019050506040516370a0823160e01b81523060048201529091505f906001600160a01b038816906370a0823190602401602060405180830381865afa158015610ffd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110219190612c13565b9050801561103d5761103d6001600160a01b03881633836116f8565b5f806110498389611705565b9150915081845f8151811061106057611060612bff565b602090810291909101015250506040516370a0823160e01b81523060048201525f91506001600160a01b038616906370a0823190602401602060405180830381865afa1580156110b2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110d69190612c13565b905080156110f2576110f26001600160a01b03861633836116f8565b5f806110fe8387611705565b91509150818460018151811061111657611116612bff565b60209081029190910101525047915061113190503382611745565b61113d81601119611546565b8260028151811061115057611150612bff565b6020026020010181815250505080825f8151811061117057611170612bff565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160a0810182525f918101828152606080830193909352608082018390528152602081019190915281526020019060019003908161119157905050905087815f815181106111e4576111e4612bff565b60200260200101819052506111f983826117ee565b5050505050505050565b5f805f805f87604001518060200190518101906112209190613090565b925092509250826001600160a01b0316866001600160a01b0316146112875760405162461bcd60e51b815260206004820152600e60248201527f746f6b656e206d69736d6174636800000000000000000000000000000000000060448201526064016101d4565b5f806112f289866001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112c9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112ed9190613070565b6119cd565b915091505f846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611333573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113579190613070565b90505f8061136581846119cd565b915091508061137c5781611378816130f0565b9250505b60208d0151611396906001600160a01b038a16905f610eaf565b60208d01516113b1906001600160a01b038a16905f19610eaf565b60208d01516040517f2646478b0000000000000000000000000000000000000000000000000000000081525f916001600160a01b031690632646478b90611406908c908a908d90899030908f90600401613108565b6020604051808303815f875af1158015611422573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114469190612c13565b60208f0151909150611463906001600160a01b038b16905f610eaf565b5f61146e8286610e8b565b9b509799505050505050505050505b935093915050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00546002036114e0576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f805f805f6114f187876119f9565b92509250925080611538576040517fc471796600000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044016101d4565b5090925090505b9250929050565b5f805f6115538585611a55565b9150915080611598576040517f22c9f7bb00000000000000000000000000000000000000000000000000000000815260048101869052602481018590526044016101d4565b509392505050565b6040517f095ea7b3000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f5114831661160f578383151615611603573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f808515841517818712828612181785841417801561164057868592509250506116ef565b505f85841315611654575092949193919260015b8386035f8112604c8213178015611687578215611679575f89945094505050506116ef565b885f945094505050506116ef565b600a82900a8981028a82828161169f5761169f612c2a565b05146116cb5784156116bb575f8b9650965050505050506116ef565b8a5f9650965050505050506116ef565b84156116e05788965094506116ef9350505050565b95508794506116ef9350505050565b94509492505050565b610f018383836001611b2d565b5f805f805f61171487876119f9565b9250925092505f806117268585611a55565b91509150818380156117355750815b9650965050505050509250929050565b80471015611788576040517fcf479181000000000000000000000000000000000000000000000000000000008152476004820152602481018290526044016101d4565b6117a1828260405180602001604052805f815250611b90565b156117aa575050565b3d156117bc576117b8611ba5565b5050565b6040517fd6bda27500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f8181523060209081526040808320815160a0810183528083018581526060808301879052608083018190529082528185015282518581529384018581528484019093529093909291905b86518110156111f95786818151811061185557611855612bff565b602002602001015193505f845f0151604001515111156119c5575f80855f01515f01516001600160a01b031663d04dfe236040518060e00160405280895f0151602001516001600160a01b031681526020018a8152602001895f01516040015181526020015f81526020016118ce8e8b60200151611bb0565b8152602001888152602001878152506040518263ffffffff1660e01b81526004016118f9919061319e565b5f60405180830381865afa158015611913573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261193a9190810190613296565b80519193509150156119c2578551602001516040517f04b19db40000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906304b19db490611994908b908590600401613342565b5f604051808303815f87803b1580156119ab575f80fd5b505af11580156119bd573d5f803e3d5ffd5b505050505b50505b60010161183a565b5f806001600160e01b038416601b0b60e085901d6119ec828287611eab565b9350935050509250929050565b5f808060ff841681037f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861115611a4457600a860460018201600a88065f1493509350935050611a4e565b8593509150600190505b9250925092565b5f601b83900b8314838382611ab9577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e1000000000000000000860515611a9957620186a0860595506005850194505b8586601b0b14611ab457600a86059550846001019450611a99565b611acf565b855f03611acf57505f92506001915061153f9050565b848560030b14611b12575f851215611aef57505f925082915061153f9050565b60405163d556b11160e01b815260048101839052602481018290526044016101d4565b50506001600160e01b03841660e084901b1791509250929050565b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f5114831661160f578383151615611603573d5f823e3d81fd5b5f805f83516020850186885af1949350505050565b6040513d5f823e3d81fd5b60605f825167ffffffffffffffff811115611bcd57611bcd6122c6565b604051908082528060200260200182016040528015611bf6578160200160208202803683370190505b5090505f80845111611c08575f611c0e565b83516001015b85516001010190505f8167ffffffffffffffff811115611c3057611c306122c6565b604051908082528060200260200182016040528015611c6357816020015b6060815260200190600190039081611c4e5790505b5090505f611c87604080516002815233602082015230818301526060810190915290565b828281518110611c9957611c99612bff565b60200260200101819052505f5b8751811015611cf6578180600101925050878181518110611cc957611cc9612bff565b6020026020010151838381518110611ce357611ce3612bff565b6020908102919091010152600101611ca6565b50855115611ea157808060010191505083828281518110611d1957611d19612bff565b60200260200101819052505f5b8651811015611e9f57611dd5878281518110611d4457611d44612bff565b60200260200101515f0151611db2611d808a8581518110611d6757611d67612bff565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f908152601c91909152603c902090565b898481518110611dc457611dc4612bff565b602002602001015160400151611fc0565b611e0e576040517f52bf9848000000000000000000000000000000000000000000000000000000008152600481018290526024016101d4565b868181518110611e2057611e20612bff565b60200260200101515f01516001600160a01b03165f1b858281518110611e4857611e48612bff565b6020026020010181815250508180600101925050868181518110611e6e57611e6e612bff565b602002602001015160200151838381518110611e8c57611e8c612bff565b6020908102919091010152600101611d26565b505b5095945050505050565b5f805f851215611ef1576040517f4a7d166b00000000000000000000000000000000000000000000000000000000815260048101869052602481018590526044016101d4565b845f03611f0357505f9050600161147d565b8460ff8416850185811215611f355760405163d556b11160e01b815260048101889052602481018790526044016101d4565b5f805f831215611f8157604c19831215611f58575f80955095505050505061147d565b825f03600a0a9150818481611f6f57611f6f612c2a565b049550508402909114915061147d9050565b5f831315611fb057611f9483600a613463565b9150611fa0828561346e565b95506001945061147d9350505050565b836001955095505050505061147d565b5f836001600160a01b03163b5f0361201e575f80611fde8585612033565b5090925090505f816003811115611ff757611ff761305c565b1480156120155750856001600160a01b0316826001600160a01b0316145b9250505061202c565b612029848484612079565b90505b9392505050565b5f805f835160410361206a576020840151604085015160608601515f1a61205c888285856120e3565b955095509550505050611a4e565b505081515f9150600290611a4e565b8051604080517f1626ba7e000000000000000000000000000000000000000000000000000000008082526004820186905260248201929092525f92906020820185604483015e60205f60648401838a5afa9050825f5114601f3d1116811693505050509392505050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561211c57505f915060039050826121a1565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa15801561216d573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811661219857505f9250600191508290506121a1565b92505f91508190505b9450945094915050565b5f602082840312156121bb575f80fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461202c575f80fd5b6001600160a01b03811681146121fe575f80fd5b50565b803561220c816121ea565b919050565b5f8083601f840112612221575f80fd5b50813567ffffffffffffffff811115612238575f80fd5b60208301915083602082850101111561153f575f80fd5b5f805f805f8060a08789031215612264575f80fd5b863561226f816121ea565b9550602087013561227f816121ea565b94506040870135935060608701359250608087013567ffffffffffffffff8111156122a8575f80fd5b6122b489828a01612211565b979a9699509497509295939492505050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff811182821017156122fd576122fd6122c6565b60405290565b6040805190810167ffffffffffffffff811182821017156122fd576122fd6122c6565b6040516080810167ffffffffffffffff811182821017156122fd576122fd6122c6565b60405160a0810167ffffffffffffffff811182821017156122fd576122fd6122c6565b60405160c0810167ffffffffffffffff811182821017156122fd576122fd6122c6565b604051601f8201601f1916810167ffffffffffffffff811182821017156123b8576123b86122c6565b604052919050565b5f67ffffffffffffffff8211156123d9576123d96122c6565b5060051b60200190565b80151581146121fe575f80fd5b803561220c816123e3565b5f67ffffffffffffffff821115612414576124146122c6565b50601f01601f191660200190565b5f82601f830112612431575f80fd5b813561244461243f826123fb565b61238f565b818152846020838601011115612458575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60608284031215612484575f80fd5b61248c6122da565b90508135612499816121ea565b815260208201356124a9816121ea565b6020820152604082013567ffffffffffffffff8111156124c7575f80fd5b6124d384828501612422565b60408301525092915050565b5f82601f8301126124ee575f80fd5b813560206124fe61243f836123c0565b82815260069290921b8401810191818101908684111561251c575f80fd5b8286015b848110156125625760408189031215612537575f80fd5b61253f612303565b813561254a816121ea565b81528185013585820152835291830191604001612520565b509695505050505050565b5f82601f83011261257c575f80fd5b8135602061258c61243f836123c0565b82815260059290921b840181019181810190868411156125aa575f80fd5b8286015b8481101561256257803567ffffffffffffffff808211156125cd575f80fd5b908801906060828b03601f190112156125e4575f80fd5b6125ec6122da565b868301356125f9816121ea565b81526040838101358381111561260d575f80fd5b8401603f81018d1361261d575f80fd5b8881013561262d61243f826123c0565b81815260059190911b82018301908a8101908f83111561264b575f80fd5b928401925b828410156126695783358252928b0192908b0190612650565b858c0152505050606084013583811115612681575f80fd5b61268f8d8a83880101612422565b9183019190915250855250509183019183016125ae565b5f82601f8301126126b5575f80fd5b813560206126c561243f836123c0565b82815260059290921b840181019181810190868411156126e3575f80fd5b8286015b8481101561256257803567ffffffffffffffff80821115612706575f80fd5b90880190601f196080838c038201121561271e575f80fd5b612726612326565b8784013583811115612736575f80fd5b840160a0818e0384011215612749575f80fd5b612751612349565b925061275e898201612201565b8352604081013584811115612771575f80fd5b61277f8e8b83850101612474565b8a8501525060608082013585811115612796575f80fd5b6127a48f8c838601016124df565b6040860152506080820135858111156127bb575f80fd5b6127c98f8c838601016124df565b828601525060a0820135608085015283835260408601358a8401528086013560408401526080860135935084841115612800575f80fd5b61280e8e8b8689010161256d565b908301525086525050509183019183016126e7565b5f82601f830112612832575f80fd5b8135602061284261243f836123c0565b82815260059290921b84018101918181019086841115612860575f80fd5b8286015b8481101561256257803567ffffffffffffffff80821115612883575f80fd5b9088019060c0828b03601f190181131561289b575f80fd5b6128a361236c565b8784013581526040808501358983015260608086013582840152608091506128cc8287016123f0565b9083015260a085810135858111156128e2575f80fd5b6128f08f8c838a01016126a6565b8484015250928501359284841115612906575f80fd5b6129148e8b86890101612422565b90830152508652505050918301918301612864565b5f805f805f6080868803121561293d575f80fd5b8535612948816121ea565b9450602086013567ffffffffffffffff80821115612964575f80fd5b61297089838a01612823565b95506040880135915080821115612985575f80fd5b61299189838a01612211565b909550935060608801359150808211156129a9575f80fd5b508601604081890312156129bb575f80fd5b809150509295509295909350565b5f80604083850312156129da575f80fd5b823567ffffffffffffffff808211156129f1575f80fd5b6129fd86838701612823565b93506020850135915080821115612a12575f80fd5b50612a1f85828601612422565b9150509250929050565b5f60408236031215612a39575f80fd5b612a41612303565b823567ffffffffffffffff80821115612a58575f80fd5b612a6436838701612474565b83526020850135915080821115612a79575f80fd5b50612a863682860161256d565b60208301525092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b0380835116845280602084015116602085015250604082015160606040850152612af56060850182612a92565b949350505050565b5f815180845260208085019450602084015f5b83811015612b2c57815187529582019590820190600101612b10565b509495945050505050565b5f82825180855260208086019550808260051b8401018186015f5b84811015612bba57601f19868403018952815160606001600160a01b038251168552858201518187870152612b8982870182612afd565b91505060408083015192508582038187015250612ba68183612a92565b9a86019a9450505090830190600101612b52565b5090979650505050505050565b602081525f825160406020840152612be26060840182612ac0565b90506020840151601f19848303016040850152610ea68282612b37565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215612c23575f80fd5b5051919050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f82612c6c57634e487b7160e01b5f52601260045260245ffd5b500490565b5f815180845260208085019450602084015f5b83811015612b2c57815180516001600160a01b031688528301518388015260409096019590820190600101612c84565b5f60c08301825184526020808401518186015260408085015160408701526060808601511515606088015260808087015160c060808a015285815180885260e0975060e08b01915060e08160051b8c010187840193505f5b82811015612dd1578c820360df190184528451805187845280516001600160a01b0316888501528a81015160a080860152612d4b610120860182612ac0565b90508a820151607f19808784030160c0880152612d688383612c71565b92508b840151915080878403018f88015250612d848282612c71565b915050888201516101008601528b8301518c8601528a8301518b8601528983015192508481038a860152612db88184612b37565b978c0197968c0196945050506001919091019050612d0c565b5060a08b015198508b810360a08d0152612deb818a612a92565b9c9b505050505050505050505050565b5f604082016040835280865180835260608501915060608160051b860101925060208089015f5b83811015612e5057605f19888703018552612e3e868351612cb4565b95509382019390820190600101612e22565b5050858403818701528684528688828601375f848801820152601f909601601f19169092019094019695505050505050565b5f6001600160a01b03808716835280861660208401525083604083015260806060830152612eb36080830184612a92565b9695505050505050565b5f60208284031215612ecd575f80fd5b815161202c816123e3565b602081525f61202c6020830184612cb4565b5f8060408385031215612efb575f80fd5b505080516020909101519092909150565b5f82601f830112612f1b575f80fd5b8151612f2961243f826123fb565b818152846020838601011115612f3d575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f6020808385031215612f6a575f80fd5b825167ffffffffffffffff80821115612f81575f80fd5b818501915085601f830112612f94575f80fd5b8151612fa261243f826123c0565b81815260059190911b83018401908481019088831115612fc0575f80fd5b8585015b8381101561304f57805185811115612fda575f80fd5b86016060818c03601f1901811315612ff0575f80fd5b612ff86122da565b8983015160048110613008575f80fd5b8152604083810151613019816121ea565b828c015291830151918883111561302e575f80fd5b61303c8e8c85870101612f0c565b9082015285525050918601918601612fc4565b5098975050505050505050565b634e487b7160e01b5f52602160045260245ffd5b5f60208284031215613080575f80fd5b815160ff8116811461202c575f80fd5b5f805f606084860312156130a2575f80fd5b83516130ad816121ea565b60208501519093506130be816121ea565b604085015190925067ffffffffffffffff8111156130da575f80fd5b6130e686828701612f0c565b9150509250925092565b5f6001820161310157613101612c3e565b5060010190565b5f6001600160a01b038089168352876020840152808716604084015285606084015280851660808401525060c060a083015261314760c0830184612a92565b98975050505050505050565b5f8282518085526020808601955060208260051b840101602086015f5b84811015612bba57601f1986840301895261318c838351612afd565b98840198925090830190600101613170565b602081526001600160a01b038251166020820152602082015160408201525f604083015160e060608401526131d7610100840182612a92565b9050606084015160808401526080840151601f19808584030160a08601526131ff8383613153565b925060a08601519150808584030160c086015261321c8383612afd565b925060c08601519150808584030160e086015250610ea68282612afd565b5f82601f830112613249575f80fd5b8151602061325961243f836123c0565b8083825260208201915060208460051b87010193508684111561327a575f80fd5b602086015b84811015612562578051835291830191830161327f565b5f80604083850312156132a7575f80fd5b825167ffffffffffffffff808211156132be575f80fd5b818501915085601f8301126132d1575f80fd5b815160206132e161243f836123c0565b82815260059290921b840181019181810190898411156132ff575f80fd5b948201945b8386101561331d57855182529482019490820190613304565b91880151919650909350505080821115613335575f80fd5b50612a1f8582860161323a565b5f604082018483526020604060208501528185518084526060860191506020870193505f5b81811015612bba57845183529383019391830191600101613367565b600181815b808511156133bd57815f19048211156133a3576133a3612c3e565b808516156133b057918102915b93841c9390800290613388565b509250929050565b5f826133d357506001610184565b816133df57505f610184565b81600181146133f557600281146133ff5761341b565b6001915050610184565b60ff84111561341057613410612c3e565b50506001821b610184565b5060208310610133831016604e8410600b841016171561343e575081810a610184565b6134488383613383565b805f190482111561345b5761345b612c3e565b029392505050565b5f61202c83836133c5565b808202811582820484141761018457610184612c3e56","sourceMap":"996:3932:232:-:0;;;1620:1:229;1583:38;;1131:83:232;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1204:6;;2365:1:160;1505:66;2539;1750:29:229;;;;;;1760:10;;1772:6;;1750:29;:::i;:::-;;;;;;;;1794:11;;;;:21;:30;;;:37;:42;1790:119;;1885:11;;;;;1874:23;;;;;;:::i;:::-;;;;-1:-1:-1;;1874:23:229;;;;;;;;;1864:34;;1874:23;1864:34;;;;1852:46;;1790:119;1628:287;2797:79:231;1131:83:232;996:3932;;14:127:238;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:253;218:2;212:9;260:4;248:17;;-1:-1:-1;;;;;280:34:238;;316:22;;;277:62;274:88;;;342:18;;:::i;:::-;378:2;371:22;146:253;:::o;404:257::-;476:4;470:11;;;508:17;;-1:-1:-1;;;;;540:34:238;;576:22;;;537:62;534:88;;;602:18;;:::i;666:275::-;737:2;731:9;802:2;783:13;;-1:-1:-1;;779:27:238;767:40;;-1:-1:-1;;;;;822:34:238;;858:22;;;819:62;816:88;;;884:18;;:::i;:::-;920:2;913:22;666:275;;-1:-1:-1;666:275:238:o;946:131::-;-1:-1:-1;;;;;1021:31:238;;1011:42;;1001:70;;1067:1;1064;1057:12;1001:70;946:131;:::o;1082:527::-;1135:5;1188:3;1181:4;1173:6;1169:17;1165:27;1155:55;;1206:1;1203;1196:12;1155:55;1229:13;;-1:-1:-1;;;;;1254:26:238;;1251:52;;;1283:18;;:::i;:::-;1327:55;1370:2;1351:13;;-1:-1:-1;;1347:27:238;1376:4;1343:38;1327:55;:::i;:::-;1407:2;1398:7;1391:19;1453:3;1446:4;1441:2;1433:6;1429:15;1425:26;1422:35;1419:55;;;1470:1;1467;1460:12;1419:55;1528:2;1521:4;1513:6;1509:17;1502:4;1493:7;1489:18;1483:48;1576:1;1551:16;;;1569:4;1547:27;1540:38;;;;1555:7;1082:527;-1:-1:-1;;;1082:527:238:o;1614:198::-;1689:4;-1:-1:-1;;;;;1711:30:238;;1708:56;;;1744:18;;:::i;:::-;-1:-1:-1;1789:1:238;1785:14;1801:4;1781:25;;1614:198::o;1817:2134::-;1897:5;1950:3;1943:4;1935:6;1931:17;1927:27;1917:55;;1968:1;1965;1958:12;1917:55;1997:6;1991:13;2023:4;2047:75;2063:58;2118:2;2063:58;:::i;:::-;2047:75;:::i;:::-;2156:15;;;2242:1;2238:10;;;;2226:23;;2222:32;;;2187:12;;;;2266:15;;;2263:35;;;2294:1;2291;2284:12;2263:35;2330:2;2322:6;2318:15;2342:1580;2358:6;2353:3;2350:15;2342:1580;;;2431:10;;-1:-1:-1;;;;;2498:19:238;;;2495:39;;;2530:1;2527;2520:12;2495:39;2557:24;;;;2629:4;2605:12;;;-1:-1:-1;;2601:26:238;2597:37;2594:57;;;2647:1;2644;2637:12;2594:57;2677:22;;:::i;:::-;2741:2;2737;2733:11;2727:18;2758:33;2783:7;2758:33;:::i;:::-;2804:22;;2849:2;2886:11;;;2880:18;2914:16;;;2911:36;;;2943:1;2940;2933:12;2911:36;2970:17;;3022:2;3014:11;;3010:21;-1:-1:-1;3000:49:238;;3045:1;3042;3035:12;3000:49;3086:2;3082;3078:11;3072:18;3116:75;3132:58;3187:2;3132:58;:::i;3116:75::-;3235:17;;;3333:1;3329:10;;;;3321:19;;3317:28;;;3274:14;;;;3361:17;;;3358:37;;;3391:1;3388;3381:12;3358:37;3421:11;;;;3445:167;3463:8;3456:5;3453:19;3445:167;;;3545:12;;3531:27;;3484:14;;;;3584;;;;3445:167;;;3632:14;;;3625:29;-1:-1:-1;;;3697:4:238;3689:13;;3683:20;3719:16;;;3716:36;;;3748:1;3745;3738:12;3716:36;3788:60;3844:3;3839:2;3828:8;3824:2;3820:17;3816:26;3788:60;:::i;:::-;3772:14;;;3765:84;;;;-1:-1:-1;3862:18:238;;-1:-1:-1;;3900:12:238;;;;2375;;2342:1580;;;-1:-1:-1;3940:5:238;1817:2134;-1:-1:-1;;;;;;1817:2134:238:o;3956:1916::-;4065:6;4096:2;4139;4127:9;4118:7;4114:23;4110:32;4107:52;;;4155:1;4152;4145:12;4107:52;4182:16;;-1:-1:-1;;;;;4247:14:238;;;4244:34;;;4274:1;4271;4264:12;4244:34;4297:22;;;;4353:4;4335:16;;;4331:27;4328:47;;;4371:1;4368;4361:12;4328:47;4397:22;;:::i;:::-;4449:2;4443:9;4461:33;4486:7;4461:33;:::i;:::-;4503:22;;4556:11;;;4550:18;4580:16;;;4577:36;;;4609:1;4606;4599:12;4577:36;4632:17;;4683:4;4665:16;;;4661:27;4658:47;;;4701:1;4698;4691:12;4658:47;4729:22;;:::i;:::-;4782:2;4776:9;4810:2;4800:8;4797:16;4794:36;;;4826:1;4823;4816:12;4794:36;4849:17;;4900:4;4882:16;;;4878:27;4875:47;;;4918:1;4915;4908:12;4875:47;4946:22;;:::i;:::-;4998:2;4992:9;5010:33;5035:7;5010:33;:::i;:::-;5052:24;;5106:11;;;5100:18;5127:33;5100:18;5127:33;:::i;:::-;5176:16;;;5169:33;5241:4;5233:13;;5227:20;5259:16;;;5256:36;;;5288:1;5285;5278:12;5256:36;5328:55;5375:7;5364:8;5360:2;5356:17;5328:55;:::i;:::-;5321:4;5308:18;;5301:83;-1:-1:-1;5393:24:238;;-1:-1:-1;5448:11:238;;;5442:18;5472:16;;;5469:36;;;5501:1;5498;5491:12;5469:36;5539:82;5613:7;5602:8;5598:2;5594:17;5539:82;:::i;:::-;5534:2;5525:7;5521:16;5514:108;;5654:7;5649:2;5642:5;5638:14;5631:31;;;5701:4;5697:2;5693:13;5687:20;5671:36;;5732:2;5722:8;5719:16;5716:36;;;5748:1;5745;5738:12;5716:36;5786:55;5833:7;5822:8;5818:2;5814:17;5786:55;:::i;:::-;5779:4;5768:16;;5761:81;5772:5;3956:1916;-1:-1:-1;;;;;;3956:1916:238:o;5877:288::-;5918:3;5956:5;5950:12;5983:6;5978:3;5971:19;6039:6;6032:4;6025:5;6021:16;6014:4;6009:3;6005:14;5999:47;6091:1;6084:4;6075:6;6070:3;6066:16;6062:27;6055:38;6154:4;6147:2;6143:7;6138:2;6130:6;6126:15;6122:29;6117:3;6113:39;6109:50;6102:57;;;5877:288;;;;:::o;6170:2005::-;6219:3;6247:4;6286:5;6280:12;6313:4;6308:3;6301:17;6354:1;6350;6345:3;6341:11;6337:19;6413:2;6398:12;6392:19;6388:28;6381:4;6376:3;6372:14;6365:52;6436:4;6495:2;6481:12;6477:21;6471:28;6518:4;6574:2;6558:14;6554:23;6547:4;6542:3;6538:14;6531:47;6633:4;6619:12;6615:23;6609:30;6587:52;;6658:3;6648:13;;6692:4;6686:3;6681;6677:13;6670:27;6719:47;6761:3;6756;6752:13;6736:14;6719:47;:::i;:::-;6803:14;;;6797:21;6848:15;;;6834:12;;;6827:37;6914:21;;6944;;;6706:60;;-1:-1:-1;7076:23:238;;;6983:14;;;;7037:1;7033:14;;;7022:26;;7018:35;;7117:1;7127:1022;7141:6;7138:1;7135:13;7127:1022;;;7208:16;;;-1:-1:-1;;7204:30:238;7190:45;;7258:13;;7341:9;;7337:18;;7324:32;;7397:11;;;7391:18;7429:13;;;7422:25;;;7508:21;;7298:13;;;7542:24;;;7630:23;;;;7677:1;;7588:13;;;;7691:209;7707:8;7702:3;7699:17;7691:209;;;7784:15;;7770:30;;7869:17;;;;7735:1;7726:11;;;;;7826:14;;;;7691:209;;;7695:3;7949:2;7945;7941:11;7935:18;7913:40;;7999:4;7992:5;7988:16;7983:2;7977:4;7973:13;7966:39;8026;8059:5;8043:14;8026:39;:::i;:::-;8018:47;;;;;;8100:2;8092:6;8088:15;8078:25;;8136:2;8129:5;8125:14;8116:23;;7163:1;7160;7156:9;7151:14;;7127:1022;;;-1:-1:-1;8165:4:238;6170:2005;-1:-1:-1;;;;;;;;;;;;6170:2005:238:o;8180:753::-;-1:-1:-1;;;;;8453:15:238;;;8435:34;;8505:2;8500;8485:18;;;8478:30;;;8548:13;;8544:22;;;8524:18;;;8517:50;8602:15;;8596:22;8656:4;8634:20;;;8627:34;8378:4;;8684:59;8415:3;8723:19;;8596:22;8684:59;:::i;:::-;8670:73;;8792:2;8784:6;8780:15;8774:22;8865:2;8861:7;8849:9;8841:6;8837:22;8833:36;8827:3;8816:9;8812:19;8805:65;8887:40;8920:6;8904:14;8887:40;:::i;:::-;8879:48;8180:753;-1:-1:-1;;;;;;8180:753:238:o;8938:257::-;9117:2;9106:9;9099:21;9080:4;9137:52;9185:2;9174:9;9170:18;9162:6;9137:52;:::i;:::-;9129:60;8938:257;-1:-1:-1;;;8938:257:238:o;:::-;996:3932:232;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x60806040526004361061003e575f3560e01c806301ffc9a71461004b57806323e30c8b1461007f57806393be095e146100ac578063c55377d6146100df575b348015610049575f80fd5b005b348015610056575f80fd5b5061006a6100653660046121ab565b6100f2565b60405190151581526020015b60405180910390f35b34801561008a575f80fd5b5061009e61009936600461224f565b61018a565b604051908152602001610076565b3480156100b7575f80fd5b5061009e7f000000000000000000000000000000000000000000000000000000000000000081565b6100496100ed366004612929565b610227565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f23e30c8b00000000000000000000000000000000000000000000000000000000148061018457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f6001600160a01b03871630146101dd576040517f8b1f7c640000000000000000000000000000000000000000000000000000000081526001600160a01b03881660048201526024015b60405180910390fd5b5f806101eb848601866129c9565b915091506101f982826108b1565b507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd998975050505050505050565b61022f610dc7565b61023881612a29565b7f0000000000000000000000000000000000000000000000000000000000000000158015906102ad5750806040516020016102739190612bc7565b604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000014155b156102e4576040517f8812562900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845f815181106102f6576102f6612bff565b602002602001015160800151515f148061032e57508460018151811061031e5761031e612bff565b602002602001015160800151515f145b15610365576040517f9c95219f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516002146103db5760405162461bcd60e51b8152602060048201526024808201527f556e65787065637465642074616b65206f726465727320636f6e666967206c6560448201527f6e6774680000000000000000000000000000000000000000000000000000000060648201526084016101d4565b5f855f815181106103ee576103ee612bff565b6020026020010151608001515f8151811061040b5761040b612bff565b60200260200101515f015160400151865f8151811061042c5761042c612bff565b6020026020010151608001515f8151811061044957610449612bff565b6020026020010151602001518151811061046557610465612bff565b60200260200101515f015190505f8660018151811061048657610486612bff565b6020026020010151608001515f815181106104a3576104a3612bff565b60200260200101515f015160400151876001815181106104c5576104c5612bff565b6020026020010151608001515f815181106104e2576104e2612bff565b602002602001015160200151815181106104fe576104fe612bff565b60200260200101515f015190508660018151811061051e5761051e612bff565b6020026020010151608001515f8151811061053b5761053b612bff565b60200260200101515f0151606001518760018151811061055d5761055d612bff565b6020026020010151608001515f8151811061057a5761057a612bff565b6020026020010151604001518151811061059657610596612bff565b60200260200101515f01516001600160a01b0316826001600160a01b0316146106275760405162461bcd60e51b815260206004820152603660248201527f737461727420616e6420656e64206f726465727320494f20646f204e4f54206360448201527f6c6f73652074686520726f75746520636972637569740000000000000000000060648201526084016101d4565b5f61063183610df5565b90505f61063d83610df5565b6040516370a0823160e01b81526001600160a01b038c811660048301529192505f91600291908716906370a0823190602401602060405180830381865afa15801561068a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106ae9190612c13565b6106b89190612c52565b90505f6106c58285610e8b565b90506106db6001600160a01b0387168d5f610eaf565b6106f06001600160a01b0387168d5f19610eaf565b6107178b5f8151811061070557610705612bff565b60200260200101516020015182610f2e565b1561074057808b5f8151811061072f5761072f612bff565b602002602001015160200181815250505b5f8b5f8151811061075357610753612bff565b602002602001015160600190151590811515815250505f8b8b8b60405160200161077f93929190612dfb565b60408051601f19818403018152908290527f5cffe9de00000000000000000000000000000000000000000000000000000000825291506001600160a01b038e1690635cffe9de906107da9030908b9088908790600401612e82565b6020604051808303815f875af11580156107f6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061081a9190612ebd565b610850576040517f92111eb200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108646001600160a01b0388168e5f610eaf565b6108796108708a612a29565b88878988610f68565b50505050505050506108aa60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5050505050565b5f825f815181106108c4576108c4612bff565b6020026020010151608001515f815181106108e1576108e1612bff565b60200260200101515f015160600151835f8151811061090257610902612bff565b6020026020010151608001515f8151811061091f5761091f612bff565b6020026020010151604001518151811061093b5761093b612bff565b60200260200101515f015190505f80336001600160a01b03166369c72856865f8151811061096b5761096b612bff565b60200260200101516040518263ffffffff1660e01b815260040161098f9190612ed8565b60408051808303815f875af11580156109aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ce9190612eea565b85519193509150829015610bdd575f858060200190518101906109f19190612f59565b90505f5b8151811015610bda575f828281518110610a1157610a11612bff565b6020026020010151905060016003811115610a2e57610a2e61305c565b81516003811115610a4157610a4161305c565b03610a5a57610a51818589611203565b97509350610bd1565b5f81516003811115610a6e57610a6e61305c565b03610ad15760405162461bcd60e51b815260206004820152602d60248201527f7261696e64657820726f757465206c65672074797065206973206e6f7420796560448201526c1d081a5b5c1b195b595b9d1959609a1b60648201526084016101d4565b600281516003811115610ae657610ae661305c565b03610b595760405162461bcd60e51b815260206004820152602e60248201527f62616c616e63657220726f757465206c65672074797065206973206e6f74207960448201527f657420696d706c656d656e74656400000000000000000000000000000000000060648201526084016101d4565b600381516003811115610b6e57610b6e61305c565b03610bd15760405162461bcd60e51b815260206004820152602d60248201527f73746162756c6c20726f757465206c65672074797065206973206e6f7420796560448201526c1d081a5b5c1b195b595b9d1959609a1b60648201526084016101d4565b506001016109f5565b50505b5f86600181518110610bf157610bf1612bff565b6020026020010151608001515f81518110610c0e57610c0e612bff565b60200260200101515f01516040015187600181518110610c3057610c30612bff565b6020026020010151608001515f81518110610c4d57610c4d612bff565b60200260200101516020015181518110610c6957610c69612bff565b6020908102919091010151519050610c8b6001600160a01b038216335f610eaf565b610ca06001600160a01b038216335f19610eaf565b610cc887600181518110610cb657610cb6612bff565b60200260200101516020015183610f2e565b15610cf2578187600181518110610ce157610ce1612bff565b602002602001015160200181815250505b5f87600181518110610d0657610d06612bff565b602002602001015160600190151590811515815250505f80336001600160a01b03166369c728568a600181518110610d4057610d40612bff565b60200260200101516040518263ffffffff1660e01b8152600401610d649190612ed8565b60408051808303815f875af1158015610d7f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da39190612eea565b9092509050610dbc6001600160a01b038416335f610eaf565b505050505050505050565b610dcf611485565b60027f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b6040517f54636d2b0000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201525f9073f66761f6b5f58202998d6cd944c81b22dc6d4f1e906354636d2b906024016020604051808303815f875af1158015610e67573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101849190613070565b5f805f610e9885856114e2565b91509150610ea68282611546565b95945050505050565b610ebb8383835f6115a0565b610f2957610ecc83835f60016115a0565b610ef457604051635274afe760e01b81526001600160a01b03841660048201526024016101d4565b610f0183838360016115a0565b610f2957604051635274afe760e01b81526001600160a01b03841660048201526024016101d4565b505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d610f5c8484848461161b565b12979650505050505050565b6040805160018082528183019092525f91816020015b6060815260200190600190039081610f7e575050604080516003808252608082019092529192505f919060208201606080368337019050506040516370a0823160e01b81523060048201529091505f906001600160a01b038816906370a0823190602401602060405180830381865afa158015610ffd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110219190612c13565b9050801561103d5761103d6001600160a01b03881633836116f8565b5f806110498389611705565b9150915081845f8151811061106057611060612bff565b602090810291909101015250506040516370a0823160e01b81523060048201525f91506001600160a01b038616906370a0823190602401602060405180830381865afa1580156110b2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110d69190612c13565b905080156110f2576110f26001600160a01b03861633836116f8565b5f806110fe8387611705565b91509150818460018151811061111657611116612bff565b60209081029190910101525047915061113190503382611745565b61113d81601119611546565b8260028151811061115057611150612bff565b6020026020010181815250505080825f8151811061117057611170612bff565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160a0810182525f918101828152606080830193909352608082018390528152602081019190915281526020019060019003908161119157905050905087815f815181106111e4576111e4612bff565b60200260200101819052506111f983826117ee565b5050505050505050565b5f805f805f87604001518060200190518101906112209190613090565b925092509250826001600160a01b0316866001600160a01b0316146112875760405162461bcd60e51b815260206004820152600e60248201527f746f6b656e206d69736d6174636800000000000000000000000000000000000060448201526064016101d4565b5f806112f289866001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112c9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112ed9190613070565b6119cd565b915091505f846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611333573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113579190613070565b90505f8061136581846119cd565b915091508061137c5781611378816130f0565b9250505b60208d0151611396906001600160a01b038a16905f610eaf565b60208d01516113b1906001600160a01b038a16905f19610eaf565b60208d01516040517f2646478b0000000000000000000000000000000000000000000000000000000081525f916001600160a01b031690632646478b90611406908c908a908d90899030908f90600401613108565b6020604051808303815f875af1158015611422573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114469190612c13565b60208f0151909150611463906001600160a01b038b16905f610eaf565b5f61146e8286610e8b565b9b509799505050505050505050505b935093915050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00546002036114e0576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f805f805f6114f187876119f9565b92509250925080611538576040517fc471796600000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044016101d4565b5090925090505b9250929050565b5f805f6115538585611a55565b9150915080611598576040517f22c9f7bb00000000000000000000000000000000000000000000000000000000815260048101869052602481018590526044016101d4565b509392505050565b6040517f095ea7b3000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f5114831661160f578383151615611603573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f808515841517818712828612181785841417801561164057868592509250506116ef565b505f85841315611654575092949193919260015b8386035f8112604c8213178015611687578215611679575f89945094505050506116ef565b885f945094505050506116ef565b600a82900a8981028a82828161169f5761169f612c2a565b05146116cb5784156116bb575f8b9650965050505050506116ef565b8a5f9650965050505050506116ef565b84156116e05788965094506116ef9350505050565b95508794506116ef9350505050565b94509492505050565b610f018383836001611b2d565b5f805f805f61171487876119f9565b9250925092505f806117268585611a55565b91509150818380156117355750815b9650965050505050509250929050565b80471015611788576040517fcf479181000000000000000000000000000000000000000000000000000000008152476004820152602481018290526044016101d4565b6117a1828260405180602001604052805f815250611b90565b156117aa575050565b3d156117bc576117b8611ba5565b5050565b6040517fd6bda27500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f8181523060209081526040808320815160a0810183528083018581526060808301879052608083018190529082528185015282518581529384018581528484019093529093909291905b86518110156111f95786818151811061185557611855612bff565b602002602001015193505f845f0151604001515111156119c5575f80855f01515f01516001600160a01b031663d04dfe236040518060e00160405280895f0151602001516001600160a01b031681526020018a8152602001895f01516040015181526020015f81526020016118ce8e8b60200151611bb0565b8152602001888152602001878152506040518263ffffffff1660e01b81526004016118f9919061319e565b5f60405180830381865afa158015611913573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261193a9190810190613296565b80519193509150156119c2578551602001516040517f04b19db40000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906304b19db490611994908b908590600401613342565b5f604051808303815f87803b1580156119ab575f80fd5b505af11580156119bd573d5f803e3d5ffd5b505050505b50505b60010161183a565b5f806001600160e01b038416601b0b60e085901d6119ec828287611eab565b9350935050509250929050565b5f808060ff841681037f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861115611a4457600a860460018201600a88065f1493509350935050611a4e565b8593509150600190505b9250925092565b5f601b83900b8314838382611ab9577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e1000000000000000000860515611a9957620186a0860595506005850194505b8586601b0b14611ab457600a86059550846001019450611a99565b611acf565b855f03611acf57505f92506001915061153f9050565b848560030b14611b12575f851215611aef57505f925082915061153f9050565b60405163d556b11160e01b815260048101839052602481018290526044016101d4565b50506001600160e01b03841660e084901b1791509250929050565b6040517fa9059cbb000000000000000000000000000000000000000000000000000000005f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f5114831661160f578383151615611603573d5f823e3d81fd5b5f805f83516020850186885af1949350505050565b6040513d5f823e3d81fd5b60605f825167ffffffffffffffff811115611bcd57611bcd6122c6565b604051908082528060200260200182016040528015611bf6578160200160208202803683370190505b5090505f80845111611c08575f611c0e565b83516001015b85516001010190505f8167ffffffffffffffff811115611c3057611c306122c6565b604051908082528060200260200182016040528015611c6357816020015b6060815260200190600190039081611c4e5790505b5090505f611c87604080516002815233602082015230818301526060810190915290565b828281518110611c9957611c99612bff565b60200260200101819052505f5b8751811015611cf6578180600101925050878181518110611cc957611cc9612bff565b6020026020010151838381518110611ce357611ce3612bff565b6020908102919091010152600101611ca6565b50855115611ea157808060010191505083828281518110611d1957611d19612bff565b60200260200101819052505f5b8651811015611e9f57611dd5878281518110611d4457611d44612bff565b60200260200101515f0151611db2611d808a8581518110611d6757611d67612bff565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f908152601c91909152603c902090565b898481518110611dc457611dc4612bff565b602002602001015160400151611fc0565b611e0e576040517f52bf9848000000000000000000000000000000000000000000000000000000008152600481018290526024016101d4565b868181518110611e2057611e20612bff565b60200260200101515f01516001600160a01b03165f1b858281518110611e4857611e48612bff565b6020026020010181815250508180600101925050868181518110611e6e57611e6e612bff565b602002602001015160200151838381518110611e8c57611e8c612bff565b6020908102919091010152600101611d26565b505b5095945050505050565b5f805f851215611ef1576040517f4a7d166b00000000000000000000000000000000000000000000000000000000815260048101869052602481018590526044016101d4565b845f03611f0357505f9050600161147d565b8460ff8416850185811215611f355760405163d556b11160e01b815260048101889052602481018790526044016101d4565b5f805f831215611f8157604c19831215611f58575f80955095505050505061147d565b825f03600a0a9150818481611f6f57611f6f612c2a565b049550508402909114915061147d9050565b5f831315611fb057611f9483600a613463565b9150611fa0828561346e565b95506001945061147d9350505050565b836001955095505050505061147d565b5f836001600160a01b03163b5f0361201e575f80611fde8585612033565b5090925090505f816003811115611ff757611ff761305c565b1480156120155750856001600160a01b0316826001600160a01b0316145b9250505061202c565b612029848484612079565b90505b9392505050565b5f805f835160410361206a576020840151604085015160608601515f1a61205c888285856120e3565b955095509550505050611a4e565b505081515f9150600290611a4e565b8051604080517f1626ba7e000000000000000000000000000000000000000000000000000000008082526004820186905260248201929092525f92906020820185604483015e60205f60648401838a5afa9050825f5114601f3d1116811693505050509392505050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561211c57505f915060039050826121a1565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa15801561216d573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811661219857505f9250600191508290506121a1565b92505f91508190505b9450945094915050565b5f602082840312156121bb575f80fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461202c575f80fd5b6001600160a01b03811681146121fe575f80fd5b50565b803561220c816121ea565b919050565b5f8083601f840112612221575f80fd5b50813567ffffffffffffffff811115612238575f80fd5b60208301915083602082850101111561153f575f80fd5b5f805f805f8060a08789031215612264575f80fd5b863561226f816121ea565b9550602087013561227f816121ea565b94506040870135935060608701359250608087013567ffffffffffffffff8111156122a8575f80fd5b6122b489828a01612211565b979a9699509497509295939492505050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff811182821017156122fd576122fd6122c6565b60405290565b6040805190810167ffffffffffffffff811182821017156122fd576122fd6122c6565b6040516080810167ffffffffffffffff811182821017156122fd576122fd6122c6565b60405160a0810167ffffffffffffffff811182821017156122fd576122fd6122c6565b60405160c0810167ffffffffffffffff811182821017156122fd576122fd6122c6565b604051601f8201601f1916810167ffffffffffffffff811182821017156123b8576123b86122c6565b604052919050565b5f67ffffffffffffffff8211156123d9576123d96122c6565b5060051b60200190565b80151581146121fe575f80fd5b803561220c816123e3565b5f67ffffffffffffffff821115612414576124146122c6565b50601f01601f191660200190565b5f82601f830112612431575f80fd5b813561244461243f826123fb565b61238f565b818152846020838601011115612458575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60608284031215612484575f80fd5b61248c6122da565b90508135612499816121ea565b815260208201356124a9816121ea565b6020820152604082013567ffffffffffffffff8111156124c7575f80fd5b6124d384828501612422565b60408301525092915050565b5f82601f8301126124ee575f80fd5b813560206124fe61243f836123c0565b82815260069290921b8401810191818101908684111561251c575f80fd5b8286015b848110156125625760408189031215612537575f80fd5b61253f612303565b813561254a816121ea565b81528185013585820152835291830191604001612520565b509695505050505050565b5f82601f83011261257c575f80fd5b8135602061258c61243f836123c0565b82815260059290921b840181019181810190868411156125aa575f80fd5b8286015b8481101561256257803567ffffffffffffffff808211156125cd575f80fd5b908801906060828b03601f190112156125e4575f80fd5b6125ec6122da565b868301356125f9816121ea565b81526040838101358381111561260d575f80fd5b8401603f81018d1361261d575f80fd5b8881013561262d61243f826123c0565b81815260059190911b82018301908a8101908f83111561264b575f80fd5b928401925b828410156126695783358252928b0192908b0190612650565b858c0152505050606084013583811115612681575f80fd5b61268f8d8a83880101612422565b9183019190915250855250509183019183016125ae565b5f82601f8301126126b5575f80fd5b813560206126c561243f836123c0565b82815260059290921b840181019181810190868411156126e3575f80fd5b8286015b8481101561256257803567ffffffffffffffff80821115612706575f80fd5b90880190601f196080838c038201121561271e575f80fd5b612726612326565b8784013583811115612736575f80fd5b840160a0818e0384011215612749575f80fd5b612751612349565b925061275e898201612201565b8352604081013584811115612771575f80fd5b61277f8e8b83850101612474565b8a8501525060608082013585811115612796575f80fd5b6127a48f8c838601016124df565b6040860152506080820135858111156127bb575f80fd5b6127c98f8c838601016124df565b828601525060a0820135608085015283835260408601358a8401528086013560408401526080860135935084841115612800575f80fd5b61280e8e8b8689010161256d565b908301525086525050509183019183016126e7565b5f82601f830112612832575f80fd5b8135602061284261243f836123c0565b82815260059290921b84018101918181019086841115612860575f80fd5b8286015b8481101561256257803567ffffffffffffffff80821115612883575f80fd5b9088019060c0828b03601f190181131561289b575f80fd5b6128a361236c565b8784013581526040808501358983015260608086013582840152608091506128cc8287016123f0565b9083015260a085810135858111156128e2575f80fd5b6128f08f8c838a01016126a6565b8484015250928501359284841115612906575f80fd5b6129148e8b86890101612422565b90830152508652505050918301918301612864565b5f805f805f6080868803121561293d575f80fd5b8535612948816121ea565b9450602086013567ffffffffffffffff80821115612964575f80fd5b61297089838a01612823565b95506040880135915080821115612985575f80fd5b61299189838a01612211565b909550935060608801359150808211156129a9575f80fd5b508601604081890312156129bb575f80fd5b809150509295509295909350565b5f80604083850312156129da575f80fd5b823567ffffffffffffffff808211156129f1575f80fd5b6129fd86838701612823565b93506020850135915080821115612a12575f80fd5b50612a1f85828601612422565b9150509250929050565b5f60408236031215612a39575f80fd5b612a41612303565b823567ffffffffffffffff80821115612a58575f80fd5b612a6436838701612474565b83526020850135915080821115612a79575f80fd5b50612a863682860161256d565b60208301525092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b0380835116845280602084015116602085015250604082015160606040850152612af56060850182612a92565b949350505050565b5f815180845260208085019450602084015f5b83811015612b2c57815187529582019590820190600101612b10565b509495945050505050565b5f82825180855260208086019550808260051b8401018186015f5b84811015612bba57601f19868403018952815160606001600160a01b038251168552858201518187870152612b8982870182612afd565b91505060408083015192508582038187015250612ba68183612a92565b9a86019a9450505090830190600101612b52565b5090979650505050505050565b602081525f825160406020840152612be26060840182612ac0565b90506020840151601f19848303016040850152610ea68282612b37565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215612c23575f80fd5b5051919050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f82612c6c57634e487b7160e01b5f52601260045260245ffd5b500490565b5f815180845260208085019450602084015f5b83811015612b2c57815180516001600160a01b031688528301518388015260409096019590820190600101612c84565b5f60c08301825184526020808401518186015260408085015160408701526060808601511515606088015260808087015160c060808a015285815180885260e0975060e08b01915060e08160051b8c010187840193505f5b82811015612dd1578c820360df190184528451805187845280516001600160a01b0316888501528a81015160a080860152612d4b610120860182612ac0565b90508a820151607f19808784030160c0880152612d688383612c71565b92508b840151915080878403018f88015250612d848282612c71565b915050888201516101008601528b8301518c8601528a8301518b8601528983015192508481038a860152612db88184612b37565b978c0197968c0196945050506001919091019050612d0c565b5060a08b015198508b810360a08d0152612deb818a612a92565b9c9b505050505050505050505050565b5f604082016040835280865180835260608501915060608160051b860101925060208089015f5b83811015612e5057605f19888703018552612e3e868351612cb4565b95509382019390820190600101612e22565b5050858403818701528684528688828601375f848801820152601f909601601f19169092019094019695505050505050565b5f6001600160a01b03808716835280861660208401525083604083015260806060830152612eb36080830184612a92565b9695505050505050565b5f60208284031215612ecd575f80fd5b815161202c816123e3565b602081525f61202c6020830184612cb4565b5f8060408385031215612efb575f80fd5b505080516020909101519092909150565b5f82601f830112612f1b575f80fd5b8151612f2961243f826123fb565b818152846020838601011115612f3d575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f6020808385031215612f6a575f80fd5b825167ffffffffffffffff80821115612f81575f80fd5b818501915085601f830112612f94575f80fd5b8151612fa261243f826123c0565b81815260059190911b83018401908481019088831115612fc0575f80fd5b8585015b8381101561304f57805185811115612fda575f80fd5b86016060818c03601f1901811315612ff0575f80fd5b612ff86122da565b8983015160048110613008575f80fd5b8152604083810151613019816121ea565b828c015291830151918883111561302e575f80fd5b61303c8e8c85870101612f0c565b9082015285525050918601918601612fc4565b5098975050505050505050565b634e487b7160e01b5f52602160045260245ffd5b5f60208284031215613080575f80fd5b815160ff8116811461202c575f80fd5b5f805f606084860312156130a2575f80fd5b83516130ad816121ea565b60208501519093506130be816121ea565b604085015190925067ffffffffffffffff8111156130da575f80fd5b6130e686828701612f0c565b9150509250925092565b5f6001820161310157613101612c3e565b5060010190565b5f6001600160a01b038089168352876020840152808716604084015285606084015280851660808401525060c060a083015261314760c0830184612a92565b98975050505050505050565b5f8282518085526020808601955060208260051b840101602086015f5b84811015612bba57601f1986840301895261318c838351612afd565b98840198925090830190600101613170565b602081526001600160a01b038251166020820152602082015160408201525f604083015160e060608401526131d7610100840182612a92565b9050606084015160808401526080840151601f19808584030160a08601526131ff8383613153565b925060a08601519150808584030160c086015261321c8383612afd565b925060c08601519150808584030160e086015250610ea68282612afd565b5f82601f830112613249575f80fd5b8151602061325961243f836123c0565b8083825260208201915060208460051b87010193508684111561327a575f80fd5b602086015b84811015612562578051835291830191830161327f565b5f80604083850312156132a7575f80fd5b825167ffffffffffffffff808211156132be575f80fd5b818501915085601f8301126132d1575f80fd5b815160206132e161243f836123c0565b82815260059290921b840181019181810190898411156132ff575f80fd5b948201945b8386101561331d57855182529482019490820190613304565b91880151919650909350505080821115613335575f80fd5b50612a1f8582860161323a565b5f604082018483526020604060208501528185518084526060860191506020870193505f5b81811015612bba57845183529383019391830191600101613367565b600181815b808511156133bd57815f19048211156133a3576133a3612c3e565b808516156133b057918102915b93841c9390800290613388565b509250929050565b5f826133d357506001610184565b816133df57505f610184565b81600181146133f557600281146133ff5761341b565b6001915050610184565b60ff84111561341057613410612c3e565b50506001821b610184565b5060208310610133831016604e8410600b841016171561343e575081810a610184565b6134488383613383565b805f190482111561345b5761345b612c3e565b029392505050565b5f61202c83836133c5565b808202811582820484141761018457610184612c3e56","sourceMap":"996:3932:232:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2910:209:231;;;;;;;;;;-1:-1:-1;2910:209:231;;;;;:::i;:::-;;:::i;:::-;;;516:14:238;;509:22;491:41;;479:2;464:18;2910:209:231;;;;;;;;3835:640;;;;;;;;;;-1:-1:-1;3835:640:231;;;;;:::i;:::-;;:::i;:::-;;;2167:25:238;;;2155:2;2140:18;3835:640:231;2021:177:238;1583:38:229;;;;;;;;;;;;;;;5799:3344:231;;;;;;:::i;:::-;;:::i;2910:209::-;2995:4;3018:54;;;3033:39;3018:54;;:94;;-1:-1:-1;844:25:166;829:40;;;;3076:36:231;3011:101;2910:209;-1:-1:-1;;2910:209:231:o;3835:640::-;3957:7;-1:-1:-1;;;;;4028:26:231;;4049:4;4028:26;4024:87;;4077:23;;;;;-1:-1:-1;;;;;14367:55:238;;4077:23:231;;;14349:74:238;14322:18;;4077:23:231;;;;;;;;4024:87;4122:38;;4203:47;;;;4214:4;4203:47;:::i;:::-;4121:129;;;;4385:35;4395:10;4407:12;4385:9;:35::i;:::-;-1:-1:-1;453:45:221;;3835:640:231;-1:-1:-1;;;;;;;;3835:640:231:o;5799:3344::-;3023:21:160;:19;:21::i;:::-;1921:186:229::1;6010:4:231::0;1921:186:229::1;:::i;:::-;1978:9;:23:::0;;::::1;::::0;:67:::1;;;2039:4;2028:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;2018:27;;;;;;2005:9;:40;;1978:67;1974:116;;;2068:11;;;;;;;;;;;;;;1974:116;6099:10:231::2;6110:1;6099:13;;;;;;;;:::i;:::-;;;;;;;:20;;;:27;6130:1;6099:32;:68;;;;6135:10;6146:1;6135:13;;;;;;;;:::i;:::-;;;;;;;:20;;;:27;6166:1;6135:32;6099:68;6095:129;;;6190:23;;;;;;;;;;;;;;6095:129;6242:10;:17;6263:1;6242:22;6234:71;;;::::0;-1:-1:-1;;;6234:71:231;;18922:2:238;6234:71:231::2;::::0;::::2;18904:21:238::0;18961:2;18941:18;;;18934:30;19000:34;18980:18;;;18973:62;19071:6;19051:18;;;19044:34;19095:19;;6234:71:231::2;18720:400:238::0;6234:71:231::2;6316:33;6352:10;6363:1;6352:13;;;;;;;;:::i;:::-;;;;;;;:20;;;6373:1;6352:23;;;;;;;;:::i;:::-;;;;;;;:29;;;:41;;;6394:10;6405:1;6394:13;;;;;;;;:::i;:::-;;;;;;;:20;;;6415:1;6394:23;;;;;;;;:::i;:::-;;;;;;;:36;;;6352:79;;;;;;;;:::i;:::-;;;;;;;:85;;;6316:121;;6447:31;6481:10;6492:1;6481:13;;;;;;;;:::i;:::-;;;;;;;:20;;;6502:1;6481:23;;;;;;;;:::i;:::-;;;;;;;:29;;;:41;;;6523:10;6534:1;6523:13;;;;;;;;:::i;:::-;;;;;;;:20;;;6544:1;6523:23;;;;;;;;:::i;:::-;;;;;;;:36;;;6481:79;;;;;;;;:::i;:::-;;;;;;;:85;;;6447:119;;6627:10;6638:1;6627:13;;;;;;;;:::i;:::-;;;;;;;:20;;;6648:1;6627:23;;;;;;;;:::i;:::-;;;;;;;:29;;;:42;;;6687:10;6698:1;6687:13;;;;;;;;:::i;:::-;;;;;;;:20;;;6708:1;6687:23;;;;;;;;:::i;:::-;;;;;;;:37;;;6627:111;;;;;;;;:::i;:::-;;;;;;;:117;;;-1:-1:-1::0;;;;;6598:146:231::2;:25;-1:-1:-1::0;;;;;6598:146:231::2;;6577:247;;;::::0;-1:-1:-1;;;6577:247:231;;19327:2:238;6577:247:231::2;::::0;::::2;19309:21:238::0;19366:2;19346:18;;;19339:30;19405:34;19385:18;;;19378:62;19476:24;19456:18;;;19449:52;19518:19;;6577:247:231::2;19125:418:238::0;6577:247:231::2;6835:24;6862:68;6904:25;6862:41;:68::i;:::-;6835:95;;6940:22;6965:66;7007:23;6965:41;:66::i;:::-;8134:63;::::0;-1:-1:-1;;;8134:63:231;;-1:-1:-1;;;;;14367:55:238;;;8134:63:231::2;::::0;::::2;14349:74:238::0;6940:91:231;;-1:-1:-1;8108:23:231::2;::::0;8200:1:::2;::::0;8134:43;;::::2;::::0;::::2;::::0;14322:18:238;;8134:63:231::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:67;;;;:::i;:::-;8108:93;;8211:26;8240:83;8287:15;8304:18;8240:46;:83::i;:::-;8211:112:::0;-1:-1:-1;8334:69:231::2;-1:-1:-1::0;;;;;8334:46:231;::::2;8389:9:::0;8401:1:::2;8334:46;:69::i;:::-;8413:85;-1:-1:-1::0;;;;;8413:46:231;::::2;8468:9:::0;-1:-1:-1;;8413:46:231::2;:85::i;:::-;8513:65;8532:10;8543:1;8532:13;;;;;;;;:::i;:::-;;;;;;;:23;;;8557:20;8513:18;:65::i;:::-;8509:142;;;8620:20;8594:10;8605:1;8594:13;;;;;;;;:::i;:::-;;;;;;;:23;;:46;;;::::0;::::2;8509:142;8686:5;8660:10;8671:1;8660:13;;;;;;;;:::i;:::-;;;;;;;:23;;:31;;;;;;;;;::::0;::::2;8726:17;8757:10;8769:12;;8746:36;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;8746:36:231;;::::2;::::0;;;;;;;8798:75;;;8746:36;-1:-1:-1;;;;;;8798:19:231;::::2;::::0;::::2;::::0;:75:::2;::::0;8818:4:::2;::::0;8824:25;;8851:15;;8746:36;;8798:75:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8793:131;;8896:17;;;;;;;;;;;;;;8793:131;8933:69;-1:-1:-1::0;;;;;8933:46:231;::::2;8988:9:::0;9000:1:::2;8933:46;:69::i;:::-;9013:123;;9041:4:::0;9013:123:::2;:::i;:::-;9047:25;9074:18;9094:23;9119:16;9013:27;:123::i;:::-;6016:3127;;;;;;;3054:1:160::1;3065:20:::0;2365:1;1505:66;3972:62;3749:292;3065:20;5799:3344:231;;;;;:::o;1265:2159:232:-;1388:27;1418:10;1429:1;1418:13;;;;;;;;:::i;:::-;;;;;;;:20;;;1439:1;1418:23;;;;;;;;:::i;:::-;;;;;;;:29;;;:42;;;1461:10;1472:1;1461:13;;;;;;;;:::i;:::-;;;;;;;:20;;;1482:1;1461:23;;;;;;;;:::i;:::-;;;;;;;:37;;;1418:81;;;;;;;;:::i;:::-;;;;;;;:87;;;1388:117;;1516:25;1543:24;1584:10;-1:-1:-1;;;;;1571:36:232;;1608:10;1619:1;1608:13;;;;;;;;:::i;:::-;;;;;;;1571:51;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1725:19;;1515:107;;-1:-1:-1;1515:107:232;-1:-1:-1;1515:107:232;;1725:23;1721:907;;1764:27;1805:12;1794:38;;;;;;;;;;;;:::i;:::-;1764:68;;1852:9;1847:771;1871:9;:16;1867:1;:20;1847:771;;;1912:19;1934:9;1944:1;1934:12;;;;;;;;:::i;:::-;;;;;;;1912:34;;1989:18;1969:38;;;;;;;;:::i;:::-;:16;;:38;;;;;;;;:::i;:::-;;1965:639;;2076:63;2093:3;2098:19;2119;2076:16;:63::i;:::-;2031:108;-1:-1:-1;2031:108:232;-1:-1:-1;1965:639:232;;;2188:20;2168:16;;:40;;;;;;;;:::i;:::-;;2164:440;;2232:55;;-1:-1:-1;;;2232:55:232;;28561:2:238;2232:55:232;;;28543:21:238;28600:2;28580:18;;;28573:30;28639:34;28619:18;;;28612:62;-1:-1:-1;;;28690:18:238;;;28683:43;28743:19;;2232:55:232;28359:409:238;2164:440:232;2336:21;2316:16;;:41;;;;;;;;:::i;:::-;;2312:292;;2381:56;;-1:-1:-1;;;2381:56:232;;28975:2:238;2381:56:232;;;28957:21:238;29014:2;28994:18;;;28987:30;29053:34;29033:18;;;29026:62;29124:16;29104:18;;;29097:44;29158:19;;2381:56:232;28773:410:238;2312:292:232;2486:20;2466:16;;:40;;;;;;;;:::i;:::-;;2462:142;;2530:55;;-1:-1:-1;;;2530:55:232;;29390:2:238;2530:55:232;;;29372:21:238;29429:2;29409:18;;;29402:30;29468:34;29448:18;;;29441:62;-1:-1:-1;;;29519:18:238;;;29512:43;29572:19;;2530:55:232;29188:409:238;2462:142:232;-1:-1:-1;1889:3:232;;1847:771;;;;1750:878;1721:907;2638:31;2672:10;2683:1;2672:13;;;;;;;;:::i;:::-;;;;;;;:20;;;2693:1;2672:23;;;;;;;;:::i;:::-;;;;;;;:29;;;:41;;;2714:10;2725:1;2714:13;;;;;;;;:::i;:::-;;;;;;;:20;;;2735:1;2714:23;;;;;;;;:::i;:::-;;;;;;;:36;;;2672:79;;;;;;;;:::i;:::-;;;;;;;;;;;:85;;-1:-1:-1;2767:59:232;-1:-1:-1;;;;;2767:44:232;;2812:10;2672:85;2767:44;:59::i;:::-;2836:75;-1:-1:-1;;;;;2836:44:232;;2881:10;-1:-1:-1;;2836:44:232;:75::i;:::-;2978:64;2997:10;3008:1;2997:13;;;;;;;;:::i;:::-;;;;;;;:23;;;3022:19;2978:18;:64::i;:::-;2974:140;;;3084:19;3058:10;3069:1;3058:13;;;;;;;;:::i;:::-;;;;;;;:23;;:45;;;;;2974:140;3149:5;3123:10;3134:1;3123:13;;;;;;;;:::i;:::-;;;;;;;:23;;:31;;;;;;;;;;;3190:25;3217:24;3258:10;-1:-1:-1;;;;;3245:36:232;;3282:10;3293:1;3282:13;;;;;;;;:::i;:::-;;;;;;;3245:51;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3189:107;;-1:-1:-1;3189:107:232;-1:-1:-1;3358:59:232;-1:-1:-1;;;;;3358:44:232;;3403:10;3415:1;3358:44;:59::i;:::-;1377:2047;;;;;;;1265:2159;;:::o;3749:292:160:-;3872:25;:23;:25::i;:::-;2407:1;1505:66;3972:62;3749:292::o;1465:146:227:-;1552:52;;;;;-1:-1:-1;;;;;14367:55:238;;1552:52:227;;;14349:74:238;1528:5:227;;1080:42;;1552:45;;14322:18:238;;1552:52:227;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;7453:263:174:-;7547:5;7565:24;7591:15;7610:41;7635:5;7642:8;7610:24;:41::i;:::-;7564:87;;;;7668:41;7681:17;7700:8;7668:12;:41::i;:::-;7661:48;7453:263;-1:-1:-1;;;;;7453:263:174:o;5098:367:151:-;5190:42;5203:5;5210:7;5219:5;5226;5190:12;:42::i;:::-;5185:274;;5253:37;5266:5;5273:7;5282:1;5285:4;5253:12;:37::i;:::-;5248:91;;5299:40;;-1:-1:-1;;;5299:40:151;;-1:-1:-1;;;;;14367:55:238;;5299:40:151;;;14349:74:238;14322:18;;5299:40:151;14203:226:238;5248:91:151;5358:41;5371:5;5378:7;5387:5;5394:4;5358:12;:41::i;:::-;5353:95;;5408:40;;-1:-1:-1;;;5408:40:151;;-1:-1:-1;;;;;14367:55:238;;5408:40:151;;;14349:74:238;14322:18;;5408:40:151;14203:226:238;5353:95:151;5098:367;;;:::o;26445:429:174:-;26498:4;-1:-1:-1;;;;;17672:16:174;;;17668:2;17657:32;;;;17718:4;17714:16;;;;17672;;;17657:32;;;;17714:16;;;26705:106;17657:32;17714:16;17657:32;17714:16;26705:44;:106::i;:::-;-1:-1:-1;;26445:429:174;-1:-1:-1;;;;;;;26445:429:174:o;1049:2082:236:-;1280:18;;;1296:1;1280:18;;;;;;;;;1251:26;;1280:18;;;;;;;;;;;;;;;;;-1:-1:-1;;1331:16:236;;;1345:1;1331:16;;;;;;;;;1251:47;;-1:-1:-1;1308:20:236;;1331:16;;;;;;;;;;;-1:-1:-1;;1455:49:236;;-1:-1:-1;;;1455:49:236;;1498:4;1455:49;;;14349:74:238;1308:39:236;;-1:-1:-1;1432:20:236;;-1:-1:-1;;;;;1455:34:236;;;;;14322:18:238;;1455:49:236;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1432:72;-1:-1:-1;1522:16:236;;1518:118;;1558:63;-1:-1:-1;;;;;1558:37:236;;1596:10;1608:12;1558:37;:63::i;:::-;1650:11;1663:13;1680:72;1724:12;1738:13;1680:43;:72::i;:::-;1649:103;;;;1812:5;1790:3;1794:1;1790:6;;;;;;;;:::i;:::-;;;;;;;;;;:28;-1:-1:-1;;1938:50:236;;-1:-1:-1;;;1938:50:236;;1982:4;1938:50;;;14349:74:238;1914:21:236;;-1:-1:-1;;;;;;1938:35:236;;;;;14322:18:238;;1938:50:236;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1914:74;-1:-1:-1;2006:17:236;;2002:121;;2043:65;-1:-1:-1;;;;;2043:38:236;;2082:10;2094:13;2043:38;:65::i;:::-;2138:12;2152:13;2169:74;2213:13;2228:14;2169:43;:74::i;:::-;2137:106;;;;2303:6;2281:3;2285:1;2281:6;;;;;;;;:::i;:::-;;;;;;;;;;:29;-1:-1:-1;2795:21:236;;-1:-1:-1;2830:50:236;;-1:-1:-1;2856:10:236;2795:21;2830:17;:50::i;:::-;2916:53;2952:10;-1:-1:-1;;2916:28:236;:53::i;:::-;2894:3;2898:1;2894:6;;;;;;;;:::i;:::-;;;;;;:76;;;;;2331:650;3004:3;2991:7;2999:1;2991:10;;;;;;;;:::i;:::-;;;;;;;;;;:16;3041:15;;;3054:1;3041:15;;;;;;;;;3018:20;;3041:15;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3041:15:236;;;;;;;;;;;;;;;3018:38;;3076:4;3066;3071:1;3066:7;;;;;;;;:::i;:::-;;;;;;:14;;;;3090:34;3110:7;3119:4;3090:19;:34::i;:::-;1241:1890;;;1049:2082;;;;;:::o;3477:1392:232:-;3633:5;3640:7;3660:17;3679:15;3696:18;3729:8;:13;;;3718:52;;;;;;;;;;;;:::i;:::-;3659:111;;;;;;3820:9;-1:-1:-1;;;;;3797:32:232;:19;-1:-1:-1;;;;;3797:32:232;;3789:59;;;;-1:-1:-1;;;3789:59:232;;30700:2:238;3789:59:232;;;30682:21:238;30739:2;30719:18;;;30712:30;30778:16;30758:18;;;30751:44;30812:18;;3789:59:232;30498:338:238;3789:59:232;3860:23;3885:24;3925:94;3961:19;3997:9;-1:-1:-1;;;;;3982:34:232;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3925:35;:94::i;:::-;3859:160;;;;4061:21;4100:7;-1:-1:-1;;;;;4085:32:232;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4061:58;-1:-1:-1;4130:21:232;;4170:80;4130:21;4061:58;4170:35;:80::i;:::-;4129:121;;;;4265:8;4260:55;;4289:15;;;;:::i;:::-;;;;4260:55;4356:20;;;;4325:55;;-1:-1:-1;;;;;4325:30:232;;;4378:1;4325:30;:55::i;:::-;4421:20;;;;4390:71;;-1:-1:-1;;;;;4390:30:232;;;-1:-1:-1;;4390:30:232;:71::i;:::-;4507:20;;;;4491:146;;;;;4471:17;;-1:-1:-1;;;;;4491:50:232;;;;:146;;4555:9;;4566:15;;4583:7;;4592:13;;4615:4;;4622:5;;4491:146;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4686:20;;;;4471:166;;-1:-1:-1;4647:64:232;;-1:-1:-1;;;;;4647:30:232;;;4709:1;4647:30;:64::i;:::-;4722:20;4745:74;4792:9;4803:15;4745:46;:74::i;:::-;4722:97;-1:-1:-1;4854:7:232;;-1:-1:-1;;;;;;;;;;3477:1392:232;;;;;;;:::o;3586:157:160:-;1505:66;4560:52;2407:1;4560:63;3644:93;;3696:30;;;;;;;;;;;;;;3644:93;3586:157::o;6755:373:174:-;6843:6;6851;6870:24;6896:15;6913:13;6930:38;6952:5;6959:8;6930:21;:38::i;:::-;6869:99;;;;;;6983:8;6978:98;;7014:51;;;;;;;;31820:25:238;;;31861:18;;;31854:34;;;31793:18;;7014:51:174;31650:244:238;6978:98:174;-1:-1:-1;7093:17:174;;-1:-1:-1;7112:8:174;-1:-1:-1;6755:373:174;;;;;;:::o;16760:299::-;16848:5;16866:7;16875:13;16892:38;16902:17;16921:8;16892:9;:38::i;:::-;16865:65;;;;16945:8;16940:95;;16976:48;;;;;;;;31820:25:238;;;31861:18;;;31854:34;;;31793:18;;16976:48:174;31650:244:238;16940:95:174;-1:-1:-1;17051:1:174;16760:299;-1:-1:-1;;;16760:299:174:o;12059:1252:151:-;12289:4;12283:11;12199:23;12157:12;12307:22;;;-1:-1:-1;;;;;12355:29:151;;12349:4;12342:43;12405:4;12398:19;;;12157:12;12481:4;12157:12;12469:4;12157:12;;12453:5;12446;12441:45;12430:56;;12698:1;12691:4;12685:11;12682:18;12673:7;12669:32;12659:606;;12830:6;12820:7;12813:15;12809:28;12806:165;;;12886:16;12880:4;12875:3;12860:43;12936:16;12931:3;12924:29;12806:165;13247:1;13239:5;13227:18;13224:25;13205:16;13198:24;13194:56;13185:7;13181:70;13170:81;;12659:606;13285:4;13278:17;-1:-1:-1;12059:1252:151;;-1:-1:-1;;;;12059:1252:151:o;46861:2749:175:-;47022:6;;47608:26;;47636;;47605:58;47762:26;;;47790;;;47758:59;47519:328;47934:24;;;47487:497;48019:105;;;;48066:18;48086;48058:47;;;;;;;48019:105;47349:789;48152:12;48202:9;48190;:21;48186:329;;;-1:-1:-1;48301:18:175;;48425:9;;48244:18;;48496:4;48186:329;48551:21;;;48529:19;48677:20;;48717:2;48699:21;;48674:47;48748:210;;;;48787:7;48783:161;;;48826:1;48829:18;48818:30;;;;;;;;;48783:161;48903:18;48923:1;48895:30;;;;;;;;;48783:161;49091:2;:27;;;49151:26;;;:18;49091:27;49151:26;49091:27;49196:16;;;;:::i;:::-;;:38;49192:402;;49258:7;49254:161;;;49297:1;49300:18;49289:30;;;;;;;;;;;49254:161;49374:18;49394:1;49366:30;;;;;;;;;;;49192:402;49439:7;49435:159;;;49474:18;;-1:-1:-1;49494:8:175;-1:-1:-1;49466:37:175;;-1:-1:-1;;;;49466:37:175;49435:159;49550:8;-1:-1:-1;49560:18:175;;-1:-1:-1;49542:37:175;;-1:-1:-1;;;;49542:37:175;46861:2749;;;;;;;;:::o;1219:204:151:-;1306:37;1320:5;1327:2;1331:5;1338:4;1306:13;:37::i;6058:353:174:-;6149:5;6156:4;6173:24;6199:15;6216:13;6233:38;6255:5;6262:8;6233:21;:38::i;:::-;6172:99;;;;;;6282:11;6295:17;6316:38;6326:17;6345:8;6316:9;:38::i;:::-;6281:73;;;;6372:5;6379:8;:24;;;;;6391:12;6379:24;6364:40;;;;;;;;;6058:353;;;;;:::o;1339:506:153:-;1448:6;1424:21;:30;1420:125;;;1477:57;;;;;1504:21;1477:57;;;31820:25:238;31861:18;;;31854:34;;;31793:18;;1477:57:153;31650:244:238;1420:125:153;1558:48;1584:9;1595:6;1558:48;;;;;;;;;;;;:25;:48::i;:::-;1554:285;;;1339:506;;:::o;1554:285::-;4583:16:157;1695:33:153;1691:148;;1744:27;:25;:27::i;:::-;1339:506;;:::o;1691:148::-;1809:19;;;;;;;;;;;;;;4763:1318:235;4911:10;4848:24;1232:25:215;;;5028:4:235;1277::215;1270:20;;;1338:4;1325:18;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5104:18:235;;;;;;;;5169:16;;;;;;;;;1325:18:215;;-1:-1:-1;;5104:18:235;;5195:880;5219:4;:11;5215:1;:15;5195:880;;;5258:4;5263:1;5258:7;;;;;;;;:::i;:::-;;;;;;;5251:14;;5316:1;5283:4;:14;;;:23;;;:30;:34;5279:786;;;5338:24;5364:23;5391:4;:14;;;:26;;;-1:-1:-1;;;;;5391:32:235;;5445:438;;;;;;;;5485:4;:14;;;:20;;;-1:-1:-1;;;;;5445:438:235;;;;;5542:18;5445:438;;;;5596:4;:14;;;:23;;;5445:438;;;;5677:1;5445:438;;;;5714:45;5731:7;5740:4;:18;;;5714:16;:45::i;:::-;5445:438;;;;5793:10;5445:438;;;;5843:17;5445:438;;;5391:510;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5391:510:235;;;;;;;;;;;;:::i;:::-;5948:13;;5337:564;;-1:-1:-1;5337:564:235;-1:-1:-1;5948:17:235;5944:107;;5989:14;;:20;;;:43;;;;;-1:-1:-1;;;;;5989:24:235;;;;;;:43;;6014:9;;6025:6;;5989:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5944:107;5319:746;;5279:786;5232:3;;5195:880;;12173:248:174;12254:7;;-1:-1:-1;;;;;17672:16:174;;17668:2;17657:32;17718:4;17714:16;;;12356:58;17657:32;17714:16;12405:8;12356:19;:58::i;:::-;12349:65;;;;;;12173:248;;;;;:::o;4678:800::-;4763:6;;;4845:17;;;4837:26;;5010:16;4994:33;;4990:472;;;5207:2;5199:5;:10;5223:1;5212:12;;5234:2;5226:5;:10;5240:1;5226:15;5184:58;;;;;;;;;4990:472;5424:5;;-1:-1:-1;5432:8:174;-1:-1:-1;5442:4:174;;-1:-1:-1;4678:800:174;;;;;;:::o;14352:2402::-;14437:11;14869:46;;;;;;14533:17;14589:8;14869:46;15193:668;;15250:4;15230:17;:24;:29;15226:135;;15304:3;15283:24;;;;15341:1;15329:13;;;;15226:135;15600:17;15578;15571:46;;;15564:151;;15662:2;15641:23;;;;15686:10;;;;;15564:151;;;15193:668;;;15757:17;15778:1;15757:22;15753:94;;-1:-1:-1;2277:1:174;;-1:-1:-1;15823:4:174;;-1:-1:-1;15803:25:174;;-1:-1:-1;15803:25:174;15753:94;16071:8;16058;16052:27;;;16048:393;;16273:1;16262:8;:12;16258:85;;;-1:-1:-1;2277:1:174;;-1:-1:-1;2277:1:174;;-1:-1:-1;16298:26:174;;-1:-1:-1;16298:26:174;16258:85;16367:59;;-1:-1:-1;;;16367:59:174;;;;;31820:25:238;;;31861:18;;;31854:34;;;31793:18;;16367:59:174;31650:244:238;16048:393:174;-1:-1:-1;;;;;;;16674:28:174;;16708:4;16704:19;;;16671:53;;-1:-1:-1;14352:2402:174;;;;;:::o;8373:1244:151:-;8600:4;8594:11;8509:24;8467:12;8618:22;;;-1:-1:-1;;;;;8666:24:151;;8660:4;8653:38;8711:4;8704:19;;;8467:12;8787:4;8467:12;8775:4;8467:12;;8759:5;8752;8747:45;8736:56;;9004:1;8997:4;8991:11;8988:18;8979:7;8975:32;8965:606;;9136:6;9126:7;9119:15;9115:28;9112:165;;;9192:16;9186:4;9181:3;9166:43;9242:16;9237:3;9230:29;791:248:157;881:12;1018:4;1012;1005;999:11;992:4;986;982:15;975:5;967:6;960:5;955:68;944:79;791:248;-1:-1:-1;;;;791:248:157:o;5099:223::-;5203:4;5197:11;5247:16;5241:4;5236:3;5221:43;5289:16;5284:3;5277:29;7835:2310:212;7970:18;8028:24;8069:14;:21;8055:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8055:36:212;;8028:63;;8240:21;8314:1;8290:14;:21;:25;:57;;8346:1;8290:57;;;8318:14;:21;8342:1;8318:25;8290:57;8268:11;:18;8264:1;:22;:84;8240:108;;8363:26;8408:13;8392:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8363:59;;8436:14;8486:17;2806:4;2800:11;;2842:1;2824:20;;2886:8;2879:4;2864:20;;2857:38;2937:9;2915:20;;;2908:39;2710:26;2973:20;;2960:34;;;2800:11;2671:339;8486:17;8468:7;8476:6;8468:15;;;;;;;;:::i;:::-;;;;;;:35;;;;8523:9;8518:140;8542:11;:18;8538:1;:22;8518:140;;;8585:8;;;;;;;8629:11;8641:1;8629:14;;;;;;;;:::i;:::-;;;;;;;8611:7;8619:6;8611:15;;;;;;;;:::i;:::-;;;;;;;;;;:32;8562:3;;8518:140;;;-1:-1:-1;8676:21:212;;:25;8672:1428;;8721:8;;;;;;;8765:7;8747;8755:6;8747:15;;;;;;;;:::i;:::-;;;;;;:25;;;;8796:9;8791:1295;8815:14;:21;8811:1;:25;8791:1295;;;9493:295;9559:14;9574:1;9559:17;;;;;;;;:::i;:::-;;;;;;;:24;;;9613:92;9653:51;9678:14;9693:1;9678:17;;;;;;;;:::i;:::-;;;;;;;:25;;;3956:13:20;;3971:4;3952:24;;;3933:17;;3923:54;;3783:210;9653:51:212;1401:34:164;1323:14;1388:48;;;1497:4;1490:25;;;;1595:4;1579:21;;;1247:433;9613:92:212;9735:14;9750:1;9735:17;;;;;;;;:::i;:::-;;;;;;;:27;;;9493:36;:295::i;:::-;8865:1021;;9844:19;;;;;;;;2167:25:238;;;2140:18;;9844:19:212;2021:177:238;8865:1021:212;9945:14;9960:1;9945:17;;;;;;;;:::i;:::-;;;;;;;:24;;;-1:-1:-1;;;;;9929:42:212;9921:51;;9908:7;9916:1;9908:10;;;;;;;;:::i;:::-;;;;;;:64;;;;;9994:8;;;;;;;10042:14;10057:1;10042:17;;;;;;;;:::i;:::-;;;;;;;:25;;;10024:7;10032:6;10024:15;;;;;;;;:::i;:::-;;;;;;;;;;:43;8838:3;;8791:1295;;;;8672:1428;-1:-1:-1;10121:7:212;7835:2310;-1:-1:-1;;;;;7835:2310:212:o;8561:3045:174:-;8696:7;8705:4;8828:1;8808:17;:21;8804:2796;;;8852:59;;;;;;;;31820:25:238;;;31861:18;;;31854:34;;;31793:18;;8852:59:174;31650:244:238;8804:2796:174;9010:17;9031:1;9010:22;9006:2594;;-1:-1:-1;9056:1:174;;-1:-1:-1;9059:4:174;9048:16;;9006:2594;9274:17;9555;;;9537:36;;9595:24;;;9591:123;;;9650:45;;-1:-1:-1;;;9650:45:174;;;;;31820:25:238;;;31861:18;;;31854:34;;;31793:18;;9650:45:174;31650:244:238;9591:123:174;9742:13;9769:20;9823:1;9807:13;:17;9803:1787;;;-1:-1:-1;;10085:13:174;:19;10081:91;;;10140:1;10143:5;10132:17;;;;;;;;;;10081:91;10532:13;10531:14;;10517:2;:29;10509:37;;10605:5;10583:19;:27;;;;;:::i;:::-;;;-1:-1:-1;;10868:20:174;;:43;;;;-1:-1:-1;10846:66:174;;-1:-1:-1;10846:66:174;9803:1787;10971:1;10955:13;:17;10951:639;;;11117:28;11131:13;11117:2;:28;:::i;:::-;11109:36;-1:-1:-1;11178:27:174;11109:36;11178:19;:27;:::i;:::-;11163:42;-1:-1:-1;11479:4:174;;-1:-1:-1;11457:27:174;;-1:-1:-1;;;;11457:27:174;10951:639;11549:19;11570:4;11541:34;;;;;;;;;;1485:429:165;1591:4;1611:6;-1:-1:-1;;;;;1611:18:165;;1633:1;1611:23;1607:301;;1651:17;1670:22;1698:33;1715:4;1721:9;1698:16;:33::i;:::-;-1:-1:-1;1650:81:165;;-1:-1:-1;1650:81:165;-1:-1:-1;1759:26:165;1752:3;:33;;;;;;;;:::i;:::-;;:56;;;;;1802:6;-1:-1:-1;;;;;1789:19:165;:9;-1:-1:-1;;;;;1789:19:165;;1752:56;1745:63;;;;;;1607:301;1846:51;1873:6;1881:4;1887:9;1846:26;:51::i;:::-;1839:58;;1607:301;1485:429;;;;;:::o;2433:778:163:-;2536:17;2555:16;2573:14;2603:9;:16;2623:2;2603:22;2599:606;;2908:4;2893:20;;2887:27;2957:4;2942:20;;2936:27;3014:4;2999:20;;2993:27;2641:9;2985:36;3055:25;3066:4;2985:36;2887:27;2936;3055:10;:25::i;:::-;3048:32;;;;;;;;;;;2599:606;-1:-1:-1;;3176:16:163;;3127:1;;-1:-1:-1;3131:35:163;;3111:83;;2900:986:165;3145:16;;3500:4;3494:11;;3084:34;3518:21;;;3568:4;3559:14;;3552:28;;;3609:4;3600:14;;3593:28;;;;3043:11;;3145:16;3679:4;3667:17;;3145:9;3649:4;3640:14;;3634:51;3770:4;3764;3757;3749:6;3745:17;3740:3;3732:6;3725:5;3714:61;3699:76;;3859:8;3852:4;3846:11;3843:25;3836:4;3818:16;3815:26;3811:58;3802:7;3798:72;3788:82;;;3197:683;;2900:986;;;;;:::o;7142:1551:163:-;7268:17;;;8222:66;8209:79;;8205:164;;;-1:-1:-1;8320:1:163;;-1:-1:-1;8324:30:163;;-1:-1:-1;8356:1:163;8304:54;;8205:164;8480:24;;;8463:14;8480:24;;;;;;;;;39039:25:238;;;39112:4;39100:17;;39080:18;;;39073:45;;;;39134:18;;;39127:34;;;39177:18;;;39170:34;;;8480:24:163;;39011:19:238;;8480:24:163;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;8480:24:163;;-1:-1:-1;;8480:24:163;;;-1:-1:-1;;;;;;;8518:20:163;;8514:113;;-1:-1:-1;8570:1:163;;-1:-1:-1;8574:29:163;;-1:-1:-1;8570:1:163;;-1:-1:-1;8554:62:163;;8514:113;8645:6;-1:-1:-1;8653:20:163;;-1:-1:-1;8653:20:163;;-1:-1:-1;7142:1551:163;;;;;;;;;:::o;14:332:238:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;543:154;-1:-1:-1;;;;;622:5:238;618:54;611:5;608:65;598:93;;687:1;684;677:12;598:93;543:154;:::o;702:134::-;770:20;;799:31;770:20;799:31;:::i;:::-;702:134;;;:::o;841:347::-;892:8;902:6;956:3;949:4;941:6;937:17;933:27;923:55;;974:1;971;964:12;923:55;-1:-1:-1;997:20:238;;1040:18;1029:30;;1026:50;;;1072:1;1069;1062:12;1026:50;1109:4;1101:6;1097:17;1085:29;;1161:3;1154:4;1145:6;1137;1133:19;1129:30;1126:39;1123:59;;;1178:1;1175;1168:12;1193:823;1299:6;1307;1315;1323;1331;1339;1392:3;1380:9;1371:7;1367:23;1363:33;1360:53;;;1409:1;1406;1399:12;1360:53;1448:9;1435:23;1467:31;1492:5;1467:31;:::i;:::-;1517:5;-1:-1:-1;1574:2:238;1559:18;;1546:32;1587:33;1546:32;1587:33;:::i;:::-;1639:7;-1:-1:-1;1693:2:238;1678:18;;1665:32;;-1:-1:-1;1744:2:238;1729:18;;1716:32;;-1:-1:-1;1799:3:238;1784:19;;1771:33;1827:18;1816:30;;1813:50;;;1859:1;1856;1849:12;1813:50;1898:58;1948:7;1939:6;1928:9;1924:22;1898:58;:::i;:::-;1193:823;;;;-1:-1:-1;1193:823:238;;-1:-1:-1;1193:823:238;;1975:8;;1193:823;-1:-1:-1;;;1193:823:238:o;2203:184::-;-1:-1:-1;;;2252:1:238;2245:88;2352:4;2349:1;2342:15;2376:4;2373:1;2366:15;2392:253;2464:2;2458:9;2506:4;2494:17;;2541:18;2526:34;;2562:22;;;2523:62;2520:88;;;2588:18;;:::i;:::-;2624:2;2617:22;2392:253;:::o;2650:257::-;2722:4;2716:11;;;2754:17;;2801:18;2786:34;;2822:22;;;2783:62;2780:88;;;2848:18;;:::i;2912:253::-;2984:2;2978:9;3026:4;3014:17;;3061:18;3046:34;;3082:22;;;3043:62;3040:88;;;3108:18;;:::i;3170:253::-;3242:2;3236:9;3284:4;3272:17;;3319:18;3304:34;;3340:22;;;3301:62;3298:88;;;3366:18;;:::i;3428:253::-;3500:2;3494:9;3542:4;3530:17;;3577:18;3562:34;;3598:22;;;3559:62;3556:88;;;3624:18;;:::i;3686:275::-;3757:2;3751:9;3822:2;3803:13;;-1:-1:-1;;3799:27:238;3787:40;;3857:18;3842:34;;3878:22;;;3839:62;3836:88;;;3904:18;;:::i;:::-;3940:2;3933:22;3686:275;;-1:-1:-1;3686:275:238:o;3966:201::-;4044:4;4077:18;4069:6;4066:30;4063:56;;;4099:18;;:::i;:::-;-1:-1:-1;4144:1:238;4140:14;4156:4;4136:25;;3966:201::o;4172:118::-;4258:5;4251:13;4244:21;4237:5;4234:32;4224:60;;4280:1;4277;4270:12;4295:128;4360:20;;4389:28;4360:20;4389:28;:::i;4428:186::-;4476:4;4509:18;4501:6;4498:30;4495:56;;;4531:18;;:::i;:::-;-1:-1:-1;4597:2:238;4576:15;-1:-1:-1;;4572:29:238;4603:4;4568:40;;4428:186::o;4619:462::-;4661:5;4714:3;4707:4;4699:6;4695:17;4691:27;4681:55;;4732:1;4729;4722:12;4681:55;4768:6;4755:20;4799:48;4815:31;4843:2;4815:31;:::i;:::-;4799:48;:::i;:::-;4872:2;4863:7;4856:19;4918:3;4911:4;4906:2;4898:6;4894:15;4890:26;4887:35;4884:55;;;4935:1;4932;4925:12;4884:55;5000:2;4993:4;4985:6;4981:17;4974:4;4965:7;4961:18;4948:55;5048:1;5023:16;;;5041:4;5019:27;5012:38;;;;5027:7;4619:462;-1:-1:-1;;;4619:462:238:o;5086:624::-;5144:5;5192:4;5180:9;5175:3;5171:19;5167:30;5164:50;;;5210:1;5207;5200:12;5164:50;5232:22;;:::i;:::-;5223:31;;5291:9;5278:23;5310:33;5335:7;5310:33;:::i;:::-;5352:22;;5426:2;5411:18;;5398:32;5439:33;5398:32;5439:33;:::i;:::-;5499:2;5488:14;;5481:31;5563:2;5548:18;;5535:32;5590:18;5579:30;;5576:50;;;5622:1;5619;5612:12;5576:50;5658:45;5699:3;5690:6;5679:9;5675:22;5658:45;:::i;:::-;5653:2;5646:5;5642:14;5635:69;;5086:624;;;;:::o;5715:968::-;5773:5;5826:3;5819:4;5811:6;5807:17;5803:27;5793:55;;5844:1;5841;5834:12;5793:55;5880:6;5867:20;5906:4;5930:78;5946:61;6004:2;5946:61;:::i;5930:78::-;6042:15;;;6128:1;6124:10;;;;6112:23;;6108:32;;;6073:12;;;;6152:15;;;6149:35;;;6180:1;6177;6170:12;6149:35;6216:2;6208:6;6204:15;6228:426;6244:6;6239:3;6236:15;6228:426;;;6322:4;6316:3;6311;6307:13;6303:24;6300:44;;;6340:1;6337;6330:12;6300:44;6370:22;;:::i;:::-;6433:3;6420:17;6450:33;6475:7;6450:33;:::i;:::-;6496:22;;6567:12;;;6554:26;6538:14;;;6531:50;6594:18;;6632:12;;;;6270:4;6261:14;6228:426;;;-1:-1:-1;6672:5:238;5715:968;-1:-1:-1;;;;;;5715:968:238:o;6688:2167::-;6757:5;6810:3;6803:4;6795:6;6791:17;6787:27;6777:55;;6828:1;6825;6818:12;6777:55;6864:6;6851:20;6890:4;6914:78;6930:61;6988:2;6930:61;:::i;6914:78::-;7026:15;;;7112:1;7108:10;;;;7096:23;;7092:32;;;7057:12;;;;7136:15;;;7133:35;;;7164:1;7161;7154:12;7133:35;7200:2;7192:6;7188:15;7212:1614;7228:6;7223:3;7220:15;7212:1614;;;7314:3;7301:17;7341:18;7391:2;7378:11;7375:19;7372:39;;;7407:1;7404;7397:12;7372:39;7434:24;;;;7506:4;7482:12;;;-1:-1:-1;;7478:26:238;7474:37;7471:57;;;7524:1;7521;7514:12;7471:57;7554:22;;:::i;:::-;7625:2;7621;7617:11;7604:25;7642:33;7667:7;7642:33;:::i;:::-;7688:22;;7733:2;7777:11;;;7764:25;7805:16;;;7802:36;;;7834:1;7831;7824:12;7802:36;7861:17;;7913:2;7905:11;;7901:21;-1:-1:-1;7891:49:238;;7936:1;7933;7926:12;7891:49;7984:2;7980;7976:11;7963:25;8014:78;8030:61;8088:2;8030:61;:::i;8014:78::-;8136:17;;;8234:1;8230:10;;;;8222:19;;8218:28;;;8175:14;;;;8262:17;;;8259:37;;;8292:1;8289;8282:12;8259:37;8322:11;;;;8346:174;8364:8;8357:5;8354:19;8346:174;;;8446:19;;8432:34;;8385:14;;;;8492;;;;8346:174;;;8540:14;;;8533:29;-1:-1:-1;;;8612:4:238;8604:13;;8591:27;8634:16;;;8631:36;;;8663:1;8660;8653:12;8631:36;8703:49;8748:3;8743:2;8732:8;8728:2;8724:17;8720:26;8703:49;:::i;:::-;8687:14;;;8680:73;;;;-1:-1:-1;8766:18:238;;-1:-1:-1;;8804:12:238;;;;7245;;7212:1614;;8860:2426;8931:5;8984:3;8977:4;8969:6;8965:17;8961:27;8951:55;;9002:1;8999;8992:12;8951:55;9038:6;9025:20;9064:4;9088:78;9104:61;9162:2;9104:61;:::i;9088:78::-;9200:15;;;9286:1;9282:10;;;;9270:23;;9266:32;;;9231:12;;;;9310:15;;;9307:35;;;9338:1;9335;9328:12;9307:35;9374:2;9366:6;9362:15;9386:1871;9402:6;9397:3;9394:15;9386:1871;;;9488:3;9475:17;9515:18;9565:2;9552:11;9549:19;9546:39;;;9581:1;9578;9571:12;9546:39;9608:24;;;;-1:-1:-1;;9705:4:238;9686:12;;;9682:21;;9678:32;9675:52;;;9723:1;9720;9713:12;9675:52;9753:22;;:::i;:::-;9825:2;9821;9817:11;9804:25;9858:2;9848:8;9845:16;9842:36;;;9874:1;9871;9864:12;9842:36;9901:17;;9961:4;9942:12;;;9938:21;;9934:32;9931:52;;;9979:1;9976;9969:12;9931:52;10011:22;;:::i;:::-;9996:37;;10062:31;10089:2;10085;10081:11;10062:31;:::i;:::-;10053:7;10046:48;10144:2;10140;10136:11;10123:25;10177:2;10167:8;10164:16;10161:36;;;10193:1;10190;10183:12;10161:36;10235:62;10293:3;10288:2;10277:8;10273:2;10269:17;10265:26;10235:62;:::i;:::-;10230:2;10221:7;10217:16;10210:88;;10321:2;10373;10369;10365:11;10352:25;10406:2;10396:8;10393:16;10390:36;;;10422:1;10419;10412:12;10390:36;10464:65;10525:3;10520:2;10509:8;10505:2;10501:17;10497:26;10464:65;:::i;:::-;10459:2;10450:7;10446:16;10439:91;;10580:4;10576:2;10572:13;10559:27;10615:2;10605:8;10602:16;10599:36;;;10631:1;10628;10621:12;10599:36;10673:65;10734:3;10729:2;10718:8;10714:2;10710:17;10706:26;10673:65;:::i;:::-;10668:2;10659:7;10655:16;10648:91;;10800:4;10796:2;10792:13;10779:27;10772:4;10763:7;10759:18;10752:55;10834:7;10827:5;10820:22;10899:2;10895;10891:11;10878:25;10873:2;10866:5;10862:14;10855:49;10961:2;10957;10953:11;10940:25;10935:2;10928:5;10924:14;10917:49;11016:4;11012:2;11008:13;10995:27;10979:43;;11051:2;11041:8;11038:16;11035:36;;;11067:1;11064;11057:12;11035:36;11107:76;11179:3;11174:2;11163:8;11159:2;11155:17;11151:26;11107:76;:::i;:::-;11091:14;;;11084:100;-1:-1:-1;11197:18:238;;-1:-1:-1;;;11235:12:238;;;;9419;;9386:1871;;11291:1769;11363:5;11416:3;11409:4;11401:6;11397:17;11393:27;11383:55;;11434:1;11431;11424:12;11383:55;11470:6;11457:20;11496:4;11520:78;11536:61;11594:2;11536:61;:::i;11520:78::-;11632:15;;;11718:1;11714:10;;;;11702:23;;11698:32;;;11663:12;;;;11742:15;;;11739:35;;;11770:1;11767;11760:12;11739:35;11806:2;11798:6;11794:15;11818:1213;11834:6;11829:3;11826:15;11818:1213;;;11920:3;11907:17;11947:18;11997:2;11984:11;11981:19;11978:39;;;12013:1;12010;12003:12;11978:39;12040:24;;;;12087:4;12115:12;;;-1:-1:-1;;12111:26:238;12107:35;-1:-1:-1;12104:55:238;;;12155:1;12152;12145:12;12104:55;12185:22;;:::i;:::-;12255:2;12251;12247:11;12234:25;12227:5;12220:40;12283:2;12342;12338;12334:11;12321:25;12316:2;12309:5;12305:14;12298:49;12370:2;12429;12425;12421:11;12408:25;12403:2;12396:5;12392:14;12385:49;12457:3;12447:13;;12496:28;12520:2;12516;12512:11;12496:28;:::i;:::-;12480:14;;;12473:52;12548:3;12593:11;;;12580:25;12621:16;;;12618:36;;;12650:1;12647;12640:12;12618:36;12690:78;12764:3;12759:2;12748:8;12744:2;12740:17;12736:26;12690:78;:::i;:::-;12674:14;;;12667:102;-1:-1:-1;12811:11:238;;;12798:25;;12839:16;;;12836:36;;;12868:1;12865;12858:12;12836:36;12908:49;12953:3;12948:2;12937:8;12933:2;12929:17;12925:26;12908:49;:::i;:::-;12892:14;;;12885:73;-1:-1:-1;12971:18:238;;-1:-1:-1;;;13009:12:238;;;;11851;;11818:1213;;13065:1133;13273:6;13281;13289;13297;13305;13358:3;13346:9;13337:7;13333:23;13329:33;13326:53;;;13375:1;13372;13365:12;13326:53;13414:9;13401:23;13433:31;13458:5;13433:31;:::i;:::-;13483:5;-1:-1:-1;13539:2:238;13524:18;;13511:32;13562:18;13592:14;;;13589:34;;;13619:1;13616;13609:12;13589:34;13642:79;13713:7;13704:6;13693:9;13689:22;13642:79;:::i;:::-;13632:89;;13774:2;13763:9;13759:18;13746:32;13730:48;;13803:2;13793:8;13790:16;13787:36;;;13819:1;13816;13809:12;13787:36;13858:60;13910:7;13899:8;13888:9;13884:24;13858:60;:::i;:::-;13937:8;;-1:-1:-1;13832:86:238;-1:-1:-1;14025:2:238;14010:18;;13997:32;;-1:-1:-1;14041:16:238;;;14038:36;;;14070:1;14067;14060:12;14038:36;-1:-1:-1;14093:24:238;;14151:2;14133:16;;;14129:25;14126:45;;;14167:1;14164;14157:12;14126:45;14190:2;14180:12;;;13065:1133;;;;;;;;:::o;14434:622::-;14573:6;14581;14634:2;14622:9;14613:7;14609:23;14605:32;14602:52;;;14650:1;14647;14640:12;14602:52;14690:9;14677:23;14719:18;14760:2;14752:6;14749:14;14746:34;;;14776:1;14773;14766:12;14746:34;14799:79;14870:7;14861:6;14850:9;14846:22;14799:79;:::i;:::-;14789:89;;14931:2;14920:9;14916:18;14903:32;14887:48;;14960:2;14950:8;14947:16;14944:36;;;14976:1;14973;14966:12;14944:36;;14999:51;15042:7;15031:8;15020:9;15016:24;14999:51;:::i;:::-;14989:61;;;14434:622;;;;;:::o;15061:691::-;15163:9;15222:4;15214:5;15198:14;15194:26;15190:37;15187:57;;;15240:1;15237;15230:12;15187:57;15268:22;;:::i;:::-;15326:5;15313:19;15351:18;15392:2;15384:6;15381:14;15378:34;;;15408:1;15405;15398:12;15378:34;15437:65;15487:14;15478:6;15471:5;15467:18;15437:65;:::i;:::-;15428:7;15421:82;15552:2;15545:5;15541:14;15528:28;15512:44;;15581:2;15571:8;15568:16;15565:36;;;15597:1;15594;15587:12;15565:36;;15635:81;15701:14;15690:8;15683:5;15679:20;15635:81;:::i;:::-;15630:2;15617:16;;15610:107;-1:-1:-1;15621:7:238;15061:691;-1:-1:-1;;15061:691:238:o;15757:288::-;15798:3;15836:5;15830:12;15863:6;15858:3;15851:19;15919:6;15912:4;15905:5;15901:16;15894:4;15889:3;15885:14;15879:47;15971:1;15964:4;15955:6;15950:3;15946:16;15942:27;15935:38;16034:4;16027:2;16023:7;16018:2;16010:6;16006:15;16002:29;15997:3;15993:39;15989:50;15982:57;;;15757:288;;;;:::o;16050:389::-;16104:3;-1:-1:-1;;;;;16213:2:238;16205:5;16199:12;16195:21;16190:3;16183:34;16278:2;16270:4;16263:5;16259:16;16253:23;16249:32;16242:4;16237:3;16233:14;16226:56;;16328:4;16321:5;16317:16;16311:23;16366:4;16359;16354:3;16350:14;16343:28;16387:46;16427:4;16422:3;16418:14;16404:12;16387:46;:::i;:::-;16380:53;16050:389;-1:-1:-1;;;;16050:389:238:o;16444:439::-;16497:3;16535:5;16529:12;16562:6;16557:3;16550:19;16588:4;16617;16612:3;16608:14;16601:21;;16656:4;16649:5;16645:16;16679:1;16689:169;16703:6;16700:1;16697:13;16689:169;;;16764:13;;16752:26;;16798:12;;;;16833:15;;;;16725:1;16718:9;16689:169;;;-1:-1:-1;16874:3:238;;16444:439;-1:-1:-1;;;;;16444:439:238:o;16888:1064::-;16956:3;16987;17019:5;17013:12;17046:6;17041:3;17034:19;17072:4;17101:2;17096:3;17092:12;17085:19;;17157:2;17147:6;17144:1;17140:14;17133:5;17129:26;17125:35;17194:2;17187:5;17183:14;17215:1;17225:701;17239:6;17236:1;17233:13;17225:701;;;17326:2;17322:7;17314:5;17308:4;17304:16;17300:30;17295:3;17288:43;17360:6;17354:13;17390:4;-1:-1:-1;;;;;17430:2:238;17424:9;17420:58;17414:4;17407:72;17526:2;17522;17518:11;17512:18;17565:2;17560;17554:4;17550:13;17543:25;17595:57;17648:2;17642:4;17638:13;17624:12;17595:57;:::i;:::-;17581:71;;;17675:4;17728:2;17724;17720:11;17714:18;17692:40;;17779:4;17771:6;17767:17;17762:2;17756:4;17752:13;17745:40;;17806;17839:6;17823:14;17806:40;:::i;:::-;17904:12;;;;17798:48;-1:-1:-1;;;17869:15:238;;;;17261:1;17254:9;17225:701;;;-1:-1:-1;17942:4:238;;16888:1064;-1:-1:-1;;;;;;;16888:1064:238:o;17957:569::-;18136:2;18125:9;18118:21;18099:4;18174:6;18168:13;18217:4;18212:2;18201:9;18197:18;18190:32;18245:63;18304:2;18293:9;18289:18;18275:12;18245:63;:::i;:::-;18231:77;;18357:2;18349:6;18345:15;18339:22;18431:2;18427:7;18415:9;18407:6;18403:22;18399:36;18392:4;18381:9;18377:20;18370:66;18453:67;18513:6;18497:14;18453:67;:::i;18531:184::-;-1:-1:-1;;;18580:1:238;18573:88;18680:4;18677:1;18670:15;18704:4;18701:1;18694:15;19548:184;19618:6;19671:2;19659:9;19650:7;19646:23;19642:32;19639:52;;;19687:1;19684;19677:12;19639:52;-1:-1:-1;19710:16:238;;19548:184;-1:-1:-1;19548:184:238:o;19737:::-;-1:-1:-1;;;19786:1:238;19779:88;19886:4;19883:1;19876:15;19910:4;19907:1;19900:15;19926:184;-1:-1:-1;;;19975:1:238;19968:88;20075:4;20072:1;20065:15;20099:4;20096:1;20089:15;20115:274;20155:1;20181;20171:189;;-1:-1:-1;;;20213:1:238;20206:88;20317:4;20314:1;20307:15;20345:4;20342:1;20335:15;20171:189;-1:-1:-1;20374:9:238;;20115:274::o;20394:579::-;20451:3;20489:5;20483:12;20516:6;20511:3;20504:19;20542:4;20571;20566:3;20562:14;20555:21;;20610:4;20603:5;20599:16;20633:1;20643:305;20657:6;20654:1;20651:13;20643:305;;;20716:13;;20758:9;;-1:-1:-1;;;;;20754:58:238;20742:71;;20853:11;;20847:18;20833:12;;;20826:40;20895:4;20886:14;;;;20923:15;;;;20679:1;20672:9;20643:305;;20978:2420;21039:3;21078:4;21073:3;21069:14;21110:5;21104:12;21099:3;21092:25;21136:4;21187:2;21180:5;21176:14;21170:21;21165:2;21160:3;21156:12;21149:43;21211:4;21264;21257:5;21253:16;21247:23;21240:4;21235:3;21231:14;21224:47;21290:4;21357;21350:5;21346:16;21340:23;21333:31;21326:39;21319:4;21314:3;21310:14;21303:63;21385:4;21435;21428:5;21424:16;21418:23;21473:4;21466;21461:3;21457:14;21450:28;21500:4;21533:12;21527:19;21568:6;21562:4;21555:20;21594:3;21584:13;;21624:3;21619;21615:13;21606:22;;21681:3;21671:6;21668:1;21664:14;21659:3;21655:24;21651:34;21726:2;21712:12;21708:21;21694:35;;21747:1;21757:1476;21771:6;21768:1;21765:13;21757:1476;;;21838:16;;;-1:-1:-1;;21834:31:238;21820:46;;21889:13;;21937:9;;21959:18;;;22018:21;;-1:-1:-1;;;;;22014:70:238;21997:15;;;21990:95;22126:23;;;22120:30;22173:4;22197:15;;;22190:27;22244:63;22302:3;22290:16;;22120:30;22244:63;:::i;:::-;22230:77;;22368:2;22352:14;22348:23;22342:30;22399:3;22395:8;22467:2;22458:6;22450;22446:19;22442:28;22435:4;22427:6;22423:17;22416:55;22498:56;22547:6;22531:14;22498:56;:::i;:::-;22484:70;;22615:2;22599:14;22595:23;22589:30;22567:52;;22681:2;22672:6;22664;22660:19;22656:28;22651:2;22643:6;22639:15;22632:53;;22712:56;22761:6;22745:14;22712:56;:::i;:::-;22698:70;;;22832:2;22816:14;22812:23;22806:30;22800:3;22792:6;22788:16;22781:56;22888:2;22884;22880:11;22874:18;22869:2;22861:6;22857:15;22850:43;22944:2;22940;22936:11;22930:18;22925:2;22917:6;22913:15;22906:43;22998:2;22994;22990:11;22984:18;22962:40;;23051:6;23043;23039:19;23034:2;23026:6;23022:15;23015:44;23082:67;23142:6;23126:14;23082:67;:::i;:::-;23172:15;;;;23209:14;;;;23072:77;-1:-1:-1;;;21793:1:238;21786:9;;;;;-1:-1:-1;21757:1476:238;;;21761:3;23281:4;23274:5;23270:16;23264:23;23242:45;;23331:3;23323:6;23319:16;23312:4;23307:3;23303:14;23296:40;23352;23385:6;23369:14;23352:40;:::i;:::-;23345:47;20978:2420;-1:-1:-1;;;;;;;;;;;;20978:2420:238:o;23403:1171::-;23675:4;23723:2;23712:9;23708:18;23753:2;23742:9;23735:21;23776:6;23811;23805:13;23842:6;23834;23827:22;23880:2;23869:9;23865:18;23858:25;;23942:2;23932:6;23929:1;23925:14;23914:9;23910:30;23906:39;23892:53;;23964:4;24003:2;23995:6;23991:15;24024:1;24034:274;24048:6;24045:1;24042:13;24034:274;;;24141:2;24137:7;24125:9;24117:6;24113:22;24109:36;24104:3;24097:49;24169:59;24221:6;24212;24206:13;24169:59;:::i;:::-;24159:69;-1:-1:-1;24286:12:238;;;;24251:15;;;;24070:1;24063:9;24034:274;;;24038:3;;24356:9;24348:6;24344:22;24339:2;24328:9;24324:18;24317:50;24391:6;24383;24376:22;24445:6;24437;24432:2;24424:6;24420:15;24407:45;24498:1;24472:19;;;24468:28;;24461:39;24558:2;24537:15;;;-1:-1:-1;;24533:29:238;24521:42;;;24517:51;;;;23403:1171;-1:-1:-1;;;;;;23403:1171:238:o;24579:545::-;24807:4;-1:-1:-1;;;;;24917:2:238;24909:6;24905:15;24894:9;24887:34;24969:2;24961:6;24957:15;24952:2;24941:9;24937:18;24930:43;;25009:6;25004:2;24993:9;24989:18;24982:34;25052:3;25047:2;25036:9;25032:18;25025:31;25073:45;25113:3;25102:9;25098:19;25090:6;25073:45;:::i;:::-;25065:53;24579:545;-1:-1:-1;;;;;;24579:545:238:o;25129:245::-;25196:6;25249:2;25237:9;25228:7;25224:23;25220:32;25217:52;;;25265:1;25262;25255:12;25217:52;25297:9;25291:16;25316:28;25338:5;25316:28;:::i;25379:293::-;25582:2;25571:9;25564:21;25545:4;25602:64;25662:2;25651:9;25647:18;25639:6;25602:64;:::i;25677:299::-;25810:6;25818;25871:2;25859:9;25850:7;25846:23;25842:32;25839:52;;;25887:1;25884;25877:12;25839:52;-1:-1:-1;;25910:16:238;;25966:2;25951:18;;;25945:25;25910:16;;25945:25;;-1:-1:-1;25677:299:238:o;25981:459::-;26034:5;26087:3;26080:4;26072:6;26068:17;26064:27;26054:55;;26105:1;26102;26095:12;26054:55;26134:6;26128:13;26165:48;26181:31;26209:2;26181:31;:::i;26165:48::-;26238:2;26229:7;26222:19;26284:3;26277:4;26272:2;26264:6;26260:15;26256:26;26253:35;26250:55;;;26301:1;26298;26291:12;26250:55;26359:2;26352:4;26344:6;26340:17;26333:4;26324:7;26320:18;26314:48;26407:1;26382:16;;;26400:4;26378:27;26371:38;;;;26386:7;25981:459;-1:-1:-1;;;25981:459:238:o;26445:1720::-;26567:6;26598:2;26641;26629:9;26620:7;26616:23;26612:32;26609:52;;;26657:1;26654;26647:12;26609:52;26690:9;26684:16;26719:18;26760:2;26752:6;26749:14;26746:34;;;26776:1;26773;26766:12;26746:34;26814:6;26803:9;26799:22;26789:32;;26859:7;26852:4;26848:2;26844:13;26840:27;26830:55;;26881:1;26878;26871:12;26830:55;26910:2;26904:9;26933:78;26949:61;27007:2;26949:61;:::i;26933:78::-;27045:15;;;27127:1;27123:10;;;;27115:19;;27111:28;;;27076:12;;;;27151:19;;;27148:39;;;27183:1;27180;27173:12;27148:39;27215:2;27211;27207:11;27227:908;27243:6;27238:3;27235:15;27227:908;;;27322:3;27316:10;27358:2;27345:11;27342:19;27339:39;;;27374:1;27371;27364:12;27339:39;27401:20;;27444:4;27472:16;;;-1:-1:-1;;27468:30:238;27464:39;-1:-1:-1;27461:59:238;;;27516:1;27513;27506:12;27461:59;27546:22;;:::i;:::-;27610:2;27606;27602:11;27596:18;27649:1;27640:7;27637:14;27627:42;;27665:1;27662;27655:12;27627:42;27682:22;;27727:2;27763:11;;;27757:18;27788:33;27757:18;27788:33;:::i;:::-;27841:14;;;27834:31;27900:11;;;27894:18;;27928:16;;;27925:36;;;27957:1;27954;27947:12;27925:36;27997:64;28053:7;28048:2;28037:8;28033:2;28029:17;28025:26;27997:64;:::i;:::-;27981:14;;;27974:88;28075:18;;-1:-1:-1;;28113:12:238;;;;27260;;27227:908;;;-1:-1:-1;28154:5:238;26445:1720;-1:-1:-1;;;;;;;;26445:1720:238:o;28170:184::-;-1:-1:-1;;;28219:1:238;28212:88;28319:4;28316:1;28309:15;28343:4;28340:1;28333:15;29602:273;29670:6;29723:2;29711:9;29702:7;29698:23;29694:32;29691:52;;;29739:1;29736;29729:12;29691:52;29771:9;29765:16;29821:4;29814:5;29810:16;29803:5;29800:27;29790:55;;29841:1;29838;29831:12;29880:613;29993:6;30001;30009;30062:2;30050:9;30041:7;30037:23;30033:32;30030:52;;;30078:1;30075;30068:12;30030:52;30110:9;30104:16;30129:31;30154:5;30129:31;:::i;:::-;30229:2;30214:18;;30208:25;30179:5;;-1:-1:-1;30242:33:238;30208:25;30242:33;:::i;:::-;30345:2;30330:18;;30324:25;30294:7;;-1:-1:-1;30372:18:238;30361:30;;30358:50;;;30404:1;30401;30394:12;30358:50;30427:60;30479:7;30470:6;30459:9;30455:22;30427:60;:::i;:::-;30417:70;;;29880:613;;;;;:::o;30841:135::-;30880:3;30901:17;;;30898:43;;30921:18;;:::i;:::-;-1:-1:-1;30968:1:238;30957:13;;30841:135::o;30981:664::-;31231:4;-1:-1:-1;;;;;31341:2:238;31333:6;31329:15;31318:9;31311:34;31381:6;31376:2;31365:9;31361:18;31354:34;31436:2;31428:6;31424:15;31419:2;31408:9;31404:18;31397:43;31476:6;31471:2;31460:9;31456:18;31449:34;31532:2;31524:6;31520:15;31514:3;31503:9;31499:19;31492:44;;31573:3;31567;31556:9;31552:19;31545:32;31594:45;31634:3;31623:9;31619:19;31611:6;31594:45;:::i;:::-;31586:53;30981:664;-1:-1:-1;;;;;;;;30981:664:238:o;32152:620::-;32215:3;32246;32278:5;32272:12;32305:6;32300:3;32293:19;32331:4;32360;32355:3;32351:14;32344:21;;32418:4;32408:6;32405:1;32401:14;32394:5;32390:26;32386:37;32457:4;32450:5;32446:16;32480:1;32490:256;32504:6;32501:1;32498:13;32490:256;;;32591:2;32587:7;32579:5;32573:4;32569:16;32565:30;32560:3;32553:43;32617:49;32661:4;32652:6;32646:13;32617:49;:::i;:::-;32724:12;;;;32609:57;-1:-1:-1;32689:15:238;;;;32526:1;32519:9;32490:256;;33244:1220;33423:2;33412:9;33405:21;-1:-1:-1;;;;;33472:6:238;33466:13;33462:62;33457:2;33446:9;33442:18;33435:90;33579:2;33571:6;33567:15;33561:22;33556:2;33545:9;33541:18;33534:50;33386:4;33631:2;33623:6;33619:15;33613:22;33671:4;33666:2;33655:9;33651:18;33644:32;33699:51;33745:3;33734:9;33730:19;33716:12;33699:51;:::i;:::-;33685:65;;33805:2;33797:6;33793:15;33787:22;33781:3;33770:9;33766:19;33759:51;33859:3;33851:6;33847:16;33841:23;33887:2;33883:7;33955:2;33943:9;33935:6;33931:22;33927:31;33921:3;33910:9;33906:19;33899:60;33982:62;34037:6;34021:14;33982:62;:::i;:::-;33968:76;;34093:3;34085:6;34081:16;34075:23;34053:45;;34163:2;34151:9;34143:6;34139:22;34135:31;34129:3;34118:9;34114:19;34107:60;34190:75;34258:6;34242:14;34190:75;:::i;:::-;34176:89;;34314:3;34306:6;34302:16;34296:23;34274:45;;34385:2;34373:9;34365:6;34361:22;34357:31;34350:4;34339:9;34335:20;34328:61;;34406:52;34451:6;34435:14;34406:52;:::i;34469:683::-;34534:5;34587:3;34580:4;34572:6;34568:17;34564:27;34554:55;;34605:1;34602;34595:12;34554:55;34634:6;34628:13;34660:4;34684:78;34700:61;34758:2;34700:61;:::i;34684:78::-;34784:3;34808:2;34803:3;34796:15;34836:4;34831:3;34827:14;34820:21;;34893:4;34887:2;34884:1;34880:10;34872:6;34868:23;34864:34;34850:48;;34921:3;34913:6;34910:15;34907:35;;;34938:1;34935;34928:12;34907:35;34974:4;34966:6;34962:17;34988:135;35004:6;34999:3;34996:15;34988:135;;;35070:10;;35058:23;;35101:12;;;;35021;;34988:135;;35157:1183;35317:6;35325;35378:2;35366:9;35357:7;35353:23;35349:32;35346:52;;;35394:1;35391;35384:12;35346:52;35427:9;35421:16;35456:18;35497:2;35489:6;35486:14;35483:34;;;35513:1;35510;35503:12;35483:34;35551:6;35540:9;35536:22;35526:32;;35596:7;35589:4;35585:2;35581:13;35577:27;35567:55;;35618:1;35615;35608:12;35567:55;35647:2;35641:9;35669:4;35693:78;35709:61;35767:2;35709:61;:::i;35693:78::-;35805:15;;;35887:1;35883:10;;;;35875:19;;35871:28;;;35836:12;;;;35911:19;;;35908:39;;;35943:1;35940;35933:12;35908:39;35967:11;;;;35987:135;36003:6;35998:3;35995:15;35987:135;;;36069:10;;36057:23;;36020:12;;;;36100;;;;35987:135;;;36177:18;;;36171:25;36141:5;;-1:-1:-1;36171:25:238;;-1:-1:-1;;;36208:16:238;;;36205:36;;;36237:1;36234;36227:12;36205:36;;36260:74;36326:7;36315:8;36304:9;36300:24;36260:74;:::i;36345:739::-;36551:4;36599:2;36588:9;36584:18;36629:6;36618:9;36611:25;36655:2;36693;36688;36677:9;36673:18;36666:30;36716:6;36751;36745:13;36782:6;36774;36767:22;36820:2;36809:9;36805:18;36798:25;;36858:2;36850:6;36846:15;36832:29;;36879:1;36889:169;36903:6;36900:1;36897:13;36889:169;;;36964:13;;36952:26;;37033:15;;;;36998:12;;;;36925:1;36918:9;36889:169;;37271:416;37360:1;37397:5;37360:1;37411:270;37432:7;37422:8;37419:21;37411:270;;;37491:4;37487:1;37483:6;37479:17;37473:4;37470:27;37467:53;;;37500:18;;:::i;:::-;37550:7;37540:8;37536:22;37533:55;;;37570:16;;;;37533:55;37649:22;;;;37609:15;;;;37411:270;;;37415:3;37271:416;;;;;:::o;37692:806::-;37741:5;37771:8;37761:80;;-1:-1:-1;37812:1:238;37826:5;;37761:80;37860:4;37850:76;;-1:-1:-1;37897:1:238;37911:5;;37850:76;37942:4;37960:1;37955:59;;;;38028:1;38023:130;;;;37935:218;;37955:59;37985:1;37976:10;;37999:5;;;38023:130;38060:3;38050:8;38047:17;38044:43;;;38067:18;;:::i;:::-;-1:-1:-1;;38123:1:238;38109:16;;38138:5;;37935:218;;38237:2;38227:8;38224:16;38218:3;38212:4;38209:13;38205:36;38199:2;38189:8;38186:16;38181:2;38175:4;38172:12;38168:35;38165:77;38162:159;;;-1:-1:-1;38274:19:238;;;38306:5;;38162:159;38353:34;38378:8;38372:4;38353:34;:::i;:::-;38423:6;38419:1;38415:6;38411:19;38402:7;38399:32;38396:58;;;38434:18;;:::i;:::-;38472:20;;37692:806;-1:-1:-1;;;37692:806:238:o;38503:131::-;38563:5;38592:36;38619:8;38613:4;38592:36;:::i;38639:168::-;38712:9;;;38743;;38760:15;;;38754:22;;38740:37;38730:71;;38781:18;;:::i","linkReferences":{},"immutableReferences":{"89152":[{"start":189,"length":32},{"start":570,"length":32},{"start":651,"length":32}]}},"methodIdentifiers":{"arb4(address,(bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes)[],bytes,((address,address,bytes),(address,bytes32[],bytes)[]))":"c55377d6","iTaskHash()":"93be095e","onFlashLoan(address,address,uint256,uint256,bytes)":"23e30c8b","supportsInterface(bytes4)":"01ffc9a7"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"orderBook\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV2\",\"name\":\"task\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"implementationData\",\"type\":\"bytes\"}],\"internalType\":\"struct OrderBookV6ArbConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"badInitiator\",\"type\":\"address\"}],\"name\":\"BadInitiator\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"signedCoefficient\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"exponent\",\"type\":\"int256\"}],\"name\":\"CoefficientOverflow\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"signedCoefficient\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"exponent\",\"type\":\"int256\"}],\"name\":\"ExponentOverflow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FlashLoanFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"signedCoefficient\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"exponent\",\"type\":\"int256\"}],\"name\":\"LossyConversionToFloat\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"signedCoefficient\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"exponent\",\"type\":\"int256\"}],\"name\":\"NegativeFixedDecimalConversion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoOrders\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongTask\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"orderBook\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV2\",\"name\":\"task\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"implementationData\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"struct OrderBookV6ArbConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"Construct\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[{\"internalType\":\"contract IOrderBookV6\",\"name\":\"orderBook\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"Float\",\"name\":\"minimumIO\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"maximumIO\",\"type\":\"bytes32\"},{\"internalType\":\"Float\",\"name\":\"maximumIORatio\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"IOIsInput\",\"type\":\"bool\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"vaultId\",\"type\":\"bytes32\"}],\"internalType\":\"struct IOV2[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OrderV4\",\"name\":\"order\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"inputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outputIOIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TakeOrderConfigV4[]\",\"name\":\"orders\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct TakeOrdersConfigV5[]\",\"name\":\"takeOrders\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"exchangeData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV4\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV3\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV4\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"context\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV2\",\"name\":\"task\",\"type\":\"tuple\"}],\"name\":\"arb4\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"iTaskHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onFlashLoan\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"BadInitiator(address)\":[{\"params\":{\"badInitiator\":\"The untrusted initiator of the flash loan.\"}}],\"CoefficientOverflow(int256,int256)\":[{\"details\":\"Thrown when a coefficient overflows.\"}],\"ExponentOverflow(int256,int256)\":[{\"details\":\"Thrown when an exponent overflows.\"}],\"FailedCall()\":[{\"details\":\"A call to an address target failed. The target may have reverted.\"}],\"InsufficientBalance(uint256,uint256)\":[{\"details\":\"The ETH balance of the account is not enough to perform the operation.\"}],\"LossyConversionToFloat(int256,int256)\":[{\"details\":\"Thrown when converting some value to a float when the conversion is lossy.\"}],\"NegativeFixedDecimalConversion(int256,int256)\":[{\"details\":\"Thrown when attempting to convert a negative number to an unsigned fixed-point number.\"}],\"ReentrancyGuardReentrantCall()\":[{\"details\":\"Unauthorized reentrant call.\"}],\"SafeERC20FailedOperation(address)\":[{\"details\":\"An operation with an ERC-20 token failed.\"}]},\"kind\":\"dev\",\"methods\":{\"arb4(address,(bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes)[],bytes,((address,address,bytes),(address,bytes32[],bytes)[]))\":{\"params\":{\"exchangeData\":\"Arbitrary bytes that will be passed to `_exchange` after the flash loan is taken. The inheriting contract is responsible for decoding this data and defining how it controls interactions with the external liquidity. For example, `GenericPoolOrderBookV5FlashBorrower` uses this data as a literal encoded external call.\",\"orderBook\":\"The orderbook address\",\"takeOrders\":\"As per `IOrderBookV5.takeOrders3`.\"}},\"onFlashLoan(address,address,uint256,uint256,bytes)\":{\"details\":\"Receive a flash loan.\",\"params\":{\"amount\":\"The amount of tokens lent.\",\"data\":\"Arbitrary data structure, intended to contain user-defined parameters.\",\"fee\":\"The additional amount of tokens to repay.\",\"initiator\":\"The initiator of the loan.\",\"token\":\"The loan currency.\"},\"returns\":{\"_0\":\"The keccak256 hash of \\\"ERC3156FlashBorrower.onFlashLoan\\\"\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"errors\":{\"BadInitiator(address)\":[{\"notice\":\"Thrown when the initiator is not the order book.\"}],\"FlashLoanFailed()\":[{\"notice\":\"Thrown when the flash loan fails somehow.\"}],\"InvalidSignature(uint256)\":[{\"notice\":\"Thrown when the ith signature from a list of signed contexts is invalid.\"}],\"NoOrders()\":[{\"notice\":\"MUST be thrown when take orders is called with no orders.\"}],\"WrongTask()\":[{\"notice\":\"Thrown when the task does not match the expected hash.\"}]},\"kind\":\"user\",\"methods\":{\"arb4(address,(bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes)[],bytes,((address,address,bytes),(address,bytes32[],bytes)[]))\":{\"notice\":\"Primary function to process arbitrage opportunities. Firstly the access gate is evaluated to ensure the sender is allowed to submit arbitrage. If there is no access control the sender should expect to be front run on the arb for any sufficiently profitable opportunity. This may be desirable in some cases, as the sender may simply want to be clearing the orderbook and they are expecting profit/utility from the orderbook strategies themselves somehow. Secondly the flash loan is taken and the `_exchange` hook is called to allow the inheriting contract to convert the flash loaned assets into the assets required to fill the orders. Finally the orders are taken and the remaining assets are sent to the sender.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/concrete/arb/RaindexRouterOrderBookV6Arb.sol\":\"RaindexRouterOrderBookV6Arb\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"appendCBOR\":false,\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[\":@openzeppelin/contracts/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/contracts/\",\":axelar-gmp-sdk-solidity/=lib/sushixswap-v2/lib/axelar-gmp-sdk-solidity/\",\":bytecode/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/bytecode/\",\":caller/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/caller/\",\":codegen/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/codegen/\",\":constants/=lib/rain.interpreter/src/lib/constants/\",\":deprecated/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/\",\":ds-test/=lib/sushixswap-v2/lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/lib/erc4626-tests/\",\":eval/=lib/rain.interpreter/src/lib/eval/\",\":extern/=lib/rain.interpreter/src/lib/extern/\",\":forge-gas-snapshot/=lib/sushixswap-v2/lib/forge-gas-snapshot/src/\",\":forge-std/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/forge-std/src/\",\":halmos-cheatcodes/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\",\":integrity/=lib/rain.interpreter/src/lib/integrity/\",\":mut/=lib/rain.interpreter/lib/rain.string/src/lib/mut/\",\":ns/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/ns/\",\":op/=lib/rain.interpreter/src/lib/op/\",\":openzeppelin-contracts/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/\",\":parse/=lib/rain.interpreter/src/lib/parse/\",\":rain.datacontract/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.datacontract/src/\",\":rain.interpreter.interface/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/\",\":rain.interpreter/=lib/rain.interpreter/src/\",\":rain.intorastring/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.intorastring/src/\",\":rain.lib.hash/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.hash/src/\",\":rain.lib.memkv/=lib/rain.interpreter/lib/rain.lib.memkv/src/\",\":rain.lib.typecast/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.typecast/src/\",\":rain.math.binary/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.binary/src/\",\":rain.math.fixedpoint/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.math.fixedpoint/src/\",\":rain.math.float/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/\",\":rain.math.saturating/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.math.fixedpoint/lib/rain.math.saturating/src/\",\":rain.metadata/=lib/rain.interpreter/lib/rain.metadata/src/\",\":rain.orderbook.interface/=lib/rain.orderbook.interface/src/\",\":rain.sol.codegen/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.sol.codegen/src/\",\":rain.solmem/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/\",\":rain.string/=lib/rain.interpreter/lib/rain.string/src/\",\":rain.tofu.erc20-decimals/=lib/rain.tofu.erc20-decimals/src/\",\":sol.lib.binmaskflag/=lib/rain.interpreter/lib/sol.lib.binmaskflag/src/\",\":state/=lib/rain.interpreter/src/lib/state/\",\":sushixswap-v2/=lib/sushixswap-v2/\"]},\"sources\":{\"lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.hash/src/LibHashNoAlloc.sol\":{\"keccak256\":\"0x1153c2d2ec53adca83c81c37ac958aab8b4d31e0e01f64f5189b1783375c0347\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://79d10d5165cf0d5cc8b28b76613fc114e74c33fcc2d5632f7e284dace2247927\",\"dweb:/ipfs/QmZEt4BQ6xsfiFNBQ55GoQq8Ats3Hb1v2hPFEWPDeqKrTv\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol\":{\"keccak256\":\"0x66c7ec42c6c43712be2107a50ab4529379bc76a632b425babec698d9da921ac6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://dce2778f0b638adfc5ba29c2c618c855fe725fa74a16846386aa1d56a834aa04\",\"dweb:/ipfs/QmPV9oWnzQdi58od266j62xvviavLNHqKLZfm6k2K1qy9E\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol\":{\"keccak256\":\"0xd5ea07362ab630a6a3dee4285a74cf2377044ca2e4be472755ad64d7c5d4b69d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://da5e832b40fc5c3145d3781e2e5fa60ac2052c9d08af7e300dc8ab80c4343100\",\"dweb:/ipfs/QmTzf7N5ZUdh5raqtzbM11yexiUoLC9z3Ws632MCuycq1d\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol\":{\"keccak256\":\"0x0afcb7e740d1537b252cb2676f600465ce6938398569f09ba1b9ca240dde2dfc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1c299900ac4ec268d4570ecef0d697a3013cd11a6eb74e295ee3fbc945056037\",\"dweb:/ipfs/Qmab9owJoxcA7vJT5XNayCMaUR1qxqj1NDzzisduwaJMcZ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol\":{\"keccak256\":\"0x1a6221315ce0307746c2c4827c125d821ee796c74a676787762f4778671d4f44\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1bb2332a7ee26dd0b0de9b7fe266749f54820c99ab6a3bcb6f7e6b751d47ee2d\",\"dweb:/ipfs/QmcRWpaBeCYkhy68PR3B4AgD7asuQk7PwkWxrvJbZcikLF\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC7913.sol\":{\"keccak256\":\"0xe5a126930df1d54e4a6dd5fea09010c4a7db0ea974c6c17a1e6082879f5a032b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2f58f5a90328536a6c68289916bfa4ed653d871319c7b2a416ab3f6263c4f2f5\",\"dweb:/ipfs/Qmaa9DmgUA16Urz5fuF4RbFz2NaVpNLV41ddwykSdasFUd\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303\",\"dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0xd6fa4088198f04eef10c5bce8a2f4d60554b7ec4b987f684393c01bf79b94d9f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f95ee0bbd4dd3ac730d066ba3e785ded4565e890dbec2fa7d3b9fe3bad9d0d6e\",\"dweb:/ipfs/QmSLr6bHkPFWT7ntj34jmwfyskpwo97T9jZUrk5sz3sdtR\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x304d732678032a9781ae85c8f204c8fba3d3a5e31c02616964e75cfdc5049098\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://299ced486011781dc98f638059678323c03079fefae1482abaa2135b22fa92d0\",\"dweb:/ipfs/QmbZNbcPTBxNvwChavN2kkZZs7xHhYL7mv51KrxMhsMs3j\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x0fa9e0d3a859900b5a46f70a03c73adf259603d5e05027a37fe0b45529d85346\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c2add4da0240c9f2ce47649c8bb6b11b40e98cf6f88b8bdc76b2704e89391710\",\"dweb:/ipfs/QmNQTwF2uVzu4CRtNxr8bxyP9XuW6VsZuo2Nr4KR2bZr3d\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Bytes.sol\":{\"keccak256\":\"0x8140d608316521b1fd71167c3b708ebb8659da070723fc8807609553b296ee33\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a7bf7db66869ba1e945a0390b85da2f6afc7e42a4735ca918d0d56ac90c50147\",\"dweb:/ipfs/QmRmNyhpBpgzSdQqLtrQCYE7H7eLnVVxh2Yy4YMrySR8AR\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Errors.sol\":{\"keccak256\":\"0x6afa713bfd42cf0f7656efa91201007ac465e42049d7de1d50753a373648c123\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ba1d02f4847670a1b83dec9f7d37f0b0418d6043447b69f3a29a5f9efc547fcf\",\"dweb:/ipfs/QmQ7iH2keLNUKgq2xSWcRmuBE5eZ3F5whYAkAGzCNNoEWB\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol\":{\"keccak256\":\"0x5b4802a4352474792df3107e961d1cc593e47b820c14f69d3505cb28f5a6a583\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a6f86fd01f829499fe0545ff5dda07d4521988e88bfe0bf801fc15650921ed56\",\"dweb:/ipfs/QmUUKu4ZDffHAmfkf3asuQfmLTyfpuy2Amdncc3SqfzKPG\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Panic.sol\":{\"keccak256\":\"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a\",\"dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol\":{\"keccak256\":\"0xa516cbf1c7d15d3517c2d668601ce016c54395bf5171918a14e2686977465f53\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1e1d079e8edfb58efd23a311e315a4807b01b5d1cf153f8fa2d0608b9dec3e99\",\"dweb:/ipfs/QmTBExeX2SDTkn5xbk5ssbYSx7VqRp9H4Ux1CY4uQM4b9N\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol\":{\"keccak256\":\"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b\",\"dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x36d1750bf1aa5fee9c52adb2f7857ab652daca722fc05dff533b364f67a1139a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2e5e7052539b7849d02f3ce25acc1dce29373c11cfae9f0bc918c54b780c549a\",\"dweb:/ipfs/QmRGE32xNkMTo6i4pHHMxjpiu77yPwnTA25SFngw2NXJys\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0x360cf86214a764694dae1522a38200b1737fe90e46dcf56a0f89de143071cc20\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2e393290a46ca6d1fa1addb40709d26e1d250638ab6acdd103b5af21768ebc7b\",\"dweb:/ipfs/QmPwT3tXwQ9NbGtZ99XRq7sr8LCQP8XaCrzw49JdXGn7us\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol\":{\"keccak256\":\"0x6abeed5940e1da7bb329e458db9a1c5c4ea6f86d651b952af99c6bddcd6bbb94\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5fe75e9a6b759c5d7fd82fb59bd4f58c672b36f0a69b84f4789b7c7895d3e61c\",\"dweb:/ipfs/QmX28wsir8w5sS3acfJMNHcBwoPsDpqCu7WDkPnUWLMNiZ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol\":{\"keccak256\":\"0x445455b8be33e09cf1db14e59c0d1c5aa5d312b5e754e8ae751e42313a0cae88\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d6939df526d1c3f1d773448f6451eebb8de344113744e0da121b6349658b1298\",\"dweb:/ipfs/QmPffovzJ8qGRuUh57qrnWajHqYPPrntb1EA1VRh8p5TLP\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0x2d9dc2fe26180f74c11c13663647d38e259e45f95eb88f57b61d2160b0109d3e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://81233d1f98060113d9922180bb0f14f8335856fe9f339134b09335e9f678c377\",\"dweb:/ipfs/QmWh6R35SarhAn4z2wH8SU456jJSYL2FgucfTFgbHJJN4E\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\",\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0x09e3f1c72d4c5cbe8e2644ab7313f8f7177533ae2f4c24cdcbbeaf520a73734c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://93208401215d539fa2d81626b207c1f611def7883d0e447b3b5969ebaa7b3c2c\",\"dweb:/ipfs/QmXPxDnQPx8LAweX5ZJqEcwkvs59kP4c64VVDG1Jjq1mef\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0x195533c86d0ef72bcc06456a4f66a9b941f38eb403739b00f21fd7c1abd1ae54\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b1d578337048cad08c1c03041cca5978eff5428aa130c781b271ad9e5566e1f8\",\"dweb:/ipfs/QmPFKL2r9CBsMwmUqqdcFPfHZB2qcs9g1HDrPxzWSxomvy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xb1970fac7b64e6c09611e6691791e848d5e3fe410fa5899e7df2e0afd77a99e3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://db5fbb3dddd8b7047465b62575d96231ba8a2774d37fb4737fbf23340fabbb03\",\"dweb:/ipfs/QmVUSvooZKEdEdap619tcJjTLcAuH6QBdZqAzWwnAXZAWJ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/error/ErrDecimalFloat.sol\":{\"keccak256\":\"0x3c9e3f5e6b78877add52f397e2cf452e8a1afe6b9e630fc7bbc7c2d6704d07d9\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://9840b88bf5143a94f8e7779390b025dda83530090be3503e110aa2584250c6e4\",\"dweb:/ipfs/QmemaALnbRKFChq5Ec1p4xdar5rDqEvdbQwGb2vzMVWhK9\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/LibDecimalFloat.sol\":{\"keccak256\":\"0x5c8820a79da0ac3c8558ae65c8b3b2b4579326755a4914a243f2475c1159b2aa\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://edc7ddd33798964f19aa9183fa0366321f93ab03171ba334192f65bd71a1a53d\",\"dweb:/ipfs/QmYKAKopDLGMWCfTVhwhF3vCGw6wXveKX1uTtxCyvycNkL\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/implementation/LibDecimalFloatImplementation.sol\":{\"keccak256\":\"0x182d010eee786cfa19ad44e215332c4e6fd4e9310da3e61ebd17a0309307d6b6\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1206a9557d6410c30ec82f02d44d3e857d7aabf46d607ee08bf415af14f8a799\",\"dweb:/ipfs/Qmbygfmw9K8YVQdEsNEkkHxTbTiuuDgWt7yB6gMwoYGBcp\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/table/LibLogTable.sol\":{\"keccak256\":\"0x412629a161febf0dc9c3bae0cc9fe0b8de8774d37c5f3afde2e2312478d96a98\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://c8da5302117961caad328e80cb28296ea71aadbc291312e37d3db079d84a9777\",\"dweb:/ipfs/QmWYzpex1Xrnjf3QM68n6mGFQ4KxE53fUUyDjwE3zNrtok\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol\":{\"keccak256\":\"0x57b7a7a5cbc2fc97200130e84fde3a8afc14e0729040b14670dacc7f63c3ac5f\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://4e7c7ce525e882db437b488b590fae6a817b282f88d76eb4f56986b549815e57\",\"dweb:/ipfs/QmajzM26fsaFtaAnm5cg1FZrD6N2wkLJHCxa7Atx5x6iAB\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol\":{\"keccak256\":\"0x3fc6ff807b57b681e32229380e3eda57107a1ada8dc2c1270daa84c9fca5addc\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://a82b17ddc1db163ec548648c83dd5bb2f9f4441559452933f424e0a8dff48e57\",\"dweb:/ipfs/QmdKoRbEAPxBRHJWWRwjh9Yrps1QXcJuX5mJmua8nvnq7B\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol\":{\"keccak256\":\"0xf51dffaeb88063748495e3184e335d9bb46f22881c2e8c930f2b68a32bdb39c2\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://4a66ae9e4e9b9bf83b68c4d1d609fda02f8584387740354318d4eca1e2639047\",\"dweb:/ipfs/QmXTS3azQ3ebBpJzj15HJRjTLV8zHfrFPQ7qPiic6eE3Pa\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterCallerV3.sol\":{\"keccak256\":\"0xdd13be6b4942424143613a301d020f44f67dfe6bc81550d7726cbad8d735ccdc\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://deb8adb379085983857f311d937d09f8ea1c1ecac8864f6a63f5391ba93e0929\",\"dweb:/ipfs/QmcFsrfhXyjwT8yF8UkwaCW8LMbQr4uTj3Lhcju2yeQpZZ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol\":{\"keccak256\":\"0x15796750d51d5498986438ce9546cbb1ec66dd73531f2b12f155459c97ea24c5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e73668fe127eb60cb27794da3398d7d6e8f1f9f41d71081af7016dd114c81904\",\"dweb:/ipfs/QmUe8ge3U3Fz3FzEQyXaPS2oLm9bAV2QZttP77WPrsckcK\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterV3.sol\":{\"keccak256\":\"0xe546b8a716e632ce6db719b6eb63e6ec86d530ac80ad619c47bedd470270e85a\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1359938d87ab63d170aecfbc28336db3a5598d1aacffc35f2ed1bb786ee17755\",\"dweb:/ipfs/QmbtR2wot29rpuxu1kBVvqtHBe7NVb6c2B3sXpyhj1ERkU\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IParserV2.sol\":{\"keccak256\":\"0x29935383d2b114fd0a145977340552fcbc4b674ba89949b7b40ba23c56e3586a\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://aefa76e1dd78f206cf93b9522c545e665e73e44585b3dddb70e03c6aefdf443e\",\"dweb:/ipfs/QmePBeLhR1Z7DYzhmbVkm4aUKTwDHnhJCpFXniLBuN8ryK\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV1.sol\":{\"keccak256\":\"0xc0afd50701cd68eef984a63862bd6a10552d704cca6e10f06d19d920b0777c98\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://cd3cbfa9159ceed8871f46f62c7ea235ad8537d3c6c1c004152ebf5d2d597346\",\"dweb:/ipfs/QmPSAJXAcmDeK9Qy6s2dXdeu4GJ62FKWa69VBo4ioCPcJ9\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV2.sol\":{\"keccak256\":\"0x368ace8d0f82832f08caf264e4194647b9777c0d4a0f22d88236b30c1e4c8a63\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://9c8a2141fcd76d6308156777b0a9e5a4f7f07fb3693461e2c12f07e4d8c87130\",\"dweb:/ipfs/QmPnhPz6sXzh5xBGZobAPY2WJTgvQDiYWRFKavscSPu7T5\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV3.sol\":{\"keccak256\":\"0x6f6b03c0f8e37ebe4275e0d27242754c7be815ff091ad0931a7be21ab11de628\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1f200079a3689e0d0c8efb97040737a2b4113a82f0df5d8319af36d9ad5d8b97\",\"dweb:/ipfs/QmXFzXZasmD9D7pAYC5wBtB748TZajy69V5tmSEXRd1VZk\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV1.sol\":{\"keccak256\":\"0xc01bc48e2479cab07fc799e26c3790c8cf97acc1f0f490c8f456f554d239a505\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://2981aa2eae0d414bc8ad4105bedb05026cfdad7e6af8f23805dba4835ae9fd8a\",\"dweb:/ipfs/QmQRKi5nmatC1UM2sNta9giuJX3xvvLAD5pmCeAsVWF4hF\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV2.sol\":{\"keccak256\":\"0x62c7149e3d28cd9b67d7eed183c4e59cf300689dd5cc363b011cb2cf32c1200d\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://52cf991b2dc9581222520c32cac224f6936c75183e4c6c16fafa4450a05c0de0\",\"dweb:/ipfs/QmZ7fiZYjnDhNnFXYCXC9iSYs8WAAwmsVxBd5XDA1tPPah\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol\":{\"keccak256\":\"0x7d2bc86fefbe372fc64381b320244fe9dbda1816867f3040c5bb3951869fe6a7\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://90c371494080129d5acd2bc52d092fc5cfe559147f7fc855ed01e62a7837f21e\",\"dweb:/ipfs/QmcNtPDuTxic8zqRFXf1ba6FJKmQXguxiDUY4E7wjyVwU5\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol\":{\"keccak256\":\"0xe0b94c771a7b6aa05388b4db6e238e36a4653cbfdbd3e54bbcaa7a97fc9491f4\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://59887a7f2ef60669906c5e70831ac0c9a7345313b04efb306235280f85e1db73\",\"dweb:/ipfs/QmP6Ny9m3sPCP65UmgGGpucSMgVAoDv6qURqyxUE95VU5Q\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV2.sol\":{\"keccak256\":\"0x0ae0d1b0ca245779f33ea3e5ffbfcc234533d5c75f4ec2a6f3042cf841bcc219\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0fd476c34670477ece5a217d2372637c279287af883c132f1b98db4b3ccb80bf\",\"dweb:/ipfs/QmVBfaGYovi93pDr9HosQkacCmeXQAfgM6haTQZFJsGnoE\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IParserV1.sol\":{\"keccak256\":\"0x4f6a9e028942cebebfc84328193f1d31807aac292d9b82e2df489064aa913070\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://54073f63db1f652571472cb2d07de297772c2420e1571a0cb9e0a805ee4347e7\",\"dweb:/ipfs/QmXRqBreJvC8MQd5zLNgmPUdfFa4WD6gSoxvD8hecycux4\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterCallerV4.sol\":{\"keccak256\":\"0xae8309d29bcc770df07bf5f5b463e80a6c20456d9fc9dcae203975328b257423\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://196dbc14f46e90344ed1bac0efbf87dd3dba15aeaed57678673e03f1362eb487\",\"dweb:/ipfs/QmejhzZx6G8gw76vPKvDEfVQQ9mF1kJvx5wj9qdeDoVrPH\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterStoreV3.sol\":{\"keccak256\":\"0xda4e6583c7a6cefb7d32593d0e069fb26b4822fb07d916bef68a4b4be857078e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://970ae6a0f2dcfaaea8b79fc30af89043282e159910b8c375a8027ad738e4e736\",\"dweb:/ipfs/QmQk5fhi61BcvEAUcBVFivUTzd7SZxULG5UdsNkrykjVPF\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterV4.sol\":{\"keccak256\":\"0x1617c780008c8f724516b1af0844f97c2c8c17ee87f515e3be3cce2d2731085f\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://b4d206e14a81549771cc8c62f54006b545c8acb546074e2cf66213211f3363a9\",\"dweb:/ipfs/QmNtpyVpL9riAxB8ZjHP1tp9GkdX9YVfXKVQ7an8ZL9rJD\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibContext.sol\":{\"keccak256\":\"0xaeb62b79fa753d8327c6d6af457d4b00937db798b51ba7e51d4a367176f8d8ba\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1c91eb4f6bb61ef79c217e15ec8cb88be4cca841d4efe70bfeb4858319032a2b\",\"dweb:/ipfs/QmVCfM2pufm269ExXDXPTwK8EcWA5ksT8Z1XAG6YTLX34Y\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibEvaluable.sol\":{\"keccak256\":\"0xd2b8ff7feb5fdfefa6c0068ae33bd0723f1a58a066a8ee1da46608bd3ae63da3\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://7290ceebbd842f88d4ecadc3847a555afbc8a4b4458b7def1c0cba4e28eb80bb\",\"dweb:/ipfs/QmR28Pst8QTLUSmRUDGK8f8prA5zutCeTG3F7RYXmNJ7WH\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/ns/LibNamespace.sol\":{\"keccak256\":\"0xd621d3e5f8b404309ad5d841a3658248e979c1bd59876be3afa7aa0595b4c0e6\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://801fa302f49f3734dd5cc6221dd25f73591ac8feae47351c18e30a98a4ae0ce1\",\"dweb:/ipfs/QmbwXbTSMZ4u6ZsyfseBx79PeHNAWocNHXpgnaPVmLZM38\"]},\"lib/rain.orderbook.interface/src/interface/IOrderBookV5.sol\":{\"keccak256\":\"0x81531ce21b2cf824be60f70e14b97e8d6f5df7e09a454a690f4ed8c7d41a0dc1\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e8a203d32f5e423f0f5fd47f1a7be70d0cad3b69c3d1469d19a8d85e1f14c303\",\"dweb:/ipfs/QmZH6v3Hc41SXiiuruUpntcUAXMcHqEhhpDATSArHQfe99\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v2/IOrderBookV2.sol\":{\"keccak256\":\"0x6df5dd48103f06c7a41b49e9497f9f28baa4940eb5eba4113c71b323da66e5a4\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e295c8ce419a26e44d1f5be80c1bfa8a852a0b47e0e332be9323a670806344aa\",\"dweb:/ipfs/QmbAJ1j8WTdwCBLF6mjiHihfvUZFAeiv3uTXntMWPLKTt7\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v3/IOrderBookV3.sol\":{\"keccak256\":\"0x0f90c4db32d78d1c15f6230b1f0cc1e16cca908e3981f417039816e820fe0c24\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://693ae8187a8012410ff5774e73ed11ca5279c296cfafecd75613e804197ec43f\",\"dweb:/ipfs/QmQLPSZwcPfc8MJDnaJiUT5ktsodQ48erR1uoTtF3Fa1ju\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v4/IOrderBookV4.sol\":{\"keccak256\":\"0xc94415fcd366693e78116a72df9c6b29408ad4bdb745846c5929561a5ce2a226\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://48f92b2281195b90bb5ee6a6b3866e27f25b9268729765eb6681de4c48b86d82\",\"dweb:/ipfs/QmUjiXwgsYzsRRj1o3uxo2aeboAT2VZxV5RWYbkinT9jUt\"]},\"lib/rain.orderbook.interface/src/interface/ierc3156/IERC3156FlashBorrower.sol\":{\"keccak256\":\"0xdcd81b1110e9c3c91715ac90aef1da70066bcaba8aeb3dc23df979f7f87644f9\",\"license\":\"CC0-1.0\",\"urls\":[\"bzz-raw://4572efaeb9eb30ad9b766b80cb2a8101a2cec0c9e8c78c7696f4aae710c8e2c9\",\"dweb:/ipfs/QmVsz1gtqWfxTAbsoLPvZBe6PBVXqaWNx6nu7RHr2ghLuK\"]},\"lib/rain.orderbook.interface/src/interface/ierc3156/IERC3156FlashLender.sol\":{\"keccak256\":\"0x119c477281a6ec109e9c729a254b39d7ccc9a9f5baa82fa28d0fa1e3bd2b6ae8\",\"license\":\"CC0-1.0\",\"urls\":[\"bzz-raw://19ec8289a123459659dca0389a650ca6bf6bc12d925ad7a3e61f0b1bfe68d1b6\",\"dweb:/ipfs/QmRZ9U5ECovPFmbRaBTauFjjVQcvPA7VQL7S1zJVEBTMD5\"]},\"lib/rain.orderbook.interface/src/interface/unstable/IOrderBookV6.sol\":{\"keccak256\":\"0xabb3b41a1e11614ce9638fece01c78e5b8aff3598263ef38c80367b09233b801\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://03108d4f4c13316863257e21c9be2788cd780b19ad55d4a0d3d9306d53c3f7a4\",\"dweb:/ipfs/QmNt9vWhgj4VGHq8SVMX9HWFed5LUZNEpWMxaW3SLojPsL\"]},\"lib/rain.tofu.erc20-decimals/src/interface/ITOFUTokenDecimals.sol\":{\"keccak256\":\"0xff728b82d787191dc32f7dac385baa1e194d313c84979b90934e6b8fd06ddbc5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e789fb5fcb3396d81fa487c907486b9ba7d33312502b676e43816f777e0379fd\",\"dweb:/ipfs/Qme1evJCUVHVpPteVvgwW84fNAJwLKfVi5xmJjNrhKEziR\"]},\"lib/rain.tofu.erc20-decimals/src/lib/LibTOFUTokenDecimals.sol\":{\"keccak256\":\"0x50c11116ed9fab852afd4cdc010751e93485d7c08a6fc318a8582c96ab26a068\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://f1d781fe347ab40ed0169d8ffa41f0311cceb9c7f4a31205ef118a280ecfa455\",\"dweb:/ipfs/QmecF2QZ92oh9qEzD9BRN2r9H8VwEXZQfJZRtrbUcsESQV\"]},\"lib/sushixswap-v2/src/interfaces/IRouteProcessor.sol\":{\"keccak256\":\"0x5b2289c992f34dd25943db3cbc27ece8b0a1addeb2631f812e7834b7ae3eac37\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://f21522058b7fe3c18d2353b06a5ddbf2b62d2aceebf7dd6dfdc51b081452bb3f\",\"dweb:/ipfs/QmVkicGnNWgnX1RfXJWPpQaAPbiAQfFwGWigbPi1wu2WiT\"]},\"src/abstract/OrderBookV6ArbCommon.sol\":{\"keccak256\":\"0x86534bf91571c5bde45c8489b7cf4926cdf453f98ec08c2e12b3c913b634bad5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e7b99a6d41bea365b1b7edddf96125b4c9d8a99d92b5e792a77ae852529f04bf\",\"dweb:/ipfs/QmdwY4xaCVLPYLFjy3EKBjkP8a8nGKviUKK3iP9vuW4dnE\"]},\"src/abstract/OrderBookV6RaindexRouter.sol\":{\"keccak256\":\"0x11c4a63b50e0d0aecdb279896c2a4ae1133663bca7a38e4190b4fa12a36fc386\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://a6861fdca0e65095628834ef52e4bf4c8e5aa34058f7854242cd4189dc1a166f\",\"dweb:/ipfs/Qme3Vmke6H3PzHLK73Dm4hrAB4CGtpqapHLprjL8tDzQrq\"]},\"src/concrete/arb/RaindexRouterOrderBookV6Arb.sol\":{\"keccak256\":\"0x2a4860c411bb34731fa5913889ff3d091a67d3eb3d477ad83d3f133a9da62d4e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://31ae02ce21fade0e9a00d4bf51b310e980a0875a5c94883171e33f544ef69004\",\"dweb:/ipfs/QmUCwHkSmpzgupuw5SchfS7dUW4wdemceCNtKVbQ4JY13E\"]},\"src/lib/LibOrderBook.sol\":{\"keccak256\":\"0x77b9b1fa35a044f652da6f6e9c91ee33699b3412ed651d517fbce9d180b60eb1\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://b275a56b1f85b4cee2e6e2fffb1060590978ad5b0fc5cd4f3cedf2e67287cbcb\",\"dweb:/ipfs/QmeaB2XNZsXJvLWRgNahJZCQMmmwpmLQ2txjbupEbNbYwE\"]},\"src/lib/LibOrderBookArb.sol\":{\"keccak256\":\"0x588c93733bcaebaa318c63ed3483d21b6c4f7c97c8f2c8689de9c0798f30a698\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://abd00a9eef9daa044ec525d65ca1a71dfb81aa848ab621fd0efb25715dd37b06\",\"dweb:/ipfs/QmPRoTh4xyH7GkkQBRUP2Md74QkzaeeCRrz4M8N34aERBU\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.25+commit.b61c2a91"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"struct OrderBookV6ArbConfig","name":"config","type":"tuple","components":[{"internalType":"address","name":"orderBook","type":"address"},{"internalType":"struct TaskV2","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]},{"internalType":"bytes","name":"implementationData","type":"bytes"}]}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"badInitiator","type":"address"}],"type":"error","name":"BadInitiator"},{"inputs":[{"internalType":"int256","name":"signedCoefficient","type":"int256"},{"internalType":"int256","name":"exponent","type":"int256"}],"type":"error","name":"CoefficientOverflow"},{"inputs":[{"internalType":"int256","name":"signedCoefficient","type":"int256"},{"internalType":"int256","name":"exponent","type":"int256"}],"type":"error","name":"ExponentOverflow"},{"inputs":[],"type":"error","name":"FailedCall"},{"inputs":[],"type":"error","name":"FlashLoanFailed"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"type":"error","name":"InsufficientBalance"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"type":"error","name":"InvalidSignature"},{"inputs":[{"internalType":"int256","name":"signedCoefficient","type":"int256"},{"internalType":"int256","name":"exponent","type":"int256"}],"type":"error","name":"LossyConversionToFloat"},{"inputs":[{"internalType":"int256","name":"signedCoefficient","type":"int256"},{"internalType":"int256","name":"exponent","type":"int256"}],"type":"error","name":"NegativeFixedDecimalConversion"},{"inputs":[],"type":"error","name":"NoOrders"},{"inputs":[],"type":"error","name":"ReentrancyGuardReentrantCall"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"type":"error","name":"SafeERC20FailedOperation"},{"inputs":[],"type":"error","name":"WrongTask"},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"struct OrderBookV6ArbConfig","name":"config","type":"tuple","components":[{"internalType":"address","name":"orderBook","type":"address"},{"internalType":"struct TaskV2","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]},{"internalType":"bytes","name":"implementationData","type":"bytes"}],"indexed":false}],"type":"event","name":"Construct","anonymous":false},{"inputs":[],"stateMutability":"nonpayable","type":"fallback"},{"inputs":[{"internalType":"contract IOrderBookV6","name":"orderBook","type":"address"},{"internalType":"struct TakeOrdersConfigV5[]","name":"takeOrders","type":"tuple[]","components":[{"internalType":"Float","name":"minimumIO","type":"bytes32"},{"internalType":"Float","name":"maximumIO","type":"bytes32"},{"internalType":"Float","name":"maximumIORatio","type":"bytes32"},{"internalType":"bool","name":"IOIsInput","type":"bool"},{"internalType":"struct TakeOrderConfigV4[]","name":"orders","type":"tuple[]","components":[{"internalType":"struct OrderV4","name":"order","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IOV2[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"struct IOV2[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"vaultId","type":"bytes32"}]},{"internalType":"bytes32","name":"nonce","type":"bytes32"}]},{"internalType":"uint256","name":"inputIOIndex","type":"uint256"},{"internalType":"uint256","name":"outputIOIndex","type":"uint256"},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]},{"internalType":"bytes","name":"data","type":"bytes"}]},{"internalType":"bytes","name":"exchangeData","type":"bytes"},{"internalType":"struct TaskV2","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV4","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV4","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV3","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct SignedContextV1[]","name":"signedContext","type":"tuple[]","components":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32[]","name":"context","type":"bytes32[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]}],"stateMutability":"payable","type":"function","name":"arb4"},{"inputs":[],"stateMutability":"view","type":"function","name":"iTaskHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"address","name":"initiator","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"onFlashLoan","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"stateMutability":"view","type":"function","name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}]}],"devdoc":{"kind":"dev","methods":{"arb4(address,(bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes)[],bytes,((address,address,bytes),(address,bytes32[],bytes)[]))":{"params":{"exchangeData":"Arbitrary bytes that will be passed to `_exchange` after the flash loan is taken. The inheriting contract is responsible for decoding this data and defining how it controls interactions with the external liquidity. For example, `GenericPoolOrderBookV5FlashBorrower` uses this data as a literal encoded external call.","orderBook":"The orderbook address","takeOrders":"As per `IOrderBookV5.takeOrders3`."}},"onFlashLoan(address,address,uint256,uint256,bytes)":{"details":"Receive a flash loan.","params":{"amount":"The amount of tokens lent.","data":"Arbitrary data structure, intended to contain user-defined parameters.","fee":"The additional amount of tokens to repay.","initiator":"The initiator of the loan.","token":"The loan currency."},"returns":{"_0":"The keccak256 hash of \"ERC3156FlashBorrower.onFlashLoan\""}},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas."}},"version":1},"userdoc":{"kind":"user","methods":{"arb4(address,(bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes)[],bytes,((address,address,bytes),(address,bytes32[],bytes)[]))":{"notice":"Primary function to process arbitrage opportunities. Firstly the access gate is evaluated to ensure the sender is allowed to submit arbitrage. If there is no access control the sender should expect to be front run on the arb for any sufficiently profitable opportunity. This may be desirable in some cases, as the sender may simply want to be clearing the orderbook and they are expecting profit/utility from the orderbook strategies themselves somehow. Secondly the flash loan is taken and the `_exchange` hook is called to allow the inheriting contract to convert the flash loaned assets into the assets required to fill the orders. Finally the orders are taken and the remaining assets are sent to the sender."}},"version":1}},"settings":{"remappings":["@openzeppelin/contracts/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/contracts/","axelar-gmp-sdk-solidity/=lib/sushixswap-v2/lib/axelar-gmp-sdk-solidity/","bytecode/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/bytecode/","caller/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/caller/","codegen/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/codegen/","constants/=lib/rain.interpreter/src/lib/constants/","deprecated/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/","ds-test/=lib/sushixswap-v2/lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/lib/erc4626-tests/","eval/=lib/rain.interpreter/src/lib/eval/","extern/=lib/rain.interpreter/src/lib/extern/","forge-gas-snapshot/=lib/sushixswap-v2/lib/forge-gas-snapshot/src/","forge-std/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/forge-std/src/","halmos-cheatcodes/=lib/rain.interpreter/lib/rain.string/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","integrity/=lib/rain.interpreter/src/lib/integrity/","mut/=lib/rain.interpreter/lib/rain.string/src/lib/mut/","ns/=lib/rain.interpreter/lib/rain.interpreter.interface/src/lib/ns/","op/=lib/rain.interpreter/src/lib/op/","openzeppelin-contracts/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/","parse/=lib/rain.interpreter/src/lib/parse/","rain.datacontract/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.datacontract/src/","rain.interpreter.interface/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/","rain.interpreter/=lib/rain.interpreter/src/","rain.intorastring/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.intorastring/src/","rain.lib.hash/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.hash/src/","rain.lib.memkv/=lib/rain.interpreter/lib/rain.lib.memkv/src/","rain.lib.typecast/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.typecast/src/","rain.math.binary/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.binary/src/","rain.math.fixedpoint/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.math.fixedpoint/src/","rain.math.float/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/","rain.math.saturating/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.math.float/lib/rain.math.fixedpoint/lib/rain.math.saturating/src/","rain.metadata/=lib/rain.interpreter/lib/rain.metadata/src/","rain.orderbook.interface/=lib/rain.orderbook.interface/src/","rain.sol.codegen/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.sol.codegen/src/","rain.solmem/=lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/","rain.string/=lib/rain.interpreter/lib/rain.string/src/","rain.tofu.erc20-decimals/=lib/rain.tofu.erc20-decimals/src/","sol.lib.binmaskflag/=lib/rain.interpreter/lib/sol.lib.binmaskflag/src/","state/=lib/rain.interpreter/src/lib/state/","sushixswap-v2/=lib/sushixswap-v2/"],"optimizer":{"enabled":true,"runs":1000},"metadata":{"bytecodeHash":"none","appendCBOR":false},"compilationTarget":{"src/concrete/arb/RaindexRouterOrderBookV6Arb.sol":"RaindexRouterOrderBookV6Arb"},"evmVersion":"cancun","libraries":{}},"sources":{"lib/rain.interpreter/lib/rain.interpreter.interface/lib/rain.lib.hash/src/LibHashNoAlloc.sol":{"keccak256":"0x1153c2d2ec53adca83c81c37ac958aab8b4d31e0e01f64f5189b1783375c0347","urls":["bzz-raw://79d10d5165cf0d5cc8b28b76613fc114e74c33fcc2d5632f7e284dace2247927","dweb:/ipfs/QmZEt4BQ6xsfiFNBQ55GoQq8Ats3Hb1v2hPFEWPDeqKrTv"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol":{"keccak256":"0x66c7ec42c6c43712be2107a50ab4529379bc76a632b425babec698d9da921ac6","urls":["bzz-raw://dce2778f0b638adfc5ba29c2c618c855fe725fa74a16846386aa1d56a834aa04","dweb:/ipfs/QmPV9oWnzQdi58od266j62xvviavLNHqKLZfm6k2K1qy9E"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol":{"keccak256":"0xd5ea07362ab630a6a3dee4285a74cf2377044ca2e4be472755ad64d7c5d4b69d","urls":["bzz-raw://da5e832b40fc5c3145d3781e2e5fa60ac2052c9d08af7e300dc8ab80c4343100","dweb:/ipfs/QmTzf7N5ZUdh5raqtzbM11yexiUoLC9z3Ws632MCuycq1d"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol":{"keccak256":"0x0afcb7e740d1537b252cb2676f600465ce6938398569f09ba1b9ca240dde2dfc","urls":["bzz-raw://1c299900ac4ec268d4570ecef0d697a3013cd11a6eb74e295ee3fbc945056037","dweb:/ipfs/Qmab9owJoxcA7vJT5XNayCMaUR1qxqj1NDzzisduwaJMcZ"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol":{"keccak256":"0x1a6221315ce0307746c2c4827c125d821ee796c74a676787762f4778671d4f44","urls":["bzz-raw://1bb2332a7ee26dd0b0de9b7fe266749f54820c99ab6a3bcb6f7e6b751d47ee2d","dweb:/ipfs/QmcRWpaBeCYkhy68PR3B4AgD7asuQk7PwkWxrvJbZcikLF"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC7913.sol":{"keccak256":"0xe5a126930df1d54e4a6dd5fea09010c4a7db0ea974c6c17a1e6082879f5a032b","urls":["bzz-raw://2f58f5a90328536a6c68289916bfa4ed653d871319c7b2a416ab3f6263c4f2f5","dweb:/ipfs/Qmaa9DmgUA16Urz5fuF4RbFz2NaVpNLV41ddwykSdasFUd"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2","urls":["bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303","dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0xd6fa4088198f04eef10c5bce8a2f4d60554b7ec4b987f684393c01bf79b94d9f","urls":["bzz-raw://f95ee0bbd4dd3ac730d066ba3e785ded4565e890dbec2fa7d3b9fe3bad9d0d6e","dweb:/ipfs/QmSLr6bHkPFWT7ntj34jmwfyskpwo97T9jZUrk5sz3sdtR"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0x304d732678032a9781ae85c8f204c8fba3d3a5e31c02616964e75cfdc5049098","urls":["bzz-raw://299ced486011781dc98f638059678323c03079fefae1482abaa2135b22fa92d0","dweb:/ipfs/QmbZNbcPTBxNvwChavN2kkZZs7xHhYL7mv51KrxMhsMs3j"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x0fa9e0d3a859900b5a46f70a03c73adf259603d5e05027a37fe0b45529d85346","urls":["bzz-raw://c2add4da0240c9f2ce47649c8bb6b11b40e98cf6f88b8bdc76b2704e89391710","dweb:/ipfs/QmNQTwF2uVzu4CRtNxr8bxyP9XuW6VsZuo2Nr4KR2bZr3d"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Bytes.sol":{"keccak256":"0x8140d608316521b1fd71167c3b708ebb8659da070723fc8807609553b296ee33","urls":["bzz-raw://a7bf7db66869ba1e945a0390b85da2f6afc7e42a4735ca918d0d56ac90c50147","dweb:/ipfs/QmRmNyhpBpgzSdQqLtrQCYE7H7eLnVVxh2Yy4YMrySR8AR"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Errors.sol":{"keccak256":"0x6afa713bfd42cf0f7656efa91201007ac465e42049d7de1d50753a373648c123","urls":["bzz-raw://ba1d02f4847670a1b83dec9f7d37f0b0418d6043447b69f3a29a5f9efc547fcf","dweb:/ipfs/QmQ7iH2keLNUKgq2xSWcRmuBE5eZ3F5whYAkAGzCNNoEWB"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol":{"keccak256":"0x5b4802a4352474792df3107e961d1cc593e47b820c14f69d3505cb28f5a6a583","urls":["bzz-raw://a6f86fd01f829499fe0545ff5dda07d4521988e88bfe0bf801fc15650921ed56","dweb:/ipfs/QmUUKu4ZDffHAmfkf3asuQfmLTyfpuy2Amdncc3SqfzKPG"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Panic.sol":{"keccak256":"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a","urls":["bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a","dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"keccak256":"0xa516cbf1c7d15d3517c2d668601ce016c54395bf5171918a14e2686977465f53","urls":["bzz-raw://1e1d079e8edfb58efd23a311e315a4807b01b5d1cf153f8fa2d0608b9dec3e99","dweb:/ipfs/QmTBExeX2SDTkn5xbk5ssbYSx7VqRp9H4Ux1CY4uQM4b9N"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol":{"keccak256":"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97","urls":["bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b","dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x36d1750bf1aa5fee9c52adb2f7857ab652daca722fc05dff533b364f67a1139a","urls":["bzz-raw://2e5e7052539b7849d02f3ce25acc1dce29373c11cfae9f0bc918c54b780c549a","dweb:/ipfs/QmRGE32xNkMTo6i4pHHMxjpiu77yPwnTA25SFngw2NXJys"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"keccak256":"0x360cf86214a764694dae1522a38200b1737fe90e46dcf56a0f89de143071cc20","urls":["bzz-raw://2e393290a46ca6d1fa1addb40709d26e1d250638ab6acdd103b5af21768ebc7b","dweb:/ipfs/QmPwT3tXwQ9NbGtZ99XRq7sr8LCQP8XaCrzw49JdXGn7us"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol":{"keccak256":"0x6abeed5940e1da7bb329e458db9a1c5c4ea6f86d651b952af99c6bddcd6bbb94","urls":["bzz-raw://5fe75e9a6b759c5d7fd82fb59bd4f58c672b36f0a69b84f4789b7c7895d3e61c","dweb:/ipfs/QmX28wsir8w5sS3acfJMNHcBwoPsDpqCu7WDkPnUWLMNiZ"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol":{"keccak256":"0x445455b8be33e09cf1db14e59c0d1c5aa5d312b5e754e8ae751e42313a0cae88","urls":["bzz-raw://d6939df526d1c3f1d773448f6451eebb8de344113744e0da121b6349658b1298","dweb:/ipfs/QmPffovzJ8qGRuUh57qrnWajHqYPPrntb1EA1VRh8p5TLP"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0x2d9dc2fe26180f74c11c13663647d38e259e45f95eb88f57b61d2160b0109d3e","urls":["bzz-raw://81233d1f98060113d9922180bb0f14f8335856fe9f339134b09335e9f678c377","dweb:/ipfs/QmWh6R35SarhAn4z2wH8SU456jJSYL2FgucfTFgbHJJN4E"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c","urls":["bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617","dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0x09e3f1c72d4c5cbe8e2644ab7313f8f7177533ae2f4c24cdcbbeaf520a73734c","urls":["bzz-raw://93208401215d539fa2d81626b207c1f611def7883d0e447b3b5969ebaa7b3c2c","dweb:/ipfs/QmXPxDnQPx8LAweX5ZJqEcwkvs59kP4c64VVDG1Jjq1mef"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"keccak256":"0x195533c86d0ef72bcc06456a4f66a9b941f38eb403739b00f21fd7c1abd1ae54","urls":["bzz-raw://b1d578337048cad08c1c03041cca5978eff5428aa130c781b271ad9e5566e1f8","dweb:/ipfs/QmPFKL2r9CBsMwmUqqdcFPfHZB2qcs9g1HDrPxzWSxomvy"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xb1970fac7b64e6c09611e6691791e848d5e3fe410fa5899e7df2e0afd77a99e3","urls":["bzz-raw://db5fbb3dddd8b7047465b62575d96231ba8a2774d37fb4737fbf23340fabbb03","dweb:/ipfs/QmVUSvooZKEdEdap619tcJjTLcAuH6QBdZqAzWwnAXZAWJ"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/error/ErrDecimalFloat.sol":{"keccak256":"0x3c9e3f5e6b78877add52f397e2cf452e8a1afe6b9e630fc7bbc7c2d6704d07d9","urls":["bzz-raw://9840b88bf5143a94f8e7779390b025dda83530090be3503e110aa2584250c6e4","dweb:/ipfs/QmemaALnbRKFChq5Ec1p4xdar5rDqEvdbQwGb2vzMVWhK9"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/LibDecimalFloat.sol":{"keccak256":"0x5c8820a79da0ac3c8558ae65c8b3b2b4579326755a4914a243f2475c1159b2aa","urls":["bzz-raw://edc7ddd33798964f19aa9183fa0366321f93ab03171ba334192f65bd71a1a53d","dweb:/ipfs/QmYKAKopDLGMWCfTVhwhF3vCGw6wXveKX1uTtxCyvycNkL"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/implementation/LibDecimalFloatImplementation.sol":{"keccak256":"0x182d010eee786cfa19ad44e215332c4e6fd4e9310da3e61ebd17a0309307d6b6","urls":["bzz-raw://1206a9557d6410c30ec82f02d44d3e857d7aabf46d607ee08bf415af14f8a799","dweb:/ipfs/Qmbygfmw9K8YVQdEsNEkkHxTbTiuuDgWt7yB6gMwoYGBcp"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.math.float/src/lib/table/LibLogTable.sol":{"keccak256":"0x412629a161febf0dc9c3bae0cc9fe0b8de8774d37c5f3afde2e2312478d96a98","urls":["bzz-raw://c8da5302117961caad328e80cb28296ea71aadbc291312e37d3db079d84a9777","dweb:/ipfs/QmWYzpex1Xrnjf3QM68n6mGFQ4KxE53fUUyDjwE3zNrtok"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol":{"keccak256":"0x57b7a7a5cbc2fc97200130e84fde3a8afc14e0729040b14670dacc7f63c3ac5f","urls":["bzz-raw://4e7c7ce525e882db437b488b590fae6a817b282f88d76eb4f56986b549815e57","dweb:/ipfs/QmajzM26fsaFtaAnm5cg1FZrD6N2wkLJHCxa7Atx5x6iAB"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol":{"keccak256":"0x3fc6ff807b57b681e32229380e3eda57107a1ada8dc2c1270daa84c9fca5addc","urls":["bzz-raw://a82b17ddc1db163ec548648c83dd5bb2f9f4441559452933f424e0a8dff48e57","dweb:/ipfs/QmdKoRbEAPxBRHJWWRwjh9Yrps1QXcJuX5mJmua8nvnq7B"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol":{"keccak256":"0xf51dffaeb88063748495e3184e335d9bb46f22881c2e8c930f2b68a32bdb39c2","urls":["bzz-raw://4a66ae9e4e9b9bf83b68c4d1d609fda02f8584387740354318d4eca1e2639047","dweb:/ipfs/QmXTS3azQ3ebBpJzj15HJRjTLV8zHfrFPQ7qPiic6eE3Pa"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterCallerV3.sol":{"keccak256":"0xdd13be6b4942424143613a301d020f44f67dfe6bc81550d7726cbad8d735ccdc","urls":["bzz-raw://deb8adb379085983857f311d937d09f8ea1c1ecac8864f6a63f5391ba93e0929","dweb:/ipfs/QmcFsrfhXyjwT8yF8UkwaCW8LMbQr4uTj3Lhcju2yeQpZZ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol":{"keccak256":"0x15796750d51d5498986438ce9546cbb1ec66dd73531f2b12f155459c97ea24c5","urls":["bzz-raw://e73668fe127eb60cb27794da3398d7d6e8f1f9f41d71081af7016dd114c81904","dweb:/ipfs/QmUe8ge3U3Fz3FzEQyXaPS2oLm9bAV2QZttP77WPrsckcK"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterV3.sol":{"keccak256":"0xe546b8a716e632ce6db719b6eb63e6ec86d530ac80ad619c47bedd470270e85a","urls":["bzz-raw://1359938d87ab63d170aecfbc28336db3a5598d1aacffc35f2ed1bb786ee17755","dweb:/ipfs/QmbtR2wot29rpuxu1kBVvqtHBe7NVb6c2B3sXpyhj1ERkU"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IParserV2.sol":{"keccak256":"0x29935383d2b114fd0a145977340552fcbc4b674ba89949b7b40ba23c56e3586a","urls":["bzz-raw://aefa76e1dd78f206cf93b9522c545e665e73e44585b3dddb70e03c6aefdf443e","dweb:/ipfs/QmePBeLhR1Z7DYzhmbVkm4aUKTwDHnhJCpFXniLBuN8ryK"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV1.sol":{"keccak256":"0xc0afd50701cd68eef984a63862bd6a10552d704cca6e10f06d19d920b0777c98","urls":["bzz-raw://cd3cbfa9159ceed8871f46f62c7ea235ad8537d3c6c1c004152ebf5d2d597346","dweb:/ipfs/QmPSAJXAcmDeK9Qy6s2dXdeu4GJ62FKWa69VBo4ioCPcJ9"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV2.sol":{"keccak256":"0x368ace8d0f82832f08caf264e4194647b9777c0d4a0f22d88236b30c1e4c8a63","urls":["bzz-raw://9c8a2141fcd76d6308156777b0a9e5a4f7f07fb3693461e2c12f07e4d8c87130","dweb:/ipfs/QmPnhPz6sXzh5xBGZobAPY2WJTgvQDiYWRFKavscSPu7T5"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV3.sol":{"keccak256":"0x6f6b03c0f8e37ebe4275e0d27242754c7be815ff091ad0931a7be21ab11de628","urls":["bzz-raw://1f200079a3689e0d0c8efb97040737a2b4113a82f0df5d8319af36d9ad5d8b97","dweb:/ipfs/QmXFzXZasmD9D7pAYC5wBtB748TZajy69V5tmSEXRd1VZk"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV1.sol":{"keccak256":"0xc01bc48e2479cab07fc799e26c3790c8cf97acc1f0f490c8f456f554d239a505","urls":["bzz-raw://2981aa2eae0d414bc8ad4105bedb05026cfdad7e6af8f23805dba4835ae9fd8a","dweb:/ipfs/QmQRKi5nmatC1UM2sNta9giuJX3xvvLAD5pmCeAsVWF4hF"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV2.sol":{"keccak256":"0x62c7149e3d28cd9b67d7eed183c4e59cf300689dd5cc363b011cb2cf32c1200d","urls":["bzz-raw://52cf991b2dc9581222520c32cac224f6936c75183e4c6c16fafa4450a05c0de0","dweb:/ipfs/QmZ7fiZYjnDhNnFXYCXC9iSYs8WAAwmsVxBd5XDA1tPPah"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol":{"keccak256":"0x7d2bc86fefbe372fc64381b320244fe9dbda1816867f3040c5bb3951869fe6a7","urls":["bzz-raw://90c371494080129d5acd2bc52d092fc5cfe559147f7fc855ed01e62a7837f21e","dweb:/ipfs/QmcNtPDuTxic8zqRFXf1ba6FJKmQXguxiDUY4E7wjyVwU5"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol":{"keccak256":"0xe0b94c771a7b6aa05388b4db6e238e36a4653cbfdbd3e54bbcaa7a97fc9491f4","urls":["bzz-raw://59887a7f2ef60669906c5e70831ac0c9a7345313b04efb306235280f85e1db73","dweb:/ipfs/QmP6Ny9m3sPCP65UmgGGpucSMgVAoDv6qURqyxUE95VU5Q"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV2.sol":{"keccak256":"0x0ae0d1b0ca245779f33ea3e5ffbfcc234533d5c75f4ec2a6f3042cf841bcc219","urls":["bzz-raw://0fd476c34670477ece5a217d2372637c279287af883c132f1b98db4b3ccb80bf","dweb:/ipfs/QmVBfaGYovi93pDr9HosQkacCmeXQAfgM6haTQZFJsGnoE"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IParserV1.sol":{"keccak256":"0x4f6a9e028942cebebfc84328193f1d31807aac292d9b82e2df489064aa913070","urls":["bzz-raw://54073f63db1f652571472cb2d07de297772c2420e1571a0cb9e0a805ee4347e7","dweb:/ipfs/QmXRqBreJvC8MQd5zLNgmPUdfFa4WD6gSoxvD8hecycux4"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterCallerV4.sol":{"keccak256":"0xae8309d29bcc770df07bf5f5b463e80a6c20456d9fc9dcae203975328b257423","urls":["bzz-raw://196dbc14f46e90344ed1bac0efbf87dd3dba15aeaed57678673e03f1362eb487","dweb:/ipfs/QmejhzZx6G8gw76vPKvDEfVQQ9mF1kJvx5wj9qdeDoVrPH"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterStoreV3.sol":{"keccak256":"0xda4e6583c7a6cefb7d32593d0e069fb26b4822fb07d916bef68a4b4be857078e","urls":["bzz-raw://970ae6a0f2dcfaaea8b79fc30af89043282e159910b8c375a8027ad738e4e736","dweb:/ipfs/QmQk5fhi61BcvEAUcBVFivUTzd7SZxULG5UdsNkrykjVPF"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/unstable/IInterpreterV4.sol":{"keccak256":"0x1617c780008c8f724516b1af0844f97c2c8c17ee87f515e3be3cce2d2731085f","urls":["bzz-raw://b4d206e14a81549771cc8c62f54006b545c8acb546074e2cf66213211f3363a9","dweb:/ipfs/QmNtpyVpL9riAxB8ZjHP1tp9GkdX9YVfXKVQ7an8ZL9rJD"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibContext.sol":{"keccak256":"0xaeb62b79fa753d8327c6d6af457d4b00937db798b51ba7e51d4a367176f8d8ba","urls":["bzz-raw://1c91eb4f6bb61ef79c217e15ec8cb88be4cca841d4efe70bfeb4858319032a2b","dweb:/ipfs/QmVCfM2pufm269ExXDXPTwK8EcWA5ksT8Z1XAG6YTLX34Y"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibEvaluable.sol":{"keccak256":"0xd2b8ff7feb5fdfefa6c0068ae33bd0723f1a58a066a8ee1da46608bd3ae63da3","urls":["bzz-raw://7290ceebbd842f88d4ecadc3847a555afbc8a4b4458b7def1c0cba4e28eb80bb","dweb:/ipfs/QmR28Pst8QTLUSmRUDGK8f8prA5zutCeTG3F7RYXmNJ7WH"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/ns/LibNamespace.sol":{"keccak256":"0xd621d3e5f8b404309ad5d841a3658248e979c1bd59876be3afa7aa0595b4c0e6","urls":["bzz-raw://801fa302f49f3734dd5cc6221dd25f73591ac8feae47351c18e30a98a4ae0ce1","dweb:/ipfs/QmbwXbTSMZ4u6ZsyfseBx79PeHNAWocNHXpgnaPVmLZM38"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/IOrderBookV5.sol":{"keccak256":"0x81531ce21b2cf824be60f70e14b97e8d6f5df7e09a454a690f4ed8c7d41a0dc1","urls":["bzz-raw://e8a203d32f5e423f0f5fd47f1a7be70d0cad3b69c3d1469d19a8d85e1f14c303","dweb:/ipfs/QmZH6v3Hc41SXiiuruUpntcUAXMcHqEhhpDATSArHQfe99"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v2/IOrderBookV2.sol":{"keccak256":"0x6df5dd48103f06c7a41b49e9497f9f28baa4940eb5eba4113c71b323da66e5a4","urls":["bzz-raw://e295c8ce419a26e44d1f5be80c1bfa8a852a0b47e0e332be9323a670806344aa","dweb:/ipfs/QmbAJ1j8WTdwCBLF6mjiHihfvUZFAeiv3uTXntMWPLKTt7"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v3/IOrderBookV3.sol":{"keccak256":"0x0f90c4db32d78d1c15f6230b1f0cc1e16cca908e3981f417039816e820fe0c24","urls":["bzz-raw://693ae8187a8012410ff5774e73ed11ca5279c296cfafecd75613e804197ec43f","dweb:/ipfs/QmQLPSZwcPfc8MJDnaJiUT5ktsodQ48erR1uoTtF3Fa1ju"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v4/IOrderBookV4.sol":{"keccak256":"0xc94415fcd366693e78116a72df9c6b29408ad4bdb745846c5929561a5ce2a226","urls":["bzz-raw://48f92b2281195b90bb5ee6a6b3866e27f25b9268729765eb6681de4c48b86d82","dweb:/ipfs/QmUjiXwgsYzsRRj1o3uxo2aeboAT2VZxV5RWYbkinT9jUt"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/ierc3156/IERC3156FlashBorrower.sol":{"keccak256":"0xdcd81b1110e9c3c91715ac90aef1da70066bcaba8aeb3dc23df979f7f87644f9","urls":["bzz-raw://4572efaeb9eb30ad9b766b80cb2a8101a2cec0c9e8c78c7696f4aae710c8e2c9","dweb:/ipfs/QmVsz1gtqWfxTAbsoLPvZBe6PBVXqaWNx6nu7RHr2ghLuK"],"license":"CC0-1.0"},"lib/rain.orderbook.interface/src/interface/ierc3156/IERC3156FlashLender.sol":{"keccak256":"0x119c477281a6ec109e9c729a254b39d7ccc9a9f5baa82fa28d0fa1e3bd2b6ae8","urls":["bzz-raw://19ec8289a123459659dca0389a650ca6bf6bc12d925ad7a3e61f0b1bfe68d1b6","dweb:/ipfs/QmRZ9U5ECovPFmbRaBTauFjjVQcvPA7VQL7S1zJVEBTMD5"],"license":"CC0-1.0"},"lib/rain.orderbook.interface/src/interface/unstable/IOrderBookV6.sol":{"keccak256":"0xabb3b41a1e11614ce9638fece01c78e5b8aff3598263ef38c80367b09233b801","urls":["bzz-raw://03108d4f4c13316863257e21c9be2788cd780b19ad55d4a0d3d9306d53c3f7a4","dweb:/ipfs/QmNt9vWhgj4VGHq8SVMX9HWFed5LUZNEpWMxaW3SLojPsL"],"license":"LicenseRef-DCL-1.0"},"lib/rain.tofu.erc20-decimals/src/interface/ITOFUTokenDecimals.sol":{"keccak256":"0xff728b82d787191dc32f7dac385baa1e194d313c84979b90934e6b8fd06ddbc5","urls":["bzz-raw://e789fb5fcb3396d81fa487c907486b9ba7d33312502b676e43816f777e0379fd","dweb:/ipfs/Qme1evJCUVHVpPteVvgwW84fNAJwLKfVi5xmJjNrhKEziR"],"license":"LicenseRef-DCL-1.0"},"lib/rain.tofu.erc20-decimals/src/lib/LibTOFUTokenDecimals.sol":{"keccak256":"0x50c11116ed9fab852afd4cdc010751e93485d7c08a6fc318a8582c96ab26a068","urls":["bzz-raw://f1d781fe347ab40ed0169d8ffa41f0311cceb9c7f4a31205ef118a280ecfa455","dweb:/ipfs/QmecF2QZ92oh9qEzD9BRN2r9H8VwEXZQfJZRtrbUcsESQV"],"license":"LicenseRef-DCL-1.0"},"lib/sushixswap-v2/src/interfaces/IRouteProcessor.sol":{"keccak256":"0x5b2289c992f34dd25943db3cbc27ece8b0a1addeb2631f812e7834b7ae3eac37","urls":["bzz-raw://f21522058b7fe3c18d2353b06a5ddbf2b62d2aceebf7dd6dfdc51b081452bb3f","dweb:/ipfs/QmVkicGnNWgnX1RfXJWPpQaAPbiAQfFwGWigbPi1wu2WiT"],"license":"GPL-3.0-or-later"},"src/abstract/OrderBookV6ArbCommon.sol":{"keccak256":"0x86534bf91571c5bde45c8489b7cf4926cdf453f98ec08c2e12b3c913b634bad5","urls":["bzz-raw://e7b99a6d41bea365b1b7edddf96125b4c9d8a99d92b5e792a77ae852529f04bf","dweb:/ipfs/QmdwY4xaCVLPYLFjy3EKBjkP8a8nGKviUKK3iP9vuW4dnE"],"license":"LicenseRef-DCL-1.0"},"src/abstract/OrderBookV6RaindexRouter.sol":{"keccak256":"0x11c4a63b50e0d0aecdb279896c2a4ae1133663bca7a38e4190b4fa12a36fc386","urls":["bzz-raw://a6861fdca0e65095628834ef52e4bf4c8e5aa34058f7854242cd4189dc1a166f","dweb:/ipfs/Qme3Vmke6H3PzHLK73Dm4hrAB4CGtpqapHLprjL8tDzQrq"],"license":"LicenseRef-DCL-1.0"},"src/concrete/arb/RaindexRouterOrderBookV6Arb.sol":{"keccak256":"0x2a4860c411bb34731fa5913889ff3d091a67d3eb3d477ad83d3f133a9da62d4e","urls":["bzz-raw://31ae02ce21fade0e9a00d4bf51b310e980a0875a5c94883171e33f544ef69004","dweb:/ipfs/QmUCwHkSmpzgupuw5SchfS7dUW4wdemceCNtKVbQ4JY13E"],"license":"LicenseRef-DCL-1.0"},"src/lib/LibOrderBook.sol":{"keccak256":"0x77b9b1fa35a044f652da6f6e9c91ee33699b3412ed651d517fbce9d180b60eb1","urls":["bzz-raw://b275a56b1f85b4cee2e6e2fffb1060590978ad5b0fc5cd4f3cedf2e67287cbcb","dweb:/ipfs/QmeaB2XNZsXJvLWRgNahJZCQMmmwpmLQ2txjbupEbNbYwE"],"license":"LicenseRef-DCL-1.0"},"src/lib/LibOrderBookArb.sol":{"keccak256":"0x588c93733bcaebaa318c63ed3483d21b6c4f7c97c8f2c8689de9c0798f30a698","urls":["bzz-raw://abd00a9eef9daa044ec525d65ca1a71dfb81aa848ab621fd0efb25715dd37b06","dweb:/ipfs/QmPRoTh4xyH7GkkQBRUP2Md74QkzaeeCRrz4M8N34aERBU"],"license":"LicenseRef-DCL-1.0"}},"version":1},"id":232} \ No newline at end of file From cfa521448a4495425ccf0fe497af5a15b7871f41 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Fri, 30 Jan 2026 20:16:31 +0000 Subject: [PATCH 2/6] Update index.ts --- src/core/modes/raindex/index.ts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/core/modes/raindex/index.ts b/src/core/modes/raindex/index.ts index c5058354..d051d472 100644 --- a/src/core/modes/raindex/index.ts +++ b/src/core/modes/raindex/index.ts @@ -156,9 +156,8 @@ export async function findBestRaindexRouterTrade( ), ); - const listWithProfits = []; for (const counterparty of optimals) { - listWithProfits.push({ + optimalTradeOptions.push({ ...estimateProfit( orderDetails, counterparty, @@ -170,13 +169,6 @@ export async function findBestRaindexRouterTrade( counterparty, }); } - // sort desc and pick the best - listWithProfits.sort((a, b) => { - if (a.profit < b.profit) return 1; - else if (a.profit > b.profit) return -1; - else return 0; - }); - optimalTradeOptions.push(...listWithProfits.slice(0, 1)); } // sort desc based on profitability @@ -186,8 +178,8 @@ export async function findBestRaindexRouterTrade( else return 0; }); - // simulate top picks - const promises = optimalTradeOptions.map((args) => { + // simulate top 3 picks + const promises = optimalTradeOptions.slice(0, 3).map((args) => { const { quote, profit, From bf09579b237a27c54fadcc1571fd32cc386bcbad Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Fri, 30 Jan 2026 20:32:49 +0000 Subject: [PATCH 3/6] Update index.ts --- src/core/modes/raindex/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/modes/raindex/index.ts b/src/core/modes/raindex/index.ts index d051d472..b06faa94 100644 --- a/src/core/modes/raindex/index.ts +++ b/src/core/modes/raindex/index.ts @@ -98,7 +98,7 @@ export async function findBestRaindexRouterTrade( }); // exit early if no route found - if (quoteResult.isErr()) { + if (!quoteResult || quoteResult.isErr()) { continue; } const quote = quoteResult.value; From cfecbefb5dbab102764ead2c69e1b71861969422 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Tue, 3 Feb 2026 00:28:50 +0000 Subject: [PATCH 4/6] fmt --- src/core/modes/raindex/index.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/modes/raindex/index.ts b/src/core/modes/raindex/index.ts index b06faa94..205d1425 100644 --- a/src/core/modes/raindex/index.ts +++ b/src/core/modes/raindex/index.ts @@ -12,7 +12,11 @@ import { SimulationResult, TradeType } from "../../types"; import { getOptimalSortedList } from "../../../order/pair"; import { SushiRouter, SushiRouterQuote } from "../../../router"; import { Result, extendObjectWithHeader } from "../../../common"; -import { calcCounterpartyInputProfit, calcCounterpartyInputToEthPrice, calcCounterpartyOutputToEthPrice } from "./utils"; +import { + calcCounterpartyInputProfit, + calcCounterpartyInputToEthPrice, + calcCounterpartyOutputToEthPrice, +} from "./utils"; export enum RouteLegType { RAINDEX, @@ -258,7 +262,10 @@ export function estimateProfit( counterpartyInputToEthPrice: bigint; counterpartyOutputToEthPrice: bigint; } { - const { counterpartyMaxOutput, counterpartyInputProfit } = calcCounterpartyInputProfit(counterparty, quote) + const { counterpartyMaxOutput, counterpartyInputProfit } = calcCounterpartyInputProfit( + counterparty, + quote, + ); const orderMaxInput = (orderDetails.takeOrder.quote!.maxOutput * orderDetails.takeOrder.quote!.ratio) / ONE18; // cant trade, so 0 profit From 67fbad1bb14c42dae5b921495a74bc4406fb62bc Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Wed, 18 Feb 2026 02:15:55 +0000 Subject: [PATCH 5/6] update --- src/core/modes/raindex/simulation.test.ts | 3 +++ src/core/modes/raindex/simulation.ts | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/core/modes/raindex/simulation.test.ts b/src/core/modes/raindex/simulation.test.ts index 13bcb814..80e879e0 100644 --- a/src/core/modes/raindex/simulation.test.ts +++ b/src/core/modes/raindex/simulation.test.ts @@ -72,6 +72,9 @@ describe("Test RaindexRouterTradeSimulator", () => { gasPrice: 1000000000000000000n, chainConfig: { id: 1, + routeProcessors: { + "4": "0xrouter", + }, }, contracts: { getAddressesForTrade: vi.fn().mockReturnValue({ diff --git a/src/core/modes/raindex/simulation.ts b/src/core/modes/raindex/simulation.ts index d0dc31da..116d882c 100644 --- a/src/core/modes/raindex/simulation.ts +++ b/src/core/modes/raindex/simulation.ts @@ -134,8 +134,15 @@ export class RaindexRouterTradeSimulator extends TradeSimulatorBase { const legs = [ { routeLegType: RouteLegType.SUSHI, - destination: addresses.destination as `0x${string}`, - data: rpParams.routeCode, + destination: this.tradeArgs.solver.state.chainConfig.routeProcessors["4"], + data: encodeAbiParameters( + [{ type: "address" }, { type: "address" }, { type: "bytes" }], + [ + this.tradeArgs.orderDetails.sellToken as `0x${string}`, + this.tradeArgs.counterpartyOrderDetails.buyToken as `0x${string}`, + rpParams.routeCode, + ], + ), }, ]; const exchangeData = encodeAbiParameters(ABI.Orderbook.V6.Primary.RouteLeg, [legs]); From b26e8ff377d98f8d2844593b8964212c8b5fadbe Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Mon, 23 Feb 2026 14:29:08 +0000 Subject: [PATCH 6/6] update --- src/core/modes/raindex/index.test.ts | 249 +++++++++++++++++++++++---- src/core/modes/raindex/index.ts | 124 +++++++------ src/core/modes/raindex/utils.test.ts | 140 +-------------- src/core/modes/raindex/utils.ts | 36 +--- 4 files changed, 289 insertions(+), 260 deletions(-) diff --git a/src/core/modes/raindex/index.test.ts b/src/core/modes/raindex/index.test.ts index f66b9d6e..dd1742be 100644 --- a/src/core/modes/raindex/index.test.ts +++ b/src/core/modes/raindex/index.test.ts @@ -13,6 +13,7 @@ import { extendObjectWithHeader } from "../../../common"; import { RaindexRouterTradeSimulator } from "./simulation"; import { estimateProfit, findBestRaindexRouterTrade } from "./index"; import { describe, it, expect, vi, Mock, beforeEach, assert } from "vitest"; +import { ONE18 } from "../../../math"; // mocks vi.mock("../../../common", async (importOriginal) => ({ @@ -218,7 +219,7 @@ describe("Test findBestRaindexRouterTrade function", () => { assert(result.isErr()); expect(result.error.type).toBe(TradeType.Raindex); expect(result.error.spanAttributes.error).toContain( - "no counterparties found for raindex router trade", + "no counterparties (with profitable trade) found for raindex router trade", ); expect(extendObjectWithHeader).not.toHaveBeenCalled(); expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); @@ -292,7 +293,7 @@ describe("Test findBestRaindexRouterTrade function", () => { assert(result.isErr()); expect(result.error.type).toBe(TradeType.Raindex); expect(result.error.spanAttributes.error).toContain( - "no counterparties found for raindex router trade", + "no counterparties (with profitable trade) found for raindex router trade", ); expect(extendObjectWithHeader).not.toHaveBeenCalled(); expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); @@ -417,7 +418,7 @@ describe("Test findBestRaindexRouterTrade function", () => { assert(result.isErr()); expect(result.error.type).toBe(TradeType.Raindex); expect(result.error.spanAttributes.error).toContain( - "no counterparties found for raindex router trade", + "no counterparties (with profitable trade) found for raindex router trade", ); expect(extendObjectWithHeader).not.toHaveBeenCalled(); expect(isV4OrderbookV6Spy).toHaveBeenCalledWith(orderDetails); @@ -470,8 +471,8 @@ describe("Test findBestRaindexRouterTrade function", () => { takeOrder: { id: "0xcounterpartyhash", quote: { - maxOutput: parseUnits("50", 18), - ratio: parseUnits("1", 18), + maxOutput: parseUnits("200", 18), + ratio: parseUnits("0.25", 18), }, struct: { orderbook: { id: "0xorderbook" }, @@ -492,7 +493,7 @@ describe("Test findBestRaindexRouterTrade function", () => { ); const mockQuote = { - amountOut: 100n, + amountOut: parseUnits("200", 18), price: parseUnits("1", 18), route: { pcMap: new Map(), @@ -578,8 +579,8 @@ describe("Test findBestRaindexRouterTrade function", () => { takeOrder: { id: "0xhash", quote: { - maxOutput: parseUnits("100", 18), - ratio: parseUnits("1", 18), + maxOutput: parseUnits("125", 18), + ratio: parseUnits("0.8", 18), }, struct: { orderbook: { id: "0xorderbook" }, @@ -595,7 +596,7 @@ describe("Test findBestRaindexRouterTrade function", () => { takeOrder: { id: "0xcounterparty1", quote: { - maxOutput: parseUnits("50", 18), + maxOutput: parseUnits("120", 18), ratio: parseUnits("1", 18), }, struct: { @@ -612,8 +613,8 @@ describe("Test findBestRaindexRouterTrade function", () => { takeOrder: { id: "0xcounterparty2", quote: { - maxOutput: parseUnits("60", 18), - ratio: parseUnits("1.2", 18), + maxOutput: parseUnits("160", 18), + ratio: parseUnits("0.6", 18), }, struct: { orderbook: { id: "0xorderbook" }, @@ -643,7 +644,7 @@ describe("Test findBestRaindexRouterTrade function", () => { ); const mockQuote = { - amountOut: 100n, + amountOut: parseUnits("200", 18), price: parseUnits("1", 18), route: { pcMap: new Map(), @@ -728,7 +729,7 @@ describe("Test findBestRaindexRouterTrade function", () => { type: TradeType.Raindex, solver, orderDetails, - counterpartyOrderDetails: counterparty1, + counterpartyOrderDetails: counterparty2, signer, maximumInputFixed: expect.any(BigInt), counterpartyInputToEthPrice: expect.any(BigInt), @@ -743,7 +744,7 @@ describe("Test findBestRaindexRouterTrade function", () => { type: TradeType.Raindex, solver, orderDetails, - counterpartyOrderDetails: counterparty2, + counterpartyOrderDetails: counterparty1, signer, maximumInputFixed: expect.any(BigInt), counterpartyInputToEthPrice: expect.any(BigInt), @@ -784,8 +785,8 @@ describe("Test findBestRaindexRouterTrade function", () => { takeOrder: { id: "0xcounterpartyhash", quote: { - maxOutput: parseUnits("50", 18), - ratio: parseUnits("1", 18), + maxOutput: parseUnits("150", 18), + ratio: parseUnits("0.3", 18), }, struct: { orderbook: { id: "0xorderbook" }, @@ -806,7 +807,7 @@ describe("Test findBestRaindexRouterTrade function", () => { ); const mockQuote = { - amountOut: 100n, + amountOut: parseUnits("200", 18), price: parseUnits("1", 18), route: { pcMap: new Map(), @@ -885,22 +886,20 @@ describe("Test findBestRaindexRouterTrade function", () => { }); describe("Test estimateProfit function", () => { - let calcCounterpartyInputProfitSpy: any; let calcCounterpartyOutputToEthPriceSpy: any; let calcCounterpartyInputToEthPriceSpy: any; beforeEach(() => { - calcCounterpartyInputProfitSpy = vi.spyOn(utils, "calcCounterpartyInputProfit"); calcCounterpartyOutputToEthPriceSpy = vi.spyOn(utils, "calcCounterpartyOutputToEthPrice"); calcCounterpartyInputToEthPriceSpy = vi.spyOn(utils, "calcCounterpartyInputToEthPrice"); }); - it("should return zero profit when order max input exceeds counterparty max output", () => { + it("should return zero profit when router output is lower than counterparty order max input", () => { const orderDetails = { takeOrder: { quote: { maxOutput: parseUnits("100", 18), - ratio: parseUnits("3", 18), // High ratio + ratio: parseUnits("2", 18), }, }, } as any; @@ -915,31 +914,36 @@ describe("Test estimateProfit function", () => { }, } as any; - const quote = {} as any; + const quote = { + amountOut: parseUnits("200", 18), + price: parseUnits("1", 18), + route: { + pcMap: new Map(), + route: { legs: [] }, + }, + } as any; - (calcCounterpartyInputProfitSpy as Mock).mockReturnValueOnce({ - counterpartyMaxOutput: 0n, - counterpartyInputProfit: parseUnits("200", 18), - }); const result = estimateProfit(orderDetails, counterparty, quote); - // orderMaxInput: 100e18 * 3e18 / 1e18 = 300e18 - // counterpartyMaxOutput: 40e18 (less than 300e18) + // orderMaxInput: 100e18 * 2e18 / 1e18 = 200e18 + // counterpartyMaxOutput: 50e18 (less than 200e18) + // orderMaxOutput: (min of 50e18 and 400e18) / 2e18 = 25e18 + // router output = 1 * 25e18 = 25e18 + // router output 25e18 < counterparty maxoutput 50e18 // Cannot trade, returns zero expect(result.profit).toBe(0n); expect(result.counterpartyInputToEthPrice).toBe(0n); expect(result.counterpartyOutputToEthPrice).toBe(0n); - expect(calcCounterpartyInputProfitSpy).toHaveBeenCalledWith(counterparty, quote); expect(calcCounterpartyInputToEthPriceSpy).not.toHaveBeenCalled(); expect(calcCounterpartyOutputToEthPriceSpy).not.toHaveBeenCalled(); }); - it("should return corrrect profit when order max input is lower counterparty max output", () => { + it("should return corrrect profit with only counterparty input profit", () => { const orderDetails = { takeOrder: { quote: { maxOutput: parseUnits("100", 18), - ratio: parseUnits("3", 18), + ratio: parseUnits("2", 18), }, }, } as any; @@ -954,22 +958,191 @@ describe("Test estimateProfit function", () => { }, } as any; - const quote = {} as any; + const quote = { + amountOut: parseUnits("200", 18), + price: parseUnits("3", 18), + route: { + pcMap: new Map(), + route: { legs: [] }, + }, + } as any; - (calcCounterpartyInputProfitSpy as Mock).mockReturnValueOnce({ - counterpartyMaxOutput: parseUnits("400", 18), - counterpartyInputProfit: parseUnits("100", 18), - }); (calcCounterpartyInputToEthPriceSpy as Mock).mockReturnValueOnce(parseUnits("1.5", 18)); (calcCounterpartyOutputToEthPriceSpy as Mock).mockReturnValueOnce(parseUnits("2.5", 18)); const result = estimateProfit(orderDetails, counterparty, quote, "1", "2"); // orderMaxInput: 100e18 * 3e18 / 1e18 = 300e18 // counterpartyMaxOutput: 400e18 (more than 300e18) - expect(result.profit).toBe(parseUnits("250", 18) + parseUnits("150", 18)); + + // orderMaxInput: 100e18 * 2e18 / 1e18 = 200e18 + // counterpartyMaxOutput: 50e18 (less than 200e18) + // orderMaxOutput: (min of 50e18 and 400e18) / 2e18 = 25e18 + // router output = 3 * 25e18 = 75e18 + // router output 75e18 > counterparty maxoutput 50e18 + // counterparty input profit: 75e18 - 50e18 = 25e18 * (1.5 to eth price) + expect(result.profit).toBe((parseUnits("25", 18) * parseUnits("1.5", 18)) / ONE18); + expect(result.counterpartyInputToEthPrice).toBe(parseUnits("1.5", 18)); + expect(result.counterpartyOutputToEthPrice).toBe(parseUnits("2.5", 18)); + expect(calcCounterpartyInputToEthPriceSpy).toHaveBeenCalledWith(quote, "2"); + expect(calcCounterpartyOutputToEthPriceSpy).toHaveBeenCalledWith( + parseUnits("1.5", 18), + counterparty.takeOrder.quote!.ratio, + "1", + ); + }); + + it("should return corrrect profit with only counterparty output profit capped at counterparty maxoutput", () => { + const orderDetails = { + takeOrder: { + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("2", 18), + }, + }, + } as any; + + const counterparty = { + buyTokenDecimals: 18, + takeOrder: { + quote: { + maxOutput: parseUnits("250", 18), + ratio: parseUnits("0.2", 18), + }, + }, + } as any; + + const quote = { + amountOut: parseUnits("200", 18), + price: parseUnits("0.5", 18), + route: { + pcMap: new Map(), + route: { legs: [] }, + }, + } as any; + + (calcCounterpartyInputToEthPriceSpy as Mock).mockReturnValueOnce(parseUnits("1.5", 18)); + (calcCounterpartyOutputToEthPriceSpy as Mock).mockReturnValueOnce(parseUnits("2.5", 18)); + const result = estimateProfit(orderDetails, counterparty, quote, "1", "2"); + + // orderMaxInput: 100e18 * 2e18 / 1e18 = 200e18 + // counterpartyMaxOutput: 250e18 (more than 200e18) + // orderMaxOutput: (min of 250e18 and 200e18) / 2e18 = 100e18 + // router output = 0.5 * 100e18 = 50e18 + // router output covers full counterparty trade, so no counterparty input profir + // counterparty output profit: 250e18(counterparty output) - 200e18 (order max input) = 50e18 + // profit to eth: 50e18 * 2.5 + expect(result.profit).toBe((parseUnits("50", 18) * parseUnits("2.5", 18)) / ONE18); + expect(result.counterpartyInputToEthPrice).toBe(parseUnits("1.5", 18)); + expect(result.counterpartyOutputToEthPrice).toBe(parseUnits("2.5", 18)); + expect(calcCounterpartyInputToEthPriceSpy).toHaveBeenCalledWith(quote, "2"); + expect(calcCounterpartyOutputToEthPriceSpy).toHaveBeenCalledWith( + parseUnits("1.5", 18), + counterparty.takeOrder.quote!.ratio, + "1", + ); + }); + + it("should return corrrect profit with only counterparty output profit capped at counterparty maxinput from router", () => { + const orderDetails = { + takeOrder: { + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("2", 18), + }, + }, + } as any; + + const counterparty = { + buyTokenDecimals: 18, + takeOrder: { + quote: { + maxOutput: parseUnits("400", 18), + ratio: parseUnits("0.25", 18), + }, + }, + } as any; + + const quote = { + amountOut: parseUnits("200", 18), + price: parseUnits("0.8", 18), + route: { + pcMap: new Map(), + route: { legs: [] }, + }, + } as any; + + (calcCounterpartyInputToEthPriceSpy as Mock).mockReturnValueOnce(parseUnits("1.5", 18)); + (calcCounterpartyOutputToEthPriceSpy as Mock).mockReturnValueOnce(parseUnits("2.5", 18)); + const result = estimateProfit(orderDetails, counterparty, quote, "1", "2"); + + // orderMaxInput: 100e18 * 2e18 / 1e18 = 200e18 + // counterpartyMaxOutput: 400e18 (more than 200e18) + // orderMaxOutput: (min of 200e18 and 400e18) / 2e18 = 100e18 + // router output = 0.8 * 100e18 = 80e18 + // router output covers partial counterparty trade, so no counterparty input profit, but partial countery output profit + // counterparty output: 80e18 / 0.25 = 320e18 + // counterparty output profit: 320e18 (counterparty output) - 200e18 (order max input) = 120e18 + // profit to eth: 120e18 * 2.5 + expect(result.profit).toBe((parseUnits("120", 18) * parseUnits("2.5", 18)) / ONE18); + expect(result.counterpartyInputToEthPrice).toBe(parseUnits("1.5", 18)); + expect(result.counterpartyOutputToEthPrice).toBe(parseUnits("2.5", 18)); + expect(calcCounterpartyInputToEthPriceSpy).toHaveBeenCalledWith(quote, "2"); + expect(calcCounterpartyOutputToEthPriceSpy).toHaveBeenCalledWith( + parseUnits("1.5", 18), + counterparty.takeOrder.quote!.ratio, + "1", + ); + }); + + it("should return corrrect profit with both counterparty io profits", () => { + const orderDetails = { + takeOrder: { + quote: { + maxOutput: parseUnits("100", 18), + ratio: parseUnits("2", 18), + }, + }, + } as any; + + const counterparty = { + buyTokenDecimals: 18, + takeOrder: { + quote: { + maxOutput: parseUnits("500", 18), + ratio: parseUnits("0.2", 18), + }, + }, + } as any; + + const quote = { + amountOut: parseUnits("200", 18), + price: parseUnits("1.5", 18), + route: { + pcMap: new Map(), + route: { legs: [] }, + }, + } as any; + + (calcCounterpartyInputToEthPriceSpy as Mock).mockReturnValueOnce(parseUnits("1.5", 18)); + (calcCounterpartyOutputToEthPriceSpy as Mock).mockReturnValueOnce(parseUnits("2.5", 18)); + const result = estimateProfit(orderDetails, counterparty, quote, "1", "2"); + + // orderMaxInput: 100e18 * 2e18 / 1e18 = 200e18 + // counterpartyMaxOutput: 500e18 (more than 200e18) + // orderMaxOutput: (min of 200e18 and 500e18) / 2e18 = 100e18 + // router output = 1.5 * 100e18 = 150e18 + // counterparty max input: 500e18 / 0.2 = 100e18 + // router output covers full counterparty trade, with extra tokens remaining + // counterparty input profit: 150e18 - 100e18 = 50e18 + // counterparty input profit to eth: 50e18 * 1.5 + // counterparty output profit: 500e18 (counterparty output) - 200e18 (order max input) = 300e18 + // profit to eth: 300e18 * 2.5 + expect(result.profit).toBe( + (parseUnits("300", 18) * parseUnits("2.5", 18)) / ONE18 + + (parseUnits("50", 18) * parseUnits("1.5", 18)) / ONE18, + ); expect(result.counterpartyInputToEthPrice).toBe(parseUnits("1.5", 18)); expect(result.counterpartyOutputToEthPrice).toBe(parseUnits("2.5", 18)); - expect(calcCounterpartyInputProfitSpy).toHaveBeenCalledWith(counterparty, quote); expect(calcCounterpartyInputToEthPriceSpy).toHaveBeenCalledWith(quote, "2"); expect(calcCounterpartyOutputToEthPriceSpy).toHaveBeenCalledWith( parseUnits("1.5", 18), diff --git a/src/core/modes/raindex/index.ts b/src/core/modes/raindex/index.ts index 205d1425..6e0679df 100644 --- a/src/core/modes/raindex/index.ts +++ b/src/core/modes/raindex/index.ts @@ -12,11 +12,7 @@ import { SimulationResult, TradeType } from "../../types"; import { getOptimalSortedList } from "../../../order/pair"; import { SushiRouter, SushiRouterQuote } from "../../../router"; import { Result, extendObjectWithHeader } from "../../../common"; -import { - calcCounterpartyInputProfit, - calcCounterpartyInputToEthPrice, - calcCounterpartyOutputToEthPrice, -} from "./utils"; +import { calcCounterpartyInputToEthPrice, calcCounterpartyOutputToEthPrice } from "./utils"; export enum RouteLegType { RAINDEX, @@ -183,41 +179,44 @@ export async function findBestRaindexRouterTrade( }); // simulate top 3 picks - const promises = optimalTradeOptions.slice(0, 3).map((args) => { - const { - quote, - profit, - rpParams, - routeVisual, - counterparty: counterpartyOrderDetails, - counterpartyInputToEthPrice, - counterpartyOutputToEthPrice, - } = args; - if (!Pair.isV4OrderbookV6(counterpartyOrderDetails)) { - spanAttributes["error"] = - "Cannot trade as raindex router as counterparty order is not deployed on v6 orderbook"; - return Result.err({ + const promises = optimalTradeOptions + .filter((v) => v.profit > 0n) + .slice(0, 3) + .map((args) => { + const { + quote, + profit, + rpParams, + routeVisual, + counterparty: counterpartyOrderDetails, + counterpartyInputToEthPrice, + counterpartyOutputToEthPrice, + } = args; + if (!Pair.isV4OrderbookV6(counterpartyOrderDetails)) { + spanAttributes["error"] = + "Cannot trade as raindex router as counterparty order is not deployed on v6 orderbook"; + return Result.err({ + type: TradeType.Raindex, + spanAttributes, + reason: SimulationHaltReason.UndefinedTradeDestinationAddress, + }) as SimulationResult; + } + return RaindexRouterTradeSimulator.withArgs({ type: TradeType.Raindex, - spanAttributes, - reason: SimulationHaltReason.UndefinedTradeDestinationAddress, - }) as SimulationResult; - } - return RaindexRouterTradeSimulator.withArgs({ - type: TradeType.Raindex, - solver: this, - orderDetails, - counterpartyOrderDetails, - signer, - maximumInputFixed, - counterpartyInputToEthPrice, - counterpartyOutputToEthPrice, - blockNumber, - quote, - profit, - rpParams, - routeVisual, - }).trySimulateTrade(); - }); + solver: this, + orderDetails, + counterpartyOrderDetails, + signer, + maximumInputFixed, + counterpartyInputToEthPrice, + counterpartyOutputToEthPrice, + blockNumber, + quote, + profit, + rpParams, + routeVisual, + }).trySimulateTrade(); + }); const results = await Promise.all(promises); if (results.some((res) => res.isOk())) { @@ -241,7 +240,8 @@ export async function findBestRaindexRouterTrade( allNoneNodeErrors.push(res.error.noneNodeError); } if (!results.length) { - spanAttributes["error"] = "no counterparties found for raindex router trade"; + spanAttributes["error"] = + "no counterparties (with profitable trade) found for raindex router trade"; } return Result.err({ type: TradeType.Raindex, @@ -262,22 +262,50 @@ export function estimateProfit( counterpartyInputToEthPrice: bigint; counterpartyOutputToEthPrice: bigint; } { - const { counterpartyMaxOutput, counterpartyInputProfit } = calcCounterpartyInputProfit( - counterparty, - quote, - ); - const orderMaxInput = + let orderMaxInput = (orderDetails.takeOrder.quote!.maxOutput * orderDetails.takeOrder.quote!.ratio) / ONE18; - // cant trade, so 0 profit - if (orderMaxInput > counterpartyMaxOutput) { + let orderMaxOuput = orderDetails.takeOrder.quote!.maxOutput; + + // cap order's io tomax possible trade size from counterparty + if (counterparty.takeOrder.quote!.maxOutput < orderMaxInput) { + orderMaxInput = counterparty.takeOrder.quote!.maxOutput; + orderMaxOuput = + orderDetails.takeOrder.quote!.ratio === 0n + ? orderDetails.takeOrder.quote!.maxOutput + : (orderMaxInput * ONE18) / orderDetails.takeOrder.quote!.ratio; + } + + // calculate router output and counterparty max input and profit + const routerOutput = (orderMaxOuput * quote.price) / ONE18; + let counterpartyMaxInput = + (counterparty.takeOrder.quote!.maxOutput * counterparty.takeOrder.quote!.ratio) / ONE18; + let counterpartyInputProfit = routerOutput - counterpartyMaxInput; + + // cap counterparty max input if router output is lower + if (routerOutput < counterpartyMaxInput) { + counterpartyMaxInput = routerOutput; + counterpartyInputProfit = 0n; + } + + // calculate counterparty max output from the calculated coiunterparty max input + const counterpartyMaxOutput = + counterparty.takeOrder.quote!.ratio === 0n + ? counterparty.takeOrder.quote!.maxOutput + : (counterpartyMaxInput * ONE18) / counterparty.takeOrder.quote!.ratio; + + // short circuit, cant trade + // as the counterparty max output now is lower than order's max input + if (counterpartyMaxOutput < orderMaxInput) { return { profit: 0n, counterpartyInputToEthPrice: 0n, counterpartyOutputToEthPrice: 0n, }; } - const counterpartyOutputProfit = counterpartyMaxOutput - orderMaxInput; + // from here on we are sure is trade is possible + // and we can calcultae the possible profits + const counterpartyOutputProfit = counterpartyMaxOutput - orderMaxInput; const counterpartyInputToEthPrice = calcCounterpartyInputToEthPrice(quote, outputToEthPrice); const counterpartyOutputToEthPrice = calcCounterpartyOutputToEthPrice( counterpartyInputToEthPrice, diff --git a/src/core/modes/raindex/utils.test.ts b/src/core/modes/raindex/utils.test.ts index 2bc58b66..60a86b3e 100644 --- a/src/core/modes/raindex/utils.test.ts +++ b/src/core/modes/raindex/utils.test.ts @@ -1,144 +1,6 @@ import { parseUnits } from "viem"; import { describe, it, expect } from "vitest"; -import { - calcCounterpartyInputProfit, - calcCounterpartyInputToEthPrice, - calcCounterpartyOutputToEthPrice, -} from "./utils"; - -describe("Test calcCounterpartyInputProfit function", () => { - it("should return zero input profit when sushi output equals counterparty max input", () => { - const counterparty = { - buyTokenDecimals: 18, - takeOrder: { - quote: { - maxOutput: parseUnits("100", 18), - ratio: parseUnits("2", 18), - }, - }, - } as any; - - const quote = { - amountOut: parseUnits("200", 18), - price: parseUnits("1", 18), - } as any; - - const result = calcCounterpartyInputProfit(counterparty, quote); - - // maxSushiOutput: 200e18 - // counterpartyMaxInputFixed: 100e18 * 2e18 / 1e18 = 200e18 - // counterpartyInputProfit: 0 (equal) - // counterpartyMaxOutput: 100e18 (full capacity) - expect(result.counterpartyInputProfit).toBe(0n); - expect(result.counterpartyMaxOutput).toBe(parseUnits("100", 18)); - }); - - it("should calculate positive input profit when sushi output exceeds counterparty max input", () => { - const counterparty = { - buyTokenDecimals: 18, - takeOrder: { - quote: { - maxOutput: parseUnits("100", 18), - ratio: parseUnits("2", 18), - }, - }, - } as any; - - const quote = { - amountOut: parseUnits("250", 18), - price: parseUnits("1", 18), - } as any; - - const result = calcCounterpartyInputProfit(counterparty, quote); - - // maxSushiOutput: 250e18 - // counterpartyMaxInputFixed: 100e18 * 2e18 / 1e18 = 200e18 - // counterpartyInputProfit: 250e18 - 200e18 = 50e18 - // counterpartyMaxOutput: 100e18 (at full capacity) - expect(result.counterpartyInputProfit).toBe(parseUnits("50", 18)); - expect(result.counterpartyMaxOutput).toBe(parseUnits("100", 18)); - }); - - it("should return zero input profit when sushi output is less than counterparty max input", () => { - const counterparty = { - buyTokenDecimals: 18, - takeOrder: { - quote: { - maxOutput: parseUnits("100", 18), - ratio: parseUnits("2", 18), - }, - }, - } as any; - - const quote = { - amountOut: parseUnits("150", 18), - price: parseUnits("1", 18), - } as any; - - const result = calcCounterpartyInputProfit(counterparty, quote); - - // maxSushiOutput: 150e18 - // counterpartyMaxInputFixed: 100e18 * 2e18 / 1e18 = 200e18 - // counterpartyInputProfit: 0 (less than max) - // counterpatryMaxInput: 150e18 - // counterpartyMaxOutput: 150e18 * 1e18 / 2e18 = 75e18 - expect(result.counterpartyInputProfit).toBe(0n); - expect(result.counterpartyMaxOutput).toBe(parseUnits("75", 18)); - }); - - it("should handle counterparty ratio of zero", () => { - const counterparty = { - buyTokenDecimals: 18, - takeOrder: { - quote: { - maxOutput: parseUnits("100", 18), - ratio: 0n, - }, - }, - } as any; - - const quote = { - amountOut: parseUnits("50", 18), - price: parseUnits("1", 18), - } as any; - - const result = calcCounterpartyInputProfit(counterparty, quote); - - // maxSushiOutput: 50e18 - // counterpartyMaxInputFixed: 100e18 * 0 / 1e18 = 0 - // counterpartyInputProfit: 50e18 - 0 = 50e18 - // ratio is 0, so counterpartyMaxOutput uses original maxOutput - expect(result.counterpartyInputProfit).toBe(parseUnits("50", 18)); - expect(result.counterpartyMaxOutput).toBe(parseUnits("100", 18)); - }); - - it("should calculate counterparty max output when not at full capacity", () => { - const counterparty = { - buyTokenDecimals: 18, - takeOrder: { - quote: { - maxOutput: parseUnits("200", 18), - ratio: parseUnits("2", 18), - }, - }, - } as any; - - const quote = { - amountOut: parseUnits("300", 18), - price: parseUnits("1", 18), - } as any; - - const result = calcCounterpartyInputProfit(counterparty, quote); - - // maxSushiOutput: 300e18 - // counterpartyMaxInputFixed: 200e18 * 2e18 / 1e18 = 400e18 - // counterpartyInputProfit: 0 (300 < 400) - // counterpatryMaxInput: 300e18 - // counterpartyMaxOutput: 300e18 * 1e18 / 2e18 = 150e18 - expect(result.counterpartyInputProfit).toBe(0n); - expect(result.counterpartyMaxOutput).toBe(parseUnits("150", 18)); - }); -}); +import { calcCounterpartyInputToEthPrice, calcCounterpartyOutputToEthPrice } from "./utils"; describe("Test calcCounterpartyOutputToEthPrice function", () => { it("should use provided counterpartyOutputToEthPrice when available", () => { diff --git a/src/core/modes/raindex/utils.ts b/src/core/modes/raindex/utils.ts index 9b60b977..c4b28459 100644 --- a/src/core/modes/raindex/utils.ts +++ b/src/core/modes/raindex/utils.ts @@ -1,41 +1,7 @@ import { parseUnits } from "viem"; -import { Pair } from "../../../order"; -import { ONE18, scaleTo18 } from "../../../math"; +import { ONE18 } from "../../../math"; import { SushiRouterQuote } from "../../../router"; -export function calcCounterpartyInputProfit( - counterparty: Pair, - quote: SushiRouterQuote, -): { - counterpartyInputProfit: bigint; - counterpartyMaxOutput: bigint; -} { - const maxSushiOutput = scaleTo18(quote.amountOut, counterparty.buyTokenDecimals); - const counterpartyMaxInputFixed = - (counterparty.takeOrder.quote!.maxOutput * counterparty.takeOrder.quote!.ratio) / ONE18; - let counterpartyInputProfit = 0n; - let counterpatryMaxInput = maxSushiOutput; - if (maxSushiOutput > counterpartyMaxInputFixed) { - counterpartyInputProfit = maxSushiOutput - counterpartyMaxInputFixed; - counterpatryMaxInput = counterpartyMaxInputFixed; - } - let counterpartyMaxOutput = counterparty.takeOrder.quote!.maxOutput; - if ( - counterparty.takeOrder.quote!.ratio === 0n || - counterpatryMaxInput === counterpartyMaxInputFixed - ) { - counterpartyMaxOutput = counterparty.takeOrder.quote!.maxOutput; - } else { - counterpartyMaxOutput = - (counterpatryMaxInput * ONE18) / counterparty.takeOrder.quote!.ratio; - } - - return { - counterpartyInputProfit, - counterpartyMaxOutput, - }; -} - export function calcCounterpartyOutputToEthPrice( counterpartyInputToEthPrice: bigint, ratio: bigint,