From 0a74b5ac1aa721e0fa6a4385c1f1eb520dd147d1 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Thu, 14 Aug 2025 22:23:43 +0000 Subject: [PATCH 1/6] init --- package-lock.json | 248 +++++++++++++- package.json | 1 + src/common/abis/balancer.ts | 16 + src/common/abis/index.ts | 2 + src/core/modes/balancer/index.ts | 65 ++++ src/core/modes/balancer/simulate.ts | 310 ++++++++++++++++++ src/core/modes/index.ts | 56 ++-- src/core/types.ts | 1 + src/router/balancer.ts | 145 ++++++++ ...alancerRouterOrderBookV4ArbOrderTaker.json | 1 + test/e2e/data.js | 71 ++-- test/e2e/e2e.test.js | 291 +++++++++++++++- test/utils.js | 12 + 13 files changed, 1144 insertions(+), 75 deletions(-) create mode 100644 src/common/abis/balancer.ts create mode 100644 src/core/modes/balancer/index.ts create mode 100644 src/core/modes/balancer/simulate.ts create mode 100644 src/router/balancer.ts create mode 100644 test/abis/BalancerRouterOrderBookV4ArbOrderTaker.json diff --git a/package-lock.json b/package-lock.json index 129b0e3c..61f264b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "2.5.1", "license": "CAL-1.0", "dependencies": { + "@balancer/sdk": "^4.5.2", "@opentelemetry/api": "^1.8.0", "@opentelemetry/core": "^1.22.0", "@opentelemetry/exporter-trace-otlp-grpc": "^0.49.1", @@ -230,6 +231,250 @@ "node": ">=6.0.0" } }, + "node_modules/@balancer-labs/balancer-maths": { + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/@balancer-labs/balancer-maths/-/balancer-maths-0.0.27.tgz", + "integrity": "sha512-aXujyHYENIWTzN2aRoUVBKhmmLxvWBhGcO8I6wsRR6kkSw8SfnXvihFdf48RvfE8YnEfL7Bso+JCyqKPzRcBHQ==", + "license": "MIT", + "engines": { + "node": ">=18.x" + } + }, + "node_modules/@balancer/sdk": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@balancer/sdk/-/sdk-4.5.2.tgz", + "integrity": "sha512-tUaZX1yO8gDBOorg8eR6A39i9cSGu9QR2IJKc+IaJ5xjsHPjpyJwtRC9zFvaWDUuHDcbcV3UUMoGuEa79g8REA==", + "license": "MIT", + "dependencies": { + "@balancer-labs/balancer-maths": "0.0.27", + "@types/big.js": "6.2.2", + "big.js": "6.2.2", + "decimal.js-light": "2.5.1", + "viem": "2.27.0" + }, + "engines": { + "node": ">=18.x" + } + }, + "node_modules/@balancer/sdk/node_modules/@adraffy/ens-normalize": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz", + "integrity": "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==", + "license": "MIT" + }, + "node_modules/@balancer/sdk/node_modules/@noble/curves": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz", + "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.7.1" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@balancer/sdk/node_modules/@noble/hashes": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", + "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@balancer/sdk/node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@balancer/sdk/node_modules/@scure/bip32": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz", + "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.8.1", + "@noble/hashes": "~1.7.1", + "@scure/base": "~1.2.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@balancer/sdk/node_modules/@scure/bip39": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz", + "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.7.1", + "@scure/base": "~1.2.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@balancer/sdk/node_modules/@types/big.js": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@types/big.js/-/big.js-6.2.2.tgz", + "integrity": "sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==", + "license": "MIT" + }, + "node_modules/@balancer/sdk/node_modules/abitype": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz", + "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3 >=3.22.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/@balancer/sdk/node_modules/big.js": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.2.tgz", + "integrity": "sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, + "node_modules/@balancer/sdk/node_modules/isows": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.6.tgz", + "integrity": "sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/@balancer/sdk/node_modules/ox": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.9.tgz", + "integrity": "sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.10.1", + "@noble/curves": "^1.6.0", + "@noble/hashes": "^1.5.0", + "@scure/bip32": "^1.5.0", + "@scure/bip39": "^1.4.0", + "abitype": "^1.0.6", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@balancer/sdk/node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@balancer/sdk/node_modules/viem": { + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.27.0.tgz", + "integrity": "sha512-pKw2dcwDi6TaWlTzLHYazOgjO1GgbUpE1zdLsLNSiCjHNrMTpL/teL0wVHnJDLiB2tR5CL19LBqefYNtRUkH5Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@noble/curves": "1.8.1", + "@noble/hashes": "1.7.1", + "@scure/bip32": "1.6.2", + "@scure/bip39": "1.5.4", + "abitype": "1.0.8", + "isows": "1.0.6", + "ox": "0.6.9", + "ws": "8.18.1" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@balancer/sdk/node_modules/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -7999,8 +8244,7 @@ "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" }, "node_modules/evp_bytestokey": { "version": "1.0.3", diff --git a/package.json b/package.json index 442ed090..a84cf038 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "vitest": "npm run vitest:logger && vitest run --exclude ./src/logger/index.test.ts" }, "dependencies": { + "@balancer/sdk": "^4.5.2", "@opentelemetry/api": "^1.8.0", "@opentelemetry/core": "^1.22.0", "@opentelemetry/exporter-trace-otlp-grpc": "^0.49.1", diff --git a/src/common/abis/balancer.ts b/src/common/abis/balancer.ts new file mode 100644 index 00000000..818ac29b --- /dev/null +++ b/src/common/abis/balancer.ts @@ -0,0 +1,16 @@ +import { batchRouterAbi_V3 } from "@balancer/sdk"; + +/** Keeps the BalancerBatchRouter contract ABIs */ +export namespace BalancerBatchRouterAbi { + /** Balancer BatchRouter v3 contract structs */ + export namespace Structs { + export const SwapPathExactAmountIn = batchRouterAbi_V3[21].inputs[0]; + export const SwapPathStep = batchRouterAbi_V3[21].inputs[0].components[1]; + } + + /** BalancerBatchRouter contract primary parsed ABI */ + export namespace Primary { + /** Primary parsed ABI for SushiSwap RouteProcessor3 contract only including processRoute() function */ + export const BatchRouterV3 = batchRouterAbi_V3; + } +} diff --git a/src/common/abis/index.ts b/src/common/abis/index.ts index 385869ad..dde1052a 100644 --- a/src/common/abis/index.ts +++ b/src/common/abis/index.ts @@ -3,6 +3,7 @@ import { RouteProcessorAbi } from "./rp"; import { DeployerAbi } from "./deployer"; import { OrderbookAbi } from "./orderbook"; import { Multicall3Abi } from "./multicall"; +import { BalancerBatchRouterAbi } from "./balancer"; import { ArbitrumNodeInterfaceAbi } from "./arbitrum"; /** Keeps all necesdsary ABIs for rain solver app */ @@ -11,5 +12,6 @@ export namespace ABI { export import Orderbook = OrderbookAbi; export import Multicall3 = Multicall3Abi; export import RouteProcessor = RouteProcessorAbi; + export import BalancerBatchRouter = BalancerBatchRouterAbi; export import ArbitrumNodeInterface = ArbitrumNodeInterfaceAbi; } diff --git a/src/core/modes/balancer/index.ts b/src/core/modes/balancer/index.ts new file mode 100644 index 00000000..a6cdeee3 --- /dev/null +++ b/src/core/modes/balancer/index.ts @@ -0,0 +1,65 @@ +import { RainSolver } from "../.."; +import { Pair } from "../../../order"; +import { Token } from "sushi/currency"; +import { Result } from "../../../common"; +import { Attributes } from "@opentelemetry/api"; +import { RainSolverSigner } from "../../../signer"; +import { extendObjectWithHeader } from "../../../logger"; +import { SimulationResult, TradeType } from "../../types"; +import { trySimulateTrade } from "./simulate"; + +/** + * Tries to find the best trade against route processor for the given order, + * it will try to simulate a trade for full trade size (order's max output) + * and if it was not successful it will try again with partial trade size + * @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 ethPrice - The current ETH price + * @param toToken - The token to trade to + * @param fromToken - The token to trade from + */ +export async function findBestBalancerTrade( + this: RainSolver, + orderDetails: Pair, + signer: RainSolverSigner, + ethPrice: string, + toToken: Token, + fromToken: Token, +): Promise { + const spanAttributes: Attributes = {}; + + // exit early if eth price is unknown + if (!ethPrice) { + spanAttributes["error"] = "no route to get price of input token to eth"; + return Result.err({ + type: TradeType.Balancer, + spanAttributes, + }); + } + + const maximumInput = orderDetails.takeOrder.quote!.maxOutput; + const blockNumber = await this.state.client.getBlockNumber(); + + // try simulation for full trade size and return if succeeds + const simResult = await trySimulateTrade.call(this, { + orderDetails, + fromToken, + toToken, + signer, + maximumInputFixed: maximumInput, + ethPrice, + isPartial: false, + blockNumber, + }); + if (simResult.isOk()) { + return simResult; + } + extendObjectWithHeader(spanAttributes, simResult.error.spanAttributes, "full"); + + return Result.err({ + type: TradeType.Balancer, + spanAttributes, + noneNodeError: simResult.error.noneNodeError, + }); +} diff --git a/src/core/modes/balancer/simulate.ts b/src/core/modes/balancer/simulate.ts new file mode 100644 index 00000000..cddd6660 --- /dev/null +++ b/src/core/modes/balancer/simulate.ts @@ -0,0 +1,310 @@ +import { dryrun } from "../dryrun"; +import { RainSolver } from "../.."; +import { Pair } from "../../../order"; +import { Token } from "sushi/currency"; +// import { ChainId, Router } from "sushi"; +import { Attributes } from "@opentelemetry/api"; +import { Result, ABI } from "../../../common"; +import { extendObjectWithHeader } from "../../../logger"; +import { ONE18, scaleTo18, scaleFrom18 } from "../../../math"; +// import { RPoolFilter, visualizeRoute } from "../../../router"; +import { RainSolverSigner, RawTransaction } from "../../../signer"; +import { getBountyEnsureRainlang, parseRainlang } from "../../../task"; +import { TakeOrdersConfigType, SimulationResult, TradeType, FailedSimulation } from "../../types"; +import { encodeAbiParameters, encodeFunctionData, formatUnits, maxUint256, parseUnits } from "viem"; +import { getBalancerMarketPrice, getBestBalancerRoute } from "../../../router/balancer"; +import { AddressProvider } from "@balancer/sdk"; + +/** Specifies the reason that route processor simulation failed */ +export enum BalancerRouterSimulationHaltReason { + NoOpportunity = 1, + NoRoute = 2, + OrderRatioGreaterThanMarketPrice = 3, +} + +/** Arguments for simulating route processor trade */ +export type SimulateRouteProcessorTradeArgs = { + /** The bundled order details including tokens, decimals, and take orders */ + orderDetails: Pair; + /** The RainSolverSigner instance used for signing transactions */ + signer: RainSolverSigner; + /** The current ETH price (in 18 decimals) */ + ethPrice: string; + /** The token to be received in the swap */ + toToken: Token; + /** The token to be sold in the swap */ + fromToken: Token; + /** The maximum input amount (in 18 decimals) */ + maximumInputFixed: bigint; + /** The current block number for context */ + blockNumber: bigint; +}; + +/** + * Attempts to find a profitable opportunity (opp) for a given order by simulating a trade against route processor. + * @param this - The RainSolver instance context + * @param args - The arguments for simulating the trade + */ +export async function trySimulateTrade( + this: RainSolver, + args: SimulateRouteProcessorTradeArgs, +): Promise { + const { orderDetails, signer, ethPrice, toToken, fromToken, maximumInputFixed, blockNumber } = + args; + const gasPrice = this.state.gasPrice; + const spanAttributes: Attributes = {}; + + const maximumInput = scaleFrom18(maximumInputFixed, orderDetails.sellTokenDecimals); + spanAttributes["amountIn"] = formatUnits(maximumInputFixed, 18); + + const route = await getBestBalancerRoute.call(this.state, { + tokenIn: fromToken, + tokenOut: toToken, + swapAmount: maximumInput, + }); + // const route = Result.ok([ + // { + // steps: [ + // { + // pool: "0x88c044fb203b58b12252be7242926b1eeb113b4a", + // tokenOut: "0x4200000000000000000000000000000000000006", + // isBuffer: false, + // }, + // ], + // tokenIn: fromToken.address as `0x${string}`, + // exactAmountIn: maximumInput, + // minAmountOut: 0n, + // }, + // ]); + if (route.isErr()) { + spanAttributes["error"] = route.error.message; + return Result.err({ + type: TradeType.Balancer, + spanAttributes, + reason: BalancerRouterSimulationHaltReason.NoRoute, + }); + } + + const amountOut = await getBalancerMarketPrice.call(this.state, route.value, signer); + if (amountOut.isErr()) { + spanAttributes["error"] = amountOut.error.message; + return Result.err({ + type: TradeType.Balancer, + spanAttributes, + reason: BalancerRouterSimulationHaltReason.NoRoute, + }); + } + const rateFixed = scaleTo18(amountOut.value, orderDetails.buyTokenDecimals); + const price = (rateFixed * ONE18) / maximumInputFixed; + + spanAttributes["amountOut"] = formatUnits(amountOut.value, toToken.decimals); + spanAttributes["marketPrice"] = formatUnits(price, 18); + + // const routeVisual: string[] = []; + // try { + // visualizeRoute(fromToken, toToken, route.legs).forEach((v) => { + // routeVisual.push(v); + // }); + // } catch { + // /**/ + // } + // spanAttributes["route"] = routeVisual; + + // exit early if market price is lower than order quote ratio + if (price < orderDetails.takeOrder.quote!.ratio) { + spanAttributes["error"] = "Order's ratio greater than market price"; + const result = { + type: TradeType.RouteProcessor, + spanAttributes, + reason: BalancerRouterSimulationHaltReason.OrderRatioGreaterThanMarketPrice, + }; + return Result.err(result); + } + + spanAttributes["oppBlockNumber"] = Number(blockNumber); + + const balancerRouter = AddressProvider.BatchRouter(this.state.chainConfig.id); + const orders = [orderDetails.takeOrder.struct]; + const takeOrdersConfigStruct: TakeOrdersConfigType = { + minimumInput: 1n, + maximumInput: maxUint256, + maximumIORatio: this.appOptions.maxRatio ? maxUint256 : price, + orders, + data: encodeAbiParameters( + [{ type: "address" }, ABI.BalancerBatchRouter.Structs.SwapPathExactAmountIn], + [balancerRouter, route.value], + ), + }; + const task = { + evaluable: { + interpreter: this.state.dispair.interpreter as `0x${string}`, + store: this.state.dispair.store as `0x${string}`, + bytecode: (this.appOptions.gasCoveragePercentage === "0" + ? "0x" + : await parseRainlang( + await getBountyEnsureRainlang( + parseUnits(ethPrice, 18), + 0n, + 0n, + signer.account.address, + ), + this.state.client, + this.state.dispair, + )) as `0x${string}`, + }, + signedContext: [], + }; + const rawtx: RawTransaction = { + data: encodeFunctionData({ + abi: ABI.Orderbook.Primary.Arb, + functionName: "arb3", + args: [orderDetails.orderbook as `0x${string}`, takeOrdersConfigStruct, task], + }), + to: this.appOptions.arbAddress as `0x${string}`, + gasPrice, + }; + + // initial dryrun with 0 minimum sender output to get initial + // pass and tx gas cost to calc minimum sender output + const initDryrunResult = await dryrun( + signer, + rawtx, + gasPrice, + this.appOptions.gasLimitMultiplier, + ); + if (initDryrunResult.isErr()) { + spanAttributes["stage"] = 1; + Object.assign(initDryrunResult.error.spanAttributes, spanAttributes); + initDryrunResult.error.reason = BalancerRouterSimulationHaltReason.NoOpportunity; + (initDryrunResult.error as FailedSimulation).type = TradeType.RouteProcessor; + return Result.err(initDryrunResult.error as FailedSimulation); + } + + let { estimation, estimatedGasCost } = initDryrunResult.value; + // include dryrun initial gas estimation in logs + Object.assign(spanAttributes, initDryrunResult.value.spanAttributes); + extendObjectWithHeader( + spanAttributes, + { + gasLimit: estimation.gas.toString(), + totalCost: estimation.totalGasCost.toString(), + gasPrice: estimation.gasPrice.toString(), + ...(this.state.chainConfig.isSpecialL2 + ? { + l1Cost: estimation.l1Cost.toString(), + l1GasPrice: estimation.l1GasPrice.toString(), + } + : {}), + }, + "gasEst.initial", + ); + + // repeat the same process with headroom if gas + // coverage is not 0, 0 gas coverage means 0 minimum + // sender output which is already called above + if (this.appOptions.gasCoveragePercentage !== "0") { + const headroom = BigInt((Number(this.appOptions.gasCoveragePercentage) * 1.03).toFixed()); + spanAttributes["gasEst.initial.minBountyExpected"] = ( + (estimatedGasCost * headroom) / + 100n + ).toString(); + task.evaluable.bytecode = (await parseRainlang( + await getBountyEnsureRainlang( + parseUnits(ethPrice, 18), + 0n, + (estimatedGasCost * headroom) / 100n, + signer.account.address, + ), + this.state.client, + this.state.dispair, + )) as `0x${string}`; + rawtx.data = encodeFunctionData({ + abi: ABI.Orderbook.Primary.Arb, + functionName: "arb3", + args: [orderDetails.orderbook as `0x${string}`, takeOrdersConfigStruct, task], + }); + + const finalDryrunResult = await dryrun( + signer, + rawtx, + gasPrice, + this.appOptions.gasLimitMultiplier, + ); + if (finalDryrunResult.isErr()) { + spanAttributes["stage"] = 2; + Object.assign(finalDryrunResult.error.spanAttributes, spanAttributes); + finalDryrunResult.error.reason = BalancerRouterSimulationHaltReason.NoOpportunity; + (finalDryrunResult.error as FailedSimulation).type = TradeType.RouteProcessor; + return Result.err(finalDryrunResult.error as FailedSimulation); + } + + ({ estimation, estimatedGasCost } = finalDryrunResult.value); + // include dryrun final gas estimation in otel logs + Object.assign(spanAttributes, finalDryrunResult.value.spanAttributes); + extendObjectWithHeader( + spanAttributes, + { + gasLimit: estimation.gas.toString(), + totalCost: estimation.totalGasCost.toString(), + gasPrice: estimation.gasPrice.toString(), + ...(this.state.chainConfig.isSpecialL2 + ? { + l1Cost: estimation.l1Cost.toString(), + l1GasPrice: estimation.l1GasPrice.toString(), + } + : {}), + }, + "gasEst.final", + ); + + task.evaluable.bytecode = (await parseRainlang( + await getBountyEnsureRainlang( + parseUnits(ethPrice, 18), + 0n, + (estimatedGasCost * BigInt(this.appOptions.gasCoveragePercentage)) / 100n, + signer.account.address, + ), + this.state.client, + this.state.dispair, + )) as `0x${string}`; + rawtx.data = encodeFunctionData({ + abi: ABI.Orderbook.Primary.Arb, + functionName: "arb3", + args: [orderDetails.orderbook as `0x${string}`, takeOrdersConfigStruct, task], + }); + spanAttributes["gasEst.final.minBountyExpected"] = ( + (estimatedGasCost * BigInt(this.appOptions.gasCoveragePercentage)) / + 100n + ).toString(); + } + + // if reached here, it means there was a success and found opp + spanAttributes["foundOpp"] = true; + const result = { + type: TradeType.RouteProcessor, + spanAttributes, + rawtx, + estimatedGasCost, + oppBlockNumber: Number(blockNumber), + estimatedProfit: estimateProfit( + orderDetails, + parseUnits(ethPrice, 18), + price, + maximumInputFixed, + )!, + }; + return Result.ok(result); +} + +/** Estimates profit for a route processor clear mode */ +export function estimateProfit( + orderDetails: Pair, + ethPrice: bigint, + marketPrice: bigint, + maxInput: bigint, +): bigint { + const marketAmountOut = (maxInput * marketPrice) / ONE18; + const orderInput = (maxInput * orderDetails.takeOrder.quote!.ratio) / ONE18; + const estimatedProfit = marketAmountOut - orderInput; + return (estimatedProfit * ethPrice) / ONE18; +} diff --git a/src/core/modes/index.ts b/src/core/modes/index.ts index c70031db..4911f382 100644 --- a/src/core/modes/index.ts +++ b/src/core/modes/index.ts @@ -6,10 +6,11 @@ import { Token } from "sushi/currency"; import { FindBestTradeResult } from "../types"; import { RainSolverSigner } from "../../signer"; import { Attributes } from "@opentelemetry/api"; -import { findBestRouteProcessorTrade } from "./rp"; +// import { findBestRouteProcessorTrade } from "./rp"; import { findBestIntraOrderbookTrade } from "./intra"; import { findBestInterOrderbookTrade } from "./inter"; import { extendObjectWithHeader } from "../../logger"; +import { findBestBalancerTrade } from "./balancer"; /** Arguments for finding the best trade */ export type FindBestTradeArgs = { @@ -44,33 +45,34 @@ export async function findBestTrade( ): Promise { const { orderDetails, signer, inputToEthPrice, outputToEthPrice, toToken, fromToken } = args; const promises = [ - findBestRouteProcessorTrade.call( - this, - orderDetails, - signer, - inputToEthPrice, - toToken, - fromToken, - ), + // findBestRouteProcessorTrade.call( + // this, + // orderDetails, + // signer, + // inputToEthPrice, + // toToken, + // fromToken, + // ), + findBestBalancerTrade.call(this, orderDetails, signer, inputToEthPrice, toToken, fromToken), // include intra and inter orderbook trades types only if rpOnly is false - ...(!this.appOptions.rpOnly - ? [ - findBestIntraOrderbookTrade.call( - this, - orderDetails, - signer, - inputToEthPrice, - outputToEthPrice, - ), - findBestInterOrderbookTrade.call( - this, - orderDetails, - signer, - inputToEthPrice, - outputToEthPrice, - ), - ] - : []), + // ...(!this.appOptions.rpOnly + // ? [ + // findBestIntraOrderbookTrade.call( + // this, + // orderDetails, + // signer, + // inputToEthPrice, + // outputToEthPrice, + // ), + // findBestInterOrderbookTrade.call( + // this, + // orderDetails, + // signer, + // inputToEthPrice, + // outputToEthPrice, + // ), + // ] + // : []), ]; const results = await Promise.all(promises); diff --git a/src/core/types.ts b/src/core/types.ts index 799e3b14..292fc69f 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -27,6 +27,7 @@ export enum TradeType { RouteProcessor = "routeProcessor", IntraOrderbook = "intraOrderbook", InterOrderbook = "interOrderbook", + Balancer = "balancer", } /** Base type for process order results containing shared fields */ diff --git a/src/router/balancer.ts b/src/router/balancer.ts new file mode 100644 index 00000000..638feecb --- /dev/null +++ b/src/router/balancer.ts @@ -0,0 +1,145 @@ +/* eslint-disable no-console */ +import { + // Swap, + Token, + ChainId, + // Slippage, + SwapKind, + TokenAmount, + BalancerApi, + // SwapBuildCallInput, + // ExactInQueryOutput, + // SwapBuildOutputExactIn, + Path, + PathWithAmount, + AddressProvider, + batchRouterAbi_V3, +} from "@balancer/sdk"; +import { Token as SushiToken } from "sushi/currency"; +import { Result } from "../common"; +import { SharedState } from "../state"; +import { RainSolverSigner } from "../signer"; + +export const BALANCER_API_URL = "https://api-v3.balancer.fi/" as const; +export type BalancerRouterStep = { + pool: `0x${string}`; + tokenOut: `0x${string}`; + isBuffer: boolean; +}; + +export type BalancerRouterPath = { + tokenIn: `0x${string}`; + exactAmountIn: bigint; + minAmountOut: bigint; + steps: BalancerRouterStep[]; +}; +export type GetBestBalancerPriceParams = { + tokenIn: SushiToken; + tokenOut: SushiToken; + swapAmount: bigint; + wethIsEth?: boolean; + deadline?: bigint; + slippage?: `${number}`; +}; + +export async function getBalancerSortedRoutes( + this: SharedState, + params: GetBestBalancerPriceParams, +): Promise> { + const { tokenIn: _tokenIn, tokenOut: _tokenOut, swapAmount: _swapAmount } = params; + + console.log(ChainId[this.chainConfig.id]); + if (typeof ChainId[this.chainConfig.id] !== "string") { + return Result.err(new Error(`Unsupported chain with id: ${this.chainConfig.id}`)); + } + + const chainId = this.chainConfig.id as ChainId; + const tokenIn = new Token(chainId, _tokenIn.address, _tokenIn.decimals, _tokenIn.symbol); + const tokenOut = new Token(chainId, _tokenOut.address, _tokenOut.decimals, _tokenOut.symbol); + const swapAmount = TokenAmount.fromRawAmount(tokenIn, _swapAmount); + const swapKind = SwapKind.GivenIn; + + // API is used to fetch best swap paths from available liquidity across v2 and v3 + const balancerApi = new BalancerApi(BALANCER_API_URL, chainId); + + const sorPaths = await balancerApi.sorSwapPaths.fetchSorSwapPaths({ + chainId, + tokenIn: tokenIn.address.toLowerCase() as `0x${string}`, + tokenOut: tokenOut.address.toLowerCase() as `0x${string}`, + swapKind, + swapAmount, + useProtocolVersion: 3, + }); + console.log("sorted", sorPaths); + + if (sorPaths.length === 0) { + return Result.err(new Error("no balancer route for given token pair")); + } + + const bestRoute = convertToSwapRoute(sorPaths); + return Result.ok(bestRoute); +} + +export async function getBestBalancerRoute( + this: SharedState, + params: GetBestBalancerPriceParams, +): Promise> { + const balancerSortedRoutes = await getBalancerSortedRoutes.call(this, params); + if (balancerSortedRoutes.isErr()) { + return Result.err(balancerSortedRoutes.error); + } + + const bestRoute = { ...balancerSortedRoutes.value[0] }; + bestRoute.exactAmountIn = params.swapAmount; + + return Result.ok([bestRoute]); +} + +export async function getBalancerMarketPrice( + this: SharedState, + route: BalancerRouterPath[], + signer: RainSolverSigner, +): Promise> { + const balancerRouter = AddressProvider.BatchRouter(this.chainConfig.id); + + try { + const result = await this.client.simulateContract({ + address: balancerRouter, + abi: batchRouterAbi_V3, + functionName: "querySwapExactIn", + args: [route, signer.account.address, "0x"], + }); + return Result.ok(result.result[2][0]); + } catch (e: any) { + return Result.err(e); + } +} + +export function convertToSwapRoute(paths: Path[]): BalancerRouterPath[] { + const pathsWithAmounts = paths.map( + (p) => + new PathWithAmount( + ChainId.MAINNET, + p.tokens, + p.pools, + p.inputAmountRaw, + p.outputAmountRaw, + p.isBuffer, + ), + ); + const swaps = pathsWithAmounts.map((p) => { + return { + tokenIn: p.inputAmount.token.address, + exactAmountIn: p.inputAmount.amount, + minAmountOut: p.outputAmount.amount, + steps: p.pools.map((pool, i) => { + return { + pool, + tokenOut: p.tokens[i + 1].address, + isBuffer: p.isBuffer[i], + }; + }), + }; + }); + return swaps; +} diff --git a/test/abis/BalancerRouterOrderBookV4ArbOrderTaker.json b/test/abis/BalancerRouterOrderBookV4ArbOrderTaker.json new file mode 100644 index 00000000..94eb7293 --- /dev/null +++ b/test/abis/BalancerRouterOrderBookV4ArbOrderTaker.json @@ -0,0 +1 @@ +{"abi":[{"type":"constructor","inputs":[{"name":"config","type":"tuple","internalType":"struct OrderBookV4ArbConfigV2","components":[{"name":"orderBook","type":"address","internalType":"address"},{"name":"task","type":"tuple","internalType":"struct TaskV1","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"uint256[]","internalType":"uint256[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"implementationData","type":"bytes","internalType":"bytes"}]}],"stateMutability":"nonpayable"},{"type":"fallback","stateMutability":"nonpayable"},{"type":"function","name":"arb3","inputs":[{"name":"orderBook","type":"address","internalType":"contract IOrderBookV4"},{"name":"takeOrders","type":"tuple","internalType":"struct TakeOrdersConfigV3","components":[{"name":"minimumInput","type":"uint256","internalType":"uint256"},{"name":"maximumInput","type":"uint256","internalType":"uint256"},{"name":"maximumIORatio","type":"uint256","internalType":"uint256"},{"name":"orders","type":"tuple[]","internalType":"struct TakeOrderConfigV3[]","components":[{"name":"order","type":"tuple","internalType":"struct OrderV3","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IO[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"decimals","type":"uint8","internalType":"uint8"},{"name":"vaultId","type":"uint256","internalType":"uint256"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IO[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"decimals","type":"uint8","internalType":"uint8"},{"name":"vaultId","type":"uint256","internalType":"uint256"}]},{"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":"uint256[]","internalType":"uint256[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"data","type":"bytes","internalType":"bytes"}]},{"name":"task","type":"tuple","internalType":"struct TaskV1","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"uint256[]","internalType":"uint256[]"},{"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":"onTakeOrders","inputs":[{"name":"inputToken","type":"address","internalType":"address"},{"name":"outputToken","type":"address","internalType":"address"},{"name":"inputAmountSent","type":"uint256","internalType":"uint256"},{"name":"totalOutputAmount","type":"uint256","internalType":"uint256"},{"name":"takeOrdersData","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"x","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"type":"event","name":"Construct","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"config","type":"tuple","indexed":false,"internalType":"struct OrderBookV4ArbConfigV2","components":[{"name":"orderBook","type":"address","internalType":"address"},{"name":"task","type":"tuple","internalType":"struct TaskV1","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"uint256[]","internalType":"uint256[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"implementationData","type":"bytes","internalType":"bytes"}]}],"anonymous":false},{"type":"error","name":"InvalidSignature","inputs":[{"name":"i","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"NoOrders","inputs":[]},{"type":"error","name":"WrongTask","inputs":[]}],"bytecode":{"object":"0x60a0604052600060805234801561001557600080fd5b50604051613a38380380613a388339810160408190526100349161036e565b808060016000819055507f584f220334313e589a42a75ac60d4fa6ed5b02329a7255af822a0e4ac9cd5f1d338260405161006f9291906105e7565b60405180910390a16020810151516040015151156100b65760208082015160405161009a9201610647565b60408051601f1981840301815291905280516020909101206080525b505050610661565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156100f6576100f66100be565b60405290565b604080519081016001600160401b03811182821017156100f6576100f66100be565b604051601f8201601f191681016001600160401b0381118282101715610146576101466100be565b604052919050565b6001600160a01b038116811461016357600080fd5b50565b60005b83811015610181578181015183820152602001610169565b50506000910152565b600082601f83011261019b57600080fd5b81516001600160401b038111156101b4576101b46100be565b6101c7601f8201601f191660200161011e565b8181528460208386010111156101dc57600080fd5b6101ed826020830160208701610166565b949350505050565b60006001600160401b0382111561020e5761020e6100be565b5060051b60200190565b600082601f83011261022957600080fd5b8151602061023e610239836101f5565b61011e565b82815260059290921b8401810191818101908684111561025d57600080fd5b8286015b848110156103635780516001600160401b038082111561028057600080fd5b908801906060828b03601f190112156102995760008081fd5b6102a16100d4565b868301516102ae8161014e565b8152604083810151838111156102c45760008081fd5b8401603f81018d136102d65760008081fd5b888101516102e6610239826101f5565b81815260059190911b82018301908a8101908f8311156103065760008081fd5b928401925b828410156103245783518252928b0192908b019061030b565b858c015250505060608401518381111561033e5760008081fd5b61034c8d8a8388010161018a565b918301919091525085525050918301918301610261565b509695505050505050565b6000602080838503121561038157600080fd5b82516001600160401b038082111561039857600080fd5b90840190606082870312156103ac57600080fd5b6103b46100d4565b82516103bf8161014e565b815282840151828111156103d257600080fd5b8301604081890312156103e457600080fd5b6103ec6100fc565b8151848111156103fb57600080fd5b82016060818b03121561040d57600080fd5b6104156100d4565b81516104208161014e565b81528188015161042f8161014e565b8189015260408201518681111561044557600080fd5b6104518c82850161018a565b604083015250825250818601518481111561046b57600080fd5b6104778a828501610218565b878301525080868401525050604083015193508184111561049757600080fd5b6104a38785850161018a565b60408201529695505050505050565b600081518084526104ca816020860160208601610166565b601f01601f19169290920160200192915050565b6000604082516040855260018060a01b03808251166040870152602080830151606083821660608a015260408501519450606060808a015261052360a08a01866104b2565b888401518a82038b86015280518083529196508401925083860190600581901b870185016000805b838110156105d557898303601f19018552865180518a168452888101518985018890528051888601819052908a0190849060808701905b808310156105a25783518252928c019260019290920191908c0190610582565b508e84015193508681038f8801526105ba81856104b2565b9650505050508787019650878501945060018101905061054b565b50909c9b505050505050505050505050565b6001600160a01b0383811682526040602080840182905284519092169083015282015160608083015260009061062060a08401826104de565b90506040840151603f1984830301608085015261063d82826104b2565b9695505050505050565b60208152600061065a60208301846104de565b9392505050565b6080516133af6106896000396000818160e20152818161070d015261075e01526133af6000f3fe60806040526004361061005a5760003560e01c80637ea0b76a116100435780637ea0b76a146100bd57806393be095e146100d0578063f037e4e3146101125761005a565b806301ffc9a714610068578063059bebe61461009d575b34801561006657600080fd5b005b34801561007457600080fd5b50610088610083366004611e97565b610125565b60405190151581526020015b60405180910390f35b3480156100a957600080fd5b506100666100b8366004611efe565b61020a565b6100666100cb366004611fa8565b6106fa565b3480156100dc57600080fd5b506101047f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610094565b61006661012036600461202d565b610a5a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f059bebe60000000000000000000000000000000000000000000000000000000014806101b857507fffffffff0000000000000000000000000000000000000000000000000000000082167f7ea0b76a00000000000000000000000000000000000000000000000000000000145b8061020457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000806102198385018561214b565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526e22d473030f116ddee9f6b43ac78ba3600482018190526000196024830152929450909250819073ffffffffffffffffffffffffffffffffffffffff8b169063095ea7b3906044016020604051808303816000875af11580156102a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ca9190612347565b5082516001146103215760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420737761702070617468206c656e677468000000000000000060448201526064015b60405180910390fd5b8973ffffffffffffffffffffffffffffffffffffffff168360008151811061034b5761034b612364565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16146103ba5760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420696e70757420746f6b656e000000000000000000000000006044820152606401610318565b8873ffffffffffffffffffffffffffffffffffffffff16836000815181106103e4576103e4612364565b60200260200101516020015160018560008151811061040557610405612364565b6020026020010151602001515161041c91906123c2565b8151811061042c5761042c612364565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff161461049b5760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964206f757470757420746f6b656e0000000000000000000000006044820152606401610318565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8b16906370a0823190602401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052991906123d5565b8811156105785760405162461bcd60e51b815260206004820181905260248201527f496e73756666696369656e7420696e70757420746f6b656e2062616c616e63656044820152606401610318565b6040517f87517c4500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152808616602483015260448201819052600060648301528591908416906387517c4590608401600060405180830381600087803b1580156105fa57600080fd5b505af115801561060e573d6000803e3d6000fd5b50505050888460008151811061062657610626612364565b6020026020010151604001818152505060008460008151811061064b5761064b612364565b6020026020010151606001818152505060008060008373ffffffffffffffffffffffffffffffffffffffff1663286f580d8860001960006040518463ffffffff1660e01b81526004016106a0939291906123ee565b6000604051808303816000875af11580156106bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106e791908101906125ac565b5050505050505050505050505050505050565b610702610b0c565b61070b81612849565b7f0000000000000000000000000000000000000000000000000000000000000000158015906107805750806040516020016107469190612997565b604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000014155b156107b7576040517f8812562900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c46060840184612a84565b90506000036107ff576040517f9c95219f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061080e6060850185612a84565b600081811061081f5761081f612364565b90506020028101906108319190612ace565b61083b9080612b0c565b610849906040810190612b40565b6108566060870187612a84565b600081811061086757610867612364565b90506020028101906108799190612ace565b6020013581811061088c5761088c612364565b6108a2926020606090920201908101915061202d565b905060006108b36060860186612a84565b60008181106108c4576108c4612364565b90506020028101906108d69190612ace565b6108e09080612b0c565b6108ee906060810190612b40565b6108fb6060880188612a84565b600081811061090c5761090c612364565b905060200281019061091e9190612ace565b6040013581811061093157610931612364565b610947926020606090920201908101915061202d565b905061096b73ffffffffffffffffffffffffffffffffffffffff8316876000610b65565b61098e73ffffffffffffffffffffffffffffffffffffffff831687600019610b65565b6000808773ffffffffffffffffffffffffffffffffffffffff16630997c4a0886040518263ffffffff1660e01b81526004016109ca9190612e3a565b60408051808303816000875af11580156109e8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0c919061309e565b9092509050610a3373ffffffffffffffffffffffffffffffffffffffff8516896000610b65565b610a46610a3f87612849565b8585610d2d565b5050505050610a556001600055565b505050565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526e22d473030f116ddee9f6b43ac78ba36004820181905260001960248301529073ffffffffffffffffffffffffffffffffffffffff83169063095ea7b3906044016020604051808303816000875af1158015610ae0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a559190612347565b505050505050565b600260005403610b5e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610318565b6002600055565b801580610c0557506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0391906123d5565b155b610c775760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610318565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611105565b604080516001808252818301909252600091816020015b6060815260200190600190039081610d44575050604080516003808252608082019092529192506000919060208201606080368337019050506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1191906123d5565b90508015610e3a57610e3a73ffffffffffffffffffffffffffffffffffffffff861633836111fa565b60008573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eab91906130c2565b60ff169050610ebc82826000611250565b83600081518110610ecf57610ecf612364565b602090810291909101015250506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015610f49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6d91906123d5565b90508015610f9657610f9673ffffffffffffffffffffffffffffffffffffffff851633836111fa565b60008473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100791906130c2565b60ff16905061101882826000611250565b8360018151811061102b5761102b612364565b60209081029190910101525047905061104433826112d8565b808260028151811061105857611058612364565b60200260200101818152505050808260008151811061107957611079612364565b6020908102919091010152604080516001808252818301909252600091816020015b6040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915281526020019060019003908161109b57905050905085816000815181106110f0576110f0612364565b6020026020010181905250610b0483826113fe565b6000611167826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166115f79092919063ffffffff16565b90508051600014806111885750808060200190518101906111889190612347565b610a555760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610318565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610cc9565b60008260121115611285576012839003600283161561127b57611273858261160e565b9150506112d1565b611273858261165f565b60128311156112ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee830160018316156112c4576112738582611697565b61127385826116e5565b50825b9392505050565b804710156113285760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610318565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611382576040519150601f19603f3d011682016040523d82523d6000602084013e611387565b606091505b5050905080610a555760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610318565b336114316040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915290565b60005b83518110156115f05783818151811061144f5761144f612364565b6020026020010151915060008260000151604001515111156115e8578151805160209182015160008681523090935260408320839273ffffffffffffffffffffffffffffffffffffffff169163d6e3357a9187600001516040015160006114ba8d8b60200151611708565b604080516000815260208101918290527fffffffff0000000000000000000000000000000000000000000000000000000060e089901b16909152611506959493929190602481016130df565b600060405180830381865afa158015611523573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261154b919081019061318f565b80519193509150156115e5578351602001516040517f946aadc600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063946aadc6906115b290889085906004016131f3565b600060405180830381600087803b1580156115cc57600080fd5b505af11580156115e0573d6000803e3d6000fd5b505050505b50505b600101611434565b5050505050565b60606116068484600085611a18565b949350505050565b6000604e821061163057821561162657600019611629565b60005b9050610204565b50600a81900a828102908381838161164a5761164a61320c565b041461165857600019611606565b5092915050565b600a81900a61166e818461323b565b9050604e821061020457821561168e5761168982600a613336565b6112d1565b60009392505050565b6000604e82106116bb5782156116ae5760016116b1565b60005b60ff169050610204565b600a82900a8084816116cf576116cf61320c565b0491508082028414611658575060010192915050565b6000604e82101561168e5781600a0a83816117025761170261320c565b046112d1565b60606000825167ffffffffffffffff8111156117265761172661204a565b60405190808252806020026020018201604052801561174f578160200160208202803683370190505b509050600080845111611763576000611769565b83516001015b855160010101905060008167ffffffffffffffff81111561178c5761178c61204a565b6040519080825280602002602001820160405280156117bf57816020015b60608152602001906001900390816117aa5790505b50905060006117e4604080516002815233602082015230818301526060810190915290565b8282815181106117f6576117f6612364565b602002602001018190525060005b875181101561185457818060010192505087818151811061182757611827612364565b602002602001015183838151811061184157611841612364565b6020908102919091010152600101611804565b50855115611a0e5780806001019150508382828151811061187757611877612364565b602002602001018190525060005b8651811015611a0c576119368782815181106118a3576118a3612364565b6020026020010151600001516119136118e08a85815181106118c7576118c7612364565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b89848151811061192557611925612364565b602002602001015160400151611b17565b61196f576040517f52bf984800000000000000000000000000000000000000000000000000000000815260048101829052602401610318565b86818151811061198157611981612364565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168582815181106119b5576119b5612364565b60200260200101818152505081806001019250508681815181106119db576119db612364565b6020026020010151602001518383815181106119f9576119f9612364565b6020908102919091010152600101611885565b505b5095945050505050565b606082471015611a905760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610318565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ab99190613342565b60006040518083038185875af1925050503d8060008114611af6576040519150601f19603f3d011682016040523d82523d6000602084013e611afb565b606091505b5091509150611b0c87838387611b92565b979650505050505050565b6000806000611b268585611c18565b90925090506000816004811115611b3f57611b3f613354565b148015611b7757508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611b885750611b88868686611c5d565b9695505050505050565b60608315611c0e578251600003611c075773ffffffffffffffffffffffffffffffffffffffff85163b611c075760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610318565b5081611606565b6116068383611d9c565b6000808251604103611c4e5760208301516040840151606085015160001a611c4287828585611dc6565b94509450505050611c56565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c94929190613383565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cff9190613342565b600060405180830381855afa9150503d8060008114611d3a576040519150601f19603f3d011682016040523d82523d6000602084013e611d3f565b606091505b5091509150818015611d5357506020815110155b8015611b88575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d9190830160209081019084016123d5565b149695505050505050565b815115611dac5781518083602001fd5b8060405162461bcd60e51b8152600401610318919061339c565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611dfd5750600090506003611e8e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e51573d6000803e3d6000fd5b5050604051601f19015191505073ffffffffffffffffffffffffffffffffffffffff8116611e8757600060019250925050611e8e565b9150600090505b94509492505050565b600060208284031215611ea957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146112d157600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611efb57600080fd5b50565b60008060008060008060a08789031215611f1757600080fd5b8635611f2281611ed9565b95506020870135611f3281611ed9565b94506040870135935060608701359250608087013567ffffffffffffffff80821115611f5d57600080fd5b818901915089601f830112611f7157600080fd5b813581811115611f8057600080fd5b8a6020828501011115611f9257600080fd5b6020830194508093505050509295509295509295565b600080600060608486031215611fbd57600080fd5b8335611fc881611ed9565b9250602084013567ffffffffffffffff80821115611fe557600080fd5b9085019060a08288031215611ff957600080fd5b9092506040850135908082111561200f57600080fd5b5084016040818703121561202257600080fd5b809150509250925092565b60006020828403121561203f57600080fd5b81356112d181611ed9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561209c5761209c61204a565b60405290565b6040516060810167ffffffffffffffff8111828210171561209c5761209c61204a565b6040805190810167ffffffffffffffff8111828210171561209c5761209c61204a565b604051601f8201601f1916810167ffffffffffffffff811182821017156121115761211161204a565b604052919050565b600067ffffffffffffffff8211156121335761213361204a565b5060051b60200190565b8015158114611efb57600080fd5b6000806040838503121561215e57600080fd5b6121688335611ed9565b8235915067ffffffffffffffff6020840135111561218557600080fd5b6020830135830184601f82011261219b57600080fd5b6121ad6121a88235612119565b6120e8565b81358082526020808301929160051b8401018710156121cb57600080fd5b602083015b6020843560051b8501018110156123395767ffffffffffffffff813511156121f757600080fd5b803584016080601f19828b0301121561220f57600080fd5b612217612079565b6122246020830135611ed9565b6020820135815267ffffffffffffffff6040830135111561224457600080fd5b604082013582018a603f82011261225a57600080fd5b61226a6121a86020830135612119565b602082810135808352908201919060600283016040018d101561228c57600080fd5b604083015b60406060602086013502850101811015612309576060818f0312156122b557600080fd5b6122bd6120a2565b6122c78235611ed9565b813581526122d86020830135611ed9565b602082013560208201526122ef604083013561213d565b604082810135908201528352602090920191606001612291565b506020848101919091526060858101356040860152608090950135948401949094525050845292830192016121d0565b508093505050509250929050565b60006020828403121561235957600080fd5b81516112d18161213d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561020457610204612393565b6000602082840312156123e757600080fd5b5051919050565b600060808083016080845280875180835260a0925060a08601915060a08160051b8701016020808b016000805b858110156124ee578a85037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600187528251805173ffffffffffffffffffffffffffffffffffffffff9081168752858201518688018c905280518c8901819052908701919085908c8a01905b808310156124c25784518051851683528a81015185168b8401526040908101511515908301529389019360019290920191606090910190612486565b50604085810151908b01526060948501519490990193909352505050958301959183019160010161241b565b505050870189905287151560408801528681036060880152600281527f30780000000000000000000000000000000000000000000000000000000000006020820152604081019a9950505050505050505050565b600082601f83011261255357600080fd5b815160206125636121a883612119565b8083825260208201915060208460051b87010193508684111561258557600080fd5b602086015b848110156125a1578051835291830191830161258a565b509695505050505050565b6000806000606084860312156125c157600080fd5b835167ffffffffffffffff808211156125d957600080fd5b6125e587838801612542565b94506020915081860151818111156125fc57600080fd5b8601601f8101881361260d57600080fd5b805161261b6121a882612119565b81815260059190911b8201840190848101908a83111561263a57600080fd5b928501925b8284101561266157835161265281611ed9565b8252928501929085019061263f565b60408a015190975094505050508082111561267b57600080fd5b5061268886828701612542565b9150509250925092565b600082601f8301126126a357600080fd5b813567ffffffffffffffff8111156126bd576126bd61204a565b6126d06020601f19601f840116016120e8565b8181528460208386010111156126e557600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261271357600080fd5b813560206127236121a883612119565b82815260059290921b8401810191818101908684111561274257600080fd5b8286015b848110156125a157803567ffffffffffffffff8082111561276657600080fd5b908801906060828b03601f1901121561277f5760008081fd5b6127876120a2565b8683013561279481611ed9565b8152604083810135838111156127aa5760008081fd5b8401603f81018d136127bc5760008081fd5b888101356127cc6121a882612119565b81815260059190911b82018301908a8101908f8311156127ec5760008081fd5b928401925b8284101561280a5783358252928b0192908b01906127f1565b858c01525050506060840135838111156128245760008081fd5b6128328d8a83880101612692565b918301919091525085525050918301918301612746565b60006040823603121561285b57600080fd5b6128636120c5565b823567ffffffffffffffff8082111561287b57600080fd5b81850191506060823603121561289057600080fd5b6128986120a2565b82356128a381611ed9565b815260208301356128b381611ed9565b60208201526040830135828111156128ca57600080fd5b6128d636828601612692565b604083015250835260208501359150808211156128f257600080fd5b506128ff36828601612702565b60208301525092915050565b60005b8381101561292657818101518382015260200161290e565b50506000910152565b6000815180845261294781602086016020860161290b565b601f01601f19169290920160200192915050565b60008151808452602080850194506020840160005b8381101561298c57815187529582019590820190600101612970565b509495945050505050565b60006020808352606084516040808487015273ffffffffffffffffffffffffffffffffffffffff808351166060880152808584015116608088015260408301519250606060a08801526129ed60c088018461292f565b925084880151601f19808986030160408a01528482518087528887019150888160051b880101898501945060005b82811015612a73578489830301845285518781511683528b8101518b8d850152612a478c85018261295b565b918a0151848303858c0152919050612a5f818361292f565b978d0197958d019593505050600101612a1b565b509c9b505050505050505050505050565b6000808335601e19843603018112612a9b57600080fd5b83018035915067ffffffffffffffff821115612ab657600080fd5b6020019150600581901b3603821315611c5657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612b0257600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61833603018112612b0257600080fd5b6000808335601e19843603018112612b5757600080fd5b83018035915067ffffffffffffffff821115612b7257600080fd5b6020019150606081023603821315611c5657600080fd5b6000808335601e19843603018112612ba057600080fd5b830160208101925035905067ffffffffffffffff811115612bc057600080fd5b8060051b3603821315611c5657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112612c0657600080fd5b90910192915050565b6000808335601e19843603018112612c2657600080fd5b830160208101925035905067ffffffffffffffff811115612c4657600080fd5b803603821315611c5657600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6000808335601e19843603018112612c9757600080fd5b830160208101925035905067ffffffffffffffff811115612cb757600080fd5b606081023603821315611c5657600080fd5b60ff81168114611efb57600080fd5b8183526000602080850194508260005b8581101561298c578135612cfb81611ed9565b73ffffffffffffffffffffffffffffffffffffffff16875281830135612d2081612cc9565b60ff16878401526040828101359088015260609687019690910190600101612ce8565b818352602080840193600091600585811b830182018585805b89811015612e2b57601f19878503018b52612d77838a612bd2565b60608135612d8481611ed9565b73ffffffffffffffffffffffffffffffffffffffff168652612da882890183612b89565b828a8901528083890152608092507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612de2578586fd5b881b808289850137870190506040612dfc84820185612c0f565b94508389840301828a0152612e148484018683612c55565b9f8b019f9850505094880194505050600101612d5c565b50919998505050505050505050565b6000602080835260c083018435828501526040828601358186015260608187013581870152612e6b81880188612b89565b60a060808901528481865260e08901905060e08260051b8a010195508260005b83811015613071577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff208b890301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81863603018112612eec57600080fd5b85018035368290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61018112612f2157600080fd5b60808a5281018035612f3281611ed9565b73ffffffffffffffffffffffffffffffffffffffff80821660808d0152612f5b8d840184612bd2565b915060a0808d01528135612f6e81611ed9565b81166101208d0152818d0135612f8381611ed9565b166101408c0152612f96818b0182612c0f565b9150896101608d0152612fae6101808d018383612c55565b915050612fbd8a830183612c80565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808e85030160c08f0152612ff3848385612cd8565b93506130018c860186612c80565b93509150808e85030160e08f01525061301b838383612cd8565b9250505060808201356101008c01528b8301358c8c0152898301358a8c015261304689840184612b89565b935091508a8103898c015261305c818484612d43565b9a505050928901925090880190600101612e8b565b505050505050506130856080860186612c0f565b9250601f198583030160a0860152611b88828483612c55565b600080604083850312156130b157600080fd5b505080516020909101519092909150565b6000602082840312156130d457600080fd5b81516112d181612cc9565b73ffffffffffffffffffffffffffffffffffffffff8716815260006020878184015260c0604084015261311560c084018861292f565b86606085015283810360808501528086518083528383019150838160051b84010184890160005b8381101561316a57601f1986840301855261315883835161295b565b9487019492509086019060010161313c565b505086810360a088015261317e818961295b565b9d9c50505050505050505050505050565b600080604083850312156131a257600080fd5b825167ffffffffffffffff808211156131ba57600080fd5b6131c686838701612542565b935060208501519150808211156131dc57600080fd5b506131e985828601612542565b9150509250929050565b828152604060208201526000611606604083018461295b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b808202811582820484141761020457610204612393565b600181815b8085111561328d57816000190482111561327357613273612393565b8085161561328057918102915b93841c9390800290613257565b509250929050565b6000826132a457506001610204565b816132b157506000610204565b81600181146132c757600281146132d1576132ed565b6001915050610204565b60ff8411156132e2576132e2612393565b50506001821b610204565b5060208310610133831016604e8410600b8410161715613310575081810a610204565b61331a8383613252565b806000190482111561332e5761332e612393565b029392505050565b60006112d18383613295565b60008251612b0281846020870161290b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b828152604060208201526000611606604083018461292f565b6020815260006112d1602083018461292f56","sourceMap":"2203:3849:53:-:0;;;1597:1:51;1560:38;;2407:240:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2482:6;2489::52;1716:1:5;1821:7;:22;;;;1729:29:51;1739:10;1751:6;1729:29;;;;;;;:::i;:::-;;;;;;;;1773:11;;;;:21;:30;;;:37;:42;1769:119;;1864:11;;;;;1853:23;;;;;;:::i;:::-;;;;-1:-1:-1;;1853:23:51;;;;;;;;;1843:34;;1853:23;1843:34;;;;1831:46;;1769:119;1605:289;2418:81:52;2407:240:53;2203:3849;;14:127:56;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:56;;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:56;;576:22;;;537:62;534:88;;;602:18;;:::i;666:275::-;737:2;731:9;802:2;783:13;;-1:-1:-1;;779:27:56;767:40;;-1:-1:-1;;;;;822:34:56;;858:22;;;819:62;816:88;;;884:18;;:::i;:::-;920:2;913:22;666:275;;-1:-1:-1;666:275:56:o;946:131::-;-1:-1:-1;;;;;1021:31:56;;1011:42;;1001:70;;1067:1;1064;1057:12;1001:70;946:131;:::o;1082:250::-;1167:1;1177:113;1191:6;1188:1;1185:13;1177:113;;;1267:11;;;1261:18;1248:11;;;1241:39;1213:2;1206:10;1177:113;;;-1:-1:-1;;1324:1:56;1306:16;;1299:27;1082:250::o;1337:509::-;1390:5;1443:3;1436:4;1428:6;1424:17;1420:27;1410:55;;1461:1;1458;1451:12;1410:55;1484:13;;-1:-1:-1;;;;;1509:26:56;;1506:52;;;1538:18;;:::i;:::-;1582:55;1625:2;1606:13;;-1:-1:-1;;1602:27:56;1631:4;1598:38;1582:55;:::i;:::-;1662:2;1653:7;1646:19;1708:3;1701:4;1696:2;1688:6;1684:15;1680:26;1677:35;1674:55;;;1725:1;1722;1715:12;1674:55;1738:77;1812:2;1805:4;1796:7;1792:18;1785:4;1777:6;1773:17;1738:77;:::i;:::-;1833:7;1337:509;-1:-1:-1;;;;1337:509:56:o;1851:198::-;1926:4;-1:-1:-1;;;;;1948:30:56;;1945:56;;;1981:18;;:::i;:::-;-1:-1:-1;2026:1:56;2022:14;2038:4;2018:25;;1851:198::o;2054:2494::-;2134:5;2187:3;2180:4;2172:6;2168:17;2164:27;2154:55;;2205:1;2202;2195:12;2154:55;2234:6;2228:13;2260:4;2284:75;2300:58;2355:2;2300:58;:::i;:::-;2284:75;:::i;:::-;2393:15;;;2479:1;2475:10;;;;2463:23;;2459:32;;;2424:12;;;;2503:15;;;2500:35;;;2531:1;2528;2521:12;2500:35;2567:2;2559:6;2555:15;2579:1940;2595:6;2590:3;2587:15;2579:1940;;;2668:10;;-1:-1:-1;;;;;2735:19:56;;;2732:39;;;2767:1;2764;2757:12;2732:39;2794:24;;;;2866:4;2842:12;;;-1:-1:-1;;2838:26:56;2834:37;2831:127;;;2912:1;2941:2;2937;2930:14;2831:127;2984:22;;:::i;:::-;3048:2;3044;3040:11;3034:18;3065:33;3090:7;3065:33;:::i;:::-;3111:22;;3156:2;3193:11;;;3187:18;3221:16;;;3218:106;;;3278:1;3307:2;3303;3296:14;3218:106;3347:17;;3399:2;3391:11;;3387:21;-1:-1:-1;3377:119:56;;3450:1;3479:2;3475;3468:14;3377:119;3534:2;3530;3526:11;3520:18;3564:76;3580:59;3635:3;3580:59;:::i;3564:76::-;3684:18;;;3783:1;3779:11;;;;3771:20;;3767:29;;;3724:14;;;;3812:17;;;3809:110;;;3871:1;3901:3;3896;3889:16;3809:110;3945:11;;;;3969:167;3987:8;3980:5;3977:19;3969:167;;;4069:12;;4055:27;;4008:14;;;;4108;;;;3969:167;;;4156:14;;;4149:29;-1:-1:-1;;;4221:4:56;4213:13;;4207:20;4243:16;;;4240:109;;;4301:1;4331:3;4326;4319:16;4240:109;4385:60;4441:3;4436:2;4425:8;4421:2;4417:17;4413:26;4385:60;:::i;:::-;4369:14;;;4362:84;;;;-1:-1:-1;4459:18:56;;-1:-1:-1;;4497:12:56;;;;2612;;2579:1940;;;-1:-1:-1;4537:5:56;2054:2494;-1:-1:-1;;;;;;2054:2494:56:o;4553:1917::-;4663:6;4694:2;4737;4725:9;4716:7;4712:23;4708:32;4705:52;;;4753:1;4750;4743:12;4705:52;4780:16;;-1:-1:-1;;;;;4845:14:56;;;4842:34;;;4872:1;4869;4862:12;4842:34;4895:22;;;;4951:4;4933:16;;;4929:27;4926:47;;;4969:1;4966;4959:12;4926:47;4995:22;;:::i;:::-;5047:2;5041:9;5059:33;5084:7;5059:33;:::i;:::-;5101:22;;5154:11;;;5148:18;5178:16;;;5175:36;;;5207:1;5204;5197:12;5175:36;5230:17;;5281:4;5263:16;;;5259:27;5256:47;;;5299:1;5296;5289:12;5256:47;5327:22;;:::i;:::-;5380:2;5374:9;5408:2;5398:8;5395:16;5392:36;;;5424:1;5421;5414:12;5392:36;5447:17;;5498:4;5480:16;;;5476:27;5473:47;;;5516:1;5513;5506:12;5473:47;5544:22;;:::i;:::-;5596:2;5590:9;5608:33;5633:7;5608:33;:::i;:::-;5650:24;;5704:11;;;5698:18;5725:33;5698:18;5725:33;:::i;:::-;5774:16;;;5767:33;5839:4;5831:13;;5825:20;5857:16;;;5854:36;;;5886:1;5883;5876:12;5854:36;5926:55;5973:7;5962:8;5958:2;5954:17;5926:55;:::i;:::-;5919:4;5906:18;;5899:83;-1:-1:-1;5991:24:56;;-1:-1:-1;6046:11:56;;;6040:18;6070:16;;;6067:36;;;6099:1;6096;6089:12;6067:36;6137:82;6211:7;6200:8;6196:2;6192:17;6137:82;:::i;:::-;6132:2;6123:7;6119:16;6112:108;;6252:7;6247:2;6240:5;6236:14;6229:31;;;6299:4;6295:2;6291:13;6285:20;6269:36;;6330:2;6320:8;6317:16;6314:36;;;6346:1;6343;6336:12;6314:36;6384:55;6431:7;6420:8;6416:2;6412:17;6384:55;:::i;:::-;6377:4;6366:16;;6359:81;6370:5;4553:1917;-1:-1:-1;;;;;;4553:1917:56:o;6475:270::-;6516:3;6554:5;6548:12;6581:6;6576:3;6569:19;6597:76;6666:6;6659:4;6654:3;6650:14;6643:4;6636:5;6632:16;6597:76;:::i;:::-;6727:2;6706:15;-1:-1:-1;;6702:29:56;6693:39;;;;6734:4;6689:50;;6475:270;-1:-1:-1;;6475:270:56:o;6750:2011::-;6799:3;6827:4;6866:5;6860:12;6893:4;6888:3;6881:17;6934:1;6930;6925:3;6921:11;6917:19;6993:2;6978:12;6972:19;6968:28;6961:4;6956:3;6952:14;6945:52;7016:4;7075:2;7061:12;7057:21;7051:28;7098:4;7154:2;7138:14;7134:23;7127:4;7122:3;7118:14;7111:47;7213:4;7199:12;7195:23;7189:30;7167:52;;7250:4;7244:3;7239;7235:13;7228:27;7277:47;7319:3;7314;7310:13;7294:14;7277:47;:::i;:::-;7361:14;;;7355:21;7406:15;;;7392:12;;;7385:37;7472:21;;7502;;;7264:60;;-1:-1:-1;7634:23:56;;;-1:-1:-1;7541:14:56;;;;7595:1;7591:14;;;7580:26;;7576:35;;7675:1;;7706:1029;7722:6;7717:3;7714:15;7706:1029;;;7793:16;;;-1:-1:-1;;7789:30:56;7775:45;;7843:13;;7926:9;;7922:18;;7909:32;;7982:11;;;7976:18;8014:13;;;8007:25;;;8093:21;;7883:13;;;8127:24;;;8216:23;;;;8263:1;;8183:3;8173:14;;;8277:209;8293:8;8288:3;8285:17;8277:209;;;8370:15;;8356:30;;8455:17;;;;8321:1;8312:11;;;;;8412:14;;;;8277:209;;;8281:3;8535:2;8531;8527:11;8521:18;8499:40;;8585:4;8578:5;8574:16;8569:2;8563:4;8559:13;8552:39;8612;8645:5;8629:14;8612:39;:::i;:::-;8604:47;;;;;;8686:2;8678:6;8674:15;8664:25;;8722:2;8715:5;8711:14;8702:23;;7748:1;7743:3;7739:11;7732:18;;7706:1029;;;-1:-1:-1;8751:4:56;;6750:2011;-1:-1:-1;;;;;;;;;;;;6750:2011:56:o;8766:755::-;-1:-1:-1;;;;;9041:15:56;;;9023:34;;9093:2;9088;9073:18;;;9066:30;;;9136:13;;9132:22;;;9112:18;;;9105:50;9190:15;;9184:22;9244:4;9222:20;;;9215:34;8966:4;;9272:59;9003:3;9311:19;;9184:22;9272:59;:::i;:::-;9258:73;;9380:2;9372:6;9368:15;9362:22;9453:2;9449:7;9437:9;9429:6;9425:22;9421:36;9415:3;9404:9;9400:19;9393:65;9475:40;9508:6;9492:14;9475:40;:::i;:::-;9467:48;8766:755;-1:-1:-1;;;;;;8766:755:56:o;9526:255::-;9703:2;9692:9;9685:21;9666:4;9723:52;9771:2;9760:9;9756:18;9748:6;9723:52;:::i;:::-;9715:60;9526:255;-1:-1:-1;;;9526:255:56:o;:::-;2203:3849:53;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x60806040526004361061005a5760003560e01c80637ea0b76a116100435780637ea0b76a146100bd57806393be095e146100d0578063f037e4e3146101125761005a565b806301ffc9a714610068578063059bebe61461009d575b34801561006657600080fd5b005b34801561007457600080fd5b50610088610083366004611e97565b610125565b60405190151581526020015b60405180910390f35b3480156100a957600080fd5b506100666100b8366004611efe565b61020a565b6100666100cb366004611fa8565b6106fa565b3480156100dc57600080fd5b506101047f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610094565b61006661012036600461202d565b610a5a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f059bebe60000000000000000000000000000000000000000000000000000000014806101b857507fffffffff0000000000000000000000000000000000000000000000000000000082167f7ea0b76a00000000000000000000000000000000000000000000000000000000145b8061020457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000806102198385018561214b565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526e22d473030f116ddee9f6b43ac78ba3600482018190526000196024830152929450909250819073ffffffffffffffffffffffffffffffffffffffff8b169063095ea7b3906044016020604051808303816000875af11580156102a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ca9190612347565b5082516001146103215760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420737761702070617468206c656e677468000000000000000060448201526064015b60405180910390fd5b8973ffffffffffffffffffffffffffffffffffffffff168360008151811061034b5761034b612364565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16146103ba5760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420696e70757420746f6b656e000000000000000000000000006044820152606401610318565b8873ffffffffffffffffffffffffffffffffffffffff16836000815181106103e4576103e4612364565b60200260200101516020015160018560008151811061040557610405612364565b6020026020010151602001515161041c91906123c2565b8151811061042c5761042c612364565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff161461049b5760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964206f757470757420746f6b656e0000000000000000000000006044820152606401610318565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8b16906370a0823190602401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052991906123d5565b8811156105785760405162461bcd60e51b815260206004820181905260248201527f496e73756666696369656e7420696e70757420746f6b656e2062616c616e63656044820152606401610318565b6040517f87517c4500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152808616602483015260448201819052600060648301528591908416906387517c4590608401600060405180830381600087803b1580156105fa57600080fd5b505af115801561060e573d6000803e3d6000fd5b50505050888460008151811061062657610626612364565b6020026020010151604001818152505060008460008151811061064b5761064b612364565b6020026020010151606001818152505060008060008373ffffffffffffffffffffffffffffffffffffffff1663286f580d8860001960006040518463ffffffff1660e01b81526004016106a0939291906123ee565b6000604051808303816000875af11580156106bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106e791908101906125ac565b5050505050505050505050505050505050565b610702610b0c565b61070b81612849565b7f0000000000000000000000000000000000000000000000000000000000000000158015906107805750806040516020016107469190612997565b604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000014155b156107b7576040517f8812562900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c46060840184612a84565b90506000036107ff576040517f9c95219f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061080e6060850185612a84565b600081811061081f5761081f612364565b90506020028101906108319190612ace565b61083b9080612b0c565b610849906040810190612b40565b6108566060870187612a84565b600081811061086757610867612364565b90506020028101906108799190612ace565b6020013581811061088c5761088c612364565b6108a2926020606090920201908101915061202d565b905060006108b36060860186612a84565b60008181106108c4576108c4612364565b90506020028101906108d69190612ace565b6108e09080612b0c565b6108ee906060810190612b40565b6108fb6060880188612a84565b600081811061090c5761090c612364565b905060200281019061091e9190612ace565b6040013581811061093157610931612364565b610947926020606090920201908101915061202d565b905061096b73ffffffffffffffffffffffffffffffffffffffff8316876000610b65565b61098e73ffffffffffffffffffffffffffffffffffffffff831687600019610b65565b6000808773ffffffffffffffffffffffffffffffffffffffff16630997c4a0886040518263ffffffff1660e01b81526004016109ca9190612e3a565b60408051808303816000875af11580156109e8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0c919061309e565b9092509050610a3373ffffffffffffffffffffffffffffffffffffffff8516896000610b65565b610a46610a3f87612849565b8585610d2d565b5050505050610a556001600055565b505050565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526e22d473030f116ddee9f6b43ac78ba36004820181905260001960248301529073ffffffffffffffffffffffffffffffffffffffff83169063095ea7b3906044016020604051808303816000875af1158015610ae0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a559190612347565b505050505050565b600260005403610b5e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610318565b6002600055565b801580610c0557506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0391906123d5565b155b610c775760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610318565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611105565b604080516001808252818301909252600091816020015b6060815260200190600190039081610d44575050604080516003808252608082019092529192506000919060208201606080368337019050506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1191906123d5565b90508015610e3a57610e3a73ffffffffffffffffffffffffffffffffffffffff861633836111fa565b60008573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eab91906130c2565b60ff169050610ebc82826000611250565b83600081518110610ecf57610ecf612364565b602090810291909101015250506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015610f49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6d91906123d5565b90508015610f9657610f9673ffffffffffffffffffffffffffffffffffffffff851633836111fa565b60008473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100791906130c2565b60ff16905061101882826000611250565b8360018151811061102b5761102b612364565b60209081029190910101525047905061104433826112d8565b808260028151811061105857611058612364565b60200260200101818152505050808260008151811061107957611079612364565b6020908102919091010152604080516001808252818301909252600091816020015b6040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915281526020019060019003908161109b57905050905085816000815181106110f0576110f0612364565b6020026020010181905250610b0483826113fe565b6000611167826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166115f79092919063ffffffff16565b90508051600014806111885750808060200190518101906111889190612347565b610a555760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610318565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610cc9565b60008260121115611285576012839003600283161561127b57611273858261160e565b9150506112d1565b611273858261165f565b60128311156112ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee830160018316156112c4576112738582611697565b61127385826116e5565b50825b9392505050565b804710156113285760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610318565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611382576040519150601f19603f3d011682016040523d82523d6000602084013e611387565b606091505b5050905080610a555760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610318565b336114316040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915290565b60005b83518110156115f05783818151811061144f5761144f612364565b6020026020010151915060008260000151604001515111156115e8578151805160209182015160008681523090935260408320839273ffffffffffffffffffffffffffffffffffffffff169163d6e3357a9187600001516040015160006114ba8d8b60200151611708565b604080516000815260208101918290527fffffffff0000000000000000000000000000000000000000000000000000000060e089901b16909152611506959493929190602481016130df565b600060405180830381865afa158015611523573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261154b919081019061318f565b80519193509150156115e5578351602001516040517f946aadc600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063946aadc6906115b290889085906004016131f3565b600060405180830381600087803b1580156115cc57600080fd5b505af11580156115e0573d6000803e3d6000fd5b505050505b50505b600101611434565b5050505050565b60606116068484600085611a18565b949350505050565b6000604e821061163057821561162657600019611629565b60005b9050610204565b50600a81900a828102908381838161164a5761164a61320c565b041461165857600019611606565b5092915050565b600a81900a61166e818461323b565b9050604e821061020457821561168e5761168982600a613336565b6112d1565b60009392505050565b6000604e82106116bb5782156116ae5760016116b1565b60005b60ff169050610204565b600a82900a8084816116cf576116cf61320c565b0491508082028414611658575060010192915050565b6000604e82101561168e5781600a0a83816117025761170261320c565b046112d1565b60606000825167ffffffffffffffff8111156117265761172661204a565b60405190808252806020026020018201604052801561174f578160200160208202803683370190505b509050600080845111611763576000611769565b83516001015b855160010101905060008167ffffffffffffffff81111561178c5761178c61204a565b6040519080825280602002602001820160405280156117bf57816020015b60608152602001906001900390816117aa5790505b50905060006117e4604080516002815233602082015230818301526060810190915290565b8282815181106117f6576117f6612364565b602002602001018190525060005b875181101561185457818060010192505087818151811061182757611827612364565b602002602001015183838151811061184157611841612364565b6020908102919091010152600101611804565b50855115611a0e5780806001019150508382828151811061187757611877612364565b602002602001018190525060005b8651811015611a0c576119368782815181106118a3576118a3612364565b6020026020010151600001516119136118e08a85815181106118c7576118c7612364565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b89848151811061192557611925612364565b602002602001015160400151611b17565b61196f576040517f52bf984800000000000000000000000000000000000000000000000000000000815260048101829052602401610318565b86818151811061198157611981612364565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168582815181106119b5576119b5612364565b60200260200101818152505081806001019250508681815181106119db576119db612364565b6020026020010151602001518383815181106119f9576119f9612364565b6020908102919091010152600101611885565b505b5095945050505050565b606082471015611a905760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610318565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ab99190613342565b60006040518083038185875af1925050503d8060008114611af6576040519150601f19603f3d011682016040523d82523d6000602084013e611afb565b606091505b5091509150611b0c87838387611b92565b979650505050505050565b6000806000611b268585611c18565b90925090506000816004811115611b3f57611b3f613354565b148015611b7757508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611b885750611b88868686611c5d565b9695505050505050565b60608315611c0e578251600003611c075773ffffffffffffffffffffffffffffffffffffffff85163b611c075760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610318565b5081611606565b6116068383611d9c565b6000808251604103611c4e5760208301516040840151606085015160001a611c4287828585611dc6565b94509450505050611c56565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c94929190613383565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cff9190613342565b600060405180830381855afa9150503d8060008114611d3a576040519150601f19603f3d011682016040523d82523d6000602084013e611d3f565b606091505b5091509150818015611d5357506020815110155b8015611b88575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d9190830160209081019084016123d5565b149695505050505050565b815115611dac5781518083602001fd5b8060405162461bcd60e51b8152600401610318919061339c565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611dfd5750600090506003611e8e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e51573d6000803e3d6000fd5b5050604051601f19015191505073ffffffffffffffffffffffffffffffffffffffff8116611e8757600060019250925050611e8e565b9150600090505b94509492505050565b600060208284031215611ea957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146112d157600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611efb57600080fd5b50565b60008060008060008060a08789031215611f1757600080fd5b8635611f2281611ed9565b95506020870135611f3281611ed9565b94506040870135935060608701359250608087013567ffffffffffffffff80821115611f5d57600080fd5b818901915089601f830112611f7157600080fd5b813581811115611f8057600080fd5b8a6020828501011115611f9257600080fd5b6020830194508093505050509295509295509295565b600080600060608486031215611fbd57600080fd5b8335611fc881611ed9565b9250602084013567ffffffffffffffff80821115611fe557600080fd5b9085019060a08288031215611ff957600080fd5b9092506040850135908082111561200f57600080fd5b5084016040818703121561202257600080fd5b809150509250925092565b60006020828403121561203f57600080fd5b81356112d181611ed9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561209c5761209c61204a565b60405290565b6040516060810167ffffffffffffffff8111828210171561209c5761209c61204a565b6040805190810167ffffffffffffffff8111828210171561209c5761209c61204a565b604051601f8201601f1916810167ffffffffffffffff811182821017156121115761211161204a565b604052919050565b600067ffffffffffffffff8211156121335761213361204a565b5060051b60200190565b8015158114611efb57600080fd5b6000806040838503121561215e57600080fd5b6121688335611ed9565b8235915067ffffffffffffffff6020840135111561218557600080fd5b6020830135830184601f82011261219b57600080fd5b6121ad6121a88235612119565b6120e8565b81358082526020808301929160051b8401018710156121cb57600080fd5b602083015b6020843560051b8501018110156123395767ffffffffffffffff813511156121f757600080fd5b803584016080601f19828b0301121561220f57600080fd5b612217612079565b6122246020830135611ed9565b6020820135815267ffffffffffffffff6040830135111561224457600080fd5b604082013582018a603f82011261225a57600080fd5b61226a6121a86020830135612119565b602082810135808352908201919060600283016040018d101561228c57600080fd5b604083015b60406060602086013502850101811015612309576060818f0312156122b557600080fd5b6122bd6120a2565b6122c78235611ed9565b813581526122d86020830135611ed9565b602082013560208201526122ef604083013561213d565b604082810135908201528352602090920191606001612291565b506020848101919091526060858101356040860152608090950135948401949094525050845292830192016121d0565b508093505050509250929050565b60006020828403121561235957600080fd5b81516112d18161213d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561020457610204612393565b6000602082840312156123e757600080fd5b5051919050565b600060808083016080845280875180835260a0925060a08601915060a08160051b8701016020808b016000805b858110156124ee578a85037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600187528251805173ffffffffffffffffffffffffffffffffffffffff9081168752858201518688018c905280518c8901819052908701919085908c8a01905b808310156124c25784518051851683528a81015185168b8401526040908101511515908301529389019360019290920191606090910190612486565b50604085810151908b01526060948501519490990193909352505050958301959183019160010161241b565b505050870189905287151560408801528681036060880152600281527f30780000000000000000000000000000000000000000000000000000000000006020820152604081019a9950505050505050505050565b600082601f83011261255357600080fd5b815160206125636121a883612119565b8083825260208201915060208460051b87010193508684111561258557600080fd5b602086015b848110156125a1578051835291830191830161258a565b509695505050505050565b6000806000606084860312156125c157600080fd5b835167ffffffffffffffff808211156125d957600080fd5b6125e587838801612542565b94506020915081860151818111156125fc57600080fd5b8601601f8101881361260d57600080fd5b805161261b6121a882612119565b81815260059190911b8201840190848101908a83111561263a57600080fd5b928501925b8284101561266157835161265281611ed9565b8252928501929085019061263f565b60408a015190975094505050508082111561267b57600080fd5b5061268886828701612542565b9150509250925092565b600082601f8301126126a357600080fd5b813567ffffffffffffffff8111156126bd576126bd61204a565b6126d06020601f19601f840116016120e8565b8181528460208386010111156126e557600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261271357600080fd5b813560206127236121a883612119565b82815260059290921b8401810191818101908684111561274257600080fd5b8286015b848110156125a157803567ffffffffffffffff8082111561276657600080fd5b908801906060828b03601f1901121561277f5760008081fd5b6127876120a2565b8683013561279481611ed9565b8152604083810135838111156127aa5760008081fd5b8401603f81018d136127bc5760008081fd5b888101356127cc6121a882612119565b81815260059190911b82018301908a8101908f8311156127ec5760008081fd5b928401925b8284101561280a5783358252928b0192908b01906127f1565b858c01525050506060840135838111156128245760008081fd5b6128328d8a83880101612692565b918301919091525085525050918301918301612746565b60006040823603121561285b57600080fd5b6128636120c5565b823567ffffffffffffffff8082111561287b57600080fd5b81850191506060823603121561289057600080fd5b6128986120a2565b82356128a381611ed9565b815260208301356128b381611ed9565b60208201526040830135828111156128ca57600080fd5b6128d636828601612692565b604083015250835260208501359150808211156128f257600080fd5b506128ff36828601612702565b60208301525092915050565b60005b8381101561292657818101518382015260200161290e565b50506000910152565b6000815180845261294781602086016020860161290b565b601f01601f19169290920160200192915050565b60008151808452602080850194506020840160005b8381101561298c57815187529582019590820190600101612970565b509495945050505050565b60006020808352606084516040808487015273ffffffffffffffffffffffffffffffffffffffff808351166060880152808584015116608088015260408301519250606060a08801526129ed60c088018461292f565b925084880151601f19808986030160408a01528482518087528887019150888160051b880101898501945060005b82811015612a73578489830301845285518781511683528b8101518b8d850152612a478c85018261295b565b918a0151848303858c0152919050612a5f818361292f565b978d0197958d019593505050600101612a1b565b509c9b505050505050505050505050565b6000808335601e19843603018112612a9b57600080fd5b83018035915067ffffffffffffffff821115612ab657600080fd5b6020019150600581901b3603821315611c5657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612b0257600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61833603018112612b0257600080fd5b6000808335601e19843603018112612b5757600080fd5b83018035915067ffffffffffffffff821115612b7257600080fd5b6020019150606081023603821315611c5657600080fd5b6000808335601e19843603018112612ba057600080fd5b830160208101925035905067ffffffffffffffff811115612bc057600080fd5b8060051b3603821315611c5657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112612c0657600080fd5b90910192915050565b6000808335601e19843603018112612c2657600080fd5b830160208101925035905067ffffffffffffffff811115612c4657600080fd5b803603821315611c5657600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6000808335601e19843603018112612c9757600080fd5b830160208101925035905067ffffffffffffffff811115612cb757600080fd5b606081023603821315611c5657600080fd5b60ff81168114611efb57600080fd5b8183526000602080850194508260005b8581101561298c578135612cfb81611ed9565b73ffffffffffffffffffffffffffffffffffffffff16875281830135612d2081612cc9565b60ff16878401526040828101359088015260609687019690910190600101612ce8565b818352602080840193600091600585811b830182018585805b89811015612e2b57601f19878503018b52612d77838a612bd2565b60608135612d8481611ed9565b73ffffffffffffffffffffffffffffffffffffffff168652612da882890183612b89565b828a8901528083890152608092507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612de2578586fd5b881b808289850137870190506040612dfc84820185612c0f565b94508389840301828a0152612e148484018683612c55565b9f8b019f9850505094880194505050600101612d5c565b50919998505050505050505050565b6000602080835260c083018435828501526040828601358186015260608187013581870152612e6b81880188612b89565b60a060808901528481865260e08901905060e08260051b8a010195508260005b83811015613071577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff208b890301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81863603018112612eec57600080fd5b85018035368290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61018112612f2157600080fd5b60808a5281018035612f3281611ed9565b73ffffffffffffffffffffffffffffffffffffffff80821660808d0152612f5b8d840184612bd2565b915060a0808d01528135612f6e81611ed9565b81166101208d0152818d0135612f8381611ed9565b166101408c0152612f96818b0182612c0f565b9150896101608d0152612fae6101808d018383612c55565b915050612fbd8a830183612c80565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808e85030160c08f0152612ff3848385612cd8565b93506130018c860186612c80565b93509150808e85030160e08f01525061301b838383612cd8565b9250505060808201356101008c01528b8301358c8c0152898301358a8c015261304689840184612b89565b935091508a8103898c015261305c818484612d43565b9a505050928901925090880190600101612e8b565b505050505050506130856080860186612c0f565b9250601f198583030160a0860152611b88828483612c55565b600080604083850312156130b157600080fd5b505080516020909101519092909150565b6000602082840312156130d457600080fd5b81516112d181612cc9565b73ffffffffffffffffffffffffffffffffffffffff8716815260006020878184015260c0604084015261311560c084018861292f565b86606085015283810360808501528086518083528383019150838160051b84010184890160005b8381101561316a57601f1986840301855261315883835161295b565b9487019492509086019060010161313c565b505086810360a088015261317e818961295b565b9d9c50505050505050505050505050565b600080604083850312156131a257600080fd5b825167ffffffffffffffff808211156131ba57600080fd5b6131c686838701612542565b935060208501519150808211156131dc57600080fd5b506131e985828601612542565b9150509250929050565b828152604060208201526000611606604083018461295b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b808202811582820484141761020457610204612393565b600181815b8085111561328d57816000190482111561327357613273612393565b8085161561328057918102915b93841c9390800290613257565b509250929050565b6000826132a457506001610204565b816132b157506000610204565b81600181146132c757600281146132d1576132ed565b6001915050610204565b60ff8411156132e2576132e2612393565b50506001821b610204565b5060208310610133831016604e8410600b8410161715613310575081810a610204565b61331a8383613252565b806000190482111561332e5761332e612393565b029392505050565b60006112d18383613295565b60008251612b0281846020870161290b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b828152604060208201526000611606604083018461292f565b6020815260006112d1602083018461292f56","sourceMap":"2203:3849:53:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2533:290:52;;;;;;;;;;-1:-1:-1;2533:290:52;;;;;:::i;:::-;;:::i;:::-;;;612:14:56;;605:22;587:41;;575:2;560:18;2533:290:52;;;;;;;;2883:3110:53;;;;;;;;;;-1:-1:-1;2883:3110:53;;;;;:::i;:::-;;:::i;2877:1011:52:-;;;;;;:::i;:::-;;:::i;1560:38:51:-;;;;;;;;;;;;;;;;;;2797:25:56;;;2785:2;2770:18;1560:38:51;2651:177:56;2653:179:53;;;;;;:::i;:::-;;:::i;2533:290:52:-;2618:4;2642:55;;;2657:40;2642:55;;2641:135;;-1:-1:-1;2715:60:52;;;2730:45;2715:60;2641:135;:175;;;-1:-1:-1;952:25:14;937:40;;;;2780:36:52;2634:182;2533:290;-1:-1:-1;;2533:290:52:o;2883:3110:53:-;3215:23;;3283:96;;;;3307:14;3283:96;:::i;:::-;3548:54;;;;;3416:42;3548:54;;;7930:74:56;;;-1:-1:-1;;8020:18:56;;;8013:34;3214:165:53;;-1:-1:-1;3214:165:53;;-1:-1:-1;3416:42:53;;3548:26;;;;;;7903:18:56;;3548:54:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3655:8;:15;3674:1;3655:20;3647:57;;;;-1:-1:-1;;;3647:57:53;;8510:2:56;3647:57:53;;;8492:21:56;8549:2;8529:18;;;8522:30;8588:26;8568:18;;;8561:54;8632:18;;3647:57:53;;;;;;;;;3754:10;3722:42;;3730:8;3739:1;3730:11;;;;;;;;:::i;:::-;;;;;;;:19;;;3722:42;;;3714:74;;;;-1:-1:-1;;;3714:74:53;;9052:2:56;3714:74:53;;;9034:21:56;9091:2;9071:18;;;9064:30;9130:21;9110:18;;;9103:49;9169:18;;3714:74:53;8850:343:56;3714:74:53;3875:11;3806:80;;3814:8;3823:1;3814:11;;;;;;;;:::i;:::-;;;;;;;:17;;;3859:1;3832:8;3841:1;3832:11;;;;;;;;:::i;:::-;;;;;;;:17;;;:24;:28;;;;:::i;:::-;3814:47;;;;;;;;:::i;:::-;;;;;;;:56;;;3806:80;;;3798:113;;;;-1:-1:-1;;;3798:113:53;;9722:2:56;3798:113:53;;;9704:21:56;9761:2;9741:18;;;9734:30;9800:22;9780:18;;;9773:50;9840:18;;3798:113:53;9520:344:56;3798:113:53;3948:43;;;;;3985:4;3948:43;;;10015:74:56;3948:28:53;;;;;;9988:18:56;;3948:43:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3929:15;:62;;3921:107;;;;-1:-1:-1;;;3921:107:53;;10491:2:56;3921:107:53;;;10473:21:56;;;10510:18;;;10503:30;10569:34;10549:18;;;10542:62;10621:18;;3921:107:53;10289:356:56;3921:107:53;4312:67;;;;;:16;10967:15:56;;;4312:67:53;;;10949:34:56;11019:15;;;10999:18;;;10992:43;11051:18;;;11044:43;;;4081:29:53;11103:18:56;;;11096:55;4128:15:53;;4312:16;;;;;;10860:19:56;;4312:67:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5171:15;5143:8;5152:1;5143:11;;;;;;;;:::i;:::-;;;;;;;:25;;:43;;;;;5223:1;5196:8;5205:1;5196:11;;;;;;;;:::i;:::-;;;;;;;:24;;:28;;;;;5639:31;5672:26;5700:27;5731:14;:26;;;5758:8;-1:-1:-1;;5787:5:53;5731:68;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5731:68:53;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;2883:3110:53:o;2877:1011:52:-;2261:21:5;:19;:21::i;:::-;1900:186:51::1;3053:4:52::0;1900:186:51::1;:::i;:::-;1957:9;:23:::0;;::::1;::::0;:67:::1;;;2018:4;2007:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;1997:27;;;;;;1984:9;:40;;1957:67;1953:116;;;2047:11;;;;;;;;;;;;;;1953:116;3146:17:52::2;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;:24;;3174:1;3146:29:::0;3142:77:::2;;3198:10;;;;;;;;;;;;;;3142:77;3229:24;3256:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3274:1;3256:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:26;::::0;;::::2;:::i;:::-;:38;::::0;::::2;::::0;::::2;::::0;::::2;:::i;:::-;3295:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3313:1;3295:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:33;;;3256:73;;;;;;;:::i;:::-;:79;::::0;::::2;:73;::::0;;::::2;;:79:::0;;::::2;::::0;-1:-1:-1;3256:79:52::2;:::i;:::-;3229:106:::0;-1:-1:-1;3345:25:52::2;3373:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3391:1;3373:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:26;::::0;;::::2;:::i;:::-;:39;::::0;::::2;::::0;::::2;::::0;::::2;:::i;:::-;3413:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3431:1;3413:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:34;;;3373:75;;;;;;;:::i;:::-;:81;::::0;::::2;:75;::::0;;::::2;;:81:::0;;::::2;::::0;-1:-1:-1;3373:81:52::2;:::i;:::-;3345:109:::0;-1:-1:-1;3465:59:52::2;:36;::::0;::::2;3510:9:::0;3522:1:::2;3465:36;:59::i;:::-;3534:75;:36;::::0;::::2;3579:9:::0;-1:-1:-1;;3534:36:52::2;:75::i;:::-;3620:18;3640:19:::0;3663:9:::2;:21;;;3685:10;3663:33;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3619:77:::0;;-1:-1:-1;3619:77:52;-1:-1:-1;3741:59:52::2;:36;::::0;::::2;3786:9:::0;3798:1:::2;3741:36;:59::i;:::-;3811:70;;3839:4:::0;3811:70:::2;:::i;:::-;3845:16;3863:17;3811:27;:70::i;:::-;3063:825;;;;2292:1:5::1;2303:20:::0;1716:1;2809:7;:22;2629:209;2303:20;2877:1011:52;;;:::o;2653:179:53:-;2776:49;;;;;2724:42;2776:49;;;7930:74:56;;;-1:-1:-1;;8020:18:56;;;8013:34;2724:42:53;2776:21;;;;;;7903:18:56;;2776:49:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;3937:100:52:-;;;;;;;:::o;2336:287:5:-;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:5;;35087:2:56;2460:63:5;;;35069:21:56;35126:2;35106:18;;;35099:30;35165:33;35145:18;;;35138:61;35216:18;;2460:63:5;34885:355:56;2460:63:5;1759:1;2598:7;:18;2336:287::o;1818:573:9:-;2143:10;;;2142:62;;-1:-1:-1;2159:39:9;;;;;2183:4;2159:39;;;35480:34:56;2159:15:9;35550::56;;;35530:18;;;35523:43;2159:15:9;;;;;35392:18:56;;2159:39:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;2142:62;2121:163;;;;-1:-1:-1;;;2121:163:9;;35779:2:56;2121:163:9;;;35761:21:56;35818:2;35798:18;;;35791:30;35857:34;35837:18;;;35830:62;35928:24;35908:18;;;35901:52;35970:19;;2121:163:9;35577:418:56;2121:163:9;2321:62;;7960:42:56;7948:55;;2321:62:9;;;7930:74:56;8020:18;;;8013:34;;;2294:90:9;;2314:5;;2344:22;;7903:18:56;;2321:62:9;;;;-1:-1:-1;;2321:62:9;;;;;;;;;;;;;;;;;;;;;;;;;;;2294:19;:90::i;1058:2206:55:-;1200:18;;;1216:1;1200:18;;;;;;;;;1171:26;;1200:18;;;;;;;;;;;;;;;;;-1:-1:-1;;1251:16:55;;;1265:1;1251:16;;;;;;;;;1171:47;;-1:-1:-1;1228:20:55;;1251:16;;;;;;;;;;;-1:-1:-1;;1375:49:55;;;;;1418:4;1375:49;;;10015:74:56;1228:39:55;;-1:-1:-1;1352:20:55;;1375:34;;;;;;9988:18:56;;1375:49:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1352:72;-1:-1:-1;1442:16:55;;1438:118;;1478:63;:37;;;1516:10;1528:12;1478:37;:63::i;:::-;1569:21;1608:16;1593:41;;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1569:67;;;;1659:214;1710:12;1740:13;1858:1;1659:33;:214::i;:::-;1650:3;1654:1;1650:6;;;;;;;;:::i;:::-;;;;;;;;;;:223;-1:-1:-1;;1993:50:55;;;;;2037:4;1993:50;;;10015:74:56;1969:21:55;;1993:35;;;;;;9988:18:56;;1993:50:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1969:74;-1:-1:-1;2061:17:55;;2057:121;;2098:65;:38;;;2137:10;2149:13;2098:38;:65::i;:::-;2192:22;2232:17;2217:42;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2192:69;;;;2284:216;2335:13;2366:14;2485:1;2284:33;:216::i;:::-;2275:3;2279:1;2275:6;;;;;;;;:::i;:::-;;;;;;;;;;:225;-1:-1:-1;2985:21:55;;-1:-1:-1;3020:50:55;3046:10;2985:21;3020:17;:50::i;:::-;3093:10;3084:3;3088:1;3084:6;;;;;;;;:::i;:::-;;;;;;:19;;;;;2521:593;3137:3;3124:7;3132:1;3124:10;;;;;;;;:::i;:::-;;;;;;;;;;:16;3174:15;;;3187:1;3174:15;;;;;;;;;3151:20;;3174:15;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3174:15:55;;;;;;;;;;;;;;;3151:38;;3209:4;3199;3204:1;3199:7;;;;;;;;:::i;:::-;;;;;;:14;;;;3223:34;3243:7;3252:4;3223:19;:34::i;5196:642:9:-;5615:23;5641:69;5669:4;5641:69;;;;;;;;;;;;;;;;;5649:5;5641:27;;;;:69;;;;;:::i;:::-;5615:95;;5728:10;:17;5749:1;5728:22;:56;;;;5765:10;5754:30;;;;;;;;;;;;:::i;:::-;5720:111;;;;-1:-1:-1;;;5720:111:9;;36454:2:56;5720:111:9;;;36436:21:56;36493:2;36473:18;;;36466:30;36532:34;36512:18;;;36505:62;36603:12;36583:18;;;36576:40;36633:19;;5720:111:9;36252:406:56;941:175:9;1050:58;;7960:42:56;7948:55;;1050:58:9;;;7930:74:56;8020:18;;;8013:34;;;1023:86:9;;1043:5;;1073:23;;7903:18:56;;1050:58:9;7756:297:56;6376:849:3;6460:7;6530:8;344:2:2;6507:31:3;6503:706;;;344:2:2;6578:31:3;;;594:6:2;6631:21:3;;:25;6627:185;;6687:31;6705:1;6708:9;6687:17;:31::i;:::-;6680:38;;;;;6627:185;6772:21;6780:1;6783:9;6772:7;:21::i;6503:706::-;344:2:2;6836:8:3;:31;6832:377;;;6909:31;;;507:1:2;6962:21:3;;:25;6958:190;;7018:32;7035:1;7038:11;7018:16;:32::i;6958:190::-;7104:25;7114:1;7117:11;7104:9;:25::i;6832:377::-;-1:-1:-1;7193:1:3;6832:377;6376:849;;;;;:::o;2647:312:10:-;2761:6;2736:21;:31;;2728:73;;;;-1:-1:-1;;;2728:73:10;;36865:2:56;2728:73:10;;;36847:21:56;36904:2;36884:18;;;36877:30;36943:31;36923:18;;;36916:59;36992:18;;2728:73:10;36663:353:56;2728:73:10;2813:12;2831:9;:14;;2853:6;2831:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2812:52;;;2882:7;2874:78;;;;-1:-1:-1;;;2874:78:10;;37433:2:56;2874:78:10;;;37415:21:56;37472:2;37452:18;;;37445:30;37511:34;37491:18;;;37484:62;37582:28;37562:18;;;37555:56;37628:19;;2874:78:10;37231:422:56;4688:935:54;4836:10;4859:18;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4859:18:54;4892:9;4887:730;4911:4;:11;4907:1;:15;4887:730;;;4950:4;4955:1;4950:7;;;;;;;;:::i;:::-;;;;;;;4943:14;;5008:1;4975:4;:14;;;:23;;;:30;:34;4971:636;;;5081:14;;:26;;5135:20;;;;;5030:22;1218:25:42;;;5226:4:54;1256:20:42;;;1324:4;1311:18;;5030:22:54;;5081:32;;;;;5254:4;:14;;;:23;;;5318:1;5342:45;5359:7;5368:4;:18;;;5342:16;:45::i;:::-;5409:16;;;5423:1;5409:16;;;;;;;;;5081:362;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5081:362:54;;;;;;;;;;;;:::i;:::-;5490:13;;5029:414;;-1:-1:-1;5029:414:54;-1:-1:-1;5490:17:54;5486:107;;5531:14;;:20;;;:43;;;;;:24;;;;;;;:43;;5556:9;;5567:6;;5531:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5486:107;5011:596;;4971:636;4924:3;;4887:730;;;;4763:860;;4688:935;;:::o;4108:223:10:-;4241:12;4272:52;4294:6;4302:4;4308:1;4311:12;4272:21;:52::i;:::-;4265:59;4108:223;-1:-1:-1;;;;4108:223:10:o;3853:689:3:-;3933:9;817:2:2;3982:9:3;:34;3978:548;;4040:6;;:30;;-1:-1:-1;;4040:30:3;;;4049:1;4040:30;4036:34;;3978:548;;;-1:-1:-1;4252:2:3;:15;;;4289:6;;;;:1;4252:15;4289:6;4252:15;4476:6;;;;:::i;:::-;;:11;:35;;-1:-1:-1;;4476:35:3;;;-1:-1:-1;4490:1:3;4472:39;-1:-1:-1;;3853:689:3:o;2909:688::-;3084:2;:15;;;3123:5;3084:15;3123:1;:5;:::i;:::-;3119:9;;817:2:2;3498:9:3;:34;3494:97;;3552:6;;:28;;3565:15;3571:9;3565:2;:15;:::i;:::-;3552:28;;;3561:1;3548:32;2909:688;-1:-1:-1;;;2909:688:3:o;5491:598::-;5572:9;817:2:2;5621:11:3;:36;5617:456;;5681:6;;:14;;5694:1;5681:14;;;5690:1;5681:14;5677:18;;;;5617:456;;;5746:2;:17;;;;5785:1;5746:17;5785:5;;;;:::i;:::-;;5781:9;;6009:1;6005;:5;6000:1;:10;5996:63;;-1:-1:-1;6039:1:3;6034:6;;5491:598;-1:-1:-1;;5491:598:3:o;4915:207::-;4989:7;817:2:2;5039:11:3;:36;;:66;;5093:11;5087:2;:17;5082:1;:23;;;;;:::i;:::-;;5039:66;;7619:2290:39;7754:18;7812:24;7853:14;:21;7839:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7839:36:39;;7812:63;;8024:21;8098:1;8074:14;:21;:25;:57;;8130:1;8074:57;;;8102:14;:21;8126:1;8102:25;8074:57;8052:11;:18;8048:1;:22;:84;8024:108;;8147:26;8192:13;8176:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8147:59;;8220:14;8270:17;3181:4:23;3175:11;;3213:1;3199:16;;2741:10:39;3246:4:23;3235:16;;3228:27;2779:4:39;3275:16:23;;;3268:27;2664:16:39;3321::23;;3308:30;;;3175:11;2625:169:39;8270:17;8252:7;8260:6;8252:15;;;;;;;;:::i;:::-;;;;;;:35;;;;8307:9;8302:140;8326:11;:18;8322:1;:22;8302:140;;;8369:8;;;;;;;8413:11;8425:1;8413:14;;;;;;;;:::i;:::-;;;;;;;8395:7;8403:6;8395:15;;;;;;;;:::i;:::-;;;;;;;;;;:32;8346:3;;8302:140;;;-1:-1:-1;8460:21:39;;:25;8456:1408;;8505:8;;;;;;;8549:7;8531;8539:6;8531:15;;;;;;;;:::i;:::-;;;;;;:25;;;;8580:9;8575:1275;8599:14;:21;8595:1;:25;8575:1275;;;9277:284;9343:14;9358:1;9343:17;;;;;;;;:::i;:::-;;;;;;;:24;;;9397:81;9426:51;9451:14;9466:1;9451:17;;;;;;;;:::i;:::-;;;;;;;:25;;;4172:13:0;;4187:4;4168:24;;;4149:17;;4139:54;;3999:210;9426:51:39;7389:34:12;7189:15;7376:48;;;7444:4;7437:18;;;;7495:4;7479:21;;;7120:396;9397:81:39;9508:14;9523:1;9508:17;;;;;;;;:::i;:::-;;;;;;;:27;;;9277:36;:284::i;:::-;8649:1010;;9617:19;;;;;;;;2797:25:56;;;2770:18;;9617:19:39;2651:177:56;8649:1010:39;9710:14;9725:1;9710:17;;;;;;;;:::i;:::-;;;;;;;:24;;;9694:42;;9681:7;9689:1;9681:10;;;;;;;;:::i;:::-;;;;;;:55;;;;;9758:8;;;;;;;9806:14;9821:1;9806:17;;;;;;;;:::i;:::-;;;;;;;:25;;;9788:7;9796:6;9788:15;;;;;;;;:::i;:::-;;;;;;;;;;:43;8622:3;;8575:1275;;;;8456:1408;-1:-1:-1;9885:7:39;7619:2290;-1:-1:-1;;;;;7619:2290:39:o;5165:446:10:-;5330:12;5387:5;5362:21;:30;;5354:81;;;;-1:-1:-1;;;5354:81:10;;42460:2:56;5354:81:10;;;42442:21:56;42499:2;42479:18;;;42472:30;42538:34;42518:18;;;42511:62;42609:8;42589:18;;;42582:36;42635:19;;5354:81:10;42258:402:56;5354:81:10;5446:12;5460:23;5487:6;:11;;5506:5;5513:4;5487:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5445:73;;;;5535:69;5562:6;5570:7;5579:10;5591:12;5535:26;:69::i;:::-;5528:76;5165:446;-1:-1:-1;;;;;;;5165:446:10:o;1014:366:13:-;1120:4;1137:17;1156:24;1184:33;1201:4;1207:9;1184:16;:33::i;:::-;1136:81;;-1:-1:-1;1136:81:13;-1:-1:-1;1256:26:13;1247:5;:35;;;;;;;;:::i;:::-;;:58;;;;;1299:6;1286:19;;:9;:19;;;1247:58;1246:127;;;;1322:51;1349:6;1357:4;1363:9;1322:26;:51::i;:::-;1227:146;1014:366;-1:-1:-1;;;;;;1014:366:13:o;7671:628:10:-;7851:12;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;1702:19;;;;8113:60;;;;-1:-1:-1;;;8113:60:10;;43348:2:56;8113:60:10;;;43330:21:56;43387:2;43367:18;;;43360:30;43426:31;43406:18;;;43399:59;43475:18;;8113:60:10;43146:353:56;8113:60:10;-1:-1:-1;8208:10:10;8201:17;;7875:418;8249:33;8257:10;8269:12;8249:7;:33::i;2145:730:12:-;2226:7;2235:12;2263:9;:16;2283:2;2263:22;2259:610;;2599:4;2584:20;;2578:27;2648:4;2633:20;;2627:27;2705:4;2690:20;;2684:27;2301:9;2676:36;2746:25;2757:4;2676:36;2578:27;2627;2746:10;:25::i;:::-;2739:32;;;;;;;;;2259:610;-1:-1:-1;2818:1:12;;-1:-1:-1;2822:35:12;2259:610;2145:730;;;;;:::o;1786:473:13:-;1929:4;1946:12;1960:19;1983:6;:17;;2037:34;;;2073:4;2079:9;2014:75;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;2014:75:13;;;;;;;;;;;;;;;;;;;;;;;;;;;1983:116;;;;2014:75;1983:116;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1945:154;;;;2117:7;:42;;;;;2157:2;2140:6;:13;:19;;2117:42;:134;;;;-1:-1:-1;2175:29:13;;2216:34;;2175:29;;;;;;;;;;;;:::i;:::-;:76;;1786:473;-1:-1:-1;;;;;;1786:473:13:o;8821:540:10:-;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;-1:-1:-1;;;9324:20:10;;;;;;;;:::i;5009:1456:12:-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:12;;-1:-1:-1;6123:30:12;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;44437:25:56;;;44510:4;44498:17;;44478:18;;;44471:45;;;;44532:18;;;44525:34;;;44575:18;;;44568:34;;;6276:24:12;;44409:19:56;;6276:24:12;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:12;;-1:-1:-1;;6276:24:12;;;-1:-1:-1;;6314:20:12;;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;-1:-1:-1;6437:20:12;;-1:-1:-1;5009:1456:12;;;;;;;;:::o;14:332:56:-;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;639:154;725:42;718:5;714:54;707:5;704:65;694:93;;783:1;780;773:12;694:93;639:154;:::o;798:1005::-;904:6;912;920;928;936;944;997:3;985:9;976:7;972:23;968:33;965:53;;;1014:1;1011;1004:12;965:53;1053:9;1040:23;1072:31;1097:5;1072:31;:::i;:::-;1122:5;-1:-1:-1;1179:2:56;1164:18;;1151:32;1192:33;1151:32;1192:33;:::i;:::-;1244:7;-1:-1:-1;1298:2:56;1283:18;;1270:32;;-1:-1:-1;1349:2:56;1334:18;;1321:32;;-1:-1:-1;1404:3:56;1389:19;;1376:33;1428:18;1458:14;;;1455:34;;;1485:1;1482;1475:12;1455:34;1523:6;1512:9;1508:22;1498:32;;1568:7;1561:4;1557:2;1553:13;1549:27;1539:55;;1590:1;1587;1580:12;1539:55;1630:2;1617:16;1656:2;1648:6;1645:14;1642:34;;;1672:1;1669;1662:12;1642:34;1717:7;1712:2;1703:6;1699:2;1695:15;1691:24;1688:37;1685:57;;;1738:1;1735;1728:12;1685:57;1769:2;1765;1761:11;1751:21;;1791:6;1781:16;;;;;798:1005;;;;;;;;:::o;1808:838::-;1970:6;1978;1986;2039:2;2027:9;2018:7;2014:23;2010:32;2007:52;;;2055:1;2052;2045:12;2007:52;2094:9;2081:23;2113:31;2138:5;2113:31;:::i;:::-;2163:5;-1:-1:-1;2219:2:56;2204:18;;2191:32;2242:18;2272:14;;;2269:34;;;2299:1;2296;2289:12;2269:34;2322:22;;;;2378:3;2360:16;;;2356:26;2353:46;;;2395:1;2392;2385:12;2353:46;2418:2;;-1:-1:-1;2473:2:56;2458:18;;2445:32;;2489:16;;;2486:36;;;2518:1;2515;2508:12;2486:36;-1:-1:-1;2541:24:56;;2599:2;2581:16;;;2577:25;2574:45;;;2615:1;2612;2605:12;2574:45;2638:2;2628:12;;;1808:838;;;;;:::o;2833:247::-;2892:6;2945:2;2933:9;2924:7;2920:23;2916:32;2913:52;;;2961:1;2958;2951:12;2913:52;3000:9;2987:23;3019:31;3044:5;3019:31;:::i;3085:184::-;3137:77;3134:1;3127:88;3234:4;3231:1;3224:15;3258:4;3255:1;3248:15;3274:253;3346:2;3340:9;3388:4;3376:17;;3423:18;3408:34;;3444:22;;;3405:62;3402:88;;;3470:18;;:::i;:::-;3506:2;3499:22;3274:253;:::o;3532:::-;3604:2;3598:9;3646:4;3634:17;;3681:18;3666:34;;3702:22;;;3663:62;3660:88;;;3728:18;;:::i;3790:257::-;3862:4;3856:11;;;3894:17;;3941:18;3926:34;;3962:22;;;3923:62;3920:88;;;3988:18;;:::i;4052:334::-;4123:2;4117:9;4179:2;4169:13;;-1:-1:-1;;4165:86:56;4153:99;;4282:18;4267:34;;4303:22;;;4264:62;4261:88;;;4329:18;;:::i;:::-;4365:2;4358:22;4052:334;;-1:-1:-1;4052:334:56:o;4391:204::-;4472:4;4505:18;4497:6;4494:30;4491:56;;;4527:18;;:::i;:::-;-1:-1:-1;4572:1:56;4568:14;4584:4;4564:25;;4391:204::o;4600:118::-;4686:5;4679:13;4672:21;4665:5;4662:32;4652:60;;4708:1;4705;4698:12;4723:3028;4863:6;4871;4924:2;4912:9;4903:7;4899:23;4895:32;4892:52;;;4940:1;4937;4930:12;4892:52;4953:49;4991:9;4978:23;4953:49;:::i;:::-;5034:9;5021:23;5011:33;;5093:18;5087:2;5076:9;5072:18;5059:32;5056:56;5053:76;;;5125:1;5122;5115:12;5053:76;5191:2;5180:9;5176:18;5163:32;5152:9;5148:48;5234:7;5227:4;5223:2;5219:13;5215:27;5205:55;;5256:1;5253;5246:12;5205:55;5280:95;5296:78;5370:2;5357:16;5296:78;:::i;:::-;5280:95;:::i;:::-;5421:16;;5409:29;;;5463:2;5454:12;;;;5397:3;5497:1;5493:24;5485:33;;5481:42;5478:55;-1:-1:-1;5475:75:56;;;5546:1;5543;5536:12;5475:75;5578:2;5574;5570:11;5590:2131;5653:2;5646;5633:16;5630:1;5626:24;5622:2;5618:33;5614:42;5609:3;5606:51;5590:2131;;;5737:18;5731:3;5718:17;5715:41;5712:61;;;5769:1;5766;5759:12;5712:61;5817:3;5804:17;5800:2;5796:26;5933:4;-1:-1:-1;;5859:2:56;5850:7;5846:16;5842:89;5838:100;5835:120;;;5951:1;5948;5941:12;5835:120;5981:22;;:::i;:::-;6016:51;6062:2;6058;6054:11;6041:25;6016:51;:::i;:::-;6115:2;6111;6107:11;6094:25;6087:5;6080:40;6166:18;6160:2;6156;6152:11;6139:25;6136:49;6133:69;;;6198:1;6195;6188:12;6133:69;6254:2;6250;6246:11;6233:25;6229:2;6225:34;6299:7;6294:2;6290;6286:11;6282:25;6272:53;;6321:1;6318;6311:12;6272:53;6351:104;6367:87;6449:2;6445;6441:11;6428:25;6367:87;:::i;6351:104::-;6534:2;6526:11;;;6513:25;6499:40;;;6561:14;;;;6481:5;6637:4;6606:36;6598:45;;6645:2;6594:54;6591:67;-1:-1:-1;6588:87:56;;;6671:1;6668;6661:12;6588:87;6709:2;6705;6701:11;6725:751;6806:2;6798:4;6792:2;6788;6784:11;6771:25;6767:36;6763:2;6759:45;6755:54;6748:5;6745:65;6725:751;;;6911:4;6903:5;6894:7;6890:19;6886:30;6883:50;;;6929:1;6926;6919:12;6883:50;6965:22;;:::i;:::-;7004:45;7042:5;7029:19;7004:45;:::i;:::-;7095:5;7082:19;7073:7;7066:36;7119:54;7168:2;7161:5;7157:14;7144:28;7119:54;:::i;:::-;7239:2;7232:5;7228:14;7215:28;7210:2;7201:7;7197:16;7190:54;7261:51;7307:2;7300:5;7296:14;7283:28;7261:51;:::i;:::-;7378:2;7367:14;;;7354:28;7336:16;;;7329:54;7400:22;;7459:2;7448:14;;;;6845:4;6834:16;6725:751;;;-1:-1:-1;7507:2:56;7496:14;;;7489:29;;;;7575:4;7567:13;;;7554:27;7549:2;7538:14;;7531:51;7641:4;7633:13;;;7620:27;7602:16;;;7595:53;;;;-1:-1:-1;;7661:18:56;;7699:12;;;;5675;5590:2131;;;5594:3;7740:5;7730:15;;;;;4723:3028;;;;;:::o;8058:245::-;8125:6;8178:2;8166:9;8157:7;8153:23;8149:32;8146:52;;;8194:1;8191;8184:12;8146:52;8226:9;8220:16;8245:28;8267:5;8245:28;:::i;8661:184::-;8713:77;8710:1;8703:88;8810:4;8807:1;8800:15;8834:4;8831:1;8824:15;9198:184;9250:77;9247:1;9240:88;9347:4;9344:1;9337:15;9371:4;9368:1;9361:15;9387:128;9454:9;;;9475:11;;;9472:37;;;9489:18;;:::i;10100:184::-;10170:6;10223:2;10211:9;10202:7;10198:23;10194:32;10191:52;;;10239:1;10236;10229:12;10191:52;-1:-1:-1;10262:16:56;;10100:184;-1:-1:-1;10100:184:56:o;11317:2420::-;11687:4;11716:3;11757;11746:9;11742:19;11788:3;11777:9;11770:22;11812:6;11847;11841:13;11878:6;11870;11863:22;11904:3;11894:13;;11938:3;11927:9;11923:19;11916:26;;12001:3;11991:6;11988:1;11984:14;11973:9;11969:30;11965:40;12024:4;12063:2;12055:6;12051:15;12084:1;12105;12115:1404;12131:6;12126:3;12123:15;12115:1404;;;12200:22;;;12224:66;12196:95;12184:108;;12315:13;;12467:9;;12393:42;12463:18;;;12448:34;;12521:11;;;12515:18;12553:15;;;12546:27;;;12634:19;;12355:15;;;12666:24;;;12756:21;;;;12393:42;12801:1;;12712:15;;;;12815:430;12831:8;12826:3;12823:17;12815:430;;;12904:15;;12954:9;;12950:18;;12936:33;;13019:11;;;13013:18;13009:27;;12993:14;;;12986:51;13064:4;13128:11;;;13122:18;13115:26;13108:34;13092:14;;;13085:58;13214:17;;;;12859:1;12850:11;;;;;13180:4;13169:16;;;;12815:430;;;-1:-1:-1;13268:4:56;13315:11;;;13309:18;13292:15;;;13285:43;13351:4;13398:11;;;13392:18;13375:15;;;;13368:43;;;;-1:-1:-1;;;13497:12:56;;;;13462:15;;;;12157:1;12148:11;12115:1404;;;-1:-1:-1;;;13535:18:56;;13528:34;;;421:13;;414:21;13610:4;13595:20;;402:34;13654:22;;;13647:4;13632:20;;13625:52;11239:1;11227:14;;11273:4;11266;11257:14;;11250:28;11303:2;11294:12;;13686:45;11317:2420;-1:-1:-1;;;;;;;;;;11317:2420:56:o;13742:686::-;13807:5;13860:3;13853:4;13845:6;13841:17;13837:27;13827:55;;13878:1;13875;13868:12;13827:55;13907:6;13901:13;13933:4;13957:81;13973:64;14034:2;13973:64;:::i;13957:81::-;14060:3;14084:2;14079:3;14072:15;14112:4;14107:3;14103:14;14096:21;;14169:4;14163:2;14160:1;14156:10;14148:6;14144:23;14140:34;14126:48;;14197:3;14189:6;14186:15;14183:35;;;14214:1;14211;14204:12;14183:35;14250:4;14242:6;14238:17;14264:135;14280:6;14275:3;14272:15;14264:135;;;14346:10;;14334:23;;14377:12;;;;14297;;14264:135;;;-1:-1:-1;14417:5:56;13742:686;-1:-1:-1;;;;;;13742:686:56:o;14433:1458::-;14596:6;14604;14612;14665:2;14653:9;14644:7;14640:23;14636:32;14633:52;;;14681:1;14678;14671:12;14633:52;14714:9;14708:16;14743:18;14784:2;14776:6;14773:14;14770:34;;;14800:1;14797;14790:12;14770:34;14823:72;14887:7;14878:6;14867:9;14863:22;14823:72;:::i;:::-;14813:82;;14914:2;14904:12;;14962:2;14951:9;14947:18;14941:25;14991:2;14981:8;14978:16;14975:36;;;15007:1;15004;14997:12;14975:36;15030:24;;15085:4;15077:13;;15073:27;-1:-1:-1;15063:55:56;;15114:1;15111;15104:12;15063:55;15143:2;15137:9;15166:81;15182:64;15243:2;15182:64;:::i;15166:81::-;15281:15;;;15363:1;15359:10;;;;15351:19;;15347:28;;;15312:12;;;;15387:19;;;15384:39;;;15419:1;15416;15409:12;15384:39;15443:11;;;;15463:210;15479:6;15474:3;15471:15;15463:210;;;15552:3;15546:10;15569:31;15594:5;15569:31;:::i;:::-;15613:18;;15496:12;;;;15651;;;;15463:210;;;15743:2;15728:18;;15722:25;15692:5;;-1:-1:-1;15722:25:56;-1:-1:-1;;;;15759:16:56;;;15756:36;;;15788:1;15785;15778:12;15756:36;;15811:74;15877:7;15866:8;15855:9;15851:24;15811:74;:::i;:::-;15801:84;;;14433:1458;;;;;:::o;15896:589::-;15938:5;15991:3;15984:4;15976:6;15972:17;15968:27;15958:55;;16009:1;16006;15999:12;15958:55;16045:6;16032:20;16071:18;16067:2;16064:26;16061:52;;;16093:18;;:::i;:::-;16137:114;16245:4;-1:-1:-1;;16169:4:56;16165:2;16161:13;16157:86;16153:97;16137:114;:::i;:::-;16276:2;16267:7;16260:19;16322:3;16315:4;16310:2;16302:6;16298:15;16294:26;16291:35;16288:55;;;16339:1;16336;16329:12;16288:55;16404:2;16397:4;16389:6;16385:17;16378:4;16369:7;16365:18;16352:55;16452:1;16427:16;;;16445:4;16423:27;16416:38;;;;16431:7;15896:589;-1:-1:-1;;;15896:589:56:o;16490:2592::-;16559:5;16612:3;16605:4;16597:6;16593:17;16589:27;16579:55;;16630:1;16627;16620:12;16579:55;16666:6;16653:20;16692:4;16716:81;16732:64;16793:2;16732:64;:::i;16716:81::-;16831:15;;;16917:1;16913:10;;;;16901:23;;16897:32;;;16862:12;;;;16941:15;;;16938:35;;;16969:1;16966;16959:12;16938:35;17005:2;16997:6;16993:15;17017:2036;17033:6;17028:3;17025:15;17017:2036;;;17119:3;17106:17;17146:18;17196:2;17183:11;17180:19;17177:39;;;17212:1;17209;17202:12;17177:39;17239:24;;;;17370:4;17287:12;;;-1:-1:-1;;17283:85:56;17279:96;17276:186;;;17416:1;17445:2;17441;17434:14;17276:186;17488:22;;:::i;:::-;17559:2;17555;17551:11;17538:25;17576:33;17601:7;17576:33;:::i;:::-;17622:22;;17667:2;17711:11;;;17698:25;17739:16;;;17736:106;;;17796:1;17825:2;17821;17814:14;17736:106;17865:17;;17917:2;17909:11;;17905:21;-1:-1:-1;17895:119:56;;17968:1;17997:2;17993;17986:14;17895:119;18059:2;18055;18051:11;18038:25;18089:82;18105:65;18166:3;18105:65;:::i;18089:82::-;18215:18;;;18314:1;18310:11;;;;18302:20;;18298:29;;;18255:14;;;;18343:17;;;18340:110;;;18402:1;18432:3;18427;18420:16;18340:110;18476:11;;;;18500:174;18518:8;18511:5;18508:19;18500:174;;;18600:19;;18586:34;;18539:14;;;;18646;;;;18500:174;;;18694:14;;;18687:29;-1:-1:-1;;;18766:4:56;18758:13;;18745:27;18788:16;;;18785:109;;;18846:1;18876:3;18871;18864:16;18785:109;18930:49;18975:3;18970:2;18959:8;18955:2;18951:17;18947:26;18930:49;:::i;:::-;18914:14;;;18907:73;;;;-1:-1:-1;18993:18:56;;-1:-1:-1;;19031:12:56;;;;17050;;17017:2036;;19087:1210;19187:9;19246:4;19238:5;19222:14;19218:26;19214:37;19211:57;;;19264:1;19261;19254:12;19211:57;19292:22;;:::i;:::-;19350:5;19337:19;19375:18;19416:2;19408:6;19405:14;19402:34;;;19432:1;19429;19422:12;19402:34;19466:6;19459:5;19455:18;19445:28;;19514:4;19509:2;19493:14;19489:23;19485:34;19482:54;;;19532:1;19529;19522:12;19482:54;19560:22;;:::i;:::-;19619:2;19606:16;19631:33;19656:7;19631:33;:::i;:::-;19673:24;;19742:2;19734:11;;19721:25;19755:33;19721:25;19755:33;:::i;:::-;19817:2;19804:16;;19797:33;19876:4;19868:13;;19855:27;19894:16;;;19891:36;;;19923:1;19920;19913:12;19891:36;19963:51;19999:14;19988:8;19984:2;19980:17;19963:51;:::i;:::-;19956:4;19943:18;;19936:79;-1:-1:-1;20024:24:56;;20097:2;20086:14;;20073:28;;-1:-1:-1;20113:16:56;;;20110:36;;;20142:1;20139;20132:12;20110:36;;20180:81;20246:14;20235:8;20228:5;20224:20;20180:81;:::i;:::-;20175:2;20162:16;;20155:107;-1:-1:-1;20166:7:56;19087:1210;-1:-1:-1;;19087:1210:56:o;20302:250::-;20387:1;20397:113;20411:6;20408:1;20405:13;20397:113;;;20487:11;;;20481:18;20468:11;;;20461:39;20433:2;20426:10;20397:113;;;-1:-1:-1;;20544:1:56;20526:16;;20519:27;20302:250::o;20557:329::-;20598:3;20636:5;20630:12;20663:6;20658:3;20651:19;20679:76;20748:6;20741:4;20736:3;20732:14;20725:4;20718:5;20714:16;20679:76;:::i;:::-;20800:2;20788:15;-1:-1:-1;;20784:88:56;20775:98;;;;20875:4;20771:109;;20557:329;-1:-1:-1;;20557:329:56:o;20891:439::-;20944:3;20982:5;20976:12;21009:6;21004:3;20997:19;21035:4;21064;21059:3;21055:14;21048:21;;21103:4;21096:5;21092:16;21126:1;21136:169;21150:6;21147:1;21144:13;21136:169;;;21211:13;;21199:26;;21245:12;;;;21280:15;;;;21172:1;21165:9;21136:169;;;-1:-1:-1;21321:3:56;;20891:439;-1:-1:-1;;;;;20891:439:56:o;21335:1808::-;21475:4;21504:2;21533;21522:9;21515:21;21555:2;21592:6;21586:13;21618:4;21658;21653:2;21642:9;21638:18;21631:32;21682:42;21785:2;21770:12;21764:19;21760:28;21755:2;21744:9;21740:18;21733:56;21860:2;21854;21840:12;21836:21;21830:28;21826:37;21820:3;21809:9;21805:19;21798:66;21919:4;21905:12;21901:23;21895:30;21873:52;;21962:2;21956:3;21945:9;21941:19;21934:31;21985:53;22033:3;22022:9;22018:19;22002:14;21985:53;:::i;:::-;21974:64;;22087:2;22079:6;22075:15;22069:22;-1:-1:-1;;22239:2:56;22227:9;22222:3;22218:19;22214:28;22207:4;22196:9;22192:20;22185:58;22263:3;22295:14;22289:21;22331:6;22326:3;22319:19;22363:2;22358:3;22354:12;22347:19;;22419:2;22409:6;22406:1;22402:14;22397:3;22393:24;22389:33;22465:2;22449:14;22445:23;22431:37;;22486:1;22496:618;22510:6;22507:1;22504:13;22496:618;;;22593:2;22587:3;22579:6;22575:16;22571:25;22566:3;22559:38;22626:6;22620:13;22676:2;22671;22665:9;22661:18;22653:6;22646:34;22729:2;22725;22721:11;22715:18;22770:2;22765;22757:6;22753:15;22746:27;22800:61;22857:2;22849:6;22845:15;22829:14;22800:61;:::i;:::-;22902:11;;;22896:18;22951:19;;;22934:15;;;22927:44;22896:18;22786:75;-1:-1:-1;22994:40:56;22786:75;22896:18;22994:40;:::i;:::-;23057:15;;;;23092:12;;;;22984:50;-1:-1:-1;;;22532:1:56;22525:9;22496:618;;;-1:-1:-1;23131:6:56;21335:1808;-1:-1:-1;;;;;;;;;;;;21335:1808:56:o;23148:641::-;23278:4;23284:6;23344:11;23331:25;-1:-1:-1;;23423:8:56;23407:14;23403:29;23399:102;23379:18;23375:127;23365:155;;23516:1;23513;23506:12;23365:155;23543:33;;23595:20;;;-1:-1:-1;23638:18:56;23627:30;;23624:50;;;23670:1;23667;23660:12;23624:50;23703:4;23691:17;;-1:-1:-1;23754:1:56;23750:14;;;23734;23730:35;23720:46;;23717:66;;;23779:1;23776;23769:12;23794:393;23897:4;23955:11;23942:25;24045:66;24034:8;24018:14;24014:29;24010:102;23990:18;23986:127;23976:155;;24127:1;24124;24117:12;23976:155;24148:33;;;;;23794:393;-1:-1:-1;;23794:393:56:o;24192:383::-;24285:4;24343:11;24330:25;24433:66;24422:8;24406:14;24402:29;24398:102;24378:18;24374:127;24364:155;;24515:1;24512;24505:12;24580:629;24695:4;24701:6;24761:11;24748:25;-1:-1:-1;;24840:8:56;24824:14;24820:29;24816:102;24796:18;24792:127;24782:155;;24933:1;24930;24923:12;24782:155;24960:33;;25012:20;;;-1:-1:-1;25055:18:56;25044:30;;25041:50;;;25087:1;25084;25077:12;25041:50;25120:4;25108:17;;-1:-1:-1;25179:4:56;25167:17;;25151:14;25147:38;25137:49;;25134:69;;;25199:1;25196;25189:12;25214:605;25310:5;25317:6;25377:3;25364:17;-1:-1:-1;;25448:8:56;25432:14;25428:29;25424:102;25404:18;25400:127;25390:155;;25541:1;25538;25531:12;25390:155;25569:33;;25673:4;25660:18;;;-1:-1:-1;25621:21:56;;-1:-1:-1;25701:18:56;25690:30;;25687:50;;;25733:1;25730;25723:12;25687:50;25787:6;25784:1;25780:14;25764;25760:35;25753:5;25749:47;25746:67;;;25809:1;25806;25799:12;25824:355;25895:5;25954:3;25941:17;26036:66;26025:8;26009:14;26005:29;26001:102;25981:18;25977:127;25967:155;;26118:1;26115;26108:12;25967:155;26140:33;;;;25824:355;-1:-1:-1;;25824:355:56:o;26184:559::-;26242:5;26249:6;26309:3;26296:17;-1:-1:-1;;26380:8:56;26364:14;26360:29;26356:102;26336:18;26332:127;26322:155;;26473:1;26470;26463:12;26322:155;26501:33;;26605:4;26592:18;;;-1:-1:-1;26553:21:56;;-1:-1:-1;26633:18:56;26622:30;;26619:50;;;26665:1;26662;26655:12;26619:50;26712:6;26696:14;26692:27;26685:5;26681:39;26678:59;;;26733:1;26730;26723:12;26748:325;26836:6;26831:3;26824:19;26888:6;26881:5;26874:4;26869:3;26865:14;26852:43;;26940:1;26933:4;26924:6;26919:3;26915:16;26911:27;26904:38;26806:3;27062:4;-1:-1:-1;;26987:2:56;26979:6;26975:15;26971:88;26966:3;26962:98;26958:109;26951:116;;26748:325;;;;:::o;27078:593::-;27159:5;27166:6;27226:3;27213:17;-1:-1:-1;;27297:8:56;27281:14;27277:29;27273:102;27253:18;27249:127;27239:155;;27390:1;27387;27380:12;27239:155;27418:33;;27522:4;27509:18;;;-1:-1:-1;27470:21:56;;-1:-1:-1;27550:18:56;27539:30;;27536:50;;;27582:1;27579;27572:12;27536:50;27641:4;27633:6;27629:17;27613:14;27609:38;27602:5;27598:50;27595:70;;;27661:1;27658;27651:12;27676:114;27760:4;27753:5;27749:16;27742:5;27739:27;27729:55;;27780:1;27777;27770:12;27795:830;27906:6;27901:3;27894:19;27876:3;27932:4;27961;27956:3;27952:14;27945:21;;27989:5;28012:1;28022:578;28036:6;28033:1;28030:13;28022:578;;;28113:6;28100:20;28133:33;28158:7;28133:33;:::i;:::-;28204:42;28191:56;28179:69;;28289:15;;;28276:29;28318:31;28276:29;28318:31;:::i;:::-;28396:4;28383:18;28369:12;;;28362:40;28425:4;28476:15;;;28463:29;28449:12;;;28442:51;28516:4;28540:12;;;;28575:15;;;;28058:1;28051:9;28022:578;;28630:1709;28767:19;;;28805:4;28825:12;;;;28724:3;;28856:1;28893:14;;;28882:26;;28878:35;;28936:5;28724:3;;28990:1323;29006:6;29001:3;28998:15;28990:1323;;;-1:-1:-1;;29085:5:56;29079:4;29075:16;29071:89;29066:3;29059:102;29184:58;29235:6;29228:5;29184:58;:::i;:::-;29265:4;29310:2;29297:16;29326:33;29351:7;29326:33;:::i;:::-;29398:42;29385:56;29372:70;;29489:85;29562:11;;;29566:2;29489:85;:::i;:::-;29609:2;29604;29598:4;29594:13;29587:25;29647:12;29642:2;29636:4;29632:13;29625:35;29683:3;29673:13;;29719:66;29705:12;29702:84;29699:104;;;29799:1;29796;29789:12;29699:104;29832:21;;;29894:12;29879:13;;;29866:51;29940:19;;;-1:-1:-1;29982:4:56;30037:47;30072:11;;;30076:2;30037:47;:::i;:::-;29999:85;;30138:2;30131:4;30127:2;30123:13;30119:22;30114:2;30108:4;30104:13;30097:45;30163:70;30229:2;30225;30221:11;30205:14;30189;30163:70;:::i;:::-;30291:12;;;;30155:78;-1:-1:-1;;;30256:15:56;;;;-1:-1:-1;;;29032:1:56;29023:11;28990:1323;;;-1:-1:-1;30329:4:56;;28630:1709;-1:-1:-1;;;;;;;;;28630:1709:56:o;30344:4286::-;30510:4;30539:2;30568;30557:9;30550:21;30609:3;30598:9;30594:19;30662:6;30649:20;30644:2;30633:9;30629:18;30622:48;30689:2;30752;30744:6;30740:15;30727:29;30722:2;30711:9;30707:18;30700:57;30776:2;30839;30831:6;30827:15;30814:29;30809:2;30798:9;30794:18;30787:57;30887:93;30976:2;30968:6;30964:15;30956:6;30887:93;:::i;:::-;31017:4;31011:3;31000:9;30996:19;30989:33;31042:6;31072:12;31064:6;31057:28;31116:3;31105:9;31101:19;31094:26;;31185:3;31169:12;31166:1;31162:20;31151:9;31147:36;31143:46;31129:60;;31212:12;31242:1;31252:3053;31266:12;31263:1;31260:19;31252:3053;;;31361:66;31349:9;31341:6;31337:22;31333:95;31328:3;31321:108;31481:6;31468:20;31574:66;31559:12;31543:14;31539:33;31535:106;31515:18;31511:131;31501:159;;31656:1;31653;31646:12;31501:159;31686:37;;31764:19;;31840:14;31836:26;;;31864:66;31832:99;31806:126;;31796:154;;31946:1;31943;31936:12;31796:154;32038:3;32023:19;;31978:32;;32070:21;;32104:33;32070:21;32104:33;:::i;:::-;32160:42;32253:2;32244:7;32240:16;32234:3;32226:6;32222:16;32215:42;32292:70;32358:2;32349:7;32345:16;32336:7;32292:70;:::i;:::-;32270:92;;32401:4;32394;32386:6;32382:17;32375:31;32447:14;32434:28;32475:33;32500:7;32475:33;:::i;:::-;32546:16;;32540:3;32528:16;;32521:42;32604:23;;;32591:37;32641:33;32591:37;32641:33;:::i;:::-;32712:16;32706:3;32694:16;;32687:42;32780:71;32827:23;;;32831:14;32780:71;:::i;:::-;32742:109;;32889:2;32883:3;32875:6;32871:16;32864:28;32916:75;32986:3;32978:6;32974:16;32958:14;32942;32916:75;:::i;:::-;32905:86;;;33042:80;33118:2;33109:7;33105:16;33096:7;33042:80;:::i;:::-;33145:66;33271:2;33262:6;33257:3;33253:16;33249:25;33243:3;33235:6;33231:16;33224:51;33302:85;33383:3;33367:14;33351;33302:85;:::i;:::-;33288:99;;33438:80;33514:2;33505:7;33501:16;33492:7;33438:80;:::i;:::-;33400:118;;;;33581:2;33572:6;33564;33560:19;33556:28;33550:3;33542:6;33538:16;33531:54;;33612:88;33693:6;33677:14;33661;33612:88;:::i;:::-;33598:102;;;;33764:3;33755:7;33751:17;33738:31;33732:3;33724:6;33720:16;33713:57;33831:2;33824:5;33820:14;33807:28;33802:2;33794:6;33790:15;33783:53;33897:2;33890:5;33886:14;33873:28;33868:2;33860:6;33856:15;33849:53;33953:91;34040:2;34033:5;34029:14;34022:5;33953:91;:::i;:::-;33915:129;;;;34093:6;34085;34081:19;34076:2;34068:6;34064:15;34057:44;34124:101;34218:6;34202:14;34186;34124:101;:::i;:::-;34114:111;-1:-1:-1;;;34283:12:56;;;;-1:-1:-1;34248:15:56;;;;31294:1;31287:9;31252:3053;;;31256:3;;;;;;;34352:56;34403:3;34395:6;34391:16;34383:6;34352:56;:::i;:::-;34314:94;;-1:-1:-1;;34462:9:56;34454:6;34450:22;34446:95;34439:4;34428:9;34424:20;34417:125;34559:65;34617:6;34601:14;34585;34559:65;:::i;34635:245::-;34714:6;34722;34775:2;34763:9;34754:7;34750:23;34746:32;34743:52;;;34791:1;34788;34781:12;34743:52;-1:-1:-1;;34814:16:56;;34870:2;34855:18;;;34849:25;34814:16;;34849:25;;-1:-1:-1;34635:245:56:o;36000:247::-;36068:6;36121:2;36109:9;36100:7;36096:23;36092:32;36089:52;;;36137:1;36134;36127:12;36089:52;36169:9;36163:16;36188:29;36211:5;36188:29;:::i;37658:1572::-;38213:42;38205:6;38201:55;38190:9;38183:74;38164:4;38276:2;38314:6;38309:2;38298:9;38294:18;38287:34;38357:3;38352:2;38341:9;38337:18;38330:31;38384:45;38424:3;38413:9;38409:19;38401:6;38384:45;:::i;:::-;38465:6;38460:2;38449:9;38445:18;38438:34;38521:9;38513:6;38509:22;38503:3;38492:9;38488:19;38481:51;38552:6;38587;38581:13;38618:6;38610;38603:22;38653:2;38645:6;38641:15;38634:22;;38712:2;38702:6;38699:1;38695:14;38687:6;38683:27;38679:36;38750:2;38742:6;38738:15;38771:1;38781:322;38795:6;38792:1;38789:13;38781:322;;;-1:-1:-1;;38872:6:56;38864;38860:19;38856:92;38851:3;38844:105;38972:51;39016:6;39007;39001:13;38972:51;:::i;:::-;39081:12;;;;38962:61;-1:-1:-1;39046:15:56;;;;38817:1;38810:9;38781:322;;;38785:3;;39152:9;39144:6;39140:22;39134:3;39123:9;39119:19;39112:51;39180:44;39217:6;39209;39180:44;:::i;:::-;39172:52;37658:1572;-1:-1:-1;;;;;;;;;;;;;37658:1572:56:o;39235:614::-;39364:6;39372;39425:2;39413:9;39404:7;39400:23;39396:32;39393:52;;;39441:1;39438;39431:12;39393:52;39474:9;39468:16;39503:18;39544:2;39536:6;39533:14;39530:34;;;39560:1;39557;39550:12;39530:34;39583:72;39647:7;39638:6;39627:9;39623:22;39583:72;:::i;:::-;39573:82;;39701:2;39690:9;39686:18;39680:25;39664:41;;39730:2;39720:8;39717:16;39714:36;;;39746:1;39743;39736:12;39714:36;;39769:74;39835:7;39824:8;39813:9;39809:24;39769:74;:::i;:::-;39759:84;;;39235:614;;;;;:::o;39854:367::-;40096:6;40085:9;40078:25;40139:2;40134;40123:9;40119:18;40112:30;40059:4;40159:56;40211:2;40200:9;40196:18;40188:6;40159:56;:::i;40226:184::-;40278:77;40275:1;40268:88;40375:4;40372:1;40365:15;40399:4;40396:1;40389:15;40415:168;40488:9;;;40519;;40536:15;;;40530:22;;40516:37;40506:71;;40557:18;;:::i;40588:476::-;40677:1;40714:5;40677:1;40728:330;40749:7;40739:8;40736:21;40728:330;;;40868:4;-1:-1:-1;;40796:77:56;40790:4;40787:87;40784:113;;;40877:18;;:::i;:::-;40927:7;40917:8;40913:22;40910:55;;;40947:16;;;;40910:55;41026:22;;;;40986:15;;;;40728:330;;;40732:3;40588:476;;;;;:::o;41069:866::-;41118:5;41148:8;41138:80;;-1:-1:-1;41189:1:56;41203:5;;41138:80;41237:4;41227:76;;-1:-1:-1;41274:1:56;41288:5;;41227:76;41319:4;41337:1;41332:59;;;;41405:1;41400:130;;;;41312:218;;41332:59;41362:1;41353:10;;41376:5;;;41400:130;41437:3;41427:8;41424:17;41421:43;;;41444:18;;:::i;:::-;-1:-1:-1;;41500:1:56;41486:16;;41515:5;;41312:218;;41614:2;41604:8;41601:16;41595:3;41589:4;41586:13;41582:36;41576:2;41566:8;41563:16;41558:2;41552:4;41549:12;41545:35;41542:77;41539:159;;;-1:-1:-1;41651:19:56;;;41683:5;;41539:159;41730:34;41755:8;41749:4;41730:34;:::i;:::-;41860:6;-1:-1:-1;;41788:79:56;41779:7;41776:92;41773:118;;;41871:18;;:::i;:::-;41909:20;;41069:866;-1:-1:-1;;;41069:866:56:o;41940:131::-;42000:5;42029:36;42056:8;42050:4;42029:36;:::i;42665:287::-;42794:3;42832:6;42826:13;42848:66;42907:6;42902:3;42895:4;42887:6;42883:17;42848:66;:::i;42957:184::-;43009:77;43006:1;42999:88;43106:4;43103:1;43096:15;43130:4;43127:1;43120:15;43504:288;43679:6;43668:9;43661:25;43722:2;43717;43706:9;43702:18;43695:30;43642:4;43742:44;43782:2;43771:9;43767:18;43759:6;43742:44;:::i;43986:219::-;44135:2;44124:9;44117:21;44098:4;44155:44;44195:2;44184:9;44180:18;44172:6;44155:44;:::i","linkReferences":{},"immutableReferences":{"6454":[{"start":226,"length":32},{"start":1805,"length":32},{"start":1886,"length":32}]}},"methodIdentifiers":{"arb3(address,(uint256,uint256,uint256,((address,(address,address,bytes),(address,uint8,uint256)[],(address,uint8,uint256)[],bytes32),uint256,uint256,(address,uint256[],bytes)[])[],bytes),((address,address,bytes),(address,uint256[],bytes)[]))":"7ea0b76a","iTaskHash()":"93be095e","onTakeOrders(address,address,uint256,uint256,bytes)":"059bebe6","supportsInterface(bytes4)":"01ffc9a7","x(address)":"f037e4e3"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"orderBook\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV1\",\"name\":\"task\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"implementationData\",\"type\":\"bytes\"}],\"internalType\":\"struct OrderBookV4ArbConfigV2\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoOrders\",\"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 IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV1\",\"name\":\"task\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"implementationData\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"struct OrderBookV4ArbConfigV2\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"Construct\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[{\"internalType\":\"contract IOrderBookV4\",\"name\":\"orderBook\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"minimumInput\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumInput\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumIORatio\",\"type\":\"uint256\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"vaultId\",\"type\":\"uint256\"}],\"internalType\":\"struct IO[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"vaultId\",\"type\":\"uint256\"}],\"internalType\":\"struct IO[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OrderV3\",\"name\":\"order\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"inputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outputIOIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TakeOrderConfigV3[]\",\"name\":\"orders\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct TakeOrdersConfigV3\",\"name\":\"takeOrders\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV1\",\"name\":\"task\",\"type\":\"tuple\"}],\"name\":\"arb3\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"iTaskHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"inputToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"outputToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"inputAmountSent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalOutputAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"takeOrdersData\",\"type\":\"bytes\"}],\"name\":\"onTakeOrders\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"x\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"onTakeOrders(address,address,uint256,uint256,bytes)\":{\"params\":{\"inputAmountSent\":\"The amount of `inputToken` that was sent to `IOrderBookV4OrderTaker`.\",\"inputToken\":\"The token that was sent to `IOrderBookV4OrderTaker`.\",\"outputToken\":\"The token that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns.\",\"takeOrdersData\":\"The data passed to `takeOrders` by the caller.\",\"totalOutputAmount\":\"The total amount of `outputToken` that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns.\"}},\"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[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidSignature(uint256)\":[{\"notice\":\"Thrown when the ith signature from a list of signed contexts is invalid.\"}],\"NoOrders()\":[{\"notice\":\"Thrown when take orders is called with no orders.\"}],\"WrongTask()\":[{\"notice\":\"Thrown when the task does not match the expected hash.\"}]},\"kind\":\"user\",\"methods\":{\"onTakeOrders(address,address,uint256,uint256,bytes)\":{\"notice\":\"Called by `IOrderBookV4` when `takeOrders` is called with non-zero data, if it caused a non-zero input amount. I.e. if the order(s) taker received some tokens. Input and output directions are relative to the `IOrderBookV4OrderTaker` contract. If the order(s) taker had an active debt from a flash loan then that debt will be paid _before_ calculating any input amounts sent. i.e. the debt is deducted from the input amount before this callback is called.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol\":\"BalancerRouterOrderBookV4ArbOrderTaker\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"appendCBOR\":false,\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":9000},\"remappings\":[\":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.interpreter.interface/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/\",\":integrity/=lib/rain.interpreter/src/lib/integrity/\",\":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/\",\":openzeppelin/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/\",\":parse/=lib/rain.interpreter/src/lib/parse/\",\":prb-math/=lib/rain.interpreter/lib/prb-math/src/\",\":rain.datacontract/=lib/rain.interpreter/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.sol.codegen/lib/rain.math.binary/src/\",\":rain.math.fixedpoint/=lib/rain.interpreter/lib/rain.math.fixedpoint/src/\",\":rain.math.saturating/=lib/rain.interpreter/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.binmaskflag/=lib/rain.interpreter/lib/rain.sol.binmaskflag/src/\",\":rain.sol.codegen/=lib/rain.interpreter/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.math.fixedpoint/lib/rain.string/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.math.fixedpoint/src/error/ErrScale.sol\":{\"keccak256\":\"0xf078f93e8cf6360008743854983c2c98a43f7f78b95a527473089a22b81c55a0\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://580c4ad750f0ebebdf77f87feb52bce41f2d72fa4bf9221fbe3977837eb6a4d9\",\"dweb:/ipfs/QmeYydyLSLqFT5DfFDgJBEBBeBEhwvsMi3oQ4USXXrQudF\"]},\"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/FixedPointDecimalConstants.sol\":{\"keccak256\":\"0x9299cb9b7aeeaa2a60c6e248928bc173750c5361df4fc0e4d9ea94a778fcd6e6\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://3a65a4f0f3b7462cb0b0b6d165d3868010ff19192f53a8133e3e93be3d811d81\",\"dweb:/ipfs/QmSFWpSUH2cAcw7ph2c5rwvqcKWXTJgvabaRjk2P8ZMzcP\"]},\"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/LibFixedPointDecimalScale.sol\":{\"keccak256\":\"0xef9a2b240ba686ee4b31c37edfbbab1a3b276db3ad269688fa2c0d1beced6c0b\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://a4e115922faa62d4c3f64c466b9e3d27f53d611c92422828c1920c37bc51acfa\",\"dweb:/ipfs/QmPa5cnqmk8eHjkdSPzegHDN9Q4jWbNV1DHeFKh5LZ6XVk\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol\":{\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e\",\"dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34\",\"dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5\",\"dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71\",\"dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68\",\"dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931\",\"dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f\",\"dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2\",\"dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol\":{\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://77d1f1cf302cd5e1dfbbb4ce3b281b28e8c52942d4319fce43df2e1b6f02a52d\",\"dweb:/ipfs/QmT6ZXStmK3Knhh9BokeVHQ9HXTBZNgL3Eb1ar1cYg1hWy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d\",\"dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c\",\"dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7\",\"dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrBytes.sol\":{\"keccak256\":\"0x82df8bd5b6a2343eb41c47f9b58f05adb2f8fd92b146ddb31c0ea697ebe3acd4\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://f95976983e965460330e2a1d00f3ed0e2079e13a67f3364f1175723cd97b6a07\",\"dweb:/ipfs/QmQKhYbVSesLuomYv4XPapPMvLmXNLgSx2QtgK5EJhww5c\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol\":{\"keccak256\":\"0xfc1739c5c406f71e1f52ebfd163162087e9025b02444ca12ae8844c71dcd1cf5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://ae2e95f1e6260b18105369c7216e1ebc6a251ffe3548d27ce180f7885c3f6906\",\"dweb:/ipfs/QmPQEzZmQDuzp8R5rp6ABmzGD243qu8R5GX4FbHc8G4CUC\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes.sol\":{\"keccak256\":\"0x46f53ecd0554926ed6ef781485f9c3d3dfe08fa5503021aac7476c28df364f30\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://d6841328d12c44dfc3e966d2372b841f27659b592556411bcb2889ed1a8db6b2\",\"dweb:/ipfs/QmQHUvQre6Jb5VtiKDvwQiff3eLSCPxRkAs8Jy81dnPbdD\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibMemCpy.sol\":{\"keccak256\":\"0x58be272366c53e5db26413754881238127a5ccedc69439d50afbb4c4f9769006\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://49d241b4acc8462d0289eafe645c20493a615c9bef629dab4f049599373df1c7\",\"dweb:/ipfs/QmYLK8fhzz5kjdaQY29yrcgEcGv31gUABvC7eHoChgYwV7\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol\":{\"keccak256\":\"0xdadaac57081823b3a4162aeda93195d1dbe98caf1141f6d9113302909c851307\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://fa6026d3853dd4a58faa0c9ac2dda867c200963a052a4d62e8797cd3a0e29250\",\"dweb:/ipfs/QmPRKmE5tpJKwCpy3rumAMjCqDdGK8UC2r2soB1CNQwfmJ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol\":{\"keccak256\":\"0xbfea88bec2894f0ff0b3f8b3088f4a45f561aff1bc439165bcdb0e15fa0124ea\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://3ef8c1cf899aa39585cded6e6510e637fa5e60f40dae9e39688ecacd41ef9c41\",\"dweb:/ipfs/Qme4nJr2tCfkY9DDiMhcGjuvjy6jFGZvNgCeMD81YACEKR\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/error/ErrBytecode.sol\":{\"keccak256\":\"0x56d9f7a498877655b507ddb4683f4cdbb961bf38375d85c80ab66f8cf0aa9d03\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0206c9b5a55818d20b2a644c2da0a5cfbbfffb82d4e49bbd0ddd5d60df19ecb8\",\"dweb:/ipfs/QmZuMWg8zqPFDVSWKZnRxrmDpr3YQE7ERSjAFLWnK4iDyd\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterCallerV3.sol\":{\"keccak256\":\"0x17a433a06d82d1fbaa497ab0ab0a3c698f86dcdbf9b3dc6814d2f64b1592bc32\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://eb06d882eab9261c1561a3f087b4eb6b29bbf919f6902859a3464d7ecd738315\",\"dweb:/ipfs/QmacaaExc2aL4xokmcBxKy2nhRYKWkEhb2DV2KNJQbMHxK\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol\":{\"keccak256\":\"0xd3fe133132e9688f0590f273b1a9851d17b794d7ed85d5cc7a4cf961220359f3\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://bd74c48f247d80804a1fcaa664b4771cbca471cb5bc29307e585d60fb4162bf1\",\"dweb:/ipfs/QmX8PF8aVeXbKsuaBnvLpsgcyjqxHUZK2wgogmNDzQC8mr\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterV3.sol\":{\"keccak256\":\"0x152209b9afda8a9fbba404563d67566584b95f49f57f321538d66995b81de300\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://84a09751006cd68411da9684379919e6f0a6b7606050392633146374b7d10141\",\"dweb:/ipfs/QmWoST14FWQr8MqGZXruDvJn5FeQrTkKZomSjazcp6msdm\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IParserV2.sol\":{\"keccak256\":\"0x9893dfb4e05bfbf088921c5cca38265388de5ef9e127ec8674a2ce6356152725\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://19bac62db62ad9cb20a9b9790208e124bcfdf89f7deeae25b3cb30f11f680724\",\"dweb:/ipfs/QmUvj4Zcj3b6ACRjcAHRW9geoLfLUXuKydcbMakaxRFPTa\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV1.sol\":{\"keccak256\":\"0x933cbfee07ddc43390326f87034613216352250472577bd890e9589e6206fad4\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://d0f947ca6eb86ae9c03806430f5c3a946882daee9f82e436067b1c42ff554595\",\"dweb:/ipfs/QmV7jK8dK6de1HDsUjKDGfEPwVdNEzDHgVHmVZKyfGv6MQ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV2.sol\":{\"keccak256\":\"0x3f03703392207a285d41b2871c2d83df103425c1984750cc303628269e6258e5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://a9bc96c0f288ab7b6ec1a14a42e426ec745f0b1c7fcde9d7052380c64e61c8da\",\"dweb:/ipfs/QmYBobAFw36Jd2VtFtoWNqE8HxJhy3n9Eho1fsK3uBCbwc\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV3.sol\":{\"keccak256\":\"0x231a50d32c6f910d7ae13ae1d83a221ba55eb7962380572c9c354c8a3c5c52bf\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://74b19a6c17ac7fab6edee53218a35154c5fe9ad3769ce8e22bac682dd32df0e8\",\"dweb:/ipfs/QmYiG7i4tNfA4eTynoQVbNixvGepqoAedVz2isiMfxRF8D\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV1.sol\":{\"keccak256\":\"0x20aebc5f73ffd790da90b8e88d6412f9c3a11041239c669c03e188d0a6be1e3e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://24f85bcb1d9f52ae01f7127274100ef68640a823bf2b981f267faf71192d8235\",\"dweb:/ipfs/QmPmz7q4rsy9vWXixdG9qBB8fLb1Wjj8LWyq6wyuFQR2HK\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV2.sol\":{\"keccak256\":\"0x8ae6f8b21d5fba09db20a979e797339d4cc385450d4da8cb4de2331db638caee\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://162b488b86df5c57c8cecd6c02172122ab9d30d70dd135ea151db5d56bf06f62\",\"dweb:/ipfs/Qmf9Kd89mH6PE5hoQ6ahV1Dsi28AFbakeUUw12W9Dp3sHW\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol\":{\"keccak256\":\"0xe03c065839e972fde62d73c45acf6fc2e88f42e3a07f4255ef5bfdcd30d3b1f1\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e766d9cfe9464f722e02320c3936fb0b98b9417663fefba6bac3dbb21007ce82\",\"dweb:/ipfs/QmX88DnazhZw7B3Fxp1iDZXogi2k6dyMPvh2vXpXep11oQ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol\":{\"keccak256\":\"0x8986cb9ba93034751b21245398bc1ef7a55fe10d34b5d4cc4207ee9d39a3e616\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://dc7d8e706e96f0d0e53599582fadd591581484ac36921b0e4c6454c54b568c2b\",\"dweb:/ipfs/QmNczMgGQKWJiDhXVbtXeBjUEtzFtr7k41uPjiU8P6BrHT\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV2.sol\":{\"keccak256\":\"0x0a9223e817a36a9717b91f977a9fce5e698afd393aa2405979baf53a12339805\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1537576666b7462485e898ddbd36848be401b3c1e3f8317eca4112d1b21d4e74\",\"dweb:/ipfs/QmZYRLbnctnMKEZ4UYz9oZ9MFoqQy1hex29HrXPVBX5U1g\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IParserV1.sol\":{\"keccak256\":\"0x19e1a217e8c67c671e319dd0e5608d7c496fbfc02363fbb2d08626715625dd55\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://603b3234a5c084acb12d0b7e3909503869f9a6d860f91d86692e007f67aba25b\",\"dweb:/ipfs/QmU7i9uyr9qWFzD2xjn1qjgiPjb8vUjuXA6dHEuGLVkmPj\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/bytecode/LibBytecode.sol\":{\"keccak256\":\"0xdebdca9d3d2a6c1be927f6fa1f28550cd7885aa52abd378ddb65e5f6495ef87c\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://5ca7fe490fe2b1287c3c231ec34daa504b3b36fa6c3e69aacda9737db1e1b548\",\"dweb:/ipfs/QmQozWFz6qFJDiRFS1YgPWCsRZgCCQ3yEzmwTVyiCs7SxY\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibContext.sol\":{\"keccak256\":\"0xd2cfeec3582d7b0b2a09573e258230ec4a6de169e60d9078f674a7a09d0c7b2d\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://cf266d36372575856000331ebb8dca7d6025db6365d14f4c876ab55305090aba\",\"dweb:/ipfs/QmYyoYFXryPM2SRMafgUgsBbAXPeCmzLFvzhHGR3i47zHy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibEvaluable.sol\":{\"keccak256\":\"0x922f6df3f98bc94869b9c244ae349e4ecfe0f250937414af7f3699e016b9f57e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e4fd2f59466c83a6e5dfe843951880d3f1dbe98cf559746242d942ab20962166\",\"dweb:/ipfs/QmTTD9vj8ph7ocmWFAjPb4D4UiwusCg7iZEPWoRfVtEEu1\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/deprecated/caller/LibEncodedDispatch.sol\":{\"keccak256\":\"0x0d9b888a01c5d508dd3cdfd53823ad56c6e16e06d18ca8b2ac68e82b102cc60a\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://6f854a3243d04aa76169367843a97bec51574f01ddb1e31b271f8aa93e184dce\",\"dweb:/ipfs/QmRc85MSQBbqvCvdcZBHvBrA8FFfVbxYWHbNV2vshmLF95\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/ns/LibNamespace.sol\":{\"keccak256\":\"0x5e1f5a0e05fbadf8acfad550ed59d960dd05ebc1d74cfa676f22a26644cc0ee5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://ee31bfc695ae5dc841379c3164b345bb0951b8b10fd94f300d5bb2de51dd7a1e\",\"dweb:/ipfs/QmT1CqR7Lpj2bEJADgEPgY9cmTqgKLEZm1QLbZxfHEd8PY\"]},\"lib/rain.orderbook.interface/src/interface/IOrderBookV4.sol\":{\"keccak256\":\"0x715c5211361bd469a9ec916710611536d087ae5630a3fc3f80e9802ec43c4596\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://c61433f7de82ac5fbd752470aa1b9358dc70455ba85be87a9056509188f5db21\",\"dweb:/ipfs/QmaGvPxe4xpqkVMdq9mo2moJyBHB9f8wTkcxZotk7tevVH\"]},\"lib/rain.orderbook.interface/src/interface/IOrderBookV4OrderTaker.sol\":{\"keccak256\":\"0x7d197bd91214d318ce6a9ee388228494606ba7bdae36bbc6ec6ed1681ff60bd8\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://73caf415d34e06a83d104cbccf98ae76ccd522e5ae1fb32c2bb18af9bae7ccaa\",\"dweb:/ipfs/QmYbiDgjfjpX6pvjawqhtQpiTkUuX24ncHodheJPtSg4d7\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v2/IOrderBookV2.sol\":{\"keccak256\":\"0x30c528f1772e9593b5329f1458cab4cce3510a2ccca01696b506af177fffd786\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://9f53c14e5aaab2cd2fbf5b39d07c59acfdc09aff3476345816c2635de2cdd5d3\",\"dweb:/ipfs/QmaomXfmDKdoeYwbMe9cy5anx4fDEMtP4W9Rre5s5DZVE6\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v3/IOrderBookV3.sol\":{\"keccak256\":\"0xdca3fd0c6106ab98d08682e63e433b74250d1f01e646a5908c97183d9b25130b\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0f986a8388275a4144068981aa628e46bff221c2d27a3ad597a9c5fc2d4fcb09\",\"dweb:/ipfs/QmR2pxkpY4ddhLb7jdoNAVSJwYHokyGpn5Tzg3Q7YnGYgW\"]},\"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/IOrderBookV4ArbOrderTakerV2.sol\":{\"keccak256\":\"0x271d4a0fdeddc07a88b18fa52f39c840515e572d62a755f7710bbd1b20ebe389\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://64000bb3455809c1eb2a8789023286ad9ccaa2cdfe014cff480e96bb1b7ad6a3\",\"dweb:/ipfs/QmRDgNHR4mYjxvHJUNMaaDZdAnxZ7yDF9kCL3aaSYip6AH\"]},\"lib/sushixswap-v2/src/interfaces/IRouteProcessor.sol\":{\"keccak256\":\"0x5b2289c992f34dd25943db3cbc27ece8b0a1addeb2631f812e7834b7ae3eac37\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://f21522058b7fe3c18d2353b06a5ddbf2b62d2aceebf7dd6dfdc51b081452bb3f\",\"dweb:/ipfs/QmVkicGnNWgnX1RfXJWPpQaAPbiAQfFwGWigbPi1wu2WiT\"]},\"src/abstract/OrderBookV4ArbCommon.sol\":{\"keccak256\":\"0xe24cce13b3e21ae36c0aae11380128c5f0ddf542a0298f1a1845a39845e10576\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://5f5d04c151a7e9fe4a659cef55abc4a626bc2ba0e58edbd714dcbadb52f4b396\",\"dweb:/ipfs/QmZHQiYBNdxMJWoMjHnsqoj2YszvFMWrGYqDcodKpwyv98\"]},\"src/abstract/OrderBookV4ArbOrderTaker.sol\":{\"keccak256\":\"0xa419a3d91a8c362dad1bea2761e6e0218c96ff295064aad1f5548444977d7896\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0995be2430baeccbf24ead130e100f6d19a354b2703d65a3544a9bf516ff4c6c\",\"dweb:/ipfs/QmVaKDPVFe8U4MxnR3vwr7yLPrxo6hzYEud4XZzkHShsMu\"]},\"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol\":{\"keccak256\":\"0x2cd70a0a532aabe6b5df682078bb2bc60afb519c05502389e2ca334ef95131ca\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://172cd3ad61d01b30127a129bbf1ab8091e664ef66e7514ff3651189022f2917e\",\"dweb:/ipfs/QmS7SigcghYoJuzXoKEY89hx7gGSCWsBBZ1qf7tkNACjN9\"]},\"src/lib/LibOrderBook.sol\":{\"keccak256\":\"0xa33a7731cde01162cc5d5a1d28b96a17626a6919971620850f92cc32a20342cf\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://9bcbc37dd34292bca2ebdc620b418fbfd8b65039a3d040512f9c8d091ed1f2bf\",\"dweb:/ipfs/QmQEBw7n6QKuzF1BMtxyYcZTk8eK4Hed8QVEwuQtUUJ4AM\"]},\"src/lib/LibOrderBookArb.sol\":{\"keccak256\":\"0xe6ba0ae436fbb48193585beaaac8fc9b367ec9f511281b55e6cbc354c7faae90\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://2b69af34b0acdabe929170984243f7a04581df75010d790147b86f72bc6411c2\",\"dweb:/ipfs/QmZAYyTLrfB5w3uintmQp1Au32YyVrknfqcd6hLLvf1RKk\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.25+commit.b61c2a91"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"struct OrderBookV4ArbConfigV2","name":"config","type":"tuple","components":[{"internalType":"address","name":"orderBook","type":"address"},{"internalType":"struct TaskV1","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","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":"uint256[]","name":"context","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]},{"internalType":"bytes","name":"implementationData","type":"bytes"}]}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"type":"error","name":"InvalidSignature"},{"inputs":[],"type":"error","name":"NoOrders"},{"inputs":[],"type":"error","name":"WrongTask"},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"struct OrderBookV4ArbConfigV2","name":"config","type":"tuple","components":[{"internalType":"address","name":"orderBook","type":"address"},{"internalType":"struct TaskV1","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","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":"uint256[]","name":"context","type":"uint256[]"},{"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 IOrderBookV4","name":"orderBook","type":"address"},{"internalType":"struct TakeOrdersConfigV3","name":"takeOrders","type":"tuple","components":[{"internalType":"uint256","name":"minimumInput","type":"uint256"},{"internalType":"uint256","name":"maximumInput","type":"uint256"},{"internalType":"uint256","name":"maximumIORatio","type":"uint256"},{"internalType":"struct TakeOrderConfigV3[]","name":"orders","type":"tuple[]","components":[{"internalType":"struct OrderV3","name":"order","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IO[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"vaultId","type":"uint256"}]},{"internalType":"struct IO[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"vaultId","type":"uint256"}]},{"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":"uint256[]","name":"context","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]},{"internalType":"bytes","name":"data","type":"bytes"}]},{"internalType":"struct TaskV1","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","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":"uint256[]","name":"context","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]}],"stateMutability":"payable","type":"function","name":"arb3"},{"inputs":[],"stateMutability":"view","type":"function","name":"iTaskHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"inputAmountSent","type":"uint256"},{"internalType":"uint256","name":"totalOutputAmount","type":"uint256"},{"internalType":"bytes","name":"takeOrdersData","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"onTakeOrders"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"stateMutability":"view","type":"function","name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"stateMutability":"payable","type":"function","name":"x"}],"devdoc":{"kind":"dev","methods":{"onTakeOrders(address,address,uint256,uint256,bytes)":{"params":{"inputAmountSent":"The amount of `inputToken` that was sent to `IOrderBookV4OrderTaker`.","inputToken":"The token that was sent to `IOrderBookV4OrderTaker`.","outputToken":"The token that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns.","takeOrdersData":"The data passed to `takeOrders` by the caller.","totalOutputAmount":"The total amount of `outputToken` that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns."}},"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[EIP 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":{"onTakeOrders(address,address,uint256,uint256,bytes)":{"notice":"Called by `IOrderBookV4` when `takeOrders` is called with non-zero data, if it caused a non-zero input amount. I.e. if the order(s) taker received some tokens. Input and output directions are relative to the `IOrderBookV4OrderTaker` contract. If the order(s) taker had an active debt from a flash loan then that debt will be paid _before_ calculating any input amounts sent. i.e. the debt is deducted from the input amount before this callback is called."}},"version":1}},"settings":{"remappings":["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.interpreter.interface/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/","integrity/=lib/rain.interpreter/src/lib/integrity/","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/","openzeppelin/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/","parse/=lib/rain.interpreter/src/lib/parse/","prb-math/=lib/rain.interpreter/lib/prb-math/src/","rain.datacontract/=lib/rain.interpreter/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.sol.codegen/lib/rain.math.binary/src/","rain.math.fixedpoint/=lib/rain.interpreter/lib/rain.math.fixedpoint/src/","rain.math.saturating/=lib/rain.interpreter/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.binmaskflag/=lib/rain.interpreter/lib/rain.sol.binmaskflag/src/","rain.sol.codegen/=lib/rain.interpreter/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.math.fixedpoint/lib/rain.string/src/","state/=lib/rain.interpreter/src/lib/state/","sushixswap-v2/=lib/sushixswap-v2/"],"optimizer":{"enabled":true,"runs":9000},"metadata":{"bytecodeHash":"none","appendCBOR":false},"compilationTarget":{"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol":"BalancerRouterOrderBookV4ArbOrderTaker"},"evmVersion":"paris","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.math.fixedpoint/src/error/ErrScale.sol":{"keccak256":"0xf078f93e8cf6360008743854983c2c98a43f7f78b95a527473089a22b81c55a0","urls":["bzz-raw://580c4ad750f0ebebdf77f87feb52bce41f2d72fa4bf9221fbe3977837eb6a4d9","dweb:/ipfs/QmeYydyLSLqFT5DfFDgJBEBBeBEhwvsMi3oQ4USXXrQudF"],"license":"LicenseRef-DCL-1.0"},"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/FixedPointDecimalConstants.sol":{"keccak256":"0x9299cb9b7aeeaa2a60c6e248928bc173750c5361df4fc0e4d9ea94a778fcd6e6","urls":["bzz-raw://3a65a4f0f3b7462cb0b0b6d165d3868010ff19192f53a8133e3e93be3d811d81","dweb:/ipfs/QmSFWpSUH2cAcw7ph2c5rwvqcKWXTJgvabaRjk2P8ZMzcP"],"license":"LicenseRef-DCL-1.0"},"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/LibFixedPointDecimalScale.sol":{"keccak256":"0xef9a2b240ba686ee4b31c37edfbbab1a3b276db3ad269688fa2c0d1beced6c0b","urls":["bzz-raw://a4e115922faa62d4c3f64c466b9e3d27f53d611c92422828c1920c37bc51acfa","dweb:/ipfs/QmPa5cnqmk8eHjkdSPzegHDN9Q4jWbNV1DHeFKh5LZ6XVk"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol":{"keccak256":"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544","urls":["bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e","dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol":{"keccak256":"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1","urls":["bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34","dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305","urls":["bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5","dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca","urls":["bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd","dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"keccak256":"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69","urls":["bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71","dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1","urls":["bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68","dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa","urls":["bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931","dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0","urls":["bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f","dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"keccak256":"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58","urls":["bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2","dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol":{"keccak256":"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80","urls":["bzz-raw://77d1f1cf302cd5e1dfbbb4ce3b281b28e8c52942d4319fce43df2e1b6f02a52d","dweb:/ipfs/QmT6ZXStmK3Knhh9BokeVHQ9HXTBZNgL3Eb1ar1cYg1hWy"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","urls":["bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d","dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","urls":["bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f","dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3","urls":["bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c","dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc","urls":["bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7","dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrBytes.sol":{"keccak256":"0x82df8bd5b6a2343eb41c47f9b58f05adb2f8fd92b146ddb31c0ea697ebe3acd4","urls":["bzz-raw://f95976983e965460330e2a1d00f3ed0e2079e13a67f3364f1175723cd97b6a07","dweb:/ipfs/QmQKhYbVSesLuomYv4XPapPMvLmXNLgSx2QtgK5EJhww5c"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol":{"keccak256":"0xfc1739c5c406f71e1f52ebfd163162087e9025b02444ca12ae8844c71dcd1cf5","urls":["bzz-raw://ae2e95f1e6260b18105369c7216e1ebc6a251ffe3548d27ce180f7885c3f6906","dweb:/ipfs/QmPQEzZmQDuzp8R5rp6ABmzGD243qu8R5GX4FbHc8G4CUC"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes.sol":{"keccak256":"0x46f53ecd0554926ed6ef781485f9c3d3dfe08fa5503021aac7476c28df364f30","urls":["bzz-raw://d6841328d12c44dfc3e966d2372b841f27659b592556411bcb2889ed1a8db6b2","dweb:/ipfs/QmQHUvQre6Jb5VtiKDvwQiff3eLSCPxRkAs8Jy81dnPbdD"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibMemCpy.sol":{"keccak256":"0x58be272366c53e5db26413754881238127a5ccedc69439d50afbb4c4f9769006","urls":["bzz-raw://49d241b4acc8462d0289eafe645c20493a615c9bef629dab4f049599373df1c7","dweb:/ipfs/QmYLK8fhzz5kjdaQY29yrcgEcGv31gUABvC7eHoChgYwV7"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol":{"keccak256":"0xdadaac57081823b3a4162aeda93195d1dbe98caf1141f6d9113302909c851307","urls":["bzz-raw://fa6026d3853dd4a58faa0c9ac2dda867c200963a052a4d62e8797cd3a0e29250","dweb:/ipfs/QmPRKmE5tpJKwCpy3rumAMjCqDdGK8UC2r2soB1CNQwfmJ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol":{"keccak256":"0xbfea88bec2894f0ff0b3f8b3088f4a45f561aff1bc439165bcdb0e15fa0124ea","urls":["bzz-raw://3ef8c1cf899aa39585cded6e6510e637fa5e60f40dae9e39688ecacd41ef9c41","dweb:/ipfs/Qme4nJr2tCfkY9DDiMhcGjuvjy6jFGZvNgCeMD81YACEKR"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/error/ErrBytecode.sol":{"keccak256":"0x56d9f7a498877655b507ddb4683f4cdbb961bf38375d85c80ab66f8cf0aa9d03","urls":["bzz-raw://0206c9b5a55818d20b2a644c2da0a5cfbbfffb82d4e49bbd0ddd5d60df19ecb8","dweb:/ipfs/QmZuMWg8zqPFDVSWKZnRxrmDpr3YQE7ERSjAFLWnK4iDyd"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterCallerV3.sol":{"keccak256":"0x17a433a06d82d1fbaa497ab0ab0a3c698f86dcdbf9b3dc6814d2f64b1592bc32","urls":["bzz-raw://eb06d882eab9261c1561a3f087b4eb6b29bbf919f6902859a3464d7ecd738315","dweb:/ipfs/QmacaaExc2aL4xokmcBxKy2nhRYKWkEhb2DV2KNJQbMHxK"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol":{"keccak256":"0xd3fe133132e9688f0590f273b1a9851d17b794d7ed85d5cc7a4cf961220359f3","urls":["bzz-raw://bd74c48f247d80804a1fcaa664b4771cbca471cb5bc29307e585d60fb4162bf1","dweb:/ipfs/QmX8PF8aVeXbKsuaBnvLpsgcyjqxHUZK2wgogmNDzQC8mr"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterV3.sol":{"keccak256":"0x152209b9afda8a9fbba404563d67566584b95f49f57f321538d66995b81de300","urls":["bzz-raw://84a09751006cd68411da9684379919e6f0a6b7606050392633146374b7d10141","dweb:/ipfs/QmWoST14FWQr8MqGZXruDvJn5FeQrTkKZomSjazcp6msdm"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IParserV2.sol":{"keccak256":"0x9893dfb4e05bfbf088921c5cca38265388de5ef9e127ec8674a2ce6356152725","urls":["bzz-raw://19bac62db62ad9cb20a9b9790208e124bcfdf89f7deeae25b3cb30f11f680724","dweb:/ipfs/QmUvj4Zcj3b6ACRjcAHRW9geoLfLUXuKydcbMakaxRFPTa"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV1.sol":{"keccak256":"0x933cbfee07ddc43390326f87034613216352250472577bd890e9589e6206fad4","urls":["bzz-raw://d0f947ca6eb86ae9c03806430f5c3a946882daee9f82e436067b1c42ff554595","dweb:/ipfs/QmV7jK8dK6de1HDsUjKDGfEPwVdNEzDHgVHmVZKyfGv6MQ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV2.sol":{"keccak256":"0x3f03703392207a285d41b2871c2d83df103425c1984750cc303628269e6258e5","urls":["bzz-raw://a9bc96c0f288ab7b6ec1a14a42e426ec745f0b1c7fcde9d7052380c64e61c8da","dweb:/ipfs/QmYBobAFw36Jd2VtFtoWNqE8HxJhy3n9Eho1fsK3uBCbwc"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV3.sol":{"keccak256":"0x231a50d32c6f910d7ae13ae1d83a221ba55eb7962380572c9c354c8a3c5c52bf","urls":["bzz-raw://74b19a6c17ac7fab6edee53218a35154c5fe9ad3769ce8e22bac682dd32df0e8","dweb:/ipfs/QmYiG7i4tNfA4eTynoQVbNixvGepqoAedVz2isiMfxRF8D"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV1.sol":{"keccak256":"0x20aebc5f73ffd790da90b8e88d6412f9c3a11041239c669c03e188d0a6be1e3e","urls":["bzz-raw://24f85bcb1d9f52ae01f7127274100ef68640a823bf2b981f267faf71192d8235","dweb:/ipfs/QmPmz7q4rsy9vWXixdG9qBB8fLb1Wjj8LWyq6wyuFQR2HK"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV2.sol":{"keccak256":"0x8ae6f8b21d5fba09db20a979e797339d4cc385450d4da8cb4de2331db638caee","urls":["bzz-raw://162b488b86df5c57c8cecd6c02172122ab9d30d70dd135ea151db5d56bf06f62","dweb:/ipfs/Qmf9Kd89mH6PE5hoQ6ahV1Dsi28AFbakeUUw12W9Dp3sHW"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol":{"keccak256":"0xe03c065839e972fde62d73c45acf6fc2e88f42e3a07f4255ef5bfdcd30d3b1f1","urls":["bzz-raw://e766d9cfe9464f722e02320c3936fb0b98b9417663fefba6bac3dbb21007ce82","dweb:/ipfs/QmX88DnazhZw7B3Fxp1iDZXogi2k6dyMPvh2vXpXep11oQ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol":{"keccak256":"0x8986cb9ba93034751b21245398bc1ef7a55fe10d34b5d4cc4207ee9d39a3e616","urls":["bzz-raw://dc7d8e706e96f0d0e53599582fadd591581484ac36921b0e4c6454c54b568c2b","dweb:/ipfs/QmNczMgGQKWJiDhXVbtXeBjUEtzFtr7k41uPjiU8P6BrHT"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV2.sol":{"keccak256":"0x0a9223e817a36a9717b91f977a9fce5e698afd393aa2405979baf53a12339805","urls":["bzz-raw://1537576666b7462485e898ddbd36848be401b3c1e3f8317eca4112d1b21d4e74","dweb:/ipfs/QmZYRLbnctnMKEZ4UYz9oZ9MFoqQy1hex29HrXPVBX5U1g"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IParserV1.sol":{"keccak256":"0x19e1a217e8c67c671e319dd0e5608d7c496fbfc02363fbb2d08626715625dd55","urls":["bzz-raw://603b3234a5c084acb12d0b7e3909503869f9a6d860f91d86692e007f67aba25b","dweb:/ipfs/QmU7i9uyr9qWFzD2xjn1qjgiPjb8vUjuXA6dHEuGLVkmPj"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/bytecode/LibBytecode.sol":{"keccak256":"0xdebdca9d3d2a6c1be927f6fa1f28550cd7885aa52abd378ddb65e5f6495ef87c","urls":["bzz-raw://5ca7fe490fe2b1287c3c231ec34daa504b3b36fa6c3e69aacda9737db1e1b548","dweb:/ipfs/QmQozWFz6qFJDiRFS1YgPWCsRZgCCQ3yEzmwTVyiCs7SxY"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibContext.sol":{"keccak256":"0xd2cfeec3582d7b0b2a09573e258230ec4a6de169e60d9078f674a7a09d0c7b2d","urls":["bzz-raw://cf266d36372575856000331ebb8dca7d6025db6365d14f4c876ab55305090aba","dweb:/ipfs/QmYyoYFXryPM2SRMafgUgsBbAXPeCmzLFvzhHGR3i47zHy"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibEvaluable.sol":{"keccak256":"0x922f6df3f98bc94869b9c244ae349e4ecfe0f250937414af7f3699e016b9f57e","urls":["bzz-raw://e4fd2f59466c83a6e5dfe843951880d3f1dbe98cf559746242d942ab20962166","dweb:/ipfs/QmTTD9vj8ph7ocmWFAjPb4D4UiwusCg7iZEPWoRfVtEEu1"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/deprecated/caller/LibEncodedDispatch.sol":{"keccak256":"0x0d9b888a01c5d508dd3cdfd53823ad56c6e16e06d18ca8b2ac68e82b102cc60a","urls":["bzz-raw://6f854a3243d04aa76169367843a97bec51574f01ddb1e31b271f8aa93e184dce","dweb:/ipfs/QmRc85MSQBbqvCvdcZBHvBrA8FFfVbxYWHbNV2vshmLF95"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/ns/LibNamespace.sol":{"keccak256":"0x5e1f5a0e05fbadf8acfad550ed59d960dd05ebc1d74cfa676f22a26644cc0ee5","urls":["bzz-raw://ee31bfc695ae5dc841379c3164b345bb0951b8b10fd94f300d5bb2de51dd7a1e","dweb:/ipfs/QmT1CqR7Lpj2bEJADgEPgY9cmTqgKLEZm1QLbZxfHEd8PY"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/IOrderBookV4.sol":{"keccak256":"0x715c5211361bd469a9ec916710611536d087ae5630a3fc3f80e9802ec43c4596","urls":["bzz-raw://c61433f7de82ac5fbd752470aa1b9358dc70455ba85be87a9056509188f5db21","dweb:/ipfs/QmaGvPxe4xpqkVMdq9mo2moJyBHB9f8wTkcxZotk7tevVH"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/IOrderBookV4OrderTaker.sol":{"keccak256":"0x7d197bd91214d318ce6a9ee388228494606ba7bdae36bbc6ec6ed1681ff60bd8","urls":["bzz-raw://73caf415d34e06a83d104cbccf98ae76ccd522e5ae1fb32c2bb18af9bae7ccaa","dweb:/ipfs/QmYbiDgjfjpX6pvjawqhtQpiTkUuX24ncHodheJPtSg4d7"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v2/IOrderBookV2.sol":{"keccak256":"0x30c528f1772e9593b5329f1458cab4cce3510a2ccca01696b506af177fffd786","urls":["bzz-raw://9f53c14e5aaab2cd2fbf5b39d07c59acfdc09aff3476345816c2635de2cdd5d3","dweb:/ipfs/QmaomXfmDKdoeYwbMe9cy5anx4fDEMtP4W9Rre5s5DZVE6"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v3/IOrderBookV3.sol":{"keccak256":"0xdca3fd0c6106ab98d08682e63e433b74250d1f01e646a5908c97183d9b25130b","urls":["bzz-raw://0f986a8388275a4144068981aa628e46bff221c2d27a3ad597a9c5fc2d4fcb09","dweb:/ipfs/QmR2pxkpY4ddhLb7jdoNAVSJwYHokyGpn5Tzg3Q7YnGYgW"],"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/IOrderBookV4ArbOrderTakerV2.sol":{"keccak256":"0x271d4a0fdeddc07a88b18fa52f39c840515e572d62a755f7710bbd1b20ebe389","urls":["bzz-raw://64000bb3455809c1eb2a8789023286ad9ccaa2cdfe014cff480e96bb1b7ad6a3","dweb:/ipfs/QmRDgNHR4mYjxvHJUNMaaDZdAnxZ7yDF9kCL3aaSYip6AH"],"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/OrderBookV4ArbCommon.sol":{"keccak256":"0xe24cce13b3e21ae36c0aae11380128c5f0ddf542a0298f1a1845a39845e10576","urls":["bzz-raw://5f5d04c151a7e9fe4a659cef55abc4a626bc2ba0e58edbd714dcbadb52f4b396","dweb:/ipfs/QmZHQiYBNdxMJWoMjHnsqoj2YszvFMWrGYqDcodKpwyv98"],"license":"LicenseRef-DCL-1.0"},"src/abstract/OrderBookV4ArbOrderTaker.sol":{"keccak256":"0xa419a3d91a8c362dad1bea2761e6e0218c96ff295064aad1f5548444977d7896","urls":["bzz-raw://0995be2430baeccbf24ead130e100f6d19a354b2703d65a3544a9bf516ff4c6c","dweb:/ipfs/QmVaKDPVFe8U4MxnR3vwr7yLPrxo6hzYEud4XZzkHShsMu"],"license":"LicenseRef-DCL-1.0"},"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol":{"keccak256":"0x2cd70a0a532aabe6b5df682078bb2bc60afb519c05502389e2ca334ef95131ca","urls":["bzz-raw://172cd3ad61d01b30127a129bbf1ab8091e664ef66e7514ff3651189022f2917e","dweb:/ipfs/QmS7SigcghYoJuzXoKEY89hx7gGSCWsBBZ1qf7tkNACjN9"],"license":"LicenseRef-DCL-1.0"},"src/lib/LibOrderBook.sol":{"keccak256":"0xa33a7731cde01162cc5d5a1d28b96a17626a6919971620850f92cc32a20342cf","urls":["bzz-raw://9bcbc37dd34292bca2ebdc620b418fbfd8b65039a3d040512f9c8d091ed1f2bf","dweb:/ipfs/QmQEBw7n6QKuzF1BMtxyYcZTk8eK4Hed8QVEwuQtUUJ4AM"],"license":"LicenseRef-DCL-1.0"},"src/lib/LibOrderBookArb.sol":{"keccak256":"0xe6ba0ae436fbb48193585beaaac8fc9b367ec9f511281b55e6cbc354c7faae90","urls":["bzz-raw://2b69af34b0acdabe929170984243f7a04581df75010d790147b86f72bc6411c2","dweb:/ipfs/QmZAYyTLrfB5w3uintmQp1Au32YyVrknfqcd6hLLvf1RKk"],"license":"LicenseRef-DCL-1.0"}},"version":1},"id":53} \ No newline at end of file diff --git a/test/e2e/data.js b/test/e2e/data.js index badd7e4a..46f4f696 100644 --- a/test/e2e/data.js +++ b/test/e2e/data.js @@ -105,45 +105,46 @@ module.exports = [ // "0x96C3673Ee4B0d5303272193BaB0c565B7ce58D7A", // "0x22025257BeF969A81eDaC0b343ce82d777931327", ], - [ - ChainId.BASE, - process?.env?.TEST_BASE_RPC, - 16418720, - [ - WNATIVE[ChainId.BASE], - new Token({ - chainId: ChainId.BASE, - address: "0x99b2B1A2aDB02B38222ADcD057783D7e5D1FCC7D", - decimals: 18, - symbol: "WLTH", - }), - new Token({ - chainId: ChainId.BASE, - address: "0x71DDE9436305D2085331AF4737ec6f1fe876Cf9f", - decimals: 18, - symbol: "PAID", - }), - new Token({ - chainId: ChainId.BASE, - address: "0x3982E57fF1b193Ca8eb03D16Db268Bd4B40818f8", - decimals: 18, - symbol: "BLOOD", - }), - ], - [ - "0x2B8804c2b652f05F7FDD8e0a02F01eE58F01667E", - "0xD6216fC19DB775Df9774a6E33526131dA7D19a2c", - "0x3ea31919Ef9b3e72Cc25657b604DB1ACDb1DdB4b", - "0xf6D07A291443F31B129Ca7e2b46C6F882f0FAa5b", - ], - [LiquidityProviders.UniswapV3, LiquidityProviders.UniswapV2, LiquidityProviders.BaseSwap], - ["1", "10000", "10000", "10000"], - ], + // [ + // ChainId.BASE, + // process?.env?.TEST_BASE_RPC, + // 16418720, + // [ + // WNATIVE[ChainId.BASE], + // new Token({ + // chainId: ChainId.BASE, + // address: "0x99b2B1A2aDB02B38222ADcD057783D7e5D1FCC7D", + // decimals: 18, + // symbol: "WLTH", + // }), + // new Token({ + // chainId: ChainId.BASE, + // address: "0x71DDE9436305D2085331AF4737ec6f1fe876Cf9f", + // decimals: 18, + // symbol: "PAID", + // }), + // new Token({ + // chainId: ChainId.BASE, + // address: "0x3982E57fF1b193Ca8eb03D16Db268Bd4B40818f8", + // decimals: 18, + // symbol: "BLOOD", + // }), + // ], + // [ + // "0x2B8804c2b652f05F7FDD8e0a02F01eE58F01667E", + // "0xD6216fC19DB775Df9774a6E33526131dA7D19a2c", + // "0x3ea31919Ef9b3e72Cc25657b604DB1ACDb1DdB4b", + // "0xf6D07A291443F31B129Ca7e2b46C6F882f0FAa5b", + // ], + // [LiquidityProviders.UniswapV3, LiquidityProviders.UniswapV2, LiquidityProviders.BaseSwap], + // ["1", "10000", "10000", "10000"], + // ], [ // unique test for aerodrome slipstream ChainId.BASE, process?.env?.TEST_BASE_RPC, - 16418720, + // 16418720, + 34181086, [WNATIVE[ChainId.BASE], USDC[ChainId.BASE]], [ "0x2B8804c2b652f05F7FDD8e0a02F01eE58F01667E", diff --git a/test/e2e/e2e.test.js b/test/e2e/e2e.test.js index d1729df2..c8ec62ae 100644 --- a/test/e2e/e2e.test.js +++ b/test/e2e/e2e.test.js @@ -2,7 +2,7 @@ require("dotenv").config(); const { assert } = require("chai"); const testData = require("./data"); const { RainSolver } = require("../../src/core"); -const { ABI } = require("../../src/common"); +const { ABI, Result } = require("../../src/common"); const { RpcState } = require("../../src/rpc"); const mockServer = require("mockttp").getLocal(); const { sendTx, waitUntilFree, estimateGasCost } = require("../../src/signer/actions"); @@ -33,8 +33,10 @@ const { rainterpreterStoreNPE2Deploy, rainterpreterParserNPE2Deploy, rainterpreterExpressionDeployerNPE2Deploy, + balancerArbDeploy, } = require("../utils"); const { SharedState } = require("../../src/state"); +const balancerHelpers = require("../../src/router/balancer"); // run tests on each network in the provided data for (let i = 0; i < testData.length; i++) { @@ -92,22 +94,289 @@ for (let i = 0; i < testData.length; i++) { quoteGas: 1_000_000n, }, }); - const dataFetcherPromise = RainDataFetcher.init( - chainId, - createPublicClient({ - chain: publicClientConfig[chainId].chain, - transport: rainSolverTransport(rpcState, { - retryCountNext: 50, - timeout: 600_000, - }), + const client = createPublicClient({ + chain: publicClientConfig[chainId].chain, + transport: rainSolverTransport(rpcState, { + retryCountNext: 50, + timeout: 600_000, }), - liquidityProviders, - ); + }); + const dataFetcherPromise = RainDataFetcher.init(chainId, client, liquidityProviders); // run tests on each rp version for (let j = 0; j < rpVersions.length; j++) { const rpVersion = rpVersions[j]; + it.only(`should clear orders successfully using route processor v${rpVersion}`, async function () { + config.rpc = [rpc]; + const viemClient = await viem.getPublicClient(); + state.client = viemClient; + state.client.simulateContract = client.simulateContract; + const dataFetcher = await dataFetcherPromise; + state.dataFetcher = dataFetcher; + dataFetcher.web3Client.transport.retryCount = 3; + const testSpan = tracer.startSpan("test-clearing"); + + // set as the route for POC + balancerHelpers.getBestBalancerRoute = async function (params) { + return Result.ok([ + { + steps: [ + { + pool: "0x88c044fb203b58b12252be7242926b1eeb113b4a", + tokenOut: "0x4200000000000000000000000000000000000006", + isBuffer: false, + }, + ], + tokenIn: params.tokenIn.address, + exactAmountIn: params.swapAmount, + minAmountOut: 0n, + }, + ]); + }; + + // reset network before each test + await helpers.reset(rpc, blockNumber); + // get bot signer + const bot = botAddress + ? (await viem.getTestClient({ account: botAddress })) + .extend(publicActions) + .extend(walletActions) + : ( + await viem.getTestClient({ + account: "0x22025257BeF969A81eDaC0b343ce82d777931327", + }) + ) + .extend(publicActions) + .extend(walletActions); + bot.sendTx = async (tx) => { + return await sendTx(bot, tx); + }; + bot.waitUntilFree = async () => { + return await waitUntilFree(bot); + }; + bot.estimateGasCost = async (tx) => { + return await estimateGasCost(bot, tx); + }; + bot.asWriteSigner = () => bot; + bot.state = state; + bot.impersonateAccount({ + address: botAddress ?? "0x22025257BeF969A81eDaC0b343ce82d777931327", + }); + await network.provider.send("hardhat_setBalance", [ + bot.account.address, + "0x4563918244F40000", + ]); + bot.BALANCE = ethers.BigNumber.from("0x4563918244F40000"); + bot.BOUNTY = []; + + // deploy contracts + const interpreter = await rainterpreterNPE2Deploy(); + const store = await rainterpreterStoreNPE2Deploy(); + const parser = await rainterpreterParserNPE2Deploy(); + const deployer = await rainterpreterExpressionDeployerNPE2Deploy({ + interpreter: interpreter.address, + store: store.address, + parser: parser.address, + }); + const orderbook = !orderbookAddress + ? await deployOrderBookNPE2() + : await ethers.getContractAt(orderbookAbi, orderbookAddress); + + const arb = !arbAddress + ? await balancerArbDeploy(orderbook.address, config.routeProcessors[rpVersion]) + : await ethers.getContractAt(ABI.Orderbook.Primary.Arb, arbAddress); + + state.dispair = { + interpreter: interpreter.address, + store: store.address, + deployer: deployer.address, + }; + + // set up tokens contracts and impersonate owners + const owners = []; + for (let i = 0; i < tokens.length; i++) { + tokens[i].contract = await ethers.getContractAt( + ERC20Artifact.abi, + tokens[i].address, + ); + tokens[i].vaultId = ethers.BigNumber.from(randomUint256()); + tokens[i].depositAmount = ethers.utils.parseUnits( + deposits[i] ?? "100", + tokens[i].decimals, + ); + // owners.push( + // (await viem.getTestClient({account: addressesWithBalance[i]})).extend(publicActions).extend(walletActions) + // // await ethers.getImpersonatedSigner(addressesWithBalance[i]) + // ); + owners.push(await ethers.getImpersonatedSigner(addressesWithBalance[i])); + await network.provider.send("hardhat_setBalance", [ + addressesWithBalance[i], + "0x4563918244F40000", + ]); + } + + // bot original token balances + const originalBotTokenBalances = []; + for (const t of tokens) { + originalBotTokenBalances.push(await t.contract.balanceOf(bot.account.address)); + } + + // dposit and add orders for each owner and return + // the deployed orders in format of a sg query. + // all orders have WETH as output and other specified + // tokens as input + let orders = []; + for (let i = 1; i < tokens.length; i++) { + const depositConfigStruct = { + token: tokens[i].address, + vaultId: tokens[i].vaultId, + amount: tokens[i].depositAmount.toString(), + }; + await tokens[i].contract + .connect(owners[i]) + .approve(orderbook.address, depositConfigStruct.amount); + await orderbook + .connect(owners[i]) + .deposit2( + depositConfigStruct.token, + depositConfigStruct.vaultId, + depositConfigStruct.amount, + [], + ); + + // prebuild bytecode: "_ _: 0 max; :;" + const ratio = "0".repeat(64); // 0 + const maxOutput = "f".repeat(64); // max + const bytecode = `0x0000000000000000000000000000000000000000000000000000000000000002${maxOutput}${ratio}0000000000000000000000000000000000000000000000000000000000000015020000000c02020002011000000110000100000000`; + const addOrderConfig = { + evaluable: { + interpreter: interpreter.address, + store: store.address, + bytecode, + }, + nonce: "0x" + "0".repeat(63) + "1", + secret: "0x" + "0".repeat(63) + "1", + validInputs: [ + { + token: tokens[0].address, + decimals: tokens[0].decimals, + vaultId: tokens[0].vaultId, + }, + ], + validOutputs: [ + { + token: tokens[i].address, + decimals: tokens[i].decimals, + vaultId: tokens[i].vaultId, + }, + ], + meta: encodeMeta("some_order"), + }; + const tx = await orderbook.connect(owners[i]).addOrder2(addOrderConfig, []); + orders.push( + await mockSgFromEvent( + await getEventArgs(tx, "AddOrderV2", orderbook), + orderbook, + tokens.map((v) => ({ ...v.contract, knownSymbol: v.symbol })), + ), + ); + } + + // run the clearing process + config.isTest = true; + config.shuffle = false; + config.signer = bot; + config.hops = 2; + config.retries = 1; + config.lps = liquidityProviders; + config.rpVersion = rpVersion; + config.arbAddress = arb.address; + config.orderbookAddress = orderbook.address; + config.testBlockNumber = BigInt(blockNumber); + config.testBlockNumberInc = BigInt(blockNumber); // increments during test updating to new block height + config.gasCoveragePercentage = "1"; + config.viemClient = viemClient; + config.dataFetcher = dataFetcher; + config.accounts = []; + config.mainAccount = bot; + config.gasPriceMultiplier = 107; + config.gasLimitMultiplier = 120; + config.dispair = { + interpreter: interpreter.address, + store: store.address, + deployer: deployer.address, + }; + + const orderManager = new OrderManager(state); + await orderManager.addOrders(orders); + orders = orderManager.getNextRoundOrders(false); + + state.gasPrice = await bot.getGasPrice(); + orderManager.getNextRoundOrders = () => orders; + const rainSolver = new RainSolver( + state, + config, + orderManager, + { + mainSigner: bot, + getRandomSigner: () => bot, + }, + // config, + ); + const { results: reports } = await rainSolver.processNextRound(undefined, false); + + // should have cleared correct number of orders + assert.ok(reports.length == tokens.length - 1, "Failed to clear all given orders"); + + // validate each cleared order + let inputProfit = ethers.constants.Zero; + let gasSpent = ethers.constants.Zero; + for (let i = 0; i < reports.length; i++) { + const report = reports[i].value; + assert.equal(report.status, ProcessOrderStatus.FoundOpportunity); + + const pair = `${tokens[0].symbol}/${tokens[i + 1].symbol}`; + const clearedAmount = ethers.BigNumber.from(report.clearedAmount); + const outputVault = await orderbook.vaultBalance( + owners[i + 1].address, + tokens[i + 1].address, + tokens[i + 1].vaultId, + ); + const inputVault = await orderbook.vaultBalance( + owners[0].address, + tokens[0].address, + tokens[0].vaultId, + ); + const botTokenBalance = await tokens[i + 1].contract.balanceOf( + bot.account.address, + ); + + assert.equal(report.tokenPair, pair); + + // should have cleared equal to vault balance or lower + assert.ok( + tokens[i + 1].depositAmount.gte(clearedAmount), + `Did not clear expected amount for: ${pair}`, + ); + assert.ok( + outputVault.eq(tokens[i + 1].depositAmount.sub(clearedAmount)), + `Unexpected current output vault balance: ${pair}`, + ); + assert.ok(inputVault.eq(0), `Unexpected current input vault balance: ${pair}`); + assert.ok( + originalBotTokenBalances[i + 1].eq(botTokenBalance), + `Unexpected current bot ${tokens[i + 1].symbol} balance`, + ); + + // collect all bot's input income (bounty) and gas cost + inputProfit = inputProfit.add(ethers.utils.parseUnits(report.inputTokenIncome)); + gasSpent = gasSpent.add(ethers.utils.parseUnits(report.gasCost.toString())); + } + + testSpan.end(); + }); + it(`should clear orders successfully using route processor v${rpVersion}`, async function () { config.rpc = [rpc]; const viemClient = await viem.getPublicClient(); diff --git a/test/utils.js b/test/utils.js index 3fe7c809..74f97157 100644 --- a/test/utils.js +++ b/test/utils.js @@ -8,6 +8,7 @@ const RainterpreterParserNPE2Artifact = require("./abis/RainterpreterParserNPE2. const RainterpreterExpressionDeployerNPE2Artifact = require("./abis/RainterpreterExpressionDeployerNPE2.json"); const GenericPoolOrderBookV4ArbOrderTakerArtifact = require("./abis/GenericPoolOrderBookV4ArbOrderTaker.json"); const RouteProcessorOrderBookV4ArbOrderTakerArtifact = require("./abis/RouteProcessorOrderBookV4ArbOrderTaker.json"); +const BalancerRouterOrderBookV4ArbOrderTakerArtifact = require("./abis/BalancerRouterOrderBookV4ArbOrderTaker.json"); /** * Deploys a simple contracts that takes no arguments for deployment @@ -34,6 +35,17 @@ exports.arbDeploy = async (orderbookAddress, rpAddress) => { }); }; +exports.balancerArbDeploy = async (orderbookAddress, rpAddress) => { + return await this.basicDeploy(BalancerRouterOrderBookV4ArbOrderTakerArtifact, { + orderBook: orderbookAddress ?? `0x${"0".repeat(40)}`, + task: { + evaluable: ABI.Orderbook.DefaultArbEvaluable, + signedContext: [], + }, + implementationData: ethers.utils.defaultAbiCoder.encode(["address"], [rpAddress]), + }); +}; + exports.genericArbrbDeploy = async (orderbookAddress) => { return await this.basicDeploy(GenericPoolOrderBookV4ArbOrderTakerArtifact, { orderBook: orderbookAddress ?? `0x${"0".repeat(40)}`, From b1e3a579b13beeff512a22401e2e958955dc33aa Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Thu, 14 Aug 2025 22:57:11 +0000 Subject: [PATCH 2/6] Update index.ts --- src/core/modes/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/modes/index.ts b/src/core/modes/index.ts index 4911f382..eebccb46 100644 --- a/src/core/modes/index.ts +++ b/src/core/modes/index.ts @@ -7,8 +7,8 @@ import { FindBestTradeResult } from "../types"; import { RainSolverSigner } from "../../signer"; import { Attributes } from "@opentelemetry/api"; // import { findBestRouteProcessorTrade } from "./rp"; -import { findBestIntraOrderbookTrade } from "./intra"; -import { findBestInterOrderbookTrade } from "./inter"; +// import { findBestIntraOrderbookTrade } from "./intra"; +// import { findBestInterOrderbookTrade } from "./inter"; import { extendObjectWithHeader } from "../../logger"; import { findBestBalancerTrade } from "./balancer"; @@ -43,7 +43,7 @@ export async function findBestTrade( this: RainSolver, args: FindBestTradeArgs, ): Promise { - const { orderDetails, signer, inputToEthPrice, outputToEthPrice, toToken, fromToken } = args; + const { orderDetails, signer, inputToEthPrice, toToken, fromToken } = args; const promises = [ // findBestRouteProcessorTrade.call( // this, From 34b90550007824e28cabb2fd069977576d0f284b Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Wed, 20 Aug 2025 17:48:18 +0000 Subject: [PATCH 3/6] update --- .env.config.yaml | 1 + config.example.yaml | 3 + src/common/abis/balancer.ts | 9 +- src/config/yaml.test.ts | 2 + src/config/yaml.ts | 7 + src/core/modes/balancer/index.test.ts | 135 +++ src/core/modes/balancer/index.ts | 2 +- src/core/modes/balancer/simulate.test.ts | 318 ++++++ src/core/modes/balancer/simulate.ts | 130 +-- src/core/modes/index.test.ts | 78 +- src/core/modes/index.ts | 74 +- src/core/modes/rp/simulate.test.ts | 79 -- src/error/common.ts | 9 +- src/error/decoder.ts | 16 +- src/router/balancer.test.ts | 1003 +++++++++++++++++ src/router/balancer.ts | 437 +++++-- src/router/marketPrice.ts | 21 + src/state/index.test.ts | 1 + src/state/index.ts | 14 + ...alancerRouterOrderBookV4ArbOrderTaker.json | 2 +- test/e2e/data.js | 73 +- test/e2e/e2e.test.js | 480 ++++---- 22 files changed, 2329 insertions(+), 565 deletions(-) create mode 100644 src/core/modes/balancer/index.test.ts create mode 100644 src/core/modes/balancer/simulate.test.ts create mode 100644 src/router/balancer.test.ts diff --git a/.env.config.yaml b/.env.config.yaml index 6650c748..f501a315 100644 --- a/.env.config.yaml +++ b/.env.config.yaml @@ -7,6 +7,7 @@ writeRpc: $WRITE_RPC subgraph: $SUBGRAPH arbAddress: $ARB_ADDRESS genericArbAddress: $GENERIC_ARB_ADDRESS +balancerArbAddress: $BALANCER_ARB_ADDRESS dispair: $DISPAIR liquidityProviders: $LIQUIDITY_PROVIDERS route: $ROUTE diff --git a/config.example.yaml b/config.example.yaml index e831ce57..1aae29de 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -42,6 +42,9 @@ arbAddress: "0x1234...5678" # Generic arb contract address, optional genericArbAddress: "0x1234...5678" +# Balancer arb contract address, optional +balancerArbAddress: "0x1234...5678" + # Dispair contract address, required dispair: "0x1234...5678" diff --git a/src/common/abis/balancer.ts b/src/common/abis/balancer.ts index 818ac29b..a9af0a83 100644 --- a/src/common/abis/balancer.ts +++ b/src/common/abis/balancer.ts @@ -1,10 +1,17 @@ +import { Prettify } from "viem"; import { batchRouterAbi_V3 } from "@balancer/sdk"; /** Keeps the BalancerBatchRouter contract ABIs */ export namespace BalancerBatchRouterAbi { /** Balancer BatchRouter v3 contract structs */ export namespace Structs { - export const SwapPathExactAmountIn = batchRouterAbi_V3[21].inputs[0]; + type _swapPathExactAmountInType = (typeof batchRouterAbi_V3)[21]["inputs"][0]; + const _swapPathExactAmountIn = structuredClone( + batchRouterAbi_V3[21].inputs[0], + ) as any as Prettify & { readonly type: "tuple" }>; + (_swapPathExactAmountIn as any).type = "tuple"; + + export const SwapPathExactAmountIn = _swapPathExactAmountIn; export const SwapPathStep = batchRouterAbi_V3[21].inputs[0].components[1]; } diff --git a/src/config/yaml.test.ts b/src/config/yaml.test.ts index 15ea713a..153ffd9a 100644 --- a/src/config/yaml.test.ts +++ b/src/config/yaml.test.ts @@ -19,6 +19,7 @@ writeRpc: - url: http://write-rpc.example.com subgraph: ["http://subgraph.example.com"] arbAddress: "0x1111111111111111111111111111111111111111" +balancerArbAddress: "0x3333333333333333333333333333333333333333" dispair: "0x2222222222222222222222222222222222222222" liquidityProviders: - lp1 @@ -72,6 +73,7 @@ sgFilter: writeRpc: [{ url: "http://write-rpc.example.com" }], subgraph: ["http://subgraph.example.com"], arbAddress: "0x1111111111111111111111111111111111111111", + balancerArbAddress: "0x3333333333333333333333333333333333333333", dispair: "0x2222222222222222222222222222222222222222", genericArbAddress: undefined, liquidityProviders: ["lp1", "lp2"], diff --git a/src/config/yaml.ts b/src/config/yaml.ts index 5a12bc83..b145f1e9 100644 --- a/src/config/yaml.ts +++ b/src/config/yaml.ts @@ -36,6 +36,8 @@ export type AppOptions = { dispair: string; /** Generic arb contract address */ genericArbAddress?: string; + /** Balancer arb contract address */ + balancerArbAddress?: string; /** List of subgraph urls */ subgraph: string[]; /** Option to maximize maxIORatio, default is true */ @@ -141,6 +143,11 @@ export namespace AppOptions { "genericArbAddress", true, ), + balancerArbAddress: Validator.resolveAddress( + input.balancerArbAddress, + "balancerArbAddress", + true, + ), liquidityProviders: Validator.resolveLiquidityProviders(input.liquidityProviders), route: Validator.resolveRouteType(input.route), ownerProfile: Validator.resolveOwnerProfile(input.ownerProfile), diff --git a/src/core/modes/balancer/index.test.ts b/src/core/modes/balancer/index.test.ts new file mode 100644 index 00000000..baccbec7 --- /dev/null +++ b/src/core/modes/balancer/index.test.ts @@ -0,0 +1,135 @@ +import { Result } from "../../../common"; +import { SimulationResult } from "../../types"; +import { findBestBalancerTrade } from "./index"; +import { extendObjectWithHeader } from "../../../logger"; +import { describe, it, expect, vi, beforeEach, Mock, assert } from "vitest"; +import { trySimulateTrade, BalancerRouterSimulationHaltReason } from "./simulate"; + +vi.mock("./simulate", async (importOriginal) => ({ + ...(await importOriginal()), + trySimulateTrade: vi.fn(), +})); + +vi.mock("../../../logger", () => ({ + extendObjectWithHeader: vi.fn(), +})); + +vi.mock("sushi/currency", async (importOriginal) => { + return { + ...(await importOriginal()), + Token: class { + constructor(args: any) { + return { ...args }; + } + }, + }; +}); + +describe("Test findBestBalancerTrade", () => { + let mockRainSolver: any; + let orderDetails: any; + let signer: any; + let ethPrice: string; + let toToken: any; + let fromToken: any; + + beforeEach(() => { + vi.clearAllMocks(); + + mockRainSolver = { + state: { + client: { + getBlockNumber: vi.fn().mockResolvedValue(123n), + }, + }, + }; + + orderDetails = { + takeOrder: { quote: { maxOutput: 1000n } }, + }; + + signer = { account: { address: "0xsigner" } }; + ethPrice = "2000"; + toToken = { address: "0xTo", decimals: 18, symbol: "TO" }; + fromToken = { address: "0xFrom", decimals: 18, symbol: "FROM" }; + }); + + it("should return success result if full trade size simulation succeeds", async () => { + const mockSuccessResult = Result.ok({ + type: "balancer", + spanAttributes: { foundOpp: true }, + estimatedProfit: 100n, + oppBlockNumber: 123, + }); + (trySimulateTrade as Mock).mockResolvedValue(mockSuccessResult); + + const result: SimulationResult = await findBestBalancerTrade.call( + mockRainSolver, + orderDetails, + signer, + ethPrice, + toToken, + fromToken, + ); + + assert(result.isOk()); + expect(result.value.spanAttributes.foundOpp).toBe(true); + expect(result.value.estimatedProfit).toBe(100n); + expect(result.value.oppBlockNumber).toBe(123); + expect(result.value.type).toBe("balancer"); + expect(trySimulateTrade).toHaveBeenCalledWith({ + orderDetails, + fromToken, + toToken, + signer, + maximumInputFixed: 1000n, + ethPrice, + isPartial: false, + blockNumber: 123n, + }); + }); + + it("should return error if no route found", async () => { + const mockErrorResult = Result.err({ + reason: BalancerRouterSimulationHaltReason.NoRoute, + spanAttributes: { route: "no-way" }, + noneNodeError: "no route available", + }); + (trySimulateTrade as Mock).mockResolvedValue(mockErrorResult); + + const result: SimulationResult = await findBestBalancerTrade.call( + mockRainSolver, + orderDetails, + signer, + ethPrice, + toToken, + fromToken, + ); + + assert(result.isErr()); + expect(result.error.noneNodeError).toBe("no route available"); + expect(result.error.type).toBe("balancer"); + expect(extendObjectWithHeader).toHaveBeenCalledWith( + expect.any(Object), + { route: "no-way" }, + "full", + ); + }); + + it("should return early if ethPrice is unknown", async () => { + const result: SimulationResult = await findBestBalancerTrade.call( + mockRainSolver, + orderDetails, + signer, + "", + toToken, + fromToken, + ); + + assert(result.isErr()); + expect(result.error.type).toBe("balancer"); + expect(result.error.spanAttributes.error).toBe( + "no route to get price of input token to eth", + ); + }); +}); diff --git a/src/core/modes/balancer/index.ts b/src/core/modes/balancer/index.ts index a6cdeee3..b4df1cbf 100644 --- a/src/core/modes/balancer/index.ts +++ b/src/core/modes/balancer/index.ts @@ -9,7 +9,7 @@ import { SimulationResult, TradeType } from "../../types"; import { trySimulateTrade } from "./simulate"; /** - * Tries to find the best trade against route processor for the given order, + * Tries to find the best trade against balancer protocol for the given order, * it will try to simulate a trade for full trade size (order's max output) * and if it was not successful it will try again with partial trade size * @param this - RainSolver instance diff --git a/src/core/modes/balancer/simulate.test.ts b/src/core/modes/balancer/simulate.test.ts new file mode 100644 index 00000000..c1cbb7b6 --- /dev/null +++ b/src/core/modes/balancer/simulate.test.ts @@ -0,0 +1,318 @@ +import { dryrun } from "../dryrun"; +import { RainSolver } from "../.."; +import { ONE18 } from "../../../math"; +import { Pair } from "../../../order"; +import { ABI, Result } from "../../../common"; +import { SimulationResult } from "../../types"; +import { encodeFunctionData, encodeAbiParameters, maxUint256 } from "viem"; +import { describe, it, expect, vi, beforeEach, Mock, assert } from "vitest"; +import { BalancerRouterError, BalancerRouterErrorType } from "../../../router/balancer"; +import { + trySimulateTrade, + SimulateBalancerTradeArgs, + BalancerRouterSimulationHaltReason, +} from "./simulate"; + +vi.mock("viem", async (importOriginal) => ({ + ...(await importOriginal()), + encodeFunctionData: vi.fn().mockReturnValue("0xdata"), + encodeAbiParameters: vi.fn().mockReturnValue("0xparams"), +})); + +vi.mock("../rp/utils", () => ({ + estimateProfit: vi.fn().mockReturnValue(123n), +})); + +vi.mock("../../../task", () => ({ + parseRainlang: vi.fn().mockResolvedValue("0xbytecode"), + getBountyEnsureRainlang: vi.fn().mockResolvedValue("rainlang"), +})); + +vi.mock("../dryrun", () => ({ + dryrun: vi.fn(), +})); + +function makeOrderDetails(ratio = 1n * ONE18): Pair { + return { + orderbook: "0xorderbook", + sellTokenDecimals: 18, + buyTokenDecimals: 18, + takeOrder: { struct: {}, quote: { ratio } }, + } as Pair; +} + +describe("Test trySimulateTrade", () => { + let solver: RainSolver; + let args: SimulateBalancerTradeArgs; + + beforeEach(() => { + vi.clearAllMocks(); + solver = { + state: { + gasPrice: 1n, + dataFetcher: { + getCurrentPoolCodeMap: vi.fn().mockReturnValue("mockPcMap"), + }, + chainConfig: { + id: 1, + isSpecialL2: false, + routeProcessors: { "4": "0xprocessor" }, + }, + dispair: { + interpreter: "0xint", + store: "0xstore", + }, + client: {}, + balancerRouter: { + routerAddress: "0xbalancerRouter", + getMarketPrice: vi.fn(), + visualizeRoute: vi.fn().mockReturnValue(["visualRoute"]), + }, + }, + appOptions: { + arbAddress: "0xarb", + balancerArbAddress: "0xbalancerArb", + gasCoveragePercentage: "0", + maxRatio: false, + route: undefined, + gasLimitMultiplier: 120, + }, + } as any; + args = { + orderDetails: makeOrderDetails(), + signer: { account: { address: "0xsigner" } }, + ethPrice: "1", + toToken: { address: "0xTo", decimals: 18, symbol: "TO" }, + fromToken: { address: "0xFrom", decimals: 18, symbol: "FROM" }, + maximumInputFixed: 10n * ONE18, + blockNumber: 123n, + isPartial: false, + } as any; + }); + + it("should return NoRoute if Router.findBestRoute returns NoWay", async () => { + (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + Result.err( + new BalancerRouterError( + "Failed to fetch balancer routes", + BalancerRouterErrorType.NoRouteFound, + ), + ), + ); + + const result: SimulationResult = await trySimulateTrade.call(solver, args); + + assert(result.isErr()); + expect(result.error).toHaveProperty("spanAttributes"); + expect(result.error).toHaveProperty("reason"); + expect(result.error.reason).toBe(BalancerRouterSimulationHaltReason.NoRoute); + expect(result.error.spanAttributes.route).toBe("no-way"); + expect(result.error.type).toBe("balancer"); + }); + + it("should return OrderRatioGreaterThanMarketPrice if price < order ratio", async () => { + (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + Result.ok({ + route: [], + amountOut: 1n * ONE18, + price: 1n * ONE18, + }), + ); + // Set order ratio higher than price + args.orderDetails = makeOrderDetails(2n * ONE18); + + const result: SimulationResult = await trySimulateTrade.call(solver, args); + + assert(result.isErr()); + expect(result.error).toHaveProperty("spanAttributes"); + expect(result.error).toHaveProperty("reason"); + expect(result.error.reason).toBe( + BalancerRouterSimulationHaltReason.OrderRatioGreaterThanMarketPrice, + ); + expect(result.error.spanAttributes.error).toBe("Order's ratio greater than market price"); + expect(Array.isArray(result.error.spanAttributes.route)).toBe(true); + expect(result.error.type).toBe("balancer"); + }); + + it("should return NoOpportunity if initial dryrun fails", async () => { + (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + Result.ok({ + route: [], + amountOut: 20n * ONE18, + price: 20n * ONE18, + }), + ); + (dryrun as Mock).mockResolvedValueOnce( + Result.err({ + spanAttributes: { stage: 1 }, + reason: BalancerRouterSimulationHaltReason.NoOpportunity, + }), + ); + args.orderDetails = makeOrderDetails(1n * ONE18); + + const result: SimulationResult = await trySimulateTrade.call(solver, args); + + assert(result.isErr()); + expect(result.error).toHaveProperty("spanAttributes"); + expect(result.error).toHaveProperty("reason"); + expect(result.error.reason).toBe(BalancerRouterSimulationHaltReason.NoOpportunity); + expect(result.error.spanAttributes.stage).toBe(1); + expect(result.error.spanAttributes.oppBlockNumber).toBe(123); + expect(result.error.type).toBe("balancer"); + }); + + it("should return ok result if all steps succeed with gasCoveragePercentage 0", async () => { + (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + Result.ok({ + route: ["route"], + amountOut: 20n * ONE18, + price: 2n * ONE18, + }), + ); + (dryrun as Mock).mockResolvedValueOnce( + Result.ok({ + estimation: { gas: 100n, totalGasCost: 200n, gasPrice: 1n }, + estimatedGasCost: 200n, + spanAttributes: {}, + }), + ); + args.orderDetails = makeOrderDetails(1n * ONE18); + solver.appOptions.gasCoveragePercentage = "0"; + + const result: SimulationResult = await trySimulateTrade.call(solver, args); + + assert(result.isOk()); + expect(result.value).toHaveProperty("spanAttributes"); + expect(result.value).toHaveProperty("rawtx"); + expect(result.value).toHaveProperty("estimatedGasCost"); + expect(result.value).toHaveProperty("oppBlockNumber"); + expect(result.value).toHaveProperty("estimatedProfit"); + expect(result.value.estimatedProfit).toBe(123n); + expect(result.value.oppBlockNumber).toBe(Number(args.blockNumber)); + expect(result.value.spanAttributes.foundOpp).toBe(true); + expect(result.value.estimatedGasCost).toBe(200n); + expect(result.value.rawtx).toHaveProperty("data", "0xdata"); + expect(result.value.rawtx).toHaveProperty("to", "0xbalancerArb"); + expect(result.value.rawtx).toHaveProperty("gasPrice", 1n); + expect(result.value.type).toBe("balancer"); + + // Assert encodeFunctionData was called correctly + expect(encodeFunctionData).toHaveBeenCalledWith({ + abi: expect.any(Array), // ArbAbi + functionName: "arb3", + args: [ + "0xorderbook", + { + data: "0xparams", + maximumIORatio: 2000000000000000000n, + maximumInput: maxUint256, + minimumInput: 1n, + orders: [{}], + }, + { + evaluable: { + bytecode: "0x", + interpreter: "0xint", + store: "0xstore", + }, + signedContext: [], + }, + ], + }); + + // Assert encodeAbiParameters was called correctly + expect(encodeAbiParameters).toHaveBeenCalledWith( + [{ type: "address" }, ABI.BalancerBatchRouter.Structs.SwapPathExactAmountIn], + ["0xbalancerRouter", "route"], + ); + }); + + it("should return ok result if all steps succeed with gasCoveragePercentage not 0", async () => { + (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + Result.ok({ + route: [], + amountOut: 20n * ONE18, + price: 20n * ONE18, + }), + ); + (dryrun as Mock) + .mockResolvedValueOnce( + Result.ok({ + estimation: { gas: 100n, totalGasCost: 200n, gasPrice: 1n }, + estimatedGasCost: 200n, + spanAttributes: { initial: "data" }, + }), + ) + .mockResolvedValueOnce( + Result.ok({ + estimation: { gas: 150n, totalGasCost: 300n, gasPrice: 1n }, + estimatedGasCost: 300n, + spanAttributes: { final: "data" }, + }), + ); + args.orderDetails = makeOrderDetails(1n * ONE18); + solver.appOptions.gasCoveragePercentage = "100"; + + const result: SimulationResult = await trySimulateTrade.call(solver, args); + + assert(result.isOk()); + expect(result.value).toHaveProperty("spanAttributes"); + expect(result.value).toHaveProperty("rawtx"); + expect(result.value).toHaveProperty("estimatedGasCost"); + expect(result.value).toHaveProperty("oppBlockNumber"); + expect(result.value).toHaveProperty("estimatedProfit"); + expect(result.value.estimatedProfit).toBe(123n); + expect(result.value.oppBlockNumber).toBe(Number(args.blockNumber)); + expect(result.value.spanAttributes.foundOpp).toBe(true); + expect(result.value.estimatedGasCost).toBe(300n); + expect(result.value.spanAttributes.initial).toBe("data"); + expect(result.value.spanAttributes.final).toBe("data"); + expect(result.value.rawtx).toHaveProperty("data", "0xdata"); + expect(result.value.rawtx).toHaveProperty("to", "0xbalancerArb"); + expect(result.value.rawtx).toHaveProperty("gasPrice", 1n); + expect(result.value.type).toBe("balancer"); + + // verify called times + expect(encodeFunctionData).toHaveBeenCalledTimes(3); + expect(encodeAbiParameters).toHaveBeenCalledTimes(1); + }); + + it("should return NoOpportunity if final dryrun fails when gasCoveragePercentage is not 0", async () => { + (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + Result.ok({ + route: [], + amountOut: 20n * ONE18, + price: 20n * ONE18, + }), + ); + (dryrun as Mock) + .mockResolvedValueOnce( + Result.ok({ + estimation: { gas: 100n, totalGasCost: 200n, gasPrice: 1n }, + estimatedGasCost: 200n, + spanAttributes: {}, + }), + ) + .mockResolvedValueOnce( + Result.err({ + spanAttributes: { stage: 2 }, + reason: BalancerRouterSimulationHaltReason.NoOpportunity, + }), + ); + args.orderDetails = makeOrderDetails(1n * ONE18); + solver.appOptions.gasCoveragePercentage = "100"; + + const result: SimulationResult = await trySimulateTrade.call(solver, args); + + assert(result.isErr()); + expect(result.error).toHaveProperty("spanAttributes"); + expect(result.error).toHaveProperty("reason"); + expect(result.error.reason).toBe(BalancerRouterSimulationHaltReason.NoOpportunity); + expect(result.error.spanAttributes.stage).toBe(2); + expect(result.error.type).toBe("balancer"); + + // verify encodeFunctionData was called twice (for both dryruns) + expect(encodeFunctionData).toHaveBeenCalledTimes(2); + expect(encodeAbiParameters).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/core/modes/balancer/simulate.ts b/src/core/modes/balancer/simulate.ts index cddd6660..db74f2f5 100644 --- a/src/core/modes/balancer/simulate.ts +++ b/src/core/modes/balancer/simulate.ts @@ -2,28 +2,28 @@ import { dryrun } from "../dryrun"; import { RainSolver } from "../.."; import { Pair } from "../../../order"; import { Token } from "sushi/currency"; -// import { ChainId, Router } from "sushi"; -import { Attributes } from "@opentelemetry/api"; +import { scaleFrom18 } from "../../../math"; +import { estimateProfit } from "../rp/utils"; import { Result, ABI } from "../../../common"; +import { Attributes } from "@opentelemetry/api"; import { extendObjectWithHeader } from "../../../logger"; -import { ONE18, scaleTo18, scaleFrom18 } from "../../../math"; -// import { RPoolFilter, visualizeRoute } from "../../../router"; import { RainSolverSigner, RawTransaction } from "../../../signer"; +import { BalancerRouter, BalancerRouterErrorType } from "../../../router/balancer"; import { getBountyEnsureRainlang, parseRainlang } from "../../../task"; import { TakeOrdersConfigType, SimulationResult, TradeType, FailedSimulation } from "../../types"; import { encodeAbiParameters, encodeFunctionData, formatUnits, maxUint256, parseUnits } from "viem"; -import { getBalancerMarketPrice, getBestBalancerRoute } from "../../../router/balancer"; -import { AddressProvider } from "@balancer/sdk"; -/** Specifies the reason that route processor simulation failed */ +/** Specifies the reason that balancer trade simulation failed */ export enum BalancerRouterSimulationHaltReason { NoOpportunity = 1, NoRoute = 2, OrderRatioGreaterThanMarketPrice = 3, + FetchFailed = 4, + SwapQueryFailed = 5, } -/** Arguments for simulating route processor trade */ -export type SimulateRouteProcessorTradeArgs = { +/** Arguments for simulating balancer protocol trade */ +export type SimulateBalancerTradeArgs = { /** The bundled order details including tokens, decimals, and take orders */ orderDetails: Pair; /** The RainSolverSigner instance used for signing transactions */ @@ -41,13 +41,13 @@ export type SimulateRouteProcessorTradeArgs = { }; /** - * Attempts to find a profitable opportunity (opp) for a given order by simulating a trade against route processor. + * Attempts to find a profitable opportunity (opp) for a given order by simulating a trade against balancer protocol. * @param this - The RainSolver instance context * @param args - The arguments for simulating the trade */ export async function trySimulateTrade( this: RainSolver, - args: SimulateRouteProcessorTradeArgs, + args: SimulateBalancerTradeArgs, ): Promise { const { orderDetails, signer, ethPrice, toToken, fromToken, maximumInputFixed, blockNumber } = args; @@ -57,64 +57,58 @@ export async function trySimulateTrade( const maximumInput = scaleFrom18(maximumInputFixed, orderDetails.sellTokenDecimals); spanAttributes["amountIn"] = formatUnits(maximumInputFixed, 18); - const route = await getBestBalancerRoute.call(this.state, { - tokenIn: fromToken, - tokenOut: toToken, - swapAmount: maximumInput, - }); - // const route = Result.ok([ - // { - // steps: [ - // { - // pool: "0x88c044fb203b58b12252be7242926b1eeb113b4a", - // tokenOut: "0x4200000000000000000000000000000000000006", - // isBuffer: false, - // }, - // ], - // tokenIn: fromToken.address as `0x${string}`, - // exactAmountIn: maximumInput, - // minAmountOut: 0n, - // }, - // ]); - if (route.isErr()) { - spanAttributes["error"] = route.error.message; - return Result.err({ - type: TradeType.Balancer, - spanAttributes, - reason: BalancerRouterSimulationHaltReason.NoRoute, - }); - } + const routeResult = await this.state.balancerRouter!.getMarketPrice( + { + tokenIn: fromToken, + tokenOut: toToken, + swapAmount: maximumInput, + }, + signer, + ); + if (routeResult.isErr()) { + spanAttributes["error"] = routeResult.error.message; + + let reason = BalancerRouterSimulationHaltReason.NoOpportunity; + if (routeResult.error.type === BalancerRouterErrorType.NoRouteFound) { + spanAttributes["route"] = "no-way"; + reason = BalancerRouterSimulationHaltReason.NoRoute; + } else if (routeResult.error.type === BalancerRouterErrorType.FetchFailed) { + reason = BalancerRouterSimulationHaltReason.FetchFailed; + } else if (routeResult.error.type === BalancerRouterErrorType.SwapQueryFailed) { + reason = BalancerRouterSimulationHaltReason.SwapQueryFailed; + } else { + reason = BalancerRouterSimulationHaltReason.NoOpportunity; + } - const amountOut = await getBalancerMarketPrice.call(this.state, route.value, signer); - if (amountOut.isErr()) { - spanAttributes["error"] = amountOut.error.message; return Result.err({ type: TradeType.Balancer, spanAttributes, - reason: BalancerRouterSimulationHaltReason.NoRoute, + reason, }); } - const rateFixed = scaleTo18(amountOut.value, orderDetails.buyTokenDecimals); - const price = (rateFixed * ONE18) / maximumInputFixed; - spanAttributes["amountOut"] = formatUnits(amountOut.value, toToken.decimals); + const route = routeResult.value; + const amountOut = route.amountOut; + const price = route.price; + + spanAttributes["amountOut"] = formatUnits(amountOut, toToken.decimals); spanAttributes["marketPrice"] = formatUnits(price, 18); - // const routeVisual: string[] = []; - // try { - // visualizeRoute(fromToken, toToken, route.legs).forEach((v) => { - // routeVisual.push(v); - // }); - // } catch { - // /**/ - // } - // spanAttributes["route"] = routeVisual; + const routeVisual: string[] = []; + try { + BalancerRouter.visualizeRoute(route.route, this.state.watchedTokens).forEach((v) => { + routeVisual.push(v); + }); + } catch { + /**/ + } + spanAttributes["route"] = routeVisual; // exit early if market price is lower than order quote ratio if (price < orderDetails.takeOrder.quote!.ratio) { spanAttributes["error"] = "Order's ratio greater than market price"; const result = { - type: TradeType.RouteProcessor, + type: TradeType.Balancer, spanAttributes, reason: BalancerRouterSimulationHaltReason.OrderRatioGreaterThanMarketPrice, }; @@ -123,7 +117,7 @@ export async function trySimulateTrade( spanAttributes["oppBlockNumber"] = Number(blockNumber); - const balancerRouter = AddressProvider.BatchRouter(this.state.chainConfig.id); + const balancerRouter = this.state.balancerRouter!.routerAddress; const orders = [orderDetails.takeOrder.struct]; const takeOrdersConfigStruct: TakeOrdersConfigType = { minimumInput: 1n, @@ -132,9 +126,10 @@ export async function trySimulateTrade( orders, data: encodeAbiParameters( [{ type: "address" }, ABI.BalancerBatchRouter.Structs.SwapPathExactAmountIn], - [balancerRouter, route.value], + [balancerRouter, route.route[0]], ), }; + const task = { evaluable: { interpreter: this.state.dispair.interpreter as `0x${string}`, @@ -160,7 +155,7 @@ export async function trySimulateTrade( functionName: "arb3", args: [orderDetails.orderbook as `0x${string}`, takeOrdersConfigStruct, task], }), - to: this.appOptions.arbAddress as `0x${string}`, + to: this.appOptions.balancerArbAddress as `0x${string}`, gasPrice, }; @@ -176,7 +171,7 @@ export async function trySimulateTrade( spanAttributes["stage"] = 1; Object.assign(initDryrunResult.error.spanAttributes, spanAttributes); initDryrunResult.error.reason = BalancerRouterSimulationHaltReason.NoOpportunity; - (initDryrunResult.error as FailedSimulation).type = TradeType.RouteProcessor; + (initDryrunResult.error as FailedSimulation).type = TradeType.Balancer; return Result.err(initDryrunResult.error as FailedSimulation); } @@ -234,7 +229,7 @@ export async function trySimulateTrade( spanAttributes["stage"] = 2; Object.assign(finalDryrunResult.error.spanAttributes, spanAttributes); finalDryrunResult.error.reason = BalancerRouterSimulationHaltReason.NoOpportunity; - (finalDryrunResult.error as FailedSimulation).type = TradeType.RouteProcessor; + (finalDryrunResult.error as FailedSimulation).type = TradeType.Balancer; return Result.err(finalDryrunResult.error as FailedSimulation); } @@ -281,7 +276,7 @@ export async function trySimulateTrade( // if reached here, it means there was a success and found opp spanAttributes["foundOpp"] = true; const result = { - type: TradeType.RouteProcessor, + type: TradeType.Balancer, spanAttributes, rawtx, estimatedGasCost, @@ -295,16 +290,3 @@ export async function trySimulateTrade( }; return Result.ok(result); } - -/** Estimates profit for a route processor clear mode */ -export function estimateProfit( - orderDetails: Pair, - ethPrice: bigint, - marketPrice: bigint, - maxInput: bigint, -): bigint { - const marketAmountOut = (maxInput * marketPrice) / ONE18; - const orderInput = (maxInput * orderDetails.takeOrder.quote!.ratio) / ONE18; - const estimatedProfit = marketAmountOut - orderInput; - return (estimatedProfit * ethPrice) / ONE18; -} diff --git a/src/core/modes/index.test.ts b/src/core/modes/index.test.ts index 1083e9ac..54fa3342 100644 --- a/src/core/modes/index.test.ts +++ b/src/core/modes/index.test.ts @@ -1,5 +1,7 @@ +import { RainSolver } from ".."; import { Result } from "../../common"; import { findBestTrade } from "./index"; +import { findBestBalancerTrade } from "./balancer"; import { findBestRouteProcessorTrade } from "./rp"; import { findBestIntraOrderbookTrade } from "./intra"; import { findBestInterOrderbookTrade } from "./inter"; @@ -17,8 +19,12 @@ vi.mock("./inter", () => ({ findBestInterOrderbookTrade: vi.fn(), })); +vi.mock("./balancer", () => ({ + findBestBalancerTrade: vi.fn(), +})); + describe("Test findBestTrade", () => { - let mockRainSolver: any; + let mockRainSolver: RainSolver; let args: any; beforeEach(() => { @@ -28,7 +34,8 @@ describe("Test findBestTrade", () => { appOptions: { rpOnly: false, }, - }; + state: {}, + } as any; args = { orderDetails: { @@ -168,6 +175,73 @@ describe("Test findBestTrade", () => { expect(findBestInterOrderbookTrade).not.toHaveBeenCalled(); }); + it("should only call balancer router when balancerRouter is available", async () => { + const mocksolver = structuredClone(mockRainSolver); + (mocksolver.state as any).balancerRouter = {}; + + const rpResult = Result.ok({ + type: "routeProcessor", + spanAttributes: { foundOpp: true }, + estimatedProfit: 100n, + oppBlockNumber: 123, + }); + const intraResult = Result.ok({ + type: "intraOrderbook", + spanAttributes: { foundOpp: true }, + estimatedProfit: 150n, + oppBlockNumber: 123, + }); + const interResult = Result.ok({ + type: "interOrderbook", + spanAttributes: { foundOpp: true }, + estimatedProfit: 120n, + oppBlockNumber: 123, + }); + const balancerResult = Result.ok({ + type: "balancer", + spanAttributes: { foundOpp: true }, + estimatedProfit: 120n, + oppBlockNumber: 123, + }); + + (findBestRouteProcessorTrade as Mock).mockResolvedValue(rpResult); + (findBestIntraOrderbookTrade as Mock).mockResolvedValue(intraResult); + (findBestInterOrderbookTrade as Mock).mockResolvedValue(interResult); + (findBestBalancerTrade as Mock).mockResolvedValue(balancerResult); + + const result = await findBestTrade.call(mocksolver, args); + + assert(result.isOk()); + expect(result.value.estimatedProfit).toBe(150n); // highest profit + expect(result.value.type).toBe("intraOrderbook"); + expect(findBestRouteProcessorTrade).toHaveBeenCalledWith( + args.orderDetails, + args.signer, + args.inputToEthPrice, + args.toToken, + args.fromToken, + ); + expect(findBestIntraOrderbookTrade).toHaveBeenCalledWith( + args.orderDetails, + args.signer, + args.inputToEthPrice, + args.outputToEthPrice, + ); + expect(findBestInterOrderbookTrade).toHaveBeenCalledWith( + args.orderDetails, + args.signer, + args.inputToEthPrice, + args.outputToEthPrice, + ); + expect(findBestBalancerTrade).toHaveBeenCalledWith( + args.orderDetails, + args.signer, + args.inputToEthPrice, + args.toToken, + args.fromToken, + ); + }); + it("should call all modes when rpOnly is false", async () => { mockRainSolver.appOptions.rpOnly = false; diff --git a/src/core/modes/index.ts b/src/core/modes/index.ts index eebccb46..12a234a4 100644 --- a/src/core/modes/index.ts +++ b/src/core/modes/index.ts @@ -6,9 +6,9 @@ import { Token } from "sushi/currency"; import { FindBestTradeResult } from "../types"; import { RainSolverSigner } from "../../signer"; import { Attributes } from "@opentelemetry/api"; -// import { findBestRouteProcessorTrade } from "./rp"; -// import { findBestIntraOrderbookTrade } from "./intra"; -// import { findBestInterOrderbookTrade } from "./inter"; +import { findBestRouteProcessorTrade } from "./rp"; +import { findBestIntraOrderbookTrade } from "./intra"; +import { findBestInterOrderbookTrade } from "./inter"; import { extendObjectWithHeader } from "../../logger"; import { findBestBalancerTrade } from "./balancer"; @@ -43,36 +43,48 @@ export async function findBestTrade( this: RainSolver, args: FindBestTradeArgs, ): Promise { - const { orderDetails, signer, inputToEthPrice, toToken, fromToken } = args; + const { orderDetails, signer, inputToEthPrice, outputToEthPrice, toToken, fromToken } = args; const promises = [ - // findBestRouteProcessorTrade.call( - // this, - // orderDetails, - // signer, - // inputToEthPrice, - // toToken, - // fromToken, - // ), - findBestBalancerTrade.call(this, orderDetails, signer, inputToEthPrice, toToken, fromToken), + findBestRouteProcessorTrade.call( + this, + orderDetails, + signer, + inputToEthPrice, + toToken, + fromToken, + ), + // include balancer trade only if balancer router is available for the operating chain + ...(this.state.balancerRouter + ? [ + findBestBalancerTrade.call( + this, + orderDetails, + signer, + inputToEthPrice, + toToken, + fromToken, + ), + ] + : []), // include intra and inter orderbook trades types only if rpOnly is false - // ...(!this.appOptions.rpOnly - // ? [ - // findBestIntraOrderbookTrade.call( - // this, - // orderDetails, - // signer, - // inputToEthPrice, - // outputToEthPrice, - // ), - // findBestInterOrderbookTrade.call( - // this, - // orderDetails, - // signer, - // inputToEthPrice, - // outputToEthPrice, - // ), - // ] - // : []), + ...(!this.appOptions.rpOnly + ? [ + findBestIntraOrderbookTrade.call( + this, + orderDetails, + signer, + inputToEthPrice, + outputToEthPrice, + ), + findBestInterOrderbookTrade.call( + this, + orderDetails, + signer, + inputToEthPrice, + outputToEthPrice, + ), + ] + : []), ]; const results = await Promise.all(promises); diff --git a/src/core/modes/rp/simulate.test.ts b/src/core/modes/rp/simulate.test.ts index 801e99af..8f987fbd 100644 --- a/src/core/modes/rp/simulate.test.ts +++ b/src/core/modes/rp/simulate.test.ts @@ -433,82 +433,3 @@ describe("Test findLargestTradeSize", () => { expect(result).toBeGreaterThan(0n); }); }); - -describe("Test findLargestTradeSize", () => { - let solver: RainSolver; - let fromToken: Token; - let toToken: Token; - let maximumInputFixed: bigint; - - beforeEach(() => { - vi.clearAllMocks(); - solver = { - state: { - gasPrice: 1n, - dataFetcher: { - getCurrentPoolCodeMap: vi.fn().mockReturnValue("mockPcMap"), - }, - chainConfig: { - id: 1, - }, - }, - appOptions: { - route: undefined, - }, - } as any; - fromToken = { address: "0xFrom", decimals: 18 } as any; - toToken = { address: "0xTo", decimals: 18 } as any; - maximumInputFixed = 10n * ONE18; - }); - - it("should return undefined if no valid trade size found (all NoWay)", () => { - (Router.findBestRoute as Mock).mockReturnValue({ status: "NoWay" }); - - const result: bigint | undefined = findLargestTradeSize.call( - solver, - makeOrderDetails(1n * ONE18), - toToken, - fromToken, - maximumInputFixed, - ); - - expect(result).toBeUndefined(); - }); - - it("should return the largest valid trade size when some routes are valid", () => { - (Router.findBestRoute as Mock).mockImplementation(() => { - return { status: "OK", amountOutBI: 4n * ONE18 }; - }); - - const orderDetails = makeOrderDetails(1n * ONE18); - - const result: bigint | undefined = findLargestTradeSize.call( - solver, - orderDetails, - toToken, - fromToken, - maximumInputFixed, - ); - - expect(typeof result).toBe("bigint"); - expect(result).toBe(3999999761581420898n); - }); - - it("should return undefined if all OK routes have price < ratio", () => { - (Router.findBestRoute as Mock).mockImplementation(() => ({ - status: "OK", - amountOutBI: 1n, // price = 1 - })); - const orderDetails = makeOrderDetails(2n * ONE18); // ratio = 2 - - const result: bigint | undefined = findLargestTradeSize.call( - solver, - orderDetails, - toToken, - fromToken, - maximumInputFixed, - ); - - expect(result).toBeUndefined(); - }); -}); diff --git a/src/error/common.ts b/src/error/common.ts index 543d153c..e9660d97 100644 --- a/src/error/common.ts +++ b/src/error/common.ts @@ -44,7 +44,14 @@ export async function errorSnapshot( if (err.details) message.push(`Details: ${err.details}`); if (typeof org.code === "number") message.push(`RPC Error Code: ${org.code}`); if (typeof org.message === "string") message.push(`RPC Error Msg: ${org.message}`); - if (message.some((v) => v.includes("unknown reason") || v.includes("execution reverted"))) { + if ( + message.some( + (v) => + v.includes("unknown reason") || + v.includes("execution reverted") || + v.includes("custom error"), + ) + ) { const { raw, decoded } = await parseRevertError(err); if (decoded) { message.push("Error Name: " + decoded.name); diff --git a/src/error/decoder.ts b/src/error/decoder.ts index f05806df..6d881661 100644 --- a/src/error/decoder.ts +++ b/src/error/decoder.ts @@ -1,7 +1,14 @@ import axios from "axios"; import assert from "assert"; import { Result } from "../common"; -import { decodeErrorResult, isHex, parseAbiItem } from "viem"; +import { balancerBatchRouterAbiExtended } from "@balancer/sdk"; +import { + isHex, + parseAbiItem, + decodeErrorResult, + toFunctionSelector, + toFunctionSignature, +} from "viem"; import { PANIC_ABI, PANIC_SELECTOR, @@ -14,6 +21,13 @@ import { /** Selector abi/sig cache at runtime */ export const SelectorCache = new Map(); +// set balancer error signatures in the cache as they are not available in the registry +balancerBatchRouterAbiExtended.forEach((abi: any) => { + if (abi.type !== "error") return; + const minimalSig = toFunctionSignature(abi).replace("error ", ""); + SelectorCache.set(toFunctionSelector(minimalSig), [minimalSig]); +}); + /** * Tries to decode the given error data by running through known matching signatures * @param data - the error data diff --git a/src/router/balancer.test.ts b/src/router/balancer.test.ts new file mode 100644 index 00000000..21c3846c --- /dev/null +++ b/src/router/balancer.test.ts @@ -0,0 +1,1003 @@ +import { Token } from "sushi/currency"; +import { TokenDetails } from "../state"; +import { describe, it, expect, vi, beforeEach, Mock, assert } from "vitest"; +import { + BalancerRouter, + BalancerRouterPath, + BalancerRouterError, + BalancerRouterErrorType, +} from "./balancer"; + +vi.mock("@balancer/sdk", async (importOriginal) => { + return { + ...(await importOriginal()), + BalancerApi: vi.fn().mockImplementation(() => ({ + sorSwapPaths: { + fetchSorSwapPaths: vi.fn(), + }, + })), + }; +}); + +describe("test BalancerRouter", () => { + describe("test init method", () => { + it("should successfully initialize BalancerRouter for supported chain", () => { + const chainId = 1; // Ethereum mainnet - supported by Balancer v3 + + const result = BalancerRouter.init(chainId); + + assert(result.isOk()); + if (result.isOk()) { + const router = result.value; + expect(router).toBeInstanceOf(BalancerRouter); + expect(router.chainId).toBe(chainId); + expect(router.protocolVersion).toBe(3); + expect(router.routeTime).toBe(60_000); + expect(router.routerAddress).toBeDefined(); + expect(router.balancerApi).toBeDefined(); + expect(router.cache).toBeInstanceOf(Map); + expect(router.cache.size).toBe(0); + } + }); + + it("should return error for unsupported chain", () => { + const unsupportedChainId = 999999; // Non-existent chain + + const result = BalancerRouter.init(unsupportedChainId); + + assert(result.isErr()); + if (result.isErr()) { + const error = result.error; + expect(error).toBeInstanceOf(BalancerRouterError); + expect(error.type).toBe(BalancerRouterErrorType.UnsupportedChain); + expect(error.message).toBe( + `Balancer router does not support chain with id: ${unsupportedChainId}`, + ); + expect(error.name).toBe("BalancerRouterError"); + } + }); + }); + + describe("test fetchSortedRoutes method", () => { + let router: BalancerRouter; + let mockBalancerApi: { sorSwapPaths: { fetchSorSwapPaths: Mock } }; + + const mockTokenIn: TokenDetails = { + address: "0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 18, + symbol: "WETH", + }; + + const mockTokenOut: TokenDetails = { + address: "0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 6, + symbol: "USDC", + }; + + const mockSwapAmount = 1000000000000000000n; // 1 WETH + + beforeEach(() => { + const routerResult = BalancerRouter.init(1); // Ethereum mainnet + if (routerResult.isOk()) { + router = routerResult.value; + mockBalancerApi = (router as any).balancerApi; + } + }); + + it("should successfully fetch sorted routes", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, // 3000 USDC + isBuffer: [false], + }, + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: "0xintermediatetoken", decimals: 6 }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool2", "0xpool3"], + inputAmountRaw: mockSwapAmount / 2n, + outputAmountRaw: 1500000000n, // 1500 USDC + isBuffer: [false, false], + }, + ]; + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + + const result = await router.fetchSortedRoutes({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(result.isOk()); + const routes = result.value; + expect(routes).toHaveLength(2); + + // check first route + expect(routes[0].tokenIn).toBe(mockTokenIn.address); + expect(routes[0].steps).toHaveLength(1); + expect(routes[0].steps[0].pool).toBe("0xpool1"); + expect(routes[0].steps[0].tokenOut).toBe(mockTokenOut.address); + expect(routes[0].steps[0].isBuffer).toBe(false); + + // check second route (multi-hop) + expect(routes[1].tokenIn).toBe(mockTokenIn.address); + expect(routes[1].steps).toHaveLength(2); + expect(routes[1].steps[0].pool).toBe("0xpool2"); + expect(routes[1].steps[0].tokenOut).toBe("0xintermediatetoken"); + expect(routes[1].steps[1].pool).toBe("0xpool3"); + expect(routes[1].steps[1].tokenOut).toBe(mockTokenOut.address); + + expect(mockBalancerApi.sorSwapPaths.fetchSorSwapPaths).toHaveBeenCalledWith({ + chainId: 1, + tokenIn: mockTokenIn.address.toLowerCase(), + tokenOut: mockTokenOut.address.toLowerCase(), + swapKind: 0, // SwapKind.GivenIn + swapAmount: expect.any(Object), // TokenAmount instance + useProtocolVersion: 3, + }); + }); + + it("should return NoRouteFound error when no routes available", async () => { + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue([]); + + const result = await router.fetchSortedRoutes({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(result.isErr()); + const error = result.error; + expect(error).toBeInstanceOf(BalancerRouterError); + expect(error.type).toBe(BalancerRouterErrorType.NoRouteFound); + expect(error.message).toBe("Found no balancer route for given token pair"); + }); + + it("should return FetchFailed error when API call throws", async () => { + const mockError = new Error("Network error"); + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockRejectedValue(mockError); + + const result = await router.fetchSortedRoutes({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(result.isErr()); + const error = result.error; + expect(error).toBeInstanceOf(BalancerRouterError); + expect(error.type).toBe(BalancerRouterErrorType.FetchFailed); + expect(error.message).toBe("Failed to fetch balancer routes"); + expect(error.cause).toBe(mockError); + }); + + it("should handle tokens without symbols", async () => { + const tokenWithoutSymbol = new Token({ + address: "0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 18, + chainId: 1, + // no symbol property + }); + + const mockSorPaths = [ + { + tokens: [ + { + address: tokenWithoutSymbol.address, + decimals: tokenWithoutSymbol.decimals, + }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, + isBuffer: [false], + }, + ]; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + + const result = await router.fetchSortedRoutes({ + tokenIn: tokenWithoutSymbol, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(result.isOk()); + expect(result.value).toHaveLength(1); + + // verify that the Token constructor was called with "unknownSymbol" + expect(mockBalancerApi.sorSwapPaths.fetchSorSwapPaths).toHaveBeenCalledWith( + expect.objectContaining({ + tokenIn: tokenWithoutSymbol.address.toLowerCase(), + tokenOut: mockTokenOut.address.toLowerCase(), + }), + ); + }); + + it("should handle buffer pools correctly", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: "0xbufferedtoken", decimals: 6 }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xbufferpool", "0xregularpool"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, + isBuffer: [true, false], // First pool is buffer + }, + ]; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + + const result = await router.fetchSortedRoutes({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(result.isOk()); + const routes = result.value; + expect(routes[0].steps).toHaveLength(2); + expect(routes[0].steps[0].isBuffer).toBe(true); + expect(routes[0].steps[1].isBuffer).toBe(false); + }); + }); + + describe("test getBestRoute method", () => { + let router: BalancerRouter; + let mockBalancerApi: { sorSwapPaths: { fetchSorSwapPaths: Mock } }; + + const mockTokenIn: TokenDetails = { + address: "0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 18, + symbol: "WETH", + }; + + const mockTokenOut: TokenDetails = { + address: "0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 6, + symbol: "USDC", + }; + + const mockSwapAmount = 1000000000000000000n; // 1 WETH + + beforeEach(() => { + const routerResult = BalancerRouter.init(1); // Ethereum mainnet + if (routerResult.isOk()) { + router = routerResult.value; + router.cache.clear(); // clear cache before each test + mockBalancerApi = (router as any).balancerApi; + } + }); + + it("should successfully get best route and cache it", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, // 3000 USDC + isBuffer: [false], + }, + ]; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + + const result = await router.getBestRoute({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(result.isOk()); + const cachedRoute = result.value; + expect(cachedRoute.route).toHaveLength(1); + expect(cachedRoute.route[0].tokenIn).toBe(mockTokenIn.address); + expect(cachedRoute.route[0].exactAmountIn).toBe(mockSwapAmount); + expect(cachedRoute.route[0].minAmountOut).toBe(3000000000n); + expect(cachedRoute.route[0].steps).toHaveLength(1); + expect(cachedRoute.route[0].steps[0].pool).toBe("0xpool1"); + expect(cachedRoute.price).toBeGreaterThan(0n); + expect(cachedRoute.validUntil).toBeGreaterThan(Date.now()); + + // verify route was cached + const cacheKey = `${mockTokenIn.address.toLowerCase()}/${mockTokenOut.address.toLowerCase()}`; + expect(router.cache.has(cacheKey)).toBe(true); + expect(router.cache.get(cacheKey)).toEqual(cachedRoute); + }); + + it("should return cached route when available and not expired", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, + isBuffer: [false], + }, + ]; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + + // First call - should fetch from API + const firstResult = await router.getBestRoute({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(firstResult.isOk()); + expect(mockBalancerApi.sorSwapPaths.fetchSorSwapPaths).toHaveBeenCalledTimes(1); + + // Second call - should return from cache + const secondResult = await router.getBestRoute({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(secondResult.isOk()); + expect(mockBalancerApi.sorSwapPaths.fetchSorSwapPaths).toHaveBeenCalledTimes(1); // No additional API call + expect(secondResult.value).toEqual(firstResult.value); + }); + + it("should ignore cache when ignoreCache is true", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, + isBuffer: [false], + }, + ]; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + + // First call + await router.getBestRoute({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + expect(mockBalancerApi.sorSwapPaths.fetchSorSwapPaths).toHaveBeenCalledTimes(1); + + // Second call with ignoreCache: true + await router.getBestRoute({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + ignoreCache: true, + }); + + expect(mockBalancerApi.sorSwapPaths.fetchSorSwapPaths).toHaveBeenCalledTimes(2); // Additional API call + }); + + it("should fetch new route when cache is expired", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, + isBuffer: [false], + }, + ]; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + + // manually add expired cache entry + const cacheKey = `${mockTokenIn.address.toLowerCase()}/${mockTokenOut.address.toLowerCase()}`; + const expiredRoute = { + route: [ + { + tokenIn: mockTokenIn.address as `0x${string}`, + exactAmountIn: mockSwapAmount, + minAmountOut: 2000000000n, + steps: [ + { + pool: "0xoldpool" as `0x${string}`, + tokenOut: mockTokenOut.address as `0x${string}`, + isBuffer: false, + }, + ], + }, + ], + validUntil: Date.now() - 1000, // Expired 1 second ago + price: 2000000000000000000000n, + }; + router.cache.set(cacheKey, expiredRoute); + + const result = await router.getBestRoute({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(result.isOk()); + expect(mockBalancerApi.sorSwapPaths.fetchSorSwapPaths).toHaveBeenCalledTimes(1); + expect(result.value.route[0].minAmountOut).toBe(3000000000n); // New route data + expect(result.value.route[0].steps[0].pool).toBe("0xpool1"); // New pool + }); + + it("should return error when fetchSortedRoutes fails", async () => { + const mockError = new Error("Network error"); + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockRejectedValue(mockError); + + const result = await router.getBestRoute({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(result.isErr()); + const error = result.error; + expect(error).toBeInstanceOf(BalancerRouterError); + expect(error.type).toBe(BalancerRouterErrorType.FetchFailed); + expect(error.cause).toBe(mockError); + }); + + it("should return error when no routes found", async () => { + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue([]); + + const result = await router.getBestRoute({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(result.isErr()); + const error = result.error; + expect(error).toBeInstanceOf(BalancerRouterError); + expect(error.type).toBe(BalancerRouterErrorType.NoRouteFound); + expect(error.message).toBe("Found no balancer route for given token pair"); + }); + + it("should calculate price correctly for multiple routes", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount / 2n, // 0.5 WETH + outputAmountRaw: 1500000000n, // 1500 USDC + isBuffer: [false], + }, + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: "0xintermediatetoken", decimals: 6 }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool2", "0xpool3"], + inputAmountRaw: mockSwapAmount / 2n, // 0.5 WETH + outputAmountRaw: 1600000000n, // 1600 USDC + isBuffer: [false, false], + }, + ]; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + + const result = await router.getBestRoute({ + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }); + + assert(result.isOk()); + const cachedRoute = result.value; + + // Should use the first route only + expect(cachedRoute.route[0].minAmountOut).toBe(3100000000n); // 1500 + 1600 = 3100 USDC total + expect(cachedRoute.route[0].exactAmountIn).toBe(mockSwapAmount); + + // Price should be calculated based on total output + const expectedAmountOut18 = 3100000000000000000000n; // 3100 * 10^18 (scaled to 18 decimals) + const expectedAmountIn18 = 1000000000000000000n; // 1 ETH in 18 decimals + const expectedPrice = (expectedAmountOut18 * 1000000000000000000n) / expectedAmountIn18; + expect(cachedRoute.price).toBe(expectedPrice); + }); + }); + + describe("test getMarketPrice method", () => { + let router: BalancerRouter; + let mockBalancerApi: { sorSwapPaths: { fetchSorSwapPaths: Mock } }; + let mockSigner: any; + + const mockTokenIn: TokenDetails = { + address: "0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 18, + symbol: "WETH", + }; + + const mockTokenOut: TokenDetails = { + address: "0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 6, + symbol: "USDC", + }; + + const mockSwapAmount = 1000000000000000000n; // 1 WETH + + beforeEach(() => { + const routerResult = BalancerRouter.init(1); // Ethereum mainnet + if (routerResult.isOk()) { + router = routerResult.value; + router.cache.clear(); // clear cache before each test + mockBalancerApi = (router as any).balancerApi; + } + + // mock signer + mockSigner = { + account: { + address: "0x1234567890123456789012345678901234567890" as `0x${string}`, + }, + simulateContract: vi.fn(), + }; + }); + + it("should successfully get market price with onchain simulation", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, // 3000 USDC + isBuffer: [false], + }, + ]; + + const mockSimulationResult = { + result: [null, null, [3100000000n]], // querySwapExactIn returns [,,[amountOut]] + }; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + mockSigner.simulateContract.mockResolvedValue(mockSimulationResult); + + const result = await router.getMarketPrice( + { + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }, + mockSigner, + ); + + assert(result.isOk()); + const marketPrice = result.value; + expect(marketPrice.amountOut).toBe(3100000000n); + expect(marketPrice.price).toBeGreaterThan(0n); + expect(marketPrice.route).toHaveLength(1); + expect(marketPrice.route[0].tokenIn).toBe(mockTokenIn.address); + expect(marketPrice.route[0].steps[0].pool).toBe("0xpool1"); + + // verify simulation was called with correct parameters + expect(mockSigner.simulateContract).toHaveBeenCalledWith({ + address: router.routerAddress, + abi: expect.any(Array), + functionName: "querySwapExactIn", + args: [expect.any(Array), mockSigner.account.address, "0x"], + }); + }); + + it("should return cached onchain price when available", async () => { + const onchainPrice = 3200000000000000000000n; + const cachedRoute = { + route: [ + { + tokenIn: mockTokenIn.address as `0x${string}`, + exactAmountIn: mockSwapAmount, + minAmountOut: 3000000000n, + steps: [ + { + pool: "0xpool1" as `0x${string}`, + tokenOut: mockTokenOut.address as `0x${string}`, + isBuffer: false, + }, + ], + }, + ], + validUntil: Date.now() + 60000, + price: 3000000000000000000000n, + onchainPrice, + }; + + // manually add cached route with onchain price + const cacheKey = `${mockTokenIn.address.toLowerCase()}/${mockTokenOut.address.toLowerCase()}`; + router.cache.set(cacheKey, cachedRoute); + + const result = await router.getMarketPrice( + { + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }, + mockSigner, + ); + + assert(result.isOk()); + const marketPrice = result.value; + expect(marketPrice.price).toBe(onchainPrice); + expect(marketPrice.amountOut).toBe(3000000000n); + expect(marketPrice.route).toEqual(cachedRoute.route); + + // Should not call simulateContract when onchainPrice is cached + expect(mockSigner.simulateContract).not.toHaveBeenCalled(); + }); + + it("should use default address when signer has no account", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, + isBuffer: [false], + }, + ]; + + const mockSimulationResult = { + result: [null, null, [3100000000n]], + }; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + mockSigner.simulateContract.mockResolvedValue(mockSimulationResult); + mockSigner.account = undefined; // No account + + const customAddress = "0x9999999999999999999999999999999999999999" as `0x${string}`; + + const result = await router.getMarketPrice( + { + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }, + mockSigner, + customAddress, + ); + + assert(result.isOk()); + expect(mockSigner.simulateContract).toHaveBeenCalledWith({ + address: router.routerAddress, + abi: expect.any(Array), + functionName: "querySwapExactIn", + args: [expect.any(Array), customAddress, "0x"], + }); + }); + + it("should fallback to cached price when simulation fails", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, + isBuffer: [false], + }, + ]; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + mockSigner.simulateContract.mockResolvedValue({ + result: [null, null, []], // Invalid simulation result + }); + + const result = await router.getMarketPrice( + { + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }, + mockSigner, + ); + + assert(result.isOk()); + const marketPrice = result.value; + // Should fallback to cached route price and amount + expect(marketPrice.amountOut).toBe(3000000000n); + expect(marketPrice.price).toBeGreaterThan(0n); + expect(marketPrice.route).toHaveLength(1); + }); + + it("should return error when getBestRoute fails", async () => { + const mockError = new Error("Network error"); + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockRejectedValue(mockError); + + const result = await router.getMarketPrice( + { + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }, + mockSigner, + ); + + assert(result.isErr()); + const error = result.error; + expect(error).toBeInstanceOf(BalancerRouterError); + expect(error.type).toBe(BalancerRouterErrorType.FetchFailed); + expect(error.cause).toBe(mockError); + }); + + it("should return SwapQueryFailed error when simulation throws", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, + isBuffer: [false], + }, + ]; + + const simulationError = new Error("Simulation failed"); + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + mockSigner.simulateContract.mockRejectedValue(simulationError); + + const result = await router.getMarketPrice( + { + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }, + mockSigner, + ); + + assert(result.isErr()); + const error = result.error; + expect(error).toBeInstanceOf(BalancerRouterError); + expect(error.type).toBe(BalancerRouterErrorType.SwapQueryFailed); + expect(error.message).toBe( + "Swap query execution failed for the given route to get market price", + ); + expect(error.cause).toBe(simulationError); + }); + + it("should update cache with onchain price after successful simulation", async () => { + const mockSorPaths = [ + { + tokens: [ + { address: mockTokenIn.address, decimals: mockTokenIn.decimals }, + { address: mockTokenOut.address, decimals: mockTokenOut.decimals }, + ], + pools: ["0xpool1"], + inputAmountRaw: mockSwapAmount, + outputAmountRaw: 3000000000n, + isBuffer: [false], + }, + ]; + + const mockSimulationResult = { + result: [null, null, [3100000000n]], + }; + + mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); + mockSigner.simulateContract.mockResolvedValue(mockSimulationResult); + + const result = await router.getMarketPrice( + { + tokenIn: mockTokenIn, + tokenOut: mockTokenOut, + swapAmount: mockSwapAmount, + }, + mockSigner, + ); + + assert(result.isOk()); + + // verify that onchain price was cached + const cacheKey = `${mockTokenIn.address.toLowerCase()}/${mockTokenOut.address.toLowerCase()}`; + const cachedRoute = router.cache.get(cacheKey); + expect(cachedRoute?.onchainPrice).toBeDefined(); + expect(cachedRoute?.onchainPrice).toBeGreaterThan(0n); + }); + }); + + describe("test visualizeRoute method", () => { + const mockTokenDetails = new Map([ + [ + "0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b", + { + address: "0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 18, + symbol: "WETH", + }, + ], + [ + "0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b", + { + address: "0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 6, + symbol: "USDC", + }, + ], + [ + "0xa2b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b", + { + address: "0xa2b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 18, + symbol: "DAI", + }, + ], + ]); + + it("should visualize multiple routes with correct percentages", () => { + const route: BalancerRouterPath[] = [ + { + tokenIn: "0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + exactAmountIn: 700000000000000000n, // 0.7 WETH (70%) + minAmountOut: 2100000000n, // 2100 USDC + steps: [ + { + pool: "0xpool1" as `0x${string}`, + tokenOut: "0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + isBuffer: false, + }, + ], + }, + { + tokenIn: "0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + exactAmountIn: 300000000000000000n, // 0.3 WETH (30%) + minAmountOut: 900000000n, // 900 USDC + steps: [ + { + pool: "0xpool2" as `0x${string}`, + tokenOut: "0xa2b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, // DAI + isBuffer: true, + }, + { + pool: "0xpool3" as `0x${string}`, + tokenOut: "0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, // USDC + isBuffer: false, + }, + ], + }, + ]; + + const result = BalancerRouter.visualizeRoute(route, mockTokenDetails); + + expect(result).toHaveLength(2); + expect(result[0]).toBe("70.00% ---> USDC/WETH (pool 0xpool1)"); + expect(result[1]).toBe( + "30.00% ---> DAI/WETH (pool 0xpool2) >> USDC/DAI (pool 0xpool3)", + ); + }); + + it("should handle unknown tokens gracefully", () => { + const route: BalancerRouterPath[] = [ + { + tokenIn: "0xunknowntoken1" as `0x${string}`, + exactAmountIn: 1000000000000000000n, + minAmountOut: 3000000000n, + steps: [ + { + pool: "0xpool1" as `0x${string}`, + tokenOut: "0xunknowntoken2" as `0x${string}`, + isBuffer: false, + }, + ], + }, + ]; + + const result = BalancerRouter.visualizeRoute(route, mockTokenDetails); + + expect(result).toHaveLength(1); + expect(result[0]).toBe("100.00% ---> unknownSymbol/unknownSymbol (pool 0xpool1)"); + }); + }); + + describe("test convertToRoutePaths method", () => { + it("should convert single path to BalancerRouterPath correctly", () => { + const mockPaths = [ + { + tokens: [ + { + address: "0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 18, + }, + { + address: "0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 6, + }, + ], + pools: ["0xpool1" as `0x${string}`], + inputAmountRaw: 1000000000000000000n, // 1 WETH + outputAmountRaw: 3000000000n, // 3000 USDC + isBuffer: [false], + protocolVersion: 3 as const, + }, + ]; + + const result = BalancerRouter.convertToRoutePaths(mockPaths); + + expect(result).toHaveLength(1); + expect(result[0].tokenIn).toBe("0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b"); + expect(result[0].exactAmountIn).toBe(1000000000000000000n); + expect(result[0].minAmountOut).toBe(3000000000n); + expect(result[0].steps).toHaveLength(1); + expect(result[0].steps[0].pool).toBe("0xpool1"); + expect(result[0].steps[0].tokenOut).toBe("0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b"); + expect(result[0].steps[0].isBuffer).toBe(false); + }); + + it("should convert multi-hop path to BalancerRouterPath correctly", () => { + const mockPaths = [ + { + tokens: [ + { + address: "0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 18, + }, // WETH + { + address: "0xa2b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 18, + }, // DAI + { + address: "0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b" as `0x${string}`, + decimals: 6, + }, // USDC + ], + pools: ["0xpool1" as `0x${string}`, "0xpool2" as `0x${string}`], + inputAmountRaw: 1000000000000000000n, // 1 WETH + outputAmountRaw: 3000000000n, // 3000 USDC + isBuffer: [false, true], // First pool normal, second is buffer + protocolVersion: 3 as const, + }, + ]; + + const result = BalancerRouter.convertToRoutePaths(mockPaths); + + expect(result).toHaveLength(1); + expect(result[0].tokenIn).toBe("0xa0b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b"); + expect(result[0].exactAmountIn).toBe(1000000000000000000n); + expect(result[0].minAmountOut).toBe(3000000000n); + expect(result[0].steps).toHaveLength(2); + + // First step: WETH -> DAI + expect(result[0].steps[0].pool).toBe("0xpool1"); + expect(result[0].steps[0].tokenOut).toBe("0xa2b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b"); + expect(result[0].steps[0].isBuffer).toBe(false); + + // Second step: DAI -> USDC + expect(result[0].steps[1].pool).toBe("0xpool2"); + expect(result[0].steps[1].tokenOut).toBe("0xa1b86a33e6c0c536b5e9f9de9c2c4b6d5e9c2c4b"); + expect(result[0].steps[1].isBuffer).toBe(true); + }); + }); +}); diff --git a/src/router/balancer.ts b/src/router/balancer.ts index 638feecb..937a6e93 100644 --- a/src/router/balancer.ts +++ b/src/router/balancer.ts @@ -1,145 +1,372 @@ -/* eslint-disable no-console */ +import { PublicClient } from "viem"; +import { ABI, Result } from "../common"; +import { TokenDetails } from "../state"; +import { ONE18, scaleTo18 } from "../math"; +import { RainSolverSigner } from "../signer"; +import { RainSolverBaseError } from "../error"; +import { Token as SushiToken } from "sushi/currency"; import { - // Swap, + Path, Token, ChainId, - // Slippage, SwapKind, TokenAmount, BalancerApi, - // SwapBuildCallInput, - // ExactInQueryOutput, - // SwapBuildOutputExactIn, - Path, PathWithAmount, AddressProvider, - batchRouterAbi_V3, + balancerV3Contracts, } from "@balancer/sdk"; -import { Token as SushiToken } from "sushi/currency"; -import { Result } from "../common"; -import { SharedState } from "../state"; -import { RainSolverSigner } from "../signer"; +// Balancer API URL for fetching routes export const BALANCER_API_URL = "https://api-v3.balancer.fi/" as const; + +/** Represents a single step in a Balancer route */ export type BalancerRouterStep = { pool: `0x${string}`; tokenOut: `0x${string}`; isBuffer: boolean; }; +/** Represents the path details for a Balancer route */ export type BalancerRouterPath = { tokenIn: `0x${string}`; exactAmountIn: bigint; minAmountOut: bigint; steps: BalancerRouterStep[]; }; -export type GetBestBalancerPriceParams = { - tokenIn: SushiToken; - tokenOut: SushiToken; + +/** Represents the parameters for fetching Balancer routes from balancer API */ +export type FetchBalancerRoutesParams = { + tokenIn: TokenDetails | SushiToken; + tokenOut: TokenDetails | SushiToken; swapAmount: bigint; - wethIsEth?: boolean; - deadline?: bigint; - slippage?: `${number}`; }; -export async function getBalancerSortedRoutes( - this: SharedState, - params: GetBestBalancerPriceParams, -): Promise> { - const { tokenIn: _tokenIn, tokenOut: _tokenOut, swapAmount: _swapAmount } = params; +/** Represents the parameters for getting the best Balancer route */ +export type GetBestBalancerRouteParams = { + tokenIn: TokenDetails | SushiToken; + tokenOut: TokenDetails | SushiToken; + swapAmount: bigint; + ignoreCache?: boolean; +}; + +/** Represents a cached Balancer route */ +export type BalancerCachedRoute = { + /** The route paths details used for getting calldata */ + route: BalancerRouterPath[]; + /** The timestamp until which the route is valid */ + validUntil: number; + /** The price of the route from balancer API */ + price: bigint; + /** + * The on-chain price of the route, this is usually equal to the + * price or pretty close, as the price might sometimes lag slightly + * due to subgraph lags + */ + onchainPrice?: bigint; +}; + +/** Enumerates the possible error types that can occur within the Balancer Router functionalities */ +export enum BalancerRouterErrorType { + UnsupportedChain, + NoRouteFound, + FetchFailed, + SwapQueryFailed, +} - console.log(ChainId[this.chainConfig.id]); - if (typeof ChainId[this.chainConfig.id] !== "string") { - return Result.err(new Error(`Unsupported chain with id: ${this.chainConfig.id}`)); +/** + * Represents an error type for the Balancer Router functionalities. + * This error class extends the `RainSolverBaseError` error class, with the `type` + * property indicates the specific category of the error, as defined by the + * `BalancerRouterErrorType` enum. The optional `cause` property can be used to + * attach the original error or any relevant context that led to this error. + * + * @example + * ```typescript + * // with cause + * throw new BalancerRouterError("msg", BalancerRouterErrorType); + * + * // without cause + * throw new BalancerRouterError("msg", BalancerRouterErrorType, originalError); + * ``` + */ +export class BalancerRouterError extends RainSolverBaseError { + type: BalancerRouterErrorType; + constructor(message: string, type: BalancerRouterErrorType, cause?: any) { + super(message, cause); + this.type = type; + this.name = "BalancerRouterError"; } +} - const chainId = this.chainConfig.id as ChainId; - const tokenIn = new Token(chainId, _tokenIn.address, _tokenIn.decimals, _tokenIn.symbol); - const tokenOut = new Token(chainId, _tokenOut.address, _tokenOut.decimals, _tokenOut.symbol); - const swapAmount = TokenAmount.fromRawAmount(tokenIn, _swapAmount); - const swapKind = SwapKind.GivenIn; - - // API is used to fetch best swap paths from available liquidity across v2 and v3 - const balancerApi = new BalancerApi(BALANCER_API_URL, chainId); - - const sorPaths = await balancerApi.sorSwapPaths.fetchSorSwapPaths({ - chainId, - tokenIn: tokenIn.address.toLowerCase() as `0x${string}`, - tokenOut: tokenOut.address.toLowerCase() as `0x${string}`, - swapKind, - swapAmount, - useProtocolVersion: 3, - }); - console.log("sorted", sorPaths); - - if (sorPaths.length === 0) { - return Result.err(new Error("no balancer route for given token pair")); +/** + * The Balancer Router class provides methods to interact with the Balancer protocol, + * including fetching routes from balancer API, getting best route and market price as well + * as managing runtime cache for routes. + */ +export class BalancerRouter { + /** The shared state of the router */ + readonly chainId: number; + /** The address of the router contract */ + readonly routerAddress: `0x${string}`; + /** The protocol version of the balancer */ + readonly protocolVersion = 3 as const; + /** The duration for which a route is considered valid in cache */ + readonly routeTime = 60_000 as const; // 1 minute in milliseconds + /** The Balancer API instance */ + readonly balancerApi: BalancerApi; + /** The cache for storing previously fetched routes that are valid until specified timestamp */ + readonly cache: Map = new Map(); + + private constructor(chainId: number) { + this.chainId = chainId; + this.routerAddress = AddressProvider.BatchRouter(this.chainId); + this.balancerApi = new BalancerApi(BALANCER_API_URL, this.chainId); } - const bestRoute = convertToSwapRoute(sorPaths); - return Result.ok(bestRoute); -} + /** + * Initializes the Balancer Router instance. + * @param chainId The chain id of the opperating chain + * @returns A Result containing the Balancer Router instance or an error + */ + static init(chainId: number): Result { + if ( + !balancerV3Contracts.BatchRouter[ + chainId as keyof typeof balancerV3Contracts.BatchRouter + ] + ) { + return Result.err( + new BalancerRouterError( + `Balancer router does not support chain with id: ${chainId}`, + BalancerRouterErrorType.UnsupportedChain, + ), + ); + } + return Result.ok(new BalancerRouter(chainId)); + } + + /** + * Gets the balancer market price for a token pair by simulating balancer swap query + * @param params The parameters for getting the best Balancer route and market price + * @param signer The signer instance + */ + async getMarketPrice( + params: GetBestBalancerRouteParams, + signer: PublicClient | RainSolverSigner, + address: `0x${string}` = `0x${"1".repeat(40)}`, + ): Promise< + Result< + { price: bigint; route: BalancerRouterPath[]; amountOut: bigint }, + BalancerRouterError + > + > { + try { + const route = await this.getBestRoute(params); + if (route.isErr()) { + return Result.err(route.error); + } + if (typeof route.value.onchainPrice === "bigint") { + return Result.ok({ + price: route.value.onchainPrice, + route: route.value.route, + amountOut: route.value.route[0].minAmountOut, + }); + } + const result = await signer.simulateContract({ + address: this.routerAddress, + abi: ABI.BalancerBatchRouter.Primary.BatchRouterV3, + functionName: "querySwapExactIn", + args: [route.value.route, signer.account?.address ?? address, "0x"], + }); + + const [price, amountOut] = (() => { + try { + const amountOut = result.result[2][0]; + const amountOut18 = scaleTo18(amountOut, params.tokenOut.decimals); + const amountIn18 = scaleTo18(params.swapAmount, params.tokenIn.decimals); + const onchainPrice = (amountOut18 * ONE18) / amountIn18; + route.value.onchainPrice = onchainPrice; + return [onchainPrice, amountOut]; + } catch { + return [route.value.price, route.value.route[0].minAmountOut]; + } + })(); -export async function getBestBalancerRoute( - this: SharedState, - params: GetBestBalancerPriceParams, -): Promise> { - const balancerSortedRoutes = await getBalancerSortedRoutes.call(this, params); - if (balancerSortedRoutes.isErr()) { - return Result.err(balancerSortedRoutes.error); + return Result.ok({ price, route: route.value.route, amountOut }); + } catch (error: any) { + return Result.err( + new BalancerRouterError( + "Swap query execution failed for the given route to get market price", + BalancerRouterErrorType.SwapQueryFailed, + error, + ), + ); + } } - const bestRoute = { ...balancerSortedRoutes.value[0] }; - bestRoute.exactAmountIn = params.swapAmount; + /** + * Gets the best Balancer route for a given token pair and swap amount + * @param params The parameters for getting the best Balancer route + */ + async getBestRoute( + params: GetBestBalancerRouteParams, + ): Promise> { + const key = `${params.tokenIn.address.toLowerCase()}/${params.tokenOut.address.toLowerCase()}`; - return Result.ok([bestRoute]); -} + // search in cache first and return early if ignoreCache is false + if (!params.ignoreCache) { + const cachedRoute = this.cache.get(key); + if (cachedRoute && cachedRoute.validUntil > Date.now()) { + return Result.ok(cachedRoute); + } + } + + const balancerSortedRoutes = await this.fetchSortedRoutes(params); + if (balancerSortedRoutes.isErr()) { + return Result.err(balancerSortedRoutes.error); + } -export async function getBalancerMarketPrice( - this: SharedState, - route: BalancerRouterPath[], - signer: RainSolverSigner, -): Promise> { - const balancerRouter = AddressProvider.BatchRouter(this.chainConfig.id); - - try { - const result = await this.client.simulateContract({ - address: balancerRouter, - abi: batchRouterAbi_V3, - functionName: "querySwapExactIn", - args: [route, signer.account.address, "0x"], + let minAmountOut = 0n; + balancerSortedRoutes.value.forEach((route) => { + minAmountOut += route.minAmountOut; }); - return Result.ok(result.result[2][0]); - } catch (e: any) { - return Result.err(e); + const amountOut18 = scaleTo18(minAmountOut, params.tokenOut.decimals); + const amountIn18 = scaleTo18(params.swapAmount, params.tokenIn.decimals); + const price = (amountOut18 * ONE18) / amountIn18; + const route = { + route: [ + { + ...balancerSortedRoutes.value[0], + exactAmountIn: params.swapAmount, + minAmountOut, + }, + ], + validUntil: Date.now() + this.routeTime, + price, + }; + this.cache.set(key, route); // store in cache + return Result.ok(route); } -} -export function convertToSwapRoute(paths: Path[]): BalancerRouterPath[] { - const pathsWithAmounts = paths.map( - (p) => - new PathWithAmount( - ChainId.MAINNET, - p.tokens, - p.pools, - p.inputAmountRaw, - p.outputAmountRaw, - p.isBuffer, - ), - ); - const swaps = pathsWithAmounts.map((p) => { - return { - tokenIn: p.inputAmount.token.address, - exactAmountIn: p.inputAmount.amount, - minAmountOut: p.outputAmount.amount, - steps: p.pools.map((pool, i) => { - return { - pool, - tokenOut: p.tokens[i + 1].address, - isBuffer: p.isBuffer[i], - }; - }), - }; - }); - return swaps; + /** + * Fetches the best Balancer route for a given token pair and swap amount. + * This method uses the Balancer API to find the best swap paths from available liquidity. + * @param params The parameters for fetching the best Balancer price + * @returns A Result containing the best Balancer route or an error + */ + async fetchSortedRoutes( + params: FetchBalancerRoutesParams, + ): Promise> { + try { + // prepare params + const { tokenIn: _tokenIn, tokenOut: _tokenOut, swapAmount: _swapAmount } = params; + const tokenIn = new Token( + this.chainId, + _tokenIn.address as `0x${string}`, + _tokenIn.decimals, + _tokenIn.symbol ?? "unknownSymbol", + ); + const tokenOut = new Token( + this.chainId, + _tokenOut.address as `0x${string}`, + _tokenOut.decimals, + _tokenOut.symbol ?? "unknownSymbol", + ); + const swapAmount = TokenAmount.fromRawAmount(tokenIn, _swapAmount); + const swapKind = SwapKind.GivenIn; + + // fetch the sorted routes from the Balancer API + const sorPaths = await this.balancerApi.sorSwapPaths.fetchSorSwapPaths({ + chainId: this.chainId, + tokenIn: tokenIn.address.toLowerCase() as `0x${string}`, + tokenOut: tokenOut.address.toLowerCase() as `0x${string}`, + swapKind, + swapAmount, + useProtocolVersion: this.protocolVersion, + }); + + // return err if no route was found + if (sorPaths.length === 0) { + return Result.err( + new BalancerRouterError( + "Found no balancer route for given token pair", + BalancerRouterErrorType.NoRouteFound, + ), + ); + } + + return Result.ok(BalancerRouter.convertToRoutePaths(sorPaths)); + } catch (error) { + return Result.err( + new BalancerRouterError( + "Failed to fetch balancer routes", + BalancerRouterErrorType.FetchFailed, + error, + ), + ); + } + } + + /** + * Method to visualize the routes, returns an array of portioned route paths strings + * @param route: The Balancer route to visualize + * @param cachedTokenDetails: A map of token addresses to their details for symbol lookup + */ + static visualizeRoute( + route: BalancerRouterPath[], + cachedTokenDetails: Map, + ): string[] { + let totalIn = 0n; + route.forEach((path) => (totalIn += path.exactAmountIn)); + return route.map( + (path) => + (Number((path.exactAmountIn * 10_000n) / totalIn) / 100).toFixed(2) + + "% ---> " + + path.steps + .map((step, i) => { + const tokenIn = i === 0 ? path.tokenIn : path.steps[i - 1].tokenOut; + const tokenOutSymbol = + cachedTokenDetails.get(step.tokenOut.toLowerCase())?.symbol ?? + "unknownSymbol"; + const tokenInSymbol = + cachedTokenDetails.get(tokenIn.toLowerCase())?.symbol ?? + "unknownSymbol"; + return tokenOutSymbol + "/" + tokenInSymbol + " (pool " + step.pool + ")"; + }) + .join(" >> "), + ); + } + + /** + * Converts an array of paths to BalancerRouterPath objects used for balancer router swap calldata + * @param paths The paths to convert + */ + static convertToRoutePaths(paths: Path[]): BalancerRouterPath[] { + const pathsWithAmounts = paths.map( + (p) => + new PathWithAmount( + ChainId.MAINNET, + p.tokens, + p.pools, + p.inputAmountRaw, + p.outputAmountRaw, + p.isBuffer, + ), + ); + const swaps = pathsWithAmounts.map((p) => { + return { + tokenIn: p.inputAmount.token.address, + exactAmountIn: p.inputAmount.amount, + minAmountOut: p.outputAmount.amount, + steps: p.pools.map((pool, i) => { + return { + pool, + tokenOut: p.tokens[i + 1].address, + isBuffer: p.isBuffer[i], + }; + }), + }; + }); + return swaps; + } } diff --git a/src/router/marketPrice.ts b/src/router/marketPrice.ts index 1a27515b..3c12e4f3 100644 --- a/src/router/marketPrice.ts +++ b/src/router/marketPrice.ts @@ -42,6 +42,27 @@ export async function getMarketPrice( RPoolFilter, ); if (route.status == "NoWay") { + // try balancer + if (this.balancerRouter) { + const balancerPriceResult = await this.balancerRouter.getMarketPrice( + { + tokenIn: fromToken, + tokenOut: toToken, + swapAmount: amountIn, + }, + this.client, + ); + if (balancerPriceResult.isOk()) { + const price = scaleTo18(balancerPriceResult.value.amountOut, toToken.decimals); + return { + price: formatUnits(price, 18), + amountOut: formatUnits( + balancerPriceResult.value.amountOut, + toToken.decimals, + ), + }; + } + } return; } else { const price = scaleTo18(route.amountOutBI, toToken.decimals); diff --git a/src/state/index.test.ts b/src/state/index.test.ts index 04bc5e39..8cb5eb18 100644 --- a/src/state/index.test.ts +++ b/src/state/index.test.ts @@ -74,6 +74,7 @@ describe("Test SharedStateConfig tryFromAppOptions", () => { expect(config.initL1GasPrice).toBe(0n); expect(config.transactionGas).toBe("120%"); expect(config.rainSolverTransportConfig).toMatchObject({ timeout: 1000 }); + expect(config.balancerRouter).toBeDefined(); }); it("should throw if iInterpreter contract call fails", async () => { diff --git a/src/state/index.ts b/src/state/index.ts index d929ca11..343705fa 100644 --- a/src/state/index.ts +++ b/src/state/index.ts @@ -13,6 +13,7 @@ import { createPublicClient, PublicClient } from "viem"; import { LiquidityProviders, RainDataFetcher } from "sushi"; import { getMarketPrice, processLiquidityProviders } from "../router"; import { rainSolverTransport, RainSolverTransportConfig } from "../rpc"; +import { BalancerRouter } from "../router/balancer"; /** * Rain dispair contracts, deployer, store and interpreter @@ -65,6 +66,8 @@ export type SharedStateConfig = { rainSolverTransportConfig?: RainSolverTransportConfig; /** RainDataFetcher instance */ dataFetcher: RainDataFetcher; + /** Balancer router instance */ + balancerRouter?: BalancerRouter; }; export namespace SharedStateConfig { export async function tryFromAppOptions(options: AppOptions): Promise { @@ -110,6 +113,13 @@ export namespace SharedStateConfig { client, liquidityProviders, ); + + const balancerRouter = (() => { + const res = BalancerRouter.init(chainId); + if (res.isOk()) return res.value; + else return undefined; + })(); + const config: SharedStateConfig = { client, rpcState, @@ -128,6 +138,7 @@ export namespace SharedStateConfig { store, deployer: options.dispair, }, + balancerRouter, }; // try to get init gas price @@ -177,6 +188,8 @@ export class SharedState { readonly transactionGas?: string; /** RainSolver transport configuration */ readonly rainSolverTransportConfig?: RainSolverTransportConfig; + /** Balancer router instance */ + readonly balancerRouter?: BalancerRouter; /** Current gas price of the operating chain */ gasPrice = 0n; @@ -204,6 +217,7 @@ export class SharedState { this.rpc = config.rpcState; this.writeRpc = config.writeRpcState; this.dataFetcher = config.dataFetcher; + this.balancerRouter = config.balancerRouter; if (typeof config.gasPriceMultiplier === "number") { this.gasPriceMultiplier = config.gasPriceMultiplier; } diff --git a/test/abis/BalancerRouterOrderBookV4ArbOrderTaker.json b/test/abis/BalancerRouterOrderBookV4ArbOrderTaker.json index 94eb7293..50d33eeb 100644 --- a/test/abis/BalancerRouterOrderBookV4ArbOrderTaker.json +++ b/test/abis/BalancerRouterOrderBookV4ArbOrderTaker.json @@ -1 +1 @@ -{"abi":[{"type":"constructor","inputs":[{"name":"config","type":"tuple","internalType":"struct OrderBookV4ArbConfigV2","components":[{"name":"orderBook","type":"address","internalType":"address"},{"name":"task","type":"tuple","internalType":"struct TaskV1","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"uint256[]","internalType":"uint256[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"implementationData","type":"bytes","internalType":"bytes"}]}],"stateMutability":"nonpayable"},{"type":"fallback","stateMutability":"nonpayable"},{"type":"function","name":"arb3","inputs":[{"name":"orderBook","type":"address","internalType":"contract IOrderBookV4"},{"name":"takeOrders","type":"tuple","internalType":"struct TakeOrdersConfigV3","components":[{"name":"minimumInput","type":"uint256","internalType":"uint256"},{"name":"maximumInput","type":"uint256","internalType":"uint256"},{"name":"maximumIORatio","type":"uint256","internalType":"uint256"},{"name":"orders","type":"tuple[]","internalType":"struct TakeOrderConfigV3[]","components":[{"name":"order","type":"tuple","internalType":"struct OrderV3","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IO[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"decimals","type":"uint8","internalType":"uint8"},{"name":"vaultId","type":"uint256","internalType":"uint256"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IO[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"decimals","type":"uint8","internalType":"uint8"},{"name":"vaultId","type":"uint256","internalType":"uint256"}]},{"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":"uint256[]","internalType":"uint256[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"data","type":"bytes","internalType":"bytes"}]},{"name":"task","type":"tuple","internalType":"struct TaskV1","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"uint256[]","internalType":"uint256[]"},{"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":"onTakeOrders","inputs":[{"name":"inputToken","type":"address","internalType":"address"},{"name":"outputToken","type":"address","internalType":"address"},{"name":"inputAmountSent","type":"uint256","internalType":"uint256"},{"name":"totalOutputAmount","type":"uint256","internalType":"uint256"},{"name":"takeOrdersData","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"x","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"type":"event","name":"Construct","inputs":[{"name":"sender","type":"address","indexed":false,"internalType":"address"},{"name":"config","type":"tuple","indexed":false,"internalType":"struct OrderBookV4ArbConfigV2","components":[{"name":"orderBook","type":"address","internalType":"address"},{"name":"task","type":"tuple","internalType":"struct TaskV1","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"uint256[]","internalType":"uint256[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"implementationData","type":"bytes","internalType":"bytes"}]}],"anonymous":false},{"type":"error","name":"InvalidSignature","inputs":[{"name":"i","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"NoOrders","inputs":[]},{"type":"error","name":"WrongTask","inputs":[]}],"bytecode":{"object":"0x60a0604052600060805234801561001557600080fd5b50604051613a38380380613a388339810160408190526100349161036e565b808060016000819055507f584f220334313e589a42a75ac60d4fa6ed5b02329a7255af822a0e4ac9cd5f1d338260405161006f9291906105e7565b60405180910390a16020810151516040015151156100b65760208082015160405161009a9201610647565b60408051601f1981840301815291905280516020909101206080525b505050610661565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156100f6576100f66100be565b60405290565b604080519081016001600160401b03811182821017156100f6576100f66100be565b604051601f8201601f191681016001600160401b0381118282101715610146576101466100be565b604052919050565b6001600160a01b038116811461016357600080fd5b50565b60005b83811015610181578181015183820152602001610169565b50506000910152565b600082601f83011261019b57600080fd5b81516001600160401b038111156101b4576101b46100be565b6101c7601f8201601f191660200161011e565b8181528460208386010111156101dc57600080fd5b6101ed826020830160208701610166565b949350505050565b60006001600160401b0382111561020e5761020e6100be565b5060051b60200190565b600082601f83011261022957600080fd5b8151602061023e610239836101f5565b61011e565b82815260059290921b8401810191818101908684111561025d57600080fd5b8286015b848110156103635780516001600160401b038082111561028057600080fd5b908801906060828b03601f190112156102995760008081fd5b6102a16100d4565b868301516102ae8161014e565b8152604083810151838111156102c45760008081fd5b8401603f81018d136102d65760008081fd5b888101516102e6610239826101f5565b81815260059190911b82018301908a8101908f8311156103065760008081fd5b928401925b828410156103245783518252928b0192908b019061030b565b858c015250505060608401518381111561033e5760008081fd5b61034c8d8a8388010161018a565b918301919091525085525050918301918301610261565b509695505050505050565b6000602080838503121561038157600080fd5b82516001600160401b038082111561039857600080fd5b90840190606082870312156103ac57600080fd5b6103b46100d4565b82516103bf8161014e565b815282840151828111156103d257600080fd5b8301604081890312156103e457600080fd5b6103ec6100fc565b8151848111156103fb57600080fd5b82016060818b03121561040d57600080fd5b6104156100d4565b81516104208161014e565b81528188015161042f8161014e565b8189015260408201518681111561044557600080fd5b6104518c82850161018a565b604083015250825250818601518481111561046b57600080fd5b6104778a828501610218565b878301525080868401525050604083015193508184111561049757600080fd5b6104a38785850161018a565b60408201529695505050505050565b600081518084526104ca816020860160208601610166565b601f01601f19169290920160200192915050565b6000604082516040855260018060a01b03808251166040870152602080830151606083821660608a015260408501519450606060808a015261052360a08a01866104b2565b888401518a82038b86015280518083529196508401925083860190600581901b870185016000805b838110156105d557898303601f19018552865180518a168452888101518985018890528051888601819052908a0190849060808701905b808310156105a25783518252928c019260019290920191908c0190610582565b508e84015193508681038f8801526105ba81856104b2565b9650505050508787019650878501945060018101905061054b565b50909c9b505050505050505050505050565b6001600160a01b0383811682526040602080840182905284519092169083015282015160608083015260009061062060a08401826104de565b90506040840151603f1984830301608085015261063d82826104b2565b9695505050505050565b60208152600061065a60208301846104de565b9392505050565b6080516133af6106896000396000818160e20152818161070d015261075e01526133af6000f3fe60806040526004361061005a5760003560e01c80637ea0b76a116100435780637ea0b76a146100bd57806393be095e146100d0578063f037e4e3146101125761005a565b806301ffc9a714610068578063059bebe61461009d575b34801561006657600080fd5b005b34801561007457600080fd5b50610088610083366004611e97565b610125565b60405190151581526020015b60405180910390f35b3480156100a957600080fd5b506100666100b8366004611efe565b61020a565b6100666100cb366004611fa8565b6106fa565b3480156100dc57600080fd5b506101047f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610094565b61006661012036600461202d565b610a5a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f059bebe60000000000000000000000000000000000000000000000000000000014806101b857507fffffffff0000000000000000000000000000000000000000000000000000000082167f7ea0b76a00000000000000000000000000000000000000000000000000000000145b8061020457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000806102198385018561214b565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526e22d473030f116ddee9f6b43ac78ba3600482018190526000196024830152929450909250819073ffffffffffffffffffffffffffffffffffffffff8b169063095ea7b3906044016020604051808303816000875af11580156102a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ca9190612347565b5082516001146103215760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420737761702070617468206c656e677468000000000000000060448201526064015b60405180910390fd5b8973ffffffffffffffffffffffffffffffffffffffff168360008151811061034b5761034b612364565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16146103ba5760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420696e70757420746f6b656e000000000000000000000000006044820152606401610318565b8873ffffffffffffffffffffffffffffffffffffffff16836000815181106103e4576103e4612364565b60200260200101516020015160018560008151811061040557610405612364565b6020026020010151602001515161041c91906123c2565b8151811061042c5761042c612364565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff161461049b5760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964206f757470757420746f6b656e0000000000000000000000006044820152606401610318565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8b16906370a0823190602401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052991906123d5565b8811156105785760405162461bcd60e51b815260206004820181905260248201527f496e73756666696369656e7420696e70757420746f6b656e2062616c616e63656044820152606401610318565b6040517f87517c4500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152808616602483015260448201819052600060648301528591908416906387517c4590608401600060405180830381600087803b1580156105fa57600080fd5b505af115801561060e573d6000803e3d6000fd5b50505050888460008151811061062657610626612364565b6020026020010151604001818152505060008460008151811061064b5761064b612364565b6020026020010151606001818152505060008060008373ffffffffffffffffffffffffffffffffffffffff1663286f580d8860001960006040518463ffffffff1660e01b81526004016106a0939291906123ee565b6000604051808303816000875af11580156106bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106e791908101906125ac565b5050505050505050505050505050505050565b610702610b0c565b61070b81612849565b7f0000000000000000000000000000000000000000000000000000000000000000158015906107805750806040516020016107469190612997565b604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000014155b156107b7576040517f8812562900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c46060840184612a84565b90506000036107ff576040517f9c95219f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061080e6060850185612a84565b600081811061081f5761081f612364565b90506020028101906108319190612ace565b61083b9080612b0c565b610849906040810190612b40565b6108566060870187612a84565b600081811061086757610867612364565b90506020028101906108799190612ace565b6020013581811061088c5761088c612364565b6108a2926020606090920201908101915061202d565b905060006108b36060860186612a84565b60008181106108c4576108c4612364565b90506020028101906108d69190612ace565b6108e09080612b0c565b6108ee906060810190612b40565b6108fb6060880188612a84565b600081811061090c5761090c612364565b905060200281019061091e9190612ace565b6040013581811061093157610931612364565b610947926020606090920201908101915061202d565b905061096b73ffffffffffffffffffffffffffffffffffffffff8316876000610b65565b61098e73ffffffffffffffffffffffffffffffffffffffff831687600019610b65565b6000808773ffffffffffffffffffffffffffffffffffffffff16630997c4a0886040518263ffffffff1660e01b81526004016109ca9190612e3a565b60408051808303816000875af11580156109e8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0c919061309e565b9092509050610a3373ffffffffffffffffffffffffffffffffffffffff8516896000610b65565b610a46610a3f87612849565b8585610d2d565b5050505050610a556001600055565b505050565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526e22d473030f116ddee9f6b43ac78ba36004820181905260001960248301529073ffffffffffffffffffffffffffffffffffffffff83169063095ea7b3906044016020604051808303816000875af1158015610ae0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a559190612347565b505050505050565b600260005403610b5e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610318565b6002600055565b801580610c0557506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0391906123d5565b155b610c775760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610318565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611105565b604080516001808252818301909252600091816020015b6060815260200190600190039081610d44575050604080516003808252608082019092529192506000919060208201606080368337019050506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1191906123d5565b90508015610e3a57610e3a73ffffffffffffffffffffffffffffffffffffffff861633836111fa565b60008573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eab91906130c2565b60ff169050610ebc82826000611250565b83600081518110610ecf57610ecf612364565b602090810291909101015250506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015610f49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6d91906123d5565b90508015610f9657610f9673ffffffffffffffffffffffffffffffffffffffff851633836111fa565b60008473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100791906130c2565b60ff16905061101882826000611250565b8360018151811061102b5761102b612364565b60209081029190910101525047905061104433826112d8565b808260028151811061105857611058612364565b60200260200101818152505050808260008151811061107957611079612364565b6020908102919091010152604080516001808252818301909252600091816020015b6040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915281526020019060019003908161109b57905050905085816000815181106110f0576110f0612364565b6020026020010181905250610b0483826113fe565b6000611167826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166115f79092919063ffffffff16565b90508051600014806111885750808060200190518101906111889190612347565b610a555760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610318565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610cc9565b60008260121115611285576012839003600283161561127b57611273858261160e565b9150506112d1565b611273858261165f565b60128311156112ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee830160018316156112c4576112738582611697565b61127385826116e5565b50825b9392505050565b804710156113285760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610318565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611382576040519150601f19603f3d011682016040523d82523d6000602084013e611387565b606091505b5050905080610a555760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610318565b336114316040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915290565b60005b83518110156115f05783818151811061144f5761144f612364565b6020026020010151915060008260000151604001515111156115e8578151805160209182015160008681523090935260408320839273ffffffffffffffffffffffffffffffffffffffff169163d6e3357a9187600001516040015160006114ba8d8b60200151611708565b604080516000815260208101918290527fffffffff0000000000000000000000000000000000000000000000000000000060e089901b16909152611506959493929190602481016130df565b600060405180830381865afa158015611523573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261154b919081019061318f565b80519193509150156115e5578351602001516040517f946aadc600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063946aadc6906115b290889085906004016131f3565b600060405180830381600087803b1580156115cc57600080fd5b505af11580156115e0573d6000803e3d6000fd5b505050505b50505b600101611434565b5050505050565b60606116068484600085611a18565b949350505050565b6000604e821061163057821561162657600019611629565b60005b9050610204565b50600a81900a828102908381838161164a5761164a61320c565b041461165857600019611606565b5092915050565b600a81900a61166e818461323b565b9050604e821061020457821561168e5761168982600a613336565b6112d1565b60009392505050565b6000604e82106116bb5782156116ae5760016116b1565b60005b60ff169050610204565b600a82900a8084816116cf576116cf61320c565b0491508082028414611658575060010192915050565b6000604e82101561168e5781600a0a83816117025761170261320c565b046112d1565b60606000825167ffffffffffffffff8111156117265761172661204a565b60405190808252806020026020018201604052801561174f578160200160208202803683370190505b509050600080845111611763576000611769565b83516001015b855160010101905060008167ffffffffffffffff81111561178c5761178c61204a565b6040519080825280602002602001820160405280156117bf57816020015b60608152602001906001900390816117aa5790505b50905060006117e4604080516002815233602082015230818301526060810190915290565b8282815181106117f6576117f6612364565b602002602001018190525060005b875181101561185457818060010192505087818151811061182757611827612364565b602002602001015183838151811061184157611841612364565b6020908102919091010152600101611804565b50855115611a0e5780806001019150508382828151811061187757611877612364565b602002602001018190525060005b8651811015611a0c576119368782815181106118a3576118a3612364565b6020026020010151600001516119136118e08a85815181106118c7576118c7612364565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b89848151811061192557611925612364565b602002602001015160400151611b17565b61196f576040517f52bf984800000000000000000000000000000000000000000000000000000000815260048101829052602401610318565b86818151811061198157611981612364565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168582815181106119b5576119b5612364565b60200260200101818152505081806001019250508681815181106119db576119db612364565b6020026020010151602001518383815181106119f9576119f9612364565b6020908102919091010152600101611885565b505b5095945050505050565b606082471015611a905760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610318565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ab99190613342565b60006040518083038185875af1925050503d8060008114611af6576040519150601f19603f3d011682016040523d82523d6000602084013e611afb565b606091505b5091509150611b0c87838387611b92565b979650505050505050565b6000806000611b268585611c18565b90925090506000816004811115611b3f57611b3f613354565b148015611b7757508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611b885750611b88868686611c5d565b9695505050505050565b60608315611c0e578251600003611c075773ffffffffffffffffffffffffffffffffffffffff85163b611c075760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610318565b5081611606565b6116068383611d9c565b6000808251604103611c4e5760208301516040840151606085015160001a611c4287828585611dc6565b94509450505050611c56565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c94929190613383565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cff9190613342565b600060405180830381855afa9150503d8060008114611d3a576040519150601f19603f3d011682016040523d82523d6000602084013e611d3f565b606091505b5091509150818015611d5357506020815110155b8015611b88575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d9190830160209081019084016123d5565b149695505050505050565b815115611dac5781518083602001fd5b8060405162461bcd60e51b8152600401610318919061339c565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611dfd5750600090506003611e8e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e51573d6000803e3d6000fd5b5050604051601f19015191505073ffffffffffffffffffffffffffffffffffffffff8116611e8757600060019250925050611e8e565b9150600090505b94509492505050565b600060208284031215611ea957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146112d157600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611efb57600080fd5b50565b60008060008060008060a08789031215611f1757600080fd5b8635611f2281611ed9565b95506020870135611f3281611ed9565b94506040870135935060608701359250608087013567ffffffffffffffff80821115611f5d57600080fd5b818901915089601f830112611f7157600080fd5b813581811115611f8057600080fd5b8a6020828501011115611f9257600080fd5b6020830194508093505050509295509295509295565b600080600060608486031215611fbd57600080fd5b8335611fc881611ed9565b9250602084013567ffffffffffffffff80821115611fe557600080fd5b9085019060a08288031215611ff957600080fd5b9092506040850135908082111561200f57600080fd5b5084016040818703121561202257600080fd5b809150509250925092565b60006020828403121561203f57600080fd5b81356112d181611ed9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561209c5761209c61204a565b60405290565b6040516060810167ffffffffffffffff8111828210171561209c5761209c61204a565b6040805190810167ffffffffffffffff8111828210171561209c5761209c61204a565b604051601f8201601f1916810167ffffffffffffffff811182821017156121115761211161204a565b604052919050565b600067ffffffffffffffff8211156121335761213361204a565b5060051b60200190565b8015158114611efb57600080fd5b6000806040838503121561215e57600080fd5b6121688335611ed9565b8235915067ffffffffffffffff6020840135111561218557600080fd5b6020830135830184601f82011261219b57600080fd5b6121ad6121a88235612119565b6120e8565b81358082526020808301929160051b8401018710156121cb57600080fd5b602083015b6020843560051b8501018110156123395767ffffffffffffffff813511156121f757600080fd5b803584016080601f19828b0301121561220f57600080fd5b612217612079565b6122246020830135611ed9565b6020820135815267ffffffffffffffff6040830135111561224457600080fd5b604082013582018a603f82011261225a57600080fd5b61226a6121a86020830135612119565b602082810135808352908201919060600283016040018d101561228c57600080fd5b604083015b60406060602086013502850101811015612309576060818f0312156122b557600080fd5b6122bd6120a2565b6122c78235611ed9565b813581526122d86020830135611ed9565b602082013560208201526122ef604083013561213d565b604082810135908201528352602090920191606001612291565b506020848101919091526060858101356040860152608090950135948401949094525050845292830192016121d0565b508093505050509250929050565b60006020828403121561235957600080fd5b81516112d18161213d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561020457610204612393565b6000602082840312156123e757600080fd5b5051919050565b600060808083016080845280875180835260a0925060a08601915060a08160051b8701016020808b016000805b858110156124ee578a85037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600187528251805173ffffffffffffffffffffffffffffffffffffffff9081168752858201518688018c905280518c8901819052908701919085908c8a01905b808310156124c25784518051851683528a81015185168b8401526040908101511515908301529389019360019290920191606090910190612486565b50604085810151908b01526060948501519490990193909352505050958301959183019160010161241b565b505050870189905287151560408801528681036060880152600281527f30780000000000000000000000000000000000000000000000000000000000006020820152604081019a9950505050505050505050565b600082601f83011261255357600080fd5b815160206125636121a883612119565b8083825260208201915060208460051b87010193508684111561258557600080fd5b602086015b848110156125a1578051835291830191830161258a565b509695505050505050565b6000806000606084860312156125c157600080fd5b835167ffffffffffffffff808211156125d957600080fd5b6125e587838801612542565b94506020915081860151818111156125fc57600080fd5b8601601f8101881361260d57600080fd5b805161261b6121a882612119565b81815260059190911b8201840190848101908a83111561263a57600080fd5b928501925b8284101561266157835161265281611ed9565b8252928501929085019061263f565b60408a015190975094505050508082111561267b57600080fd5b5061268886828701612542565b9150509250925092565b600082601f8301126126a357600080fd5b813567ffffffffffffffff8111156126bd576126bd61204a565b6126d06020601f19601f840116016120e8565b8181528460208386010111156126e557600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261271357600080fd5b813560206127236121a883612119565b82815260059290921b8401810191818101908684111561274257600080fd5b8286015b848110156125a157803567ffffffffffffffff8082111561276657600080fd5b908801906060828b03601f1901121561277f5760008081fd5b6127876120a2565b8683013561279481611ed9565b8152604083810135838111156127aa5760008081fd5b8401603f81018d136127bc5760008081fd5b888101356127cc6121a882612119565b81815260059190911b82018301908a8101908f8311156127ec5760008081fd5b928401925b8284101561280a5783358252928b0192908b01906127f1565b858c01525050506060840135838111156128245760008081fd5b6128328d8a83880101612692565b918301919091525085525050918301918301612746565b60006040823603121561285b57600080fd5b6128636120c5565b823567ffffffffffffffff8082111561287b57600080fd5b81850191506060823603121561289057600080fd5b6128986120a2565b82356128a381611ed9565b815260208301356128b381611ed9565b60208201526040830135828111156128ca57600080fd5b6128d636828601612692565b604083015250835260208501359150808211156128f257600080fd5b506128ff36828601612702565b60208301525092915050565b60005b8381101561292657818101518382015260200161290e565b50506000910152565b6000815180845261294781602086016020860161290b565b601f01601f19169290920160200192915050565b60008151808452602080850194506020840160005b8381101561298c57815187529582019590820190600101612970565b509495945050505050565b60006020808352606084516040808487015273ffffffffffffffffffffffffffffffffffffffff808351166060880152808584015116608088015260408301519250606060a08801526129ed60c088018461292f565b925084880151601f19808986030160408a01528482518087528887019150888160051b880101898501945060005b82811015612a73578489830301845285518781511683528b8101518b8d850152612a478c85018261295b565b918a0151848303858c0152919050612a5f818361292f565b978d0197958d019593505050600101612a1b565b509c9b505050505050505050505050565b6000808335601e19843603018112612a9b57600080fd5b83018035915067ffffffffffffffff821115612ab657600080fd5b6020019150600581901b3603821315611c5657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612b0257600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61833603018112612b0257600080fd5b6000808335601e19843603018112612b5757600080fd5b83018035915067ffffffffffffffff821115612b7257600080fd5b6020019150606081023603821315611c5657600080fd5b6000808335601e19843603018112612ba057600080fd5b830160208101925035905067ffffffffffffffff811115612bc057600080fd5b8060051b3603821315611c5657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112612c0657600080fd5b90910192915050565b6000808335601e19843603018112612c2657600080fd5b830160208101925035905067ffffffffffffffff811115612c4657600080fd5b803603821315611c5657600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6000808335601e19843603018112612c9757600080fd5b830160208101925035905067ffffffffffffffff811115612cb757600080fd5b606081023603821315611c5657600080fd5b60ff81168114611efb57600080fd5b8183526000602080850194508260005b8581101561298c578135612cfb81611ed9565b73ffffffffffffffffffffffffffffffffffffffff16875281830135612d2081612cc9565b60ff16878401526040828101359088015260609687019690910190600101612ce8565b818352602080840193600091600585811b830182018585805b89811015612e2b57601f19878503018b52612d77838a612bd2565b60608135612d8481611ed9565b73ffffffffffffffffffffffffffffffffffffffff168652612da882890183612b89565b828a8901528083890152608092507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612de2578586fd5b881b808289850137870190506040612dfc84820185612c0f565b94508389840301828a0152612e148484018683612c55565b9f8b019f9850505094880194505050600101612d5c565b50919998505050505050505050565b6000602080835260c083018435828501526040828601358186015260608187013581870152612e6b81880188612b89565b60a060808901528481865260e08901905060e08260051b8a010195508260005b83811015613071577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff208b890301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81863603018112612eec57600080fd5b85018035368290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61018112612f2157600080fd5b60808a5281018035612f3281611ed9565b73ffffffffffffffffffffffffffffffffffffffff80821660808d0152612f5b8d840184612bd2565b915060a0808d01528135612f6e81611ed9565b81166101208d0152818d0135612f8381611ed9565b166101408c0152612f96818b0182612c0f565b9150896101608d0152612fae6101808d018383612c55565b915050612fbd8a830183612c80565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808e85030160c08f0152612ff3848385612cd8565b93506130018c860186612c80565b93509150808e85030160e08f01525061301b838383612cd8565b9250505060808201356101008c01528b8301358c8c0152898301358a8c015261304689840184612b89565b935091508a8103898c015261305c818484612d43565b9a505050928901925090880190600101612e8b565b505050505050506130856080860186612c0f565b9250601f198583030160a0860152611b88828483612c55565b600080604083850312156130b157600080fd5b505080516020909101519092909150565b6000602082840312156130d457600080fd5b81516112d181612cc9565b73ffffffffffffffffffffffffffffffffffffffff8716815260006020878184015260c0604084015261311560c084018861292f565b86606085015283810360808501528086518083528383019150838160051b84010184890160005b8381101561316a57601f1986840301855261315883835161295b565b9487019492509086019060010161313c565b505086810360a088015261317e818961295b565b9d9c50505050505050505050505050565b600080604083850312156131a257600080fd5b825167ffffffffffffffff808211156131ba57600080fd5b6131c686838701612542565b935060208501519150808211156131dc57600080fd5b506131e985828601612542565b9150509250929050565b828152604060208201526000611606604083018461295b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b808202811582820484141761020457610204612393565b600181815b8085111561328d57816000190482111561327357613273612393565b8085161561328057918102915b93841c9390800290613257565b509250929050565b6000826132a457506001610204565b816132b157506000610204565b81600181146132c757600281146132d1576132ed565b6001915050610204565b60ff8411156132e2576132e2612393565b50506001821b610204565b5060208310610133831016604e8410600b8410161715613310575081810a610204565b61331a8383613252565b806000190482111561332e5761332e612393565b029392505050565b60006112d18383613295565b60008251612b0281846020870161290b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b828152604060208201526000611606604083018461292f565b6020815260006112d1602083018461292f56","sourceMap":"2203:3849:53:-:0;;;1597:1:51;1560:38;;2407:240:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2482:6;2489::52;1716:1:5;1821:7;:22;;;;1729:29:51;1739:10;1751:6;1729:29;;;;;;;:::i;:::-;;;;;;;;1773:11;;;;:21;:30;;;:37;:42;1769:119;;1864:11;;;;;1853:23;;;;;;:::i;:::-;;;;-1:-1:-1;;1853:23:51;;;;;;;;;1843:34;;1853:23;1843:34;;;;1831:46;;1769:119;1605:289;2418:81:52;2407:240:53;2203:3849;;14:127:56;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:56;;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:56;;576:22;;;537:62;534:88;;;602:18;;:::i;666:275::-;737:2;731:9;802:2;783:13;;-1:-1:-1;;779:27:56;767:40;;-1:-1:-1;;;;;822:34:56;;858:22;;;819:62;816:88;;;884:18;;:::i;:::-;920:2;913:22;666:275;;-1:-1:-1;666:275:56:o;946:131::-;-1:-1:-1;;;;;1021:31:56;;1011:42;;1001:70;;1067:1;1064;1057:12;1001:70;946:131;:::o;1082:250::-;1167:1;1177:113;1191:6;1188:1;1185:13;1177:113;;;1267:11;;;1261:18;1248:11;;;1241:39;1213:2;1206:10;1177:113;;;-1:-1:-1;;1324:1:56;1306:16;;1299:27;1082:250::o;1337:509::-;1390:5;1443:3;1436:4;1428:6;1424:17;1420:27;1410:55;;1461:1;1458;1451:12;1410:55;1484:13;;-1:-1:-1;;;;;1509:26:56;;1506:52;;;1538:18;;:::i;:::-;1582:55;1625:2;1606:13;;-1:-1:-1;;1602:27:56;1631:4;1598:38;1582:55;:::i;:::-;1662:2;1653:7;1646:19;1708:3;1701:4;1696:2;1688:6;1684:15;1680:26;1677:35;1674:55;;;1725:1;1722;1715:12;1674:55;1738:77;1812:2;1805:4;1796:7;1792:18;1785:4;1777:6;1773:17;1738:77;:::i;:::-;1833:7;1337:509;-1:-1:-1;;;;1337:509:56:o;1851:198::-;1926:4;-1:-1:-1;;;;;1948:30:56;;1945:56;;;1981:18;;:::i;:::-;-1:-1:-1;2026:1:56;2022:14;2038:4;2018:25;;1851:198::o;2054:2494::-;2134:5;2187:3;2180:4;2172:6;2168:17;2164:27;2154:55;;2205:1;2202;2195:12;2154:55;2234:6;2228:13;2260:4;2284:75;2300:58;2355:2;2300:58;:::i;:::-;2284:75;:::i;:::-;2393:15;;;2479:1;2475:10;;;;2463:23;;2459:32;;;2424:12;;;;2503:15;;;2500:35;;;2531:1;2528;2521:12;2500:35;2567:2;2559:6;2555:15;2579:1940;2595:6;2590:3;2587:15;2579:1940;;;2668:10;;-1:-1:-1;;;;;2735:19:56;;;2732:39;;;2767:1;2764;2757:12;2732:39;2794:24;;;;2866:4;2842:12;;;-1:-1:-1;;2838:26:56;2834:37;2831:127;;;2912:1;2941:2;2937;2930:14;2831:127;2984:22;;:::i;:::-;3048:2;3044;3040:11;3034:18;3065:33;3090:7;3065:33;:::i;:::-;3111:22;;3156:2;3193:11;;;3187:18;3221:16;;;3218:106;;;3278:1;3307:2;3303;3296:14;3218:106;3347:17;;3399:2;3391:11;;3387:21;-1:-1:-1;3377:119:56;;3450:1;3479:2;3475;3468:14;3377:119;3534:2;3530;3526:11;3520:18;3564:76;3580:59;3635:3;3580:59;:::i;3564:76::-;3684:18;;;3783:1;3779:11;;;;3771:20;;3767:29;;;3724:14;;;;3812:17;;;3809:110;;;3871:1;3901:3;3896;3889:16;3809:110;3945:11;;;;3969:167;3987:8;3980:5;3977:19;3969:167;;;4069:12;;4055:27;;4008:14;;;;4108;;;;3969:167;;;4156:14;;;4149:29;-1:-1:-1;;;4221:4:56;4213:13;;4207:20;4243:16;;;4240:109;;;4301:1;4331:3;4326;4319:16;4240:109;4385:60;4441:3;4436:2;4425:8;4421:2;4417:17;4413:26;4385:60;:::i;:::-;4369:14;;;4362:84;;;;-1:-1:-1;4459:18:56;;-1:-1:-1;;4497:12:56;;;;2612;;2579:1940;;;-1:-1:-1;4537:5:56;2054:2494;-1:-1:-1;;;;;;2054:2494:56:o;4553:1917::-;4663:6;4694:2;4737;4725:9;4716:7;4712:23;4708:32;4705:52;;;4753:1;4750;4743:12;4705:52;4780:16;;-1:-1:-1;;;;;4845:14:56;;;4842:34;;;4872:1;4869;4862:12;4842:34;4895:22;;;;4951:4;4933:16;;;4929:27;4926:47;;;4969:1;4966;4959:12;4926:47;4995:22;;:::i;:::-;5047:2;5041:9;5059:33;5084:7;5059:33;:::i;:::-;5101:22;;5154:11;;;5148:18;5178:16;;;5175:36;;;5207:1;5204;5197:12;5175:36;5230:17;;5281:4;5263:16;;;5259:27;5256:47;;;5299:1;5296;5289:12;5256:47;5327:22;;:::i;:::-;5380:2;5374:9;5408:2;5398:8;5395:16;5392:36;;;5424:1;5421;5414:12;5392:36;5447:17;;5498:4;5480:16;;;5476:27;5473:47;;;5516:1;5513;5506:12;5473:47;5544:22;;:::i;:::-;5596:2;5590:9;5608:33;5633:7;5608:33;:::i;:::-;5650:24;;5704:11;;;5698:18;5725:33;5698:18;5725:33;:::i;:::-;5774:16;;;5767:33;5839:4;5831:13;;5825:20;5857:16;;;5854:36;;;5886:1;5883;5876:12;5854:36;5926:55;5973:7;5962:8;5958:2;5954:17;5926:55;:::i;:::-;5919:4;5906:18;;5899:83;-1:-1:-1;5991:24:56;;-1:-1:-1;6046:11:56;;;6040:18;6070:16;;;6067:36;;;6099:1;6096;6089:12;6067:36;6137:82;6211:7;6200:8;6196:2;6192:17;6137:82;:::i;:::-;6132:2;6123:7;6119:16;6112:108;;6252:7;6247:2;6240:5;6236:14;6229:31;;;6299:4;6295:2;6291:13;6285:20;6269:36;;6330:2;6320:8;6317:16;6314:36;;;6346:1;6343;6336:12;6314:36;6384:55;6431:7;6420:8;6416:2;6412:17;6384:55;:::i;:::-;6377:4;6366:16;;6359:81;6370:5;4553:1917;-1:-1:-1;;;;;;4553:1917:56:o;6475:270::-;6516:3;6554:5;6548:12;6581:6;6576:3;6569:19;6597:76;6666:6;6659:4;6654:3;6650:14;6643:4;6636:5;6632:16;6597:76;:::i;:::-;6727:2;6706:15;-1:-1:-1;;6702:29:56;6693:39;;;;6734:4;6689:50;;6475:270;-1:-1:-1;;6475:270:56:o;6750:2011::-;6799:3;6827:4;6866:5;6860:12;6893:4;6888:3;6881:17;6934:1;6930;6925:3;6921:11;6917:19;6993:2;6978:12;6972:19;6968:28;6961:4;6956:3;6952:14;6945:52;7016:4;7075:2;7061:12;7057:21;7051:28;7098:4;7154:2;7138:14;7134:23;7127:4;7122:3;7118:14;7111:47;7213:4;7199:12;7195:23;7189:30;7167:52;;7250:4;7244:3;7239;7235:13;7228:27;7277:47;7319:3;7314;7310:13;7294:14;7277:47;:::i;:::-;7361:14;;;7355:21;7406:15;;;7392:12;;;7385:37;7472:21;;7502;;;7264:60;;-1:-1:-1;7634:23:56;;;-1:-1:-1;7541:14:56;;;;7595:1;7591:14;;;7580:26;;7576:35;;7675:1;;7706:1029;7722:6;7717:3;7714:15;7706:1029;;;7793:16;;;-1:-1:-1;;7789:30:56;7775:45;;7843:13;;7926:9;;7922:18;;7909:32;;7982:11;;;7976:18;8014:13;;;8007:25;;;8093:21;;7883:13;;;8127:24;;;8216:23;;;;8263:1;;8183:3;8173:14;;;8277:209;8293:8;8288:3;8285:17;8277:209;;;8370:15;;8356:30;;8455:17;;;;8321:1;8312:11;;;;;8412:14;;;;8277:209;;;8281:3;8535:2;8531;8527:11;8521:18;8499:40;;8585:4;8578:5;8574:16;8569:2;8563:4;8559:13;8552:39;8612;8645:5;8629:14;8612:39;:::i;:::-;8604:47;;;;;;8686:2;8678:6;8674:15;8664:25;;8722:2;8715:5;8711:14;8702:23;;7748:1;7743:3;7739:11;7732:18;;7706:1029;;;-1:-1:-1;8751:4:56;;6750:2011;-1:-1:-1;;;;;;;;;;;;6750:2011:56:o;8766:755::-;-1:-1:-1;;;;;9041:15:56;;;9023:34;;9093:2;9088;9073:18;;;9066:30;;;9136:13;;9132:22;;;9112:18;;;9105:50;9190:15;;9184:22;9244:4;9222:20;;;9215:34;8966:4;;9272:59;9003:3;9311:19;;9184:22;9272:59;:::i;:::-;9258:73;;9380:2;9372:6;9368:15;9362:22;9453:2;9449:7;9437:9;9429:6;9425:22;9421:36;9415:3;9404:9;9400:19;9393:65;9475:40;9508:6;9492:14;9475:40;:::i;:::-;9467:48;8766:755;-1:-1:-1;;;;;;8766:755:56:o;9526:255::-;9703:2;9692:9;9685:21;9666:4;9723:52;9771:2;9760:9;9756:18;9748:6;9723:52;:::i;:::-;9715:60;9526:255;-1:-1:-1;;;9526:255:56:o;:::-;2203:3849:53;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x60806040526004361061005a5760003560e01c80637ea0b76a116100435780637ea0b76a146100bd57806393be095e146100d0578063f037e4e3146101125761005a565b806301ffc9a714610068578063059bebe61461009d575b34801561006657600080fd5b005b34801561007457600080fd5b50610088610083366004611e97565b610125565b60405190151581526020015b60405180910390f35b3480156100a957600080fd5b506100666100b8366004611efe565b61020a565b6100666100cb366004611fa8565b6106fa565b3480156100dc57600080fd5b506101047f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610094565b61006661012036600461202d565b610a5a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f059bebe60000000000000000000000000000000000000000000000000000000014806101b857507fffffffff0000000000000000000000000000000000000000000000000000000082167f7ea0b76a00000000000000000000000000000000000000000000000000000000145b8061020457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6000806102198385018561214b565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526e22d473030f116ddee9f6b43ac78ba3600482018190526000196024830152929450909250819073ffffffffffffffffffffffffffffffffffffffff8b169063095ea7b3906044016020604051808303816000875af11580156102a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ca9190612347565b5082516001146103215760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420737761702070617468206c656e677468000000000000000060448201526064015b60405180910390fd5b8973ffffffffffffffffffffffffffffffffffffffff168360008151811061034b5761034b612364565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16146103ba5760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420696e70757420746f6b656e000000000000000000000000006044820152606401610318565b8873ffffffffffffffffffffffffffffffffffffffff16836000815181106103e4576103e4612364565b60200260200101516020015160018560008151811061040557610405612364565b6020026020010151602001515161041c91906123c2565b8151811061042c5761042c612364565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff161461049b5760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964206f757470757420746f6b656e0000000000000000000000006044820152606401610318565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8b16906370a0823190602401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052991906123d5565b8811156105785760405162461bcd60e51b815260206004820181905260248201527f496e73756666696369656e7420696e70757420746f6b656e2062616c616e63656044820152606401610318565b6040517f87517c4500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152808616602483015260448201819052600060648301528591908416906387517c4590608401600060405180830381600087803b1580156105fa57600080fd5b505af115801561060e573d6000803e3d6000fd5b50505050888460008151811061062657610626612364565b6020026020010151604001818152505060008460008151811061064b5761064b612364565b6020026020010151606001818152505060008060008373ffffffffffffffffffffffffffffffffffffffff1663286f580d8860001960006040518463ffffffff1660e01b81526004016106a0939291906123ee565b6000604051808303816000875af11580156106bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106e791908101906125ac565b5050505050505050505050505050505050565b610702610b0c565b61070b81612849565b7f0000000000000000000000000000000000000000000000000000000000000000158015906107805750806040516020016107469190612997565b604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000014155b156107b7576040517f8812562900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107c46060840184612a84565b90506000036107ff576040517f9c95219f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061080e6060850185612a84565b600081811061081f5761081f612364565b90506020028101906108319190612ace565b61083b9080612b0c565b610849906040810190612b40565b6108566060870187612a84565b600081811061086757610867612364565b90506020028101906108799190612ace565b6020013581811061088c5761088c612364565b6108a2926020606090920201908101915061202d565b905060006108b36060860186612a84565b60008181106108c4576108c4612364565b90506020028101906108d69190612ace565b6108e09080612b0c565b6108ee906060810190612b40565b6108fb6060880188612a84565b600081811061090c5761090c612364565b905060200281019061091e9190612ace565b6040013581811061093157610931612364565b610947926020606090920201908101915061202d565b905061096b73ffffffffffffffffffffffffffffffffffffffff8316876000610b65565b61098e73ffffffffffffffffffffffffffffffffffffffff831687600019610b65565b6000808773ffffffffffffffffffffffffffffffffffffffff16630997c4a0886040518263ffffffff1660e01b81526004016109ca9190612e3a565b60408051808303816000875af11580156109e8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0c919061309e565b9092509050610a3373ffffffffffffffffffffffffffffffffffffffff8516896000610b65565b610a46610a3f87612849565b8585610d2d565b5050505050610a556001600055565b505050565b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526e22d473030f116ddee9f6b43ac78ba36004820181905260001960248301529073ffffffffffffffffffffffffffffffffffffffff83169063095ea7b3906044016020604051808303816000875af1158015610ae0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a559190612347565b505050505050565b600260005403610b5e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610318565b6002600055565b801580610c0557506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015610bdf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0391906123d5565b155b610c775760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610318565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611105565b604080516001808252818301909252600091816020015b6060815260200190600190039081610d44575050604080516003808252608082019092529192506000919060208201606080368337019050506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1191906123d5565b90508015610e3a57610e3a73ffffffffffffffffffffffffffffffffffffffff861633836111fa565b60008573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eab91906130c2565b60ff169050610ebc82826000611250565b83600081518110610ecf57610ecf612364565b602090810291909101015250506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015610f49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6d91906123d5565b90508015610f9657610f9673ffffffffffffffffffffffffffffffffffffffff851633836111fa565b60008473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100791906130c2565b60ff16905061101882826000611250565b8360018151811061102b5761102b612364565b60209081029190910101525047905061104433826112d8565b808260028151811061105857611058612364565b60200260200101818152505050808260008151811061107957611079612364565b6020908102919091010152604080516001808252818301909252600091816020015b6040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915281526020019060019003908161109b57905050905085816000815181106110f0576110f0612364565b6020026020010181905250610b0483826113fe565b6000611167826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166115f79092919063ffffffff16565b90508051600014806111885750808060200190518101906111889190612347565b610a555760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610318565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a559084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610cc9565b60008260121115611285576012839003600283161561127b57611273858261160e565b9150506112d1565b611273858261165f565b60128311156112ce577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee830160018316156112c4576112738582611697565b61127385826116e5565b50825b9392505050565b804710156113285760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610318565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611382576040519150601f19603f3d011682016040523d82523d6000602084013e611387565b606091505b5050905080610a555760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610318565b336114316040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915290565b60005b83518110156115f05783818151811061144f5761144f612364565b6020026020010151915060008260000151604001515111156115e8578151805160209182015160008681523090935260408320839273ffffffffffffffffffffffffffffffffffffffff169163d6e3357a9187600001516040015160006114ba8d8b60200151611708565b604080516000815260208101918290527fffffffff0000000000000000000000000000000000000000000000000000000060e089901b16909152611506959493929190602481016130df565b600060405180830381865afa158015611523573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261154b919081019061318f565b80519193509150156115e5578351602001516040517f946aadc600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063946aadc6906115b290889085906004016131f3565b600060405180830381600087803b1580156115cc57600080fd5b505af11580156115e0573d6000803e3d6000fd5b505050505b50505b600101611434565b5050505050565b60606116068484600085611a18565b949350505050565b6000604e821061163057821561162657600019611629565b60005b9050610204565b50600a81900a828102908381838161164a5761164a61320c565b041461165857600019611606565b5092915050565b600a81900a61166e818461323b565b9050604e821061020457821561168e5761168982600a613336565b6112d1565b60009392505050565b6000604e82106116bb5782156116ae5760016116b1565b60005b60ff169050610204565b600a82900a8084816116cf576116cf61320c565b0491508082028414611658575060010192915050565b6000604e82101561168e5781600a0a83816117025761170261320c565b046112d1565b60606000825167ffffffffffffffff8111156117265761172661204a565b60405190808252806020026020018201604052801561174f578160200160208202803683370190505b509050600080845111611763576000611769565b83516001015b855160010101905060008167ffffffffffffffff81111561178c5761178c61204a565b6040519080825280602002602001820160405280156117bf57816020015b60608152602001906001900390816117aa5790505b50905060006117e4604080516002815233602082015230818301526060810190915290565b8282815181106117f6576117f6612364565b602002602001018190525060005b875181101561185457818060010192505087818151811061182757611827612364565b602002602001015183838151811061184157611841612364565b6020908102919091010152600101611804565b50855115611a0e5780806001019150508382828151811061187757611877612364565b602002602001018190525060005b8651811015611a0c576119368782815181106118a3576118a3612364565b6020026020010151600001516119136118e08a85815181106118c7576118c7612364565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b89848151811061192557611925612364565b602002602001015160400151611b17565b61196f576040517f52bf984800000000000000000000000000000000000000000000000000000000815260048101829052602401610318565b86818151811061198157611981612364565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168582815181106119b5576119b5612364565b60200260200101818152505081806001019250508681815181106119db576119db612364565b6020026020010151602001518383815181106119f9576119f9612364565b6020908102919091010152600101611885565b505b5095945050505050565b606082471015611a905760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610318565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ab99190613342565b60006040518083038185875af1925050503d8060008114611af6576040519150601f19603f3d011682016040523d82523d6000602084013e611afb565b606091505b5091509150611b0c87838387611b92565b979650505050505050565b6000806000611b268585611c18565b90925090506000816004811115611b3f57611b3f613354565b148015611b7757508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611b885750611b88868686611c5d565b9695505050505050565b60608315611c0e578251600003611c075773ffffffffffffffffffffffffffffffffffffffff85163b611c075760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610318565b5081611606565b6116068383611d9c565b6000808251604103611c4e5760208301516040840151606085015160001a611c4287828585611dc6565b94509450505050611c56565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611c94929190613383565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611cff9190613342565b600060405180830381855afa9150503d8060008114611d3a576040519150601f19603f3d011682016040523d82523d6000602084013e611d3f565b606091505b5091509150818015611d5357506020815110155b8015611b88575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611d9190830160209081019084016123d5565b149695505050505050565b815115611dac5781518083602001fd5b8060405162461bcd60e51b8152600401610318919061339c565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611dfd5750600090506003611e8e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e51573d6000803e3d6000fd5b5050604051601f19015191505073ffffffffffffffffffffffffffffffffffffffff8116611e8757600060019250925050611e8e565b9150600090505b94509492505050565b600060208284031215611ea957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146112d157600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611efb57600080fd5b50565b60008060008060008060a08789031215611f1757600080fd5b8635611f2281611ed9565b95506020870135611f3281611ed9565b94506040870135935060608701359250608087013567ffffffffffffffff80821115611f5d57600080fd5b818901915089601f830112611f7157600080fd5b813581811115611f8057600080fd5b8a6020828501011115611f9257600080fd5b6020830194508093505050509295509295509295565b600080600060608486031215611fbd57600080fd5b8335611fc881611ed9565b9250602084013567ffffffffffffffff80821115611fe557600080fd5b9085019060a08288031215611ff957600080fd5b9092506040850135908082111561200f57600080fd5b5084016040818703121561202257600080fd5b809150509250925092565b60006020828403121561203f57600080fd5b81356112d181611ed9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561209c5761209c61204a565b60405290565b6040516060810167ffffffffffffffff8111828210171561209c5761209c61204a565b6040805190810167ffffffffffffffff8111828210171561209c5761209c61204a565b604051601f8201601f1916810167ffffffffffffffff811182821017156121115761211161204a565b604052919050565b600067ffffffffffffffff8211156121335761213361204a565b5060051b60200190565b8015158114611efb57600080fd5b6000806040838503121561215e57600080fd5b6121688335611ed9565b8235915067ffffffffffffffff6020840135111561218557600080fd5b6020830135830184601f82011261219b57600080fd5b6121ad6121a88235612119565b6120e8565b81358082526020808301929160051b8401018710156121cb57600080fd5b602083015b6020843560051b8501018110156123395767ffffffffffffffff813511156121f757600080fd5b803584016080601f19828b0301121561220f57600080fd5b612217612079565b6122246020830135611ed9565b6020820135815267ffffffffffffffff6040830135111561224457600080fd5b604082013582018a603f82011261225a57600080fd5b61226a6121a86020830135612119565b602082810135808352908201919060600283016040018d101561228c57600080fd5b604083015b60406060602086013502850101811015612309576060818f0312156122b557600080fd5b6122bd6120a2565b6122c78235611ed9565b813581526122d86020830135611ed9565b602082013560208201526122ef604083013561213d565b604082810135908201528352602090920191606001612291565b506020848101919091526060858101356040860152608090950135948401949094525050845292830192016121d0565b508093505050509250929050565b60006020828403121561235957600080fd5b81516112d18161213d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561020457610204612393565b6000602082840312156123e757600080fd5b5051919050565b600060808083016080845280875180835260a0925060a08601915060a08160051b8701016020808b016000805b858110156124ee578a85037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600187528251805173ffffffffffffffffffffffffffffffffffffffff9081168752858201518688018c905280518c8901819052908701919085908c8a01905b808310156124c25784518051851683528a81015185168b8401526040908101511515908301529389019360019290920191606090910190612486565b50604085810151908b01526060948501519490990193909352505050958301959183019160010161241b565b505050870189905287151560408801528681036060880152600281527f30780000000000000000000000000000000000000000000000000000000000006020820152604081019a9950505050505050505050565b600082601f83011261255357600080fd5b815160206125636121a883612119565b8083825260208201915060208460051b87010193508684111561258557600080fd5b602086015b848110156125a1578051835291830191830161258a565b509695505050505050565b6000806000606084860312156125c157600080fd5b835167ffffffffffffffff808211156125d957600080fd5b6125e587838801612542565b94506020915081860151818111156125fc57600080fd5b8601601f8101881361260d57600080fd5b805161261b6121a882612119565b81815260059190911b8201840190848101908a83111561263a57600080fd5b928501925b8284101561266157835161265281611ed9565b8252928501929085019061263f565b60408a015190975094505050508082111561267b57600080fd5b5061268886828701612542565b9150509250925092565b600082601f8301126126a357600080fd5b813567ffffffffffffffff8111156126bd576126bd61204a565b6126d06020601f19601f840116016120e8565b8181528460208386010111156126e557600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261271357600080fd5b813560206127236121a883612119565b82815260059290921b8401810191818101908684111561274257600080fd5b8286015b848110156125a157803567ffffffffffffffff8082111561276657600080fd5b908801906060828b03601f1901121561277f5760008081fd5b6127876120a2565b8683013561279481611ed9565b8152604083810135838111156127aa5760008081fd5b8401603f81018d136127bc5760008081fd5b888101356127cc6121a882612119565b81815260059190911b82018301908a8101908f8311156127ec5760008081fd5b928401925b8284101561280a5783358252928b0192908b01906127f1565b858c01525050506060840135838111156128245760008081fd5b6128328d8a83880101612692565b918301919091525085525050918301918301612746565b60006040823603121561285b57600080fd5b6128636120c5565b823567ffffffffffffffff8082111561287b57600080fd5b81850191506060823603121561289057600080fd5b6128986120a2565b82356128a381611ed9565b815260208301356128b381611ed9565b60208201526040830135828111156128ca57600080fd5b6128d636828601612692565b604083015250835260208501359150808211156128f257600080fd5b506128ff36828601612702565b60208301525092915050565b60005b8381101561292657818101518382015260200161290e565b50506000910152565b6000815180845261294781602086016020860161290b565b601f01601f19169290920160200192915050565b60008151808452602080850194506020840160005b8381101561298c57815187529582019590820190600101612970565b509495945050505050565b60006020808352606084516040808487015273ffffffffffffffffffffffffffffffffffffffff808351166060880152808584015116608088015260408301519250606060a08801526129ed60c088018461292f565b925084880151601f19808986030160408a01528482518087528887019150888160051b880101898501945060005b82811015612a73578489830301845285518781511683528b8101518b8d850152612a478c85018261295b565b918a0151848303858c0152919050612a5f818361292f565b978d0197958d019593505050600101612a1b565b509c9b505050505050505050505050565b6000808335601e19843603018112612a9b57600080fd5b83018035915067ffffffffffffffff821115612ab657600080fd5b6020019150600581901b3603821315611c5657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612b0257600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61833603018112612b0257600080fd5b6000808335601e19843603018112612b5757600080fd5b83018035915067ffffffffffffffff821115612b7257600080fd5b6020019150606081023603821315611c5657600080fd5b6000808335601e19843603018112612ba057600080fd5b830160208101925035905067ffffffffffffffff811115612bc057600080fd5b8060051b3603821315611c5657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112612c0657600080fd5b90910192915050565b6000808335601e19843603018112612c2657600080fd5b830160208101925035905067ffffffffffffffff811115612c4657600080fd5b803603821315611c5657600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6000808335601e19843603018112612c9757600080fd5b830160208101925035905067ffffffffffffffff811115612cb757600080fd5b606081023603821315611c5657600080fd5b60ff81168114611efb57600080fd5b8183526000602080850194508260005b8581101561298c578135612cfb81611ed9565b73ffffffffffffffffffffffffffffffffffffffff16875281830135612d2081612cc9565b60ff16878401526040828101359088015260609687019690910190600101612ce8565b818352602080840193600091600585811b830182018585805b89811015612e2b57601f19878503018b52612d77838a612bd2565b60608135612d8481611ed9565b73ffffffffffffffffffffffffffffffffffffffff168652612da882890183612b89565b828a8901528083890152608092507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612de2578586fd5b881b808289850137870190506040612dfc84820185612c0f565b94508389840301828a0152612e148484018683612c55565b9f8b019f9850505094880194505050600101612d5c565b50919998505050505050505050565b6000602080835260c083018435828501526040828601358186015260608187013581870152612e6b81880188612b89565b60a060808901528481865260e08901905060e08260051b8a010195508260005b83811015613071577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff208b890301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81863603018112612eec57600080fd5b85018035368290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61018112612f2157600080fd5b60808a5281018035612f3281611ed9565b73ffffffffffffffffffffffffffffffffffffffff80821660808d0152612f5b8d840184612bd2565b915060a0808d01528135612f6e81611ed9565b81166101208d0152818d0135612f8381611ed9565b166101408c0152612f96818b0182612c0f565b9150896101608d0152612fae6101808d018383612c55565b915050612fbd8a830183612c80565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808e85030160c08f0152612ff3848385612cd8565b93506130018c860186612c80565b93509150808e85030160e08f01525061301b838383612cd8565b9250505060808201356101008c01528b8301358c8c0152898301358a8c015261304689840184612b89565b935091508a8103898c015261305c818484612d43565b9a505050928901925090880190600101612e8b565b505050505050506130856080860186612c0f565b9250601f198583030160a0860152611b88828483612c55565b600080604083850312156130b157600080fd5b505080516020909101519092909150565b6000602082840312156130d457600080fd5b81516112d181612cc9565b73ffffffffffffffffffffffffffffffffffffffff8716815260006020878184015260c0604084015261311560c084018861292f565b86606085015283810360808501528086518083528383019150838160051b84010184890160005b8381101561316a57601f1986840301855261315883835161295b565b9487019492509086019060010161313c565b505086810360a088015261317e818961295b565b9d9c50505050505050505050505050565b600080604083850312156131a257600080fd5b825167ffffffffffffffff808211156131ba57600080fd5b6131c686838701612542565b935060208501519150808211156131dc57600080fd5b506131e985828601612542565b9150509250929050565b828152604060208201526000611606604083018461295b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b808202811582820484141761020457610204612393565b600181815b8085111561328d57816000190482111561327357613273612393565b8085161561328057918102915b93841c9390800290613257565b509250929050565b6000826132a457506001610204565b816132b157506000610204565b81600181146132c757600281146132d1576132ed565b6001915050610204565b60ff8411156132e2576132e2612393565b50506001821b610204565b5060208310610133831016604e8410600b8410161715613310575081810a610204565b61331a8383613252565b806000190482111561332e5761332e612393565b029392505050565b60006112d18383613295565b60008251612b0281846020870161290b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b828152604060208201526000611606604083018461292f565b6020815260006112d1602083018461292f56","sourceMap":"2203:3849:53:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2533:290:52;;;;;;;;;;-1:-1:-1;2533:290:52;;;;;:::i;:::-;;:::i;:::-;;;612:14:56;;605:22;587:41;;575:2;560:18;2533:290:52;;;;;;;;2883:3110:53;;;;;;;;;;-1:-1:-1;2883:3110:53;;;;;:::i;:::-;;:::i;2877:1011:52:-;;;;;;:::i;:::-;;:::i;1560:38:51:-;;;;;;;;;;;;;;;;;;2797:25:56;;;2785:2;2770:18;1560:38:51;2651:177:56;2653:179:53;;;;;;:::i;:::-;;:::i;2533:290:52:-;2618:4;2642:55;;;2657:40;2642:55;;2641:135;;-1:-1:-1;2715:60:52;;;2730:45;2715:60;2641:135;:175;;;-1:-1:-1;952:25:14;937:40;;;;2780:36:52;2634:182;2533:290;-1:-1:-1;;2533:290:52:o;2883:3110:53:-;3215:23;;3283:96;;;;3307:14;3283:96;:::i;:::-;3548:54;;;;;3416:42;3548:54;;;7930:74:56;;;-1:-1:-1;;8020:18:56;;;8013:34;3214:165:53;;-1:-1:-1;3214:165:53;;-1:-1:-1;3416:42:53;;3548:26;;;;;;7903:18:56;;3548:54:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3655:8;:15;3674:1;3655:20;3647:57;;;;-1:-1:-1;;;3647:57:53;;8510:2:56;3647:57:53;;;8492:21:56;8549:2;8529:18;;;8522:30;8588:26;8568:18;;;8561:54;8632:18;;3647:57:53;;;;;;;;;3754:10;3722:42;;3730:8;3739:1;3730:11;;;;;;;;:::i;:::-;;;;;;;:19;;;3722:42;;;3714:74;;;;-1:-1:-1;;;3714:74:53;;9052:2:56;3714:74:53;;;9034:21:56;9091:2;9071:18;;;9064:30;9130:21;9110:18;;;9103:49;9169:18;;3714:74:53;8850:343:56;3714:74:53;3875:11;3806:80;;3814:8;3823:1;3814:11;;;;;;;;:::i;:::-;;;;;;;:17;;;3859:1;3832:8;3841:1;3832:11;;;;;;;;:::i;:::-;;;;;;;:17;;;:24;:28;;;;:::i;:::-;3814:47;;;;;;;;:::i;:::-;;;;;;;:56;;;3806:80;;;3798:113;;;;-1:-1:-1;;;3798:113:53;;9722:2:56;3798:113:53;;;9704:21:56;9761:2;9741:18;;;9734:30;9800:22;9780:18;;;9773:50;9840:18;;3798:113:53;9520:344:56;3798:113:53;3948:43;;;;;3985:4;3948:43;;;10015:74:56;3948:28:53;;;;;;9988:18:56;;3948:43:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3929:15;:62;;3921:107;;;;-1:-1:-1;;;3921:107:53;;10491:2:56;3921:107:53;;;10473:21:56;;;10510:18;;;10503:30;10569:34;10549:18;;;10542:62;10621:18;;3921:107:53;10289:356:56;3921:107:53;4312:67;;;;;:16;10967:15:56;;;4312:67:53;;;10949:34:56;11019:15;;;10999:18;;;10992:43;11051:18;;;11044:43;;;4081:29:53;11103:18:56;;;11096:55;4128:15:53;;4312:16;;;;;;10860:19:56;;4312:67:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5171:15;5143:8;5152:1;5143:11;;;;;;;;:::i;:::-;;;;;;;:25;;:43;;;;;5223:1;5196:8;5205:1;5196:11;;;;;;;;:::i;:::-;;;;;;;:24;;:28;;;;;5639:31;5672:26;5700:27;5731:14;:26;;;5758:8;-1:-1:-1;;5787:5:53;5731:68;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5731:68:53;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;2883:3110:53:o;2877:1011:52:-;2261:21:5;:19;:21::i;:::-;1900:186:51::1;3053:4:52::0;1900:186:51::1;:::i;:::-;1957:9;:23:::0;;::::1;::::0;:67:::1;;;2018:4;2007:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;1997:27;;;;;;1984:9;:40;;1957:67;1953:116;;;2047:11;;;;;;;;;;;;;;1953:116;3146:17:52::2;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;:24;;3174:1;3146:29:::0;3142:77:::2;;3198:10;;;;;;;;;;;;;;3142:77;3229:24;3256:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3274:1;3256:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:26;::::0;;::::2;:::i;:::-;:38;::::0;::::2;::::0;::::2;::::0;::::2;:::i;:::-;3295:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3313:1;3295:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:33;;;3256:73;;;;;;;:::i;:::-;:79;::::0;::::2;:73;::::0;;::::2;;:79:::0;;::::2;::::0;-1:-1:-1;3256:79:52::2;:::i;:::-;3229:106:::0;-1:-1:-1;3345:25:52::2;3373:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3391:1;3373:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:26;::::0;;::::2;:::i;:::-;:39;::::0;::::2;::::0;::::2;::::0;::::2;:::i;:::-;3413:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3431:1;3413:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:34;;;3373:75;;;;;;;:::i;:::-;:81;::::0;::::2;:75;::::0;;::::2;;:81:::0;;::::2;::::0;-1:-1:-1;3373:81:52::2;:::i;:::-;3345:109:::0;-1:-1:-1;3465:59:52::2;:36;::::0;::::2;3510:9:::0;3522:1:::2;3465:36;:59::i;:::-;3534:75;:36;::::0;::::2;3579:9:::0;-1:-1:-1;;3534:36:52::2;:75::i;:::-;3620:18;3640:19:::0;3663:9:::2;:21;;;3685:10;3663:33;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3619:77:::0;;-1:-1:-1;3619:77:52;-1:-1:-1;3741:59:52::2;:36;::::0;::::2;3786:9:::0;3798:1:::2;3741:36;:59::i;:::-;3811:70;;3839:4:::0;3811:70:::2;:::i;:::-;3845:16;3863:17;3811:27;:70::i;:::-;3063:825;;;;2292:1:5::1;2303:20:::0;1716:1;2809:7;:22;2629:209;2303:20;2877:1011:52;;;:::o;2653:179:53:-;2776:49;;;;;2724:42;2776:49;;;7930:74:56;;;-1:-1:-1;;8020:18:56;;;8013:34;2724:42:53;2776:21;;;;;;7903:18:56;;2776:49:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;3937:100:52:-;;;;;;;:::o;2336:287:5:-;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:5;;35087:2:56;2460:63:5;;;35069:21:56;35126:2;35106:18;;;35099:30;35165:33;35145:18;;;35138:61;35216:18;;2460:63:5;34885:355:56;2460:63:5;1759:1;2598:7;:18;2336:287::o;1818:573:9:-;2143:10;;;2142:62;;-1:-1:-1;2159:39:9;;;;;2183:4;2159:39;;;35480:34:56;2159:15:9;35550::56;;;35530:18;;;35523:43;2159:15:9;;;;;35392:18:56;;2159:39:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;2142:62;2121:163;;;;-1:-1:-1;;;2121:163:9;;35779:2:56;2121:163:9;;;35761:21:56;35818:2;35798:18;;;35791:30;35857:34;35837:18;;;35830:62;35928:24;35908:18;;;35901:52;35970:19;;2121:163:9;35577:418:56;2121:163:9;2321:62;;7960:42:56;7948:55;;2321:62:9;;;7930:74:56;8020:18;;;8013:34;;;2294:90:9;;2314:5;;2344:22;;7903:18:56;;2321:62:9;;;;-1:-1:-1;;2321:62:9;;;;;;;;;;;;;;;;;;;;;;;;;;;2294:19;:90::i;1058:2206:55:-;1200:18;;;1216:1;1200:18;;;;;;;;;1171:26;;1200:18;;;;;;;;;;;;;;;;;-1:-1:-1;;1251:16:55;;;1265:1;1251:16;;;;;;;;;1171:47;;-1:-1:-1;1228:20:55;;1251:16;;;;;;;;;;;-1:-1:-1;;1375:49:55;;;;;1418:4;1375:49;;;10015:74:56;1228:39:55;;-1:-1:-1;1352:20:55;;1375:34;;;;;;9988:18:56;;1375:49:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1352:72;-1:-1:-1;1442:16:55;;1438:118;;1478:63;:37;;;1516:10;1528:12;1478:37;:63::i;:::-;1569:21;1608:16;1593:41;;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1569:67;;;;1659:214;1710:12;1740:13;1858:1;1659:33;:214::i;:::-;1650:3;1654:1;1650:6;;;;;;;;:::i;:::-;;;;;;;;;;:223;-1:-1:-1;;1993:50:55;;;;;2037:4;1993:50;;;10015:74:56;1969:21:55;;1993:35;;;;;;9988:18:56;;1993:50:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1969:74;-1:-1:-1;2061:17:55;;2057:121;;2098:65;:38;;;2137:10;2149:13;2098:38;:65::i;:::-;2192:22;2232:17;2217:42;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2192:69;;;;2284:216;2335:13;2366:14;2485:1;2284:33;:216::i;:::-;2275:3;2279:1;2275:6;;;;;;;;:::i;:::-;;;;;;;;;;:225;-1:-1:-1;2985:21:55;;-1:-1:-1;3020:50:55;3046:10;2985:21;3020:17;:50::i;:::-;3093:10;3084:3;3088:1;3084:6;;;;;;;;:::i;:::-;;;;;;:19;;;;;2521:593;3137:3;3124:7;3132:1;3124:10;;;;;;;;:::i;:::-;;;;;;;;;;:16;3174:15;;;3187:1;3174:15;;;;;;;;;3151:20;;3174:15;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3174:15:55;;;;;;;;;;;;;;;3151:38;;3209:4;3199;3204:1;3199:7;;;;;;;;:::i;:::-;;;;;;:14;;;;3223:34;3243:7;3252:4;3223:19;:34::i;5196:642:9:-;5615:23;5641:69;5669:4;5641:69;;;;;;;;;;;;;;;;;5649:5;5641:27;;;;:69;;;;;:::i;:::-;5615:95;;5728:10;:17;5749:1;5728:22;:56;;;;5765:10;5754:30;;;;;;;;;;;;:::i;:::-;5720:111;;;;-1:-1:-1;;;5720:111:9;;36454:2:56;5720:111:9;;;36436:21:56;36493:2;36473:18;;;36466:30;36532:34;36512:18;;;36505:62;36603:12;36583:18;;;36576:40;36633:19;;5720:111:9;36252:406:56;941:175:9;1050:58;;7960:42:56;7948:55;;1050:58:9;;;7930:74:56;8020:18;;;8013:34;;;1023:86:9;;1043:5;;1073:23;;7903:18:56;;1050:58:9;7756:297:56;6376:849:3;6460:7;6530:8;344:2:2;6507:31:3;6503:706;;;344:2:2;6578:31:3;;;594:6:2;6631:21:3;;:25;6627:185;;6687:31;6705:1;6708:9;6687:17;:31::i;:::-;6680:38;;;;;6627:185;6772:21;6780:1;6783:9;6772:7;:21::i;6503:706::-;344:2:2;6836:8:3;:31;6832:377;;;6909:31;;;507:1:2;6962:21:3;;:25;6958:190;;7018:32;7035:1;7038:11;7018:16;:32::i;6958:190::-;7104:25;7114:1;7117:11;7104:9;:25::i;6832:377::-;-1:-1:-1;7193:1:3;6832:377;6376:849;;;;;:::o;2647:312:10:-;2761:6;2736:21;:31;;2728:73;;;;-1:-1:-1;;;2728:73:10;;36865:2:56;2728:73:10;;;36847:21:56;36904:2;36884:18;;;36877:30;36943:31;36923:18;;;36916:59;36992:18;;2728:73:10;36663:353:56;2728:73:10;2813:12;2831:9;:14;;2853:6;2831:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2812:52;;;2882:7;2874:78;;;;-1:-1:-1;;;2874:78:10;;37433:2:56;2874:78:10;;;37415:21:56;37472:2;37452:18;;;37445:30;37511:34;37491:18;;;37484:62;37582:28;37562:18;;;37555:56;37628:19;;2874:78:10;37231:422:56;4688:935:54;4836:10;4859:18;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4859:18:54;4892:9;4887:730;4911:4;:11;4907:1;:15;4887:730;;;4950:4;4955:1;4950:7;;;;;;;;:::i;:::-;;;;;;;4943:14;;5008:1;4975:4;:14;;;:23;;;:30;:34;4971:636;;;5081:14;;:26;;5135:20;;;;;5030:22;1218:25:42;;;5226:4:54;1256:20:42;;;1324:4;1311:18;;5030:22:54;;5081:32;;;;;5254:4;:14;;;:23;;;5318:1;5342:45;5359:7;5368:4;:18;;;5342:16;:45::i;:::-;5409:16;;;5423:1;5409:16;;;;;;;;;5081:362;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5081:362:54;;;;;;;;;;;;:::i;:::-;5490:13;;5029:414;;-1:-1:-1;5029:414:54;-1:-1:-1;5490:17:54;5486:107;;5531:14;;:20;;;:43;;;;;:24;;;;;;;:43;;5556:9;;5567:6;;5531:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5486:107;5011:596;;4971:636;4924:3;;4887:730;;;;4763:860;;4688:935;;:::o;4108:223:10:-;4241:12;4272:52;4294:6;4302:4;4308:1;4311:12;4272:21;:52::i;:::-;4265:59;4108:223;-1:-1:-1;;;;4108:223:10:o;3853:689:3:-;3933:9;817:2:2;3982:9:3;:34;3978:548;;4040:6;;:30;;-1:-1:-1;;4040:30:3;;;4049:1;4040:30;4036:34;;3978:548;;;-1:-1:-1;4252:2:3;:15;;;4289:6;;;;:1;4252:15;4289:6;4252:15;4476:6;;;;:::i;:::-;;:11;:35;;-1:-1:-1;;4476:35:3;;;-1:-1:-1;4490:1:3;4472:39;-1:-1:-1;;3853:689:3:o;2909:688::-;3084:2;:15;;;3123:5;3084:15;3123:1;:5;:::i;:::-;3119:9;;817:2:2;3498:9:3;:34;3494:97;;3552:6;;:28;;3565:15;3571:9;3565:2;:15;:::i;:::-;3552:28;;;3561:1;3548:32;2909:688;-1:-1:-1;;;2909:688:3:o;5491:598::-;5572:9;817:2:2;5621:11:3;:36;5617:456;;5681:6;;:14;;5694:1;5681:14;;;5690:1;5681:14;5677:18;;;;5617:456;;;5746:2;:17;;;;5785:1;5746:17;5785:5;;;;:::i;:::-;;5781:9;;6009:1;6005;:5;6000:1;:10;5996:63;;-1:-1:-1;6039:1:3;6034:6;;5491:598;-1:-1:-1;;5491:598:3:o;4915:207::-;4989:7;817:2:2;5039:11:3;:36;;:66;;5093:11;5087:2;:17;5082:1;:23;;;;;:::i;:::-;;5039:66;;7619:2290:39;7754:18;7812:24;7853:14;:21;7839:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7839:36:39;;7812:63;;8024:21;8098:1;8074:14;:21;:25;:57;;8130:1;8074:57;;;8102:14;:21;8126:1;8102:25;8074:57;8052:11;:18;8048:1;:22;:84;8024:108;;8147:26;8192:13;8176:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8147:59;;8220:14;8270:17;3181:4:23;3175:11;;3213:1;3199:16;;2741:10:39;3246:4:23;3235:16;;3228:27;2779:4:39;3275:16:23;;;3268:27;2664:16:39;3321::23;;3308:30;;;3175:11;2625:169:39;8270:17;8252:7;8260:6;8252:15;;;;;;;;:::i;:::-;;;;;;:35;;;;8307:9;8302:140;8326:11;:18;8322:1;:22;8302:140;;;8369:8;;;;;;;8413:11;8425:1;8413:14;;;;;;;;:::i;:::-;;;;;;;8395:7;8403:6;8395:15;;;;;;;;:::i;:::-;;;;;;;;;;:32;8346:3;;8302:140;;;-1:-1:-1;8460:21:39;;:25;8456:1408;;8505:8;;;;;;;8549:7;8531;8539:6;8531:15;;;;;;;;:::i;:::-;;;;;;:25;;;;8580:9;8575:1275;8599:14;:21;8595:1;:25;8575:1275;;;9277:284;9343:14;9358:1;9343:17;;;;;;;;:::i;:::-;;;;;;;:24;;;9397:81;9426:51;9451:14;9466:1;9451:17;;;;;;;;:::i;:::-;;;;;;;:25;;;4172:13:0;;4187:4;4168:24;;;4149:17;;4139:54;;3999:210;9426:51:39;7389:34:12;7189:15;7376:48;;;7444:4;7437:18;;;;7495:4;7479:21;;;7120:396;9397:81:39;9508:14;9523:1;9508:17;;;;;;;;:::i;:::-;;;;;;;:27;;;9277:36;:284::i;:::-;8649:1010;;9617:19;;;;;;;;2797:25:56;;;2770:18;;9617:19:39;2651:177:56;8649:1010:39;9710:14;9725:1;9710:17;;;;;;;;:::i;:::-;;;;;;;:24;;;9694:42;;9681:7;9689:1;9681:10;;;;;;;;:::i;:::-;;;;;;:55;;;;;9758:8;;;;;;;9806:14;9821:1;9806:17;;;;;;;;:::i;:::-;;;;;;;:25;;;9788:7;9796:6;9788:15;;;;;;;;:::i;:::-;;;;;;;;;;:43;8622:3;;8575:1275;;;;8456:1408;-1:-1:-1;9885:7:39;7619:2290;-1:-1:-1;;;;;7619:2290:39:o;5165:446:10:-;5330:12;5387:5;5362:21;:30;;5354:81;;;;-1:-1:-1;;;5354:81:10;;42460:2:56;5354:81:10;;;42442:21:56;42499:2;42479:18;;;42472:30;42538:34;42518:18;;;42511:62;42609:8;42589:18;;;42582:36;42635:19;;5354:81:10;42258:402:56;5354:81:10;5446:12;5460:23;5487:6;:11;;5506:5;5513:4;5487:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5445:73;;;;5535:69;5562:6;5570:7;5579:10;5591:12;5535:26;:69::i;:::-;5528:76;5165:446;-1:-1:-1;;;;;;;5165:446:10:o;1014:366:13:-;1120:4;1137:17;1156:24;1184:33;1201:4;1207:9;1184:16;:33::i;:::-;1136:81;;-1:-1:-1;1136:81:13;-1:-1:-1;1256:26:13;1247:5;:35;;;;;;;;:::i;:::-;;:58;;;;;1299:6;1286:19;;:9;:19;;;1247:58;1246:127;;;;1322:51;1349:6;1357:4;1363:9;1322:26;:51::i;:::-;1227:146;1014:366;-1:-1:-1;;;;;;1014:366:13:o;7671:628:10:-;7851:12;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;1702:19;;;;8113:60;;;;-1:-1:-1;;;8113:60:10;;43348:2:56;8113:60:10;;;43330:21:56;43387:2;43367:18;;;43360:30;43426:31;43406:18;;;43399:59;43475:18;;8113:60:10;43146:353:56;8113:60:10;-1:-1:-1;8208:10:10;8201:17;;7875:418;8249:33;8257:10;8269:12;8249:7;:33::i;2145:730:12:-;2226:7;2235:12;2263:9;:16;2283:2;2263:22;2259:610;;2599:4;2584:20;;2578:27;2648:4;2633:20;;2627:27;2705:4;2690:20;;2684:27;2301:9;2676:36;2746:25;2757:4;2676:36;2578:27;2627;2746:10;:25::i;:::-;2739:32;;;;;;;;;2259:610;-1:-1:-1;2818:1:12;;-1:-1:-1;2822:35:12;2259:610;2145:730;;;;;:::o;1786:473:13:-;1929:4;1946:12;1960:19;1983:6;:17;;2037:34;;;2073:4;2079:9;2014:75;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;2014:75:13;;;;;;;;;;;;;;;;;;;;;;;;;;;1983:116;;;;2014:75;1983:116;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1945:154;;;;2117:7;:42;;;;;2157:2;2140:6;:13;:19;;2117:42;:134;;;;-1:-1:-1;2175:29:13;;2216:34;;2175:29;;;;;;;;;;;;:::i;:::-;:76;;1786:473;-1:-1:-1;;;;;;1786:473:13:o;8821:540:10:-;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;-1:-1:-1;;;9324:20:10;;;;;;;;:::i;5009:1456:12:-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:12;;-1:-1:-1;6123:30:12;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;44437:25:56;;;44510:4;44498:17;;44478:18;;;44471:45;;;;44532:18;;;44525:34;;;44575:18;;;44568:34;;;6276:24:12;;44409:19:56;;6276:24:12;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:12;;-1:-1:-1;;6276:24:12;;;-1:-1:-1;;6314:20:12;;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;-1:-1:-1;6437:20:12;;-1:-1:-1;5009:1456:12;;;;;;;;:::o;14:332:56:-;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;639:154;725:42;718:5;714:54;707:5;704:65;694:93;;783:1;780;773:12;694:93;639:154;:::o;798:1005::-;904:6;912;920;928;936;944;997:3;985:9;976:7;972:23;968:33;965:53;;;1014:1;1011;1004:12;965:53;1053:9;1040:23;1072:31;1097:5;1072:31;:::i;:::-;1122:5;-1:-1:-1;1179:2:56;1164:18;;1151:32;1192:33;1151:32;1192:33;:::i;:::-;1244:7;-1:-1:-1;1298:2:56;1283:18;;1270:32;;-1:-1:-1;1349:2:56;1334:18;;1321:32;;-1:-1:-1;1404:3:56;1389:19;;1376:33;1428:18;1458:14;;;1455:34;;;1485:1;1482;1475:12;1455:34;1523:6;1512:9;1508:22;1498:32;;1568:7;1561:4;1557:2;1553:13;1549:27;1539:55;;1590:1;1587;1580:12;1539:55;1630:2;1617:16;1656:2;1648:6;1645:14;1642:34;;;1672:1;1669;1662:12;1642:34;1717:7;1712:2;1703:6;1699:2;1695:15;1691:24;1688:37;1685:57;;;1738:1;1735;1728:12;1685:57;1769:2;1765;1761:11;1751:21;;1791:6;1781:16;;;;;798:1005;;;;;;;;:::o;1808:838::-;1970:6;1978;1986;2039:2;2027:9;2018:7;2014:23;2010:32;2007:52;;;2055:1;2052;2045:12;2007:52;2094:9;2081:23;2113:31;2138:5;2113:31;:::i;:::-;2163:5;-1:-1:-1;2219:2:56;2204:18;;2191:32;2242:18;2272:14;;;2269:34;;;2299:1;2296;2289:12;2269:34;2322:22;;;;2378:3;2360:16;;;2356:26;2353:46;;;2395:1;2392;2385:12;2353:46;2418:2;;-1:-1:-1;2473:2:56;2458:18;;2445:32;;2489:16;;;2486:36;;;2518:1;2515;2508:12;2486:36;-1:-1:-1;2541:24:56;;2599:2;2581:16;;;2577:25;2574:45;;;2615:1;2612;2605:12;2574:45;2638:2;2628:12;;;1808:838;;;;;:::o;2833:247::-;2892:6;2945:2;2933:9;2924:7;2920:23;2916:32;2913:52;;;2961:1;2958;2951:12;2913:52;3000:9;2987:23;3019:31;3044:5;3019:31;:::i;3085:184::-;3137:77;3134:1;3127:88;3234:4;3231:1;3224:15;3258:4;3255:1;3248:15;3274:253;3346:2;3340:9;3388:4;3376:17;;3423:18;3408:34;;3444:22;;;3405:62;3402:88;;;3470:18;;:::i;:::-;3506:2;3499:22;3274:253;:::o;3532:::-;3604:2;3598:9;3646:4;3634:17;;3681:18;3666:34;;3702:22;;;3663:62;3660:88;;;3728:18;;:::i;3790:257::-;3862:4;3856:11;;;3894:17;;3941:18;3926:34;;3962:22;;;3923:62;3920:88;;;3988:18;;:::i;4052:334::-;4123:2;4117:9;4179:2;4169:13;;-1:-1:-1;;4165:86:56;4153:99;;4282:18;4267:34;;4303:22;;;4264:62;4261:88;;;4329:18;;:::i;:::-;4365:2;4358:22;4052:334;;-1:-1:-1;4052:334:56:o;4391:204::-;4472:4;4505:18;4497:6;4494:30;4491:56;;;4527:18;;:::i;:::-;-1:-1:-1;4572:1:56;4568:14;4584:4;4564:25;;4391:204::o;4600:118::-;4686:5;4679:13;4672:21;4665:5;4662:32;4652:60;;4708:1;4705;4698:12;4723:3028;4863:6;4871;4924:2;4912:9;4903:7;4899:23;4895:32;4892:52;;;4940:1;4937;4930:12;4892:52;4953:49;4991:9;4978:23;4953:49;:::i;:::-;5034:9;5021:23;5011:33;;5093:18;5087:2;5076:9;5072:18;5059:32;5056:56;5053:76;;;5125:1;5122;5115:12;5053:76;5191:2;5180:9;5176:18;5163:32;5152:9;5148:48;5234:7;5227:4;5223:2;5219:13;5215:27;5205:55;;5256:1;5253;5246:12;5205:55;5280:95;5296:78;5370:2;5357:16;5296:78;:::i;:::-;5280:95;:::i;:::-;5421:16;;5409:29;;;5463:2;5454:12;;;;5397:3;5497:1;5493:24;5485:33;;5481:42;5478:55;-1:-1:-1;5475:75:56;;;5546:1;5543;5536:12;5475:75;5578:2;5574;5570:11;5590:2131;5653:2;5646;5633:16;5630:1;5626:24;5622:2;5618:33;5614:42;5609:3;5606:51;5590:2131;;;5737:18;5731:3;5718:17;5715:41;5712:61;;;5769:1;5766;5759:12;5712:61;5817:3;5804:17;5800:2;5796:26;5933:4;-1:-1:-1;;5859:2:56;5850:7;5846:16;5842:89;5838:100;5835:120;;;5951:1;5948;5941:12;5835:120;5981:22;;:::i;:::-;6016:51;6062:2;6058;6054:11;6041:25;6016:51;:::i;:::-;6115:2;6111;6107:11;6094:25;6087:5;6080:40;6166:18;6160:2;6156;6152:11;6139:25;6136:49;6133:69;;;6198:1;6195;6188:12;6133:69;6254:2;6250;6246:11;6233:25;6229:2;6225:34;6299:7;6294:2;6290;6286:11;6282:25;6272:53;;6321:1;6318;6311:12;6272:53;6351:104;6367:87;6449:2;6445;6441:11;6428:25;6367:87;:::i;6351:104::-;6534:2;6526:11;;;6513:25;6499:40;;;6561:14;;;;6481:5;6637:4;6606:36;6598:45;;6645:2;6594:54;6591:67;-1:-1:-1;6588:87:56;;;6671:1;6668;6661:12;6588:87;6709:2;6705;6701:11;6725:751;6806:2;6798:4;6792:2;6788;6784:11;6771:25;6767:36;6763:2;6759:45;6755:54;6748:5;6745:65;6725:751;;;6911:4;6903:5;6894:7;6890:19;6886:30;6883:50;;;6929:1;6926;6919:12;6883:50;6965:22;;:::i;:::-;7004:45;7042:5;7029:19;7004:45;:::i;:::-;7095:5;7082:19;7073:7;7066:36;7119:54;7168:2;7161:5;7157:14;7144:28;7119:54;:::i;:::-;7239:2;7232:5;7228:14;7215:28;7210:2;7201:7;7197:16;7190:54;7261:51;7307:2;7300:5;7296:14;7283:28;7261:51;:::i;:::-;7378:2;7367:14;;;7354:28;7336:16;;;7329:54;7400:22;;7459:2;7448:14;;;;6845:4;6834:16;6725:751;;;-1:-1:-1;7507:2:56;7496:14;;;7489:29;;;;7575:4;7567:13;;;7554:27;7549:2;7538:14;;7531:51;7641:4;7633:13;;;7620:27;7602:16;;;7595:53;;;;-1:-1:-1;;7661:18:56;;7699:12;;;;5675;5590:2131;;;5594:3;7740:5;7730:15;;;;;4723:3028;;;;;:::o;8058:245::-;8125:6;8178:2;8166:9;8157:7;8153:23;8149:32;8146:52;;;8194:1;8191;8184:12;8146:52;8226:9;8220:16;8245:28;8267:5;8245:28;:::i;8661:184::-;8713:77;8710:1;8703:88;8810:4;8807:1;8800:15;8834:4;8831:1;8824:15;9198:184;9250:77;9247:1;9240:88;9347:4;9344:1;9337:15;9371:4;9368:1;9361:15;9387:128;9454:9;;;9475:11;;;9472:37;;;9489:18;;:::i;10100:184::-;10170:6;10223:2;10211:9;10202:7;10198:23;10194:32;10191:52;;;10239:1;10236;10229:12;10191:52;-1:-1:-1;10262:16:56;;10100:184;-1:-1:-1;10100:184:56:o;11317:2420::-;11687:4;11716:3;11757;11746:9;11742:19;11788:3;11777:9;11770:22;11812:6;11847;11841:13;11878:6;11870;11863:22;11904:3;11894:13;;11938:3;11927:9;11923:19;11916:26;;12001:3;11991:6;11988:1;11984:14;11973:9;11969:30;11965:40;12024:4;12063:2;12055:6;12051:15;12084:1;12105;12115:1404;12131:6;12126:3;12123:15;12115:1404;;;12200:22;;;12224:66;12196:95;12184:108;;12315:13;;12467:9;;12393:42;12463:18;;;12448:34;;12521:11;;;12515:18;12553:15;;;12546:27;;;12634:19;;12355:15;;;12666:24;;;12756:21;;;;12393:42;12801:1;;12712:15;;;;12815:430;12831:8;12826:3;12823:17;12815:430;;;12904:15;;12954:9;;12950:18;;12936:33;;13019:11;;;13013:18;13009:27;;12993:14;;;12986:51;13064:4;13128:11;;;13122:18;13115:26;13108:34;13092:14;;;13085:58;13214:17;;;;12859:1;12850:11;;;;;13180:4;13169:16;;;;12815:430;;;-1:-1:-1;13268:4:56;13315:11;;;13309:18;13292:15;;;13285:43;13351:4;13398:11;;;13392:18;13375:15;;;;13368:43;;;;-1:-1:-1;;;13497:12:56;;;;13462:15;;;;12157:1;12148:11;12115:1404;;;-1:-1:-1;;;13535:18:56;;13528:34;;;421:13;;414:21;13610:4;13595:20;;402:34;13654:22;;;13647:4;13632:20;;13625:52;11239:1;11227:14;;11273:4;11266;11257:14;;11250:28;11303:2;11294:12;;13686:45;11317:2420;-1:-1:-1;;;;;;;;;;11317:2420:56:o;13742:686::-;13807:5;13860:3;13853:4;13845:6;13841:17;13837:27;13827:55;;13878:1;13875;13868:12;13827:55;13907:6;13901:13;13933:4;13957:81;13973:64;14034:2;13973:64;:::i;13957:81::-;14060:3;14084:2;14079:3;14072:15;14112:4;14107:3;14103:14;14096:21;;14169:4;14163:2;14160:1;14156:10;14148:6;14144:23;14140:34;14126:48;;14197:3;14189:6;14186:15;14183:35;;;14214:1;14211;14204:12;14183:35;14250:4;14242:6;14238:17;14264:135;14280:6;14275:3;14272:15;14264:135;;;14346:10;;14334:23;;14377:12;;;;14297;;14264:135;;;-1:-1:-1;14417:5:56;13742:686;-1:-1:-1;;;;;;13742:686:56:o;14433:1458::-;14596:6;14604;14612;14665:2;14653:9;14644:7;14640:23;14636:32;14633:52;;;14681:1;14678;14671:12;14633:52;14714:9;14708:16;14743:18;14784:2;14776:6;14773:14;14770:34;;;14800:1;14797;14790:12;14770:34;14823:72;14887:7;14878:6;14867:9;14863:22;14823:72;:::i;:::-;14813:82;;14914:2;14904:12;;14962:2;14951:9;14947:18;14941:25;14991:2;14981:8;14978:16;14975:36;;;15007:1;15004;14997:12;14975:36;15030:24;;15085:4;15077:13;;15073:27;-1:-1:-1;15063:55:56;;15114:1;15111;15104:12;15063:55;15143:2;15137:9;15166:81;15182:64;15243:2;15182:64;:::i;15166:81::-;15281:15;;;15363:1;15359:10;;;;15351:19;;15347:28;;;15312:12;;;;15387:19;;;15384:39;;;15419:1;15416;15409:12;15384:39;15443:11;;;;15463:210;15479:6;15474:3;15471:15;15463:210;;;15552:3;15546:10;15569:31;15594:5;15569:31;:::i;:::-;15613:18;;15496:12;;;;15651;;;;15463:210;;;15743:2;15728:18;;15722:25;15692:5;;-1:-1:-1;15722:25:56;-1:-1:-1;;;;15759:16:56;;;15756:36;;;15788:1;15785;15778:12;15756:36;;15811:74;15877:7;15866:8;15855:9;15851:24;15811:74;:::i;:::-;15801:84;;;14433:1458;;;;;:::o;15896:589::-;15938:5;15991:3;15984:4;15976:6;15972:17;15968:27;15958:55;;16009:1;16006;15999:12;15958:55;16045:6;16032:20;16071:18;16067:2;16064:26;16061:52;;;16093:18;;:::i;:::-;16137:114;16245:4;-1:-1:-1;;16169:4:56;16165:2;16161:13;16157:86;16153:97;16137:114;:::i;:::-;16276:2;16267:7;16260:19;16322:3;16315:4;16310:2;16302:6;16298:15;16294:26;16291:35;16288:55;;;16339:1;16336;16329:12;16288:55;16404:2;16397:4;16389:6;16385:17;16378:4;16369:7;16365:18;16352:55;16452:1;16427:16;;;16445:4;16423:27;16416:38;;;;16431:7;15896:589;-1:-1:-1;;;15896:589:56:o;16490:2592::-;16559:5;16612:3;16605:4;16597:6;16593:17;16589:27;16579:55;;16630:1;16627;16620:12;16579:55;16666:6;16653:20;16692:4;16716:81;16732:64;16793:2;16732:64;:::i;16716:81::-;16831:15;;;16917:1;16913:10;;;;16901:23;;16897:32;;;16862:12;;;;16941:15;;;16938:35;;;16969:1;16966;16959:12;16938:35;17005:2;16997:6;16993:15;17017:2036;17033:6;17028:3;17025:15;17017:2036;;;17119:3;17106:17;17146:18;17196:2;17183:11;17180:19;17177:39;;;17212:1;17209;17202:12;17177:39;17239:24;;;;17370:4;17287:12;;;-1:-1:-1;;17283:85:56;17279:96;17276:186;;;17416:1;17445:2;17441;17434:14;17276:186;17488:22;;:::i;:::-;17559:2;17555;17551:11;17538:25;17576:33;17601:7;17576:33;:::i;:::-;17622:22;;17667:2;17711:11;;;17698:25;17739:16;;;17736:106;;;17796:1;17825:2;17821;17814:14;17736:106;17865:17;;17917:2;17909:11;;17905:21;-1:-1:-1;17895:119:56;;17968:1;17997:2;17993;17986:14;17895:119;18059:2;18055;18051:11;18038:25;18089:82;18105:65;18166:3;18105:65;:::i;18089:82::-;18215:18;;;18314:1;18310:11;;;;18302:20;;18298:29;;;18255:14;;;;18343:17;;;18340:110;;;18402:1;18432:3;18427;18420:16;18340:110;18476:11;;;;18500:174;18518:8;18511:5;18508:19;18500:174;;;18600:19;;18586:34;;18539:14;;;;18646;;;;18500:174;;;18694:14;;;18687:29;-1:-1:-1;;;18766:4:56;18758:13;;18745:27;18788:16;;;18785:109;;;18846:1;18876:3;18871;18864:16;18785:109;18930:49;18975:3;18970:2;18959:8;18955:2;18951:17;18947:26;18930:49;:::i;:::-;18914:14;;;18907:73;;;;-1:-1:-1;18993:18:56;;-1:-1:-1;;19031:12:56;;;;17050;;17017:2036;;19087:1210;19187:9;19246:4;19238:5;19222:14;19218:26;19214:37;19211:57;;;19264:1;19261;19254:12;19211:57;19292:22;;:::i;:::-;19350:5;19337:19;19375:18;19416:2;19408:6;19405:14;19402:34;;;19432:1;19429;19422:12;19402:34;19466:6;19459:5;19455:18;19445:28;;19514:4;19509:2;19493:14;19489:23;19485:34;19482:54;;;19532:1;19529;19522:12;19482:54;19560:22;;:::i;:::-;19619:2;19606:16;19631:33;19656:7;19631:33;:::i;:::-;19673:24;;19742:2;19734:11;;19721:25;19755:33;19721:25;19755:33;:::i;:::-;19817:2;19804:16;;19797:33;19876:4;19868:13;;19855:27;19894:16;;;19891:36;;;19923:1;19920;19913:12;19891:36;19963:51;19999:14;19988:8;19984:2;19980:17;19963:51;:::i;:::-;19956:4;19943:18;;19936:79;-1:-1:-1;20024:24:56;;20097:2;20086:14;;20073:28;;-1:-1:-1;20113:16:56;;;20110:36;;;20142:1;20139;20132:12;20110:36;;20180:81;20246:14;20235:8;20228:5;20224:20;20180:81;:::i;:::-;20175:2;20162:16;;20155:107;-1:-1:-1;20166:7:56;19087:1210;-1:-1:-1;;19087:1210:56:o;20302:250::-;20387:1;20397:113;20411:6;20408:1;20405:13;20397:113;;;20487:11;;;20481:18;20468:11;;;20461:39;20433:2;20426:10;20397:113;;;-1:-1:-1;;20544:1:56;20526:16;;20519:27;20302:250::o;20557:329::-;20598:3;20636:5;20630:12;20663:6;20658:3;20651:19;20679:76;20748:6;20741:4;20736:3;20732:14;20725:4;20718:5;20714:16;20679:76;:::i;:::-;20800:2;20788:15;-1:-1:-1;;20784:88:56;20775:98;;;;20875:4;20771:109;;20557:329;-1:-1:-1;;20557:329:56:o;20891:439::-;20944:3;20982:5;20976:12;21009:6;21004:3;20997:19;21035:4;21064;21059:3;21055:14;21048:21;;21103:4;21096:5;21092:16;21126:1;21136:169;21150:6;21147:1;21144:13;21136:169;;;21211:13;;21199:26;;21245:12;;;;21280:15;;;;21172:1;21165:9;21136:169;;;-1:-1:-1;21321:3:56;;20891:439;-1:-1:-1;;;;;20891:439:56:o;21335:1808::-;21475:4;21504:2;21533;21522:9;21515:21;21555:2;21592:6;21586:13;21618:4;21658;21653:2;21642:9;21638:18;21631:32;21682:42;21785:2;21770:12;21764:19;21760:28;21755:2;21744:9;21740:18;21733:56;21860:2;21854;21840:12;21836:21;21830:28;21826:37;21820:3;21809:9;21805:19;21798:66;21919:4;21905:12;21901:23;21895:30;21873:52;;21962:2;21956:3;21945:9;21941:19;21934:31;21985:53;22033:3;22022:9;22018:19;22002:14;21985:53;:::i;:::-;21974:64;;22087:2;22079:6;22075:15;22069:22;-1:-1:-1;;22239:2:56;22227:9;22222:3;22218:19;22214:28;22207:4;22196:9;22192:20;22185:58;22263:3;22295:14;22289:21;22331:6;22326:3;22319:19;22363:2;22358:3;22354:12;22347:19;;22419:2;22409:6;22406:1;22402:14;22397:3;22393:24;22389:33;22465:2;22449:14;22445:23;22431:37;;22486:1;22496:618;22510:6;22507:1;22504:13;22496:618;;;22593:2;22587:3;22579:6;22575:16;22571:25;22566:3;22559:38;22626:6;22620:13;22676:2;22671;22665:9;22661:18;22653:6;22646:34;22729:2;22725;22721:11;22715:18;22770:2;22765;22757:6;22753:15;22746:27;22800:61;22857:2;22849:6;22845:15;22829:14;22800:61;:::i;:::-;22902:11;;;22896:18;22951:19;;;22934:15;;;22927:44;22896:18;22786:75;-1:-1:-1;22994:40:56;22786:75;22896:18;22994:40;:::i;:::-;23057:15;;;;23092:12;;;;22984:50;-1:-1:-1;;;22532:1:56;22525:9;22496:618;;;-1:-1:-1;23131:6:56;21335:1808;-1:-1:-1;;;;;;;;;;;;21335:1808:56:o;23148:641::-;23278:4;23284:6;23344:11;23331:25;-1:-1:-1;;23423:8:56;23407:14;23403:29;23399:102;23379:18;23375:127;23365:155;;23516:1;23513;23506:12;23365:155;23543:33;;23595:20;;;-1:-1:-1;23638:18:56;23627:30;;23624:50;;;23670:1;23667;23660:12;23624:50;23703:4;23691:17;;-1:-1:-1;23754:1:56;23750:14;;;23734;23730:35;23720:46;;23717:66;;;23779:1;23776;23769:12;23794:393;23897:4;23955:11;23942:25;24045:66;24034:8;24018:14;24014:29;24010:102;23990:18;23986:127;23976:155;;24127:1;24124;24117:12;23976:155;24148:33;;;;;23794:393;-1:-1:-1;;23794:393:56:o;24192:383::-;24285:4;24343:11;24330:25;24433:66;24422:8;24406:14;24402:29;24398:102;24378:18;24374:127;24364:155;;24515:1;24512;24505:12;24580:629;24695:4;24701:6;24761:11;24748:25;-1:-1:-1;;24840:8:56;24824:14;24820:29;24816:102;24796:18;24792:127;24782:155;;24933:1;24930;24923:12;24782:155;24960:33;;25012:20;;;-1:-1:-1;25055:18:56;25044:30;;25041:50;;;25087:1;25084;25077:12;25041:50;25120:4;25108:17;;-1:-1:-1;25179:4:56;25167:17;;25151:14;25147:38;25137:49;;25134:69;;;25199:1;25196;25189:12;25214:605;25310:5;25317:6;25377:3;25364:17;-1:-1:-1;;25448:8:56;25432:14;25428:29;25424:102;25404:18;25400:127;25390:155;;25541:1;25538;25531:12;25390:155;25569:33;;25673:4;25660:18;;;-1:-1:-1;25621:21:56;;-1:-1:-1;25701:18:56;25690:30;;25687:50;;;25733:1;25730;25723:12;25687:50;25787:6;25784:1;25780:14;25764;25760:35;25753:5;25749:47;25746:67;;;25809:1;25806;25799:12;25824:355;25895:5;25954:3;25941:17;26036:66;26025:8;26009:14;26005:29;26001:102;25981:18;25977:127;25967:155;;26118:1;26115;26108:12;25967:155;26140:33;;;;25824:355;-1:-1:-1;;25824:355:56:o;26184:559::-;26242:5;26249:6;26309:3;26296:17;-1:-1:-1;;26380:8:56;26364:14;26360:29;26356:102;26336:18;26332:127;26322:155;;26473:1;26470;26463:12;26322:155;26501:33;;26605:4;26592:18;;;-1:-1:-1;26553:21:56;;-1:-1:-1;26633:18:56;26622:30;;26619:50;;;26665:1;26662;26655:12;26619:50;26712:6;26696:14;26692:27;26685:5;26681:39;26678:59;;;26733:1;26730;26723:12;26748:325;26836:6;26831:3;26824:19;26888:6;26881:5;26874:4;26869:3;26865:14;26852:43;;26940:1;26933:4;26924:6;26919:3;26915:16;26911:27;26904:38;26806:3;27062:4;-1:-1:-1;;26987:2:56;26979:6;26975:15;26971:88;26966:3;26962:98;26958:109;26951:116;;26748:325;;;;:::o;27078:593::-;27159:5;27166:6;27226:3;27213:17;-1:-1:-1;;27297:8:56;27281:14;27277:29;27273:102;27253:18;27249:127;27239:155;;27390:1;27387;27380:12;27239:155;27418:33;;27522:4;27509:18;;;-1:-1:-1;27470:21:56;;-1:-1:-1;27550:18:56;27539:30;;27536:50;;;27582:1;27579;27572:12;27536:50;27641:4;27633:6;27629:17;27613:14;27609:38;27602:5;27598:50;27595:70;;;27661:1;27658;27651:12;27676:114;27760:4;27753:5;27749:16;27742:5;27739:27;27729:55;;27780:1;27777;27770:12;27795:830;27906:6;27901:3;27894:19;27876:3;27932:4;27961;27956:3;27952:14;27945:21;;27989:5;28012:1;28022:578;28036:6;28033:1;28030:13;28022:578;;;28113:6;28100:20;28133:33;28158:7;28133:33;:::i;:::-;28204:42;28191:56;28179:69;;28289:15;;;28276:29;28318:31;28276:29;28318:31;:::i;:::-;28396:4;28383:18;28369:12;;;28362:40;28425:4;28476:15;;;28463:29;28449:12;;;28442:51;28516:4;28540:12;;;;28575:15;;;;28058:1;28051:9;28022:578;;28630:1709;28767:19;;;28805:4;28825:12;;;;28724:3;;28856:1;28893:14;;;28882:26;;28878:35;;28936:5;28724:3;;28990:1323;29006:6;29001:3;28998:15;28990:1323;;;-1:-1:-1;;29085:5:56;29079:4;29075:16;29071:89;29066:3;29059:102;29184:58;29235:6;29228:5;29184:58;:::i;:::-;29265:4;29310:2;29297:16;29326:33;29351:7;29326:33;:::i;:::-;29398:42;29385:56;29372:70;;29489:85;29562:11;;;29566:2;29489:85;:::i;:::-;29609:2;29604;29598:4;29594:13;29587:25;29647:12;29642:2;29636:4;29632:13;29625:35;29683:3;29673:13;;29719:66;29705:12;29702:84;29699:104;;;29799:1;29796;29789:12;29699:104;29832:21;;;29894:12;29879:13;;;29866:51;29940:19;;;-1:-1:-1;29982:4:56;30037:47;30072:11;;;30076:2;30037:47;:::i;:::-;29999:85;;30138:2;30131:4;30127:2;30123:13;30119:22;30114:2;30108:4;30104:13;30097:45;30163:70;30229:2;30225;30221:11;30205:14;30189;30163:70;:::i;:::-;30291:12;;;;30155:78;-1:-1:-1;;;30256:15:56;;;;-1:-1:-1;;;29032:1:56;29023:11;28990:1323;;;-1:-1:-1;30329:4:56;;28630:1709;-1:-1:-1;;;;;;;;;28630:1709:56:o;30344:4286::-;30510:4;30539:2;30568;30557:9;30550:21;30609:3;30598:9;30594:19;30662:6;30649:20;30644:2;30633:9;30629:18;30622:48;30689:2;30752;30744:6;30740:15;30727:29;30722:2;30711:9;30707:18;30700:57;30776:2;30839;30831:6;30827:15;30814:29;30809:2;30798:9;30794:18;30787:57;30887:93;30976:2;30968:6;30964:15;30956:6;30887:93;:::i;:::-;31017:4;31011:3;31000:9;30996:19;30989:33;31042:6;31072:12;31064:6;31057:28;31116:3;31105:9;31101:19;31094:26;;31185:3;31169:12;31166:1;31162:20;31151:9;31147:36;31143:46;31129:60;;31212:12;31242:1;31252:3053;31266:12;31263:1;31260:19;31252:3053;;;31361:66;31349:9;31341:6;31337:22;31333:95;31328:3;31321:108;31481:6;31468:20;31574:66;31559:12;31543:14;31539:33;31535:106;31515:18;31511:131;31501:159;;31656:1;31653;31646:12;31501:159;31686:37;;31764:19;;31840:14;31836:26;;;31864:66;31832:99;31806:126;;31796:154;;31946:1;31943;31936:12;31796:154;32038:3;32023:19;;31978:32;;32070:21;;32104:33;32070:21;32104:33;:::i;:::-;32160:42;32253:2;32244:7;32240:16;32234:3;32226:6;32222:16;32215:42;32292:70;32358:2;32349:7;32345:16;32336:7;32292:70;:::i;:::-;32270:92;;32401:4;32394;32386:6;32382:17;32375:31;32447:14;32434:28;32475:33;32500:7;32475:33;:::i;:::-;32546:16;;32540:3;32528:16;;32521:42;32604:23;;;32591:37;32641:33;32591:37;32641:33;:::i;:::-;32712:16;32706:3;32694:16;;32687:42;32780:71;32827:23;;;32831:14;32780:71;:::i;:::-;32742:109;;32889:2;32883:3;32875:6;32871:16;32864:28;32916:75;32986:3;32978:6;32974:16;32958:14;32942;32916:75;:::i;:::-;32905:86;;;33042:80;33118:2;33109:7;33105:16;33096:7;33042:80;:::i;:::-;33145:66;33271:2;33262:6;33257:3;33253:16;33249:25;33243:3;33235:6;33231:16;33224:51;33302:85;33383:3;33367:14;33351;33302:85;:::i;:::-;33288:99;;33438:80;33514:2;33505:7;33501:16;33492:7;33438:80;:::i;:::-;33400:118;;;;33581:2;33572:6;33564;33560:19;33556:28;33550:3;33542:6;33538:16;33531:54;;33612:88;33693:6;33677:14;33661;33612:88;:::i;:::-;33598:102;;;;33764:3;33755:7;33751:17;33738:31;33732:3;33724:6;33720:16;33713:57;33831:2;33824:5;33820:14;33807:28;33802:2;33794:6;33790:15;33783:53;33897:2;33890:5;33886:14;33873:28;33868:2;33860:6;33856:15;33849:53;33953:91;34040:2;34033:5;34029:14;34022:5;33953:91;:::i;:::-;33915:129;;;;34093:6;34085;34081:19;34076:2;34068:6;34064:15;34057:44;34124:101;34218:6;34202:14;34186;34124:101;:::i;:::-;34114:111;-1:-1:-1;;;34283:12:56;;;;-1:-1:-1;34248:15:56;;;;31294:1;31287:9;31252:3053;;;31256:3;;;;;;;34352:56;34403:3;34395:6;34391:16;34383:6;34352:56;:::i;:::-;34314:94;;-1:-1:-1;;34462:9:56;34454:6;34450:22;34446:95;34439:4;34428:9;34424:20;34417:125;34559:65;34617:6;34601:14;34585;34559:65;:::i;34635:245::-;34714:6;34722;34775:2;34763:9;34754:7;34750:23;34746:32;34743:52;;;34791:1;34788;34781:12;34743:52;-1:-1:-1;;34814:16:56;;34870:2;34855:18;;;34849:25;34814:16;;34849:25;;-1:-1:-1;34635:245:56:o;36000:247::-;36068:6;36121:2;36109:9;36100:7;36096:23;36092:32;36089:52;;;36137:1;36134;36127:12;36089:52;36169:9;36163:16;36188:29;36211:5;36188:29;:::i;37658:1572::-;38213:42;38205:6;38201:55;38190:9;38183:74;38164:4;38276:2;38314:6;38309:2;38298:9;38294:18;38287:34;38357:3;38352:2;38341:9;38337:18;38330:31;38384:45;38424:3;38413:9;38409:19;38401:6;38384:45;:::i;:::-;38465:6;38460:2;38449:9;38445:18;38438:34;38521:9;38513:6;38509:22;38503:3;38492:9;38488:19;38481:51;38552:6;38587;38581:13;38618:6;38610;38603:22;38653:2;38645:6;38641:15;38634:22;;38712:2;38702:6;38699:1;38695:14;38687:6;38683:27;38679:36;38750:2;38742:6;38738:15;38771:1;38781:322;38795:6;38792:1;38789:13;38781:322;;;-1:-1:-1;;38872:6:56;38864;38860:19;38856:92;38851:3;38844:105;38972:51;39016:6;39007;39001:13;38972:51;:::i;:::-;39081:12;;;;38962:61;-1:-1:-1;39046:15:56;;;;38817:1;38810:9;38781:322;;;38785:3;;39152:9;39144:6;39140:22;39134:3;39123:9;39119:19;39112:51;39180:44;39217:6;39209;39180:44;:::i;:::-;39172:52;37658:1572;-1:-1:-1;;;;;;;;;;;;;37658:1572:56:o;39235:614::-;39364:6;39372;39425:2;39413:9;39404:7;39400:23;39396:32;39393:52;;;39441:1;39438;39431:12;39393:52;39474:9;39468:16;39503:18;39544:2;39536:6;39533:14;39530:34;;;39560:1;39557;39550:12;39530:34;39583:72;39647:7;39638:6;39627:9;39623:22;39583:72;:::i;:::-;39573:82;;39701:2;39690:9;39686:18;39680:25;39664:41;;39730:2;39720:8;39717:16;39714:36;;;39746:1;39743;39736:12;39714:36;;39769:74;39835:7;39824:8;39813:9;39809:24;39769:74;:::i;:::-;39759:84;;;39235:614;;;;;:::o;39854:367::-;40096:6;40085:9;40078:25;40139:2;40134;40123:9;40119:18;40112:30;40059:4;40159:56;40211:2;40200:9;40196:18;40188:6;40159:56;:::i;40226:184::-;40278:77;40275:1;40268:88;40375:4;40372:1;40365:15;40399:4;40396:1;40389:15;40415:168;40488:9;;;40519;;40536:15;;;40530:22;;40516:37;40506:71;;40557:18;;:::i;40588:476::-;40677:1;40714:5;40677:1;40728:330;40749:7;40739:8;40736:21;40728:330;;;40868:4;-1:-1:-1;;40796:77:56;40790:4;40787:87;40784:113;;;40877:18;;:::i;:::-;40927:7;40917:8;40913:22;40910:55;;;40947:16;;;;40910:55;41026:22;;;;40986:15;;;;40728:330;;;40732:3;40588:476;;;;;:::o;41069:866::-;41118:5;41148:8;41138:80;;-1:-1:-1;41189:1:56;41203:5;;41138:80;41237:4;41227:76;;-1:-1:-1;41274:1:56;41288:5;;41227:76;41319:4;41337:1;41332:59;;;;41405:1;41400:130;;;;41312:218;;41332:59;41362:1;41353:10;;41376:5;;;41400:130;41437:3;41427:8;41424:17;41421:43;;;41444:18;;:::i;:::-;-1:-1:-1;;41500:1:56;41486:16;;41515:5;;41312:218;;41614:2;41604:8;41601:16;41595:3;41589:4;41586:13;41582:36;41576:2;41566:8;41563:16;41558:2;41552:4;41549:12;41545:35;41542:77;41539:159;;;-1:-1:-1;41651:19:56;;;41683:5;;41539:159;41730:34;41755:8;41749:4;41730:34;:::i;:::-;41860:6;-1:-1:-1;;41788:79:56;41779:7;41776:92;41773:118;;;41871:18;;:::i;:::-;41909:20;;41069:866;-1:-1:-1;;;41069:866:56:o;41940:131::-;42000:5;42029:36;42056:8;42050:4;42029:36;:::i;42665:287::-;42794:3;42832:6;42826:13;42848:66;42907:6;42902:3;42895:4;42887:6;42883:17;42848:66;:::i;42957:184::-;43009:77;43006:1;42999:88;43106:4;43103:1;43096:15;43130:4;43127:1;43120:15;43504:288;43679:6;43668:9;43661:25;43722:2;43717;43706:9;43702:18;43695:30;43642:4;43742:44;43782:2;43771:9;43767:18;43759:6;43742:44;:::i;43986:219::-;44135:2;44124:9;44117:21;44098:4;44155:44;44195:2;44184:9;44180:18;44172:6;44155:44;:::i","linkReferences":{},"immutableReferences":{"6454":[{"start":226,"length":32},{"start":1805,"length":32},{"start":1886,"length":32}]}},"methodIdentifiers":{"arb3(address,(uint256,uint256,uint256,((address,(address,address,bytes),(address,uint8,uint256)[],(address,uint8,uint256)[],bytes32),uint256,uint256,(address,uint256[],bytes)[])[],bytes),((address,address,bytes),(address,uint256[],bytes)[]))":"7ea0b76a","iTaskHash()":"93be095e","onTakeOrders(address,address,uint256,uint256,bytes)":"059bebe6","supportsInterface(bytes4)":"01ffc9a7","x(address)":"f037e4e3"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"orderBook\",\"type\":\"address\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV1\",\"name\":\"task\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"implementationData\",\"type\":\"bytes\"}],\"internalType\":\"struct OrderBookV4ArbConfigV2\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoOrders\",\"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 IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV1\",\"name\":\"task\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"implementationData\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"struct OrderBookV4ArbConfigV2\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"Construct\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[{\"internalType\":\"contract IOrderBookV4\",\"name\":\"orderBook\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"minimumInput\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumInput\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumIORatio\",\"type\":\"uint256\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"vaultId\",\"type\":\"uint256\"}],\"internalType\":\"struct IO[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"vaultId\",\"type\":\"uint256\"}],\"internalType\":\"struct IO[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OrderV3\",\"name\":\"order\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"inputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outputIOIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TakeOrderConfigV3[]\",\"name\":\"orders\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct TakeOrdersConfigV3\",\"name\":\"takeOrders\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV1\",\"name\":\"task\",\"type\":\"tuple\"}],\"name\":\"arb3\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"iTaskHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"inputToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"outputToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"inputAmountSent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalOutputAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"takeOrdersData\",\"type\":\"bytes\"}],\"name\":\"onTakeOrders\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"x\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"onTakeOrders(address,address,uint256,uint256,bytes)\":{\"params\":{\"inputAmountSent\":\"The amount of `inputToken` that was sent to `IOrderBookV4OrderTaker`.\",\"inputToken\":\"The token that was sent to `IOrderBookV4OrderTaker`.\",\"outputToken\":\"The token that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns.\",\"takeOrdersData\":\"The data passed to `takeOrders` by the caller.\",\"totalOutputAmount\":\"The total amount of `outputToken` that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns.\"}},\"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[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidSignature(uint256)\":[{\"notice\":\"Thrown when the ith signature from a list of signed contexts is invalid.\"}],\"NoOrders()\":[{\"notice\":\"Thrown when take orders is called with no orders.\"}],\"WrongTask()\":[{\"notice\":\"Thrown when the task does not match the expected hash.\"}]},\"kind\":\"user\",\"methods\":{\"onTakeOrders(address,address,uint256,uint256,bytes)\":{\"notice\":\"Called by `IOrderBookV4` when `takeOrders` is called with non-zero data, if it caused a non-zero input amount. I.e. if the order(s) taker received some tokens. Input and output directions are relative to the `IOrderBookV4OrderTaker` contract. If the order(s) taker had an active debt from a flash loan then that debt will be paid _before_ calculating any input amounts sent. i.e. the debt is deducted from the input amount before this callback is called.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol\":\"BalancerRouterOrderBookV4ArbOrderTaker\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"appendCBOR\":false,\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":9000},\"remappings\":[\":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.interpreter.interface/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/\",\":integrity/=lib/rain.interpreter/src/lib/integrity/\",\":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/\",\":openzeppelin/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/\",\":parse/=lib/rain.interpreter/src/lib/parse/\",\":prb-math/=lib/rain.interpreter/lib/prb-math/src/\",\":rain.datacontract/=lib/rain.interpreter/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.sol.codegen/lib/rain.math.binary/src/\",\":rain.math.fixedpoint/=lib/rain.interpreter/lib/rain.math.fixedpoint/src/\",\":rain.math.saturating/=lib/rain.interpreter/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.binmaskflag/=lib/rain.interpreter/lib/rain.sol.binmaskflag/src/\",\":rain.sol.codegen/=lib/rain.interpreter/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.math.fixedpoint/lib/rain.string/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.math.fixedpoint/src/error/ErrScale.sol\":{\"keccak256\":\"0xf078f93e8cf6360008743854983c2c98a43f7f78b95a527473089a22b81c55a0\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://580c4ad750f0ebebdf77f87feb52bce41f2d72fa4bf9221fbe3977837eb6a4d9\",\"dweb:/ipfs/QmeYydyLSLqFT5DfFDgJBEBBeBEhwvsMi3oQ4USXXrQudF\"]},\"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/FixedPointDecimalConstants.sol\":{\"keccak256\":\"0x9299cb9b7aeeaa2a60c6e248928bc173750c5361df4fc0e4d9ea94a778fcd6e6\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://3a65a4f0f3b7462cb0b0b6d165d3868010ff19192f53a8133e3e93be3d811d81\",\"dweb:/ipfs/QmSFWpSUH2cAcw7ph2c5rwvqcKWXTJgvabaRjk2P8ZMzcP\"]},\"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/LibFixedPointDecimalScale.sol\":{\"keccak256\":\"0xef9a2b240ba686ee4b31c37edfbbab1a3b276db3ad269688fa2c0d1beced6c0b\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://a4e115922faa62d4c3f64c466b9e3d27f53d611c92422828c1920c37bc51acfa\",\"dweb:/ipfs/QmPa5cnqmk8eHjkdSPzegHDN9Q4jWbNV1DHeFKh5LZ6XVk\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol\":{\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e\",\"dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34\",\"dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5\",\"dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71\",\"dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68\",\"dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931\",\"dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f\",\"dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2\",\"dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol\":{\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://77d1f1cf302cd5e1dfbbb4ce3b281b28e8c52942d4319fce43df2e1b6f02a52d\",\"dweb:/ipfs/QmT6ZXStmK3Knhh9BokeVHQ9HXTBZNgL3Eb1ar1cYg1hWy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d\",\"dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c\",\"dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7\",\"dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrBytes.sol\":{\"keccak256\":\"0x82df8bd5b6a2343eb41c47f9b58f05adb2f8fd92b146ddb31c0ea697ebe3acd4\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://f95976983e965460330e2a1d00f3ed0e2079e13a67f3364f1175723cd97b6a07\",\"dweb:/ipfs/QmQKhYbVSesLuomYv4XPapPMvLmXNLgSx2QtgK5EJhww5c\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol\":{\"keccak256\":\"0xfc1739c5c406f71e1f52ebfd163162087e9025b02444ca12ae8844c71dcd1cf5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://ae2e95f1e6260b18105369c7216e1ebc6a251ffe3548d27ce180f7885c3f6906\",\"dweb:/ipfs/QmPQEzZmQDuzp8R5rp6ABmzGD243qu8R5GX4FbHc8G4CUC\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes.sol\":{\"keccak256\":\"0x46f53ecd0554926ed6ef781485f9c3d3dfe08fa5503021aac7476c28df364f30\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://d6841328d12c44dfc3e966d2372b841f27659b592556411bcb2889ed1a8db6b2\",\"dweb:/ipfs/QmQHUvQre6Jb5VtiKDvwQiff3eLSCPxRkAs8Jy81dnPbdD\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibMemCpy.sol\":{\"keccak256\":\"0x58be272366c53e5db26413754881238127a5ccedc69439d50afbb4c4f9769006\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://49d241b4acc8462d0289eafe645c20493a615c9bef629dab4f049599373df1c7\",\"dweb:/ipfs/QmYLK8fhzz5kjdaQY29yrcgEcGv31gUABvC7eHoChgYwV7\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol\":{\"keccak256\":\"0xdadaac57081823b3a4162aeda93195d1dbe98caf1141f6d9113302909c851307\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://fa6026d3853dd4a58faa0c9ac2dda867c200963a052a4d62e8797cd3a0e29250\",\"dweb:/ipfs/QmPRKmE5tpJKwCpy3rumAMjCqDdGK8UC2r2soB1CNQwfmJ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol\":{\"keccak256\":\"0xbfea88bec2894f0ff0b3f8b3088f4a45f561aff1bc439165bcdb0e15fa0124ea\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://3ef8c1cf899aa39585cded6e6510e637fa5e60f40dae9e39688ecacd41ef9c41\",\"dweb:/ipfs/Qme4nJr2tCfkY9DDiMhcGjuvjy6jFGZvNgCeMD81YACEKR\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/error/ErrBytecode.sol\":{\"keccak256\":\"0x56d9f7a498877655b507ddb4683f4cdbb961bf38375d85c80ab66f8cf0aa9d03\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0206c9b5a55818d20b2a644c2da0a5cfbbfffb82d4e49bbd0ddd5d60df19ecb8\",\"dweb:/ipfs/QmZuMWg8zqPFDVSWKZnRxrmDpr3YQE7ERSjAFLWnK4iDyd\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterCallerV3.sol\":{\"keccak256\":\"0x17a433a06d82d1fbaa497ab0ab0a3c698f86dcdbf9b3dc6814d2f64b1592bc32\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://eb06d882eab9261c1561a3f087b4eb6b29bbf919f6902859a3464d7ecd738315\",\"dweb:/ipfs/QmacaaExc2aL4xokmcBxKy2nhRYKWkEhb2DV2KNJQbMHxK\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol\":{\"keccak256\":\"0xd3fe133132e9688f0590f273b1a9851d17b794d7ed85d5cc7a4cf961220359f3\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://bd74c48f247d80804a1fcaa664b4771cbca471cb5bc29307e585d60fb4162bf1\",\"dweb:/ipfs/QmX8PF8aVeXbKsuaBnvLpsgcyjqxHUZK2wgogmNDzQC8mr\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterV3.sol\":{\"keccak256\":\"0x152209b9afda8a9fbba404563d67566584b95f49f57f321538d66995b81de300\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://84a09751006cd68411da9684379919e6f0a6b7606050392633146374b7d10141\",\"dweb:/ipfs/QmWoST14FWQr8MqGZXruDvJn5FeQrTkKZomSjazcp6msdm\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IParserV2.sol\":{\"keccak256\":\"0x9893dfb4e05bfbf088921c5cca38265388de5ef9e127ec8674a2ce6356152725\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://19bac62db62ad9cb20a9b9790208e124bcfdf89f7deeae25b3cb30f11f680724\",\"dweb:/ipfs/QmUvj4Zcj3b6ACRjcAHRW9geoLfLUXuKydcbMakaxRFPTa\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV1.sol\":{\"keccak256\":\"0x933cbfee07ddc43390326f87034613216352250472577bd890e9589e6206fad4\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://d0f947ca6eb86ae9c03806430f5c3a946882daee9f82e436067b1c42ff554595\",\"dweb:/ipfs/QmV7jK8dK6de1HDsUjKDGfEPwVdNEzDHgVHmVZKyfGv6MQ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV2.sol\":{\"keccak256\":\"0x3f03703392207a285d41b2871c2d83df103425c1984750cc303628269e6258e5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://a9bc96c0f288ab7b6ec1a14a42e426ec745f0b1c7fcde9d7052380c64e61c8da\",\"dweb:/ipfs/QmYBobAFw36Jd2VtFtoWNqE8HxJhy3n9Eho1fsK3uBCbwc\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV3.sol\":{\"keccak256\":\"0x231a50d32c6f910d7ae13ae1d83a221ba55eb7962380572c9c354c8a3c5c52bf\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://74b19a6c17ac7fab6edee53218a35154c5fe9ad3769ce8e22bac682dd32df0e8\",\"dweb:/ipfs/QmYiG7i4tNfA4eTynoQVbNixvGepqoAedVz2isiMfxRF8D\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV1.sol\":{\"keccak256\":\"0x20aebc5f73ffd790da90b8e88d6412f9c3a11041239c669c03e188d0a6be1e3e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://24f85bcb1d9f52ae01f7127274100ef68640a823bf2b981f267faf71192d8235\",\"dweb:/ipfs/QmPmz7q4rsy9vWXixdG9qBB8fLb1Wjj8LWyq6wyuFQR2HK\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV2.sol\":{\"keccak256\":\"0x8ae6f8b21d5fba09db20a979e797339d4cc385450d4da8cb4de2331db638caee\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://162b488b86df5c57c8cecd6c02172122ab9d30d70dd135ea151db5d56bf06f62\",\"dweb:/ipfs/Qmf9Kd89mH6PE5hoQ6ahV1Dsi28AFbakeUUw12W9Dp3sHW\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol\":{\"keccak256\":\"0xe03c065839e972fde62d73c45acf6fc2e88f42e3a07f4255ef5bfdcd30d3b1f1\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e766d9cfe9464f722e02320c3936fb0b98b9417663fefba6bac3dbb21007ce82\",\"dweb:/ipfs/QmX88DnazhZw7B3Fxp1iDZXogi2k6dyMPvh2vXpXep11oQ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol\":{\"keccak256\":\"0x8986cb9ba93034751b21245398bc1ef7a55fe10d34b5d4cc4207ee9d39a3e616\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://dc7d8e706e96f0d0e53599582fadd591581484ac36921b0e4c6454c54b568c2b\",\"dweb:/ipfs/QmNczMgGQKWJiDhXVbtXeBjUEtzFtr7k41uPjiU8P6BrHT\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV2.sol\":{\"keccak256\":\"0x0a9223e817a36a9717b91f977a9fce5e698afd393aa2405979baf53a12339805\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1537576666b7462485e898ddbd36848be401b3c1e3f8317eca4112d1b21d4e74\",\"dweb:/ipfs/QmZYRLbnctnMKEZ4UYz9oZ9MFoqQy1hex29HrXPVBX5U1g\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IParserV1.sol\":{\"keccak256\":\"0x19e1a217e8c67c671e319dd0e5608d7c496fbfc02363fbb2d08626715625dd55\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://603b3234a5c084acb12d0b7e3909503869f9a6d860f91d86692e007f67aba25b\",\"dweb:/ipfs/QmU7i9uyr9qWFzD2xjn1qjgiPjb8vUjuXA6dHEuGLVkmPj\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/bytecode/LibBytecode.sol\":{\"keccak256\":\"0xdebdca9d3d2a6c1be927f6fa1f28550cd7885aa52abd378ddb65e5f6495ef87c\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://5ca7fe490fe2b1287c3c231ec34daa504b3b36fa6c3e69aacda9737db1e1b548\",\"dweb:/ipfs/QmQozWFz6qFJDiRFS1YgPWCsRZgCCQ3yEzmwTVyiCs7SxY\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibContext.sol\":{\"keccak256\":\"0xd2cfeec3582d7b0b2a09573e258230ec4a6de169e60d9078f674a7a09d0c7b2d\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://cf266d36372575856000331ebb8dca7d6025db6365d14f4c876ab55305090aba\",\"dweb:/ipfs/QmYyoYFXryPM2SRMafgUgsBbAXPeCmzLFvzhHGR3i47zHy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibEvaluable.sol\":{\"keccak256\":\"0x922f6df3f98bc94869b9c244ae349e4ecfe0f250937414af7f3699e016b9f57e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e4fd2f59466c83a6e5dfe843951880d3f1dbe98cf559746242d942ab20962166\",\"dweb:/ipfs/QmTTD9vj8ph7ocmWFAjPb4D4UiwusCg7iZEPWoRfVtEEu1\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/deprecated/caller/LibEncodedDispatch.sol\":{\"keccak256\":\"0x0d9b888a01c5d508dd3cdfd53823ad56c6e16e06d18ca8b2ac68e82b102cc60a\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://6f854a3243d04aa76169367843a97bec51574f01ddb1e31b271f8aa93e184dce\",\"dweb:/ipfs/QmRc85MSQBbqvCvdcZBHvBrA8FFfVbxYWHbNV2vshmLF95\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/ns/LibNamespace.sol\":{\"keccak256\":\"0x5e1f5a0e05fbadf8acfad550ed59d960dd05ebc1d74cfa676f22a26644cc0ee5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://ee31bfc695ae5dc841379c3164b345bb0951b8b10fd94f300d5bb2de51dd7a1e\",\"dweb:/ipfs/QmT1CqR7Lpj2bEJADgEPgY9cmTqgKLEZm1QLbZxfHEd8PY\"]},\"lib/rain.orderbook.interface/src/interface/IOrderBookV4.sol\":{\"keccak256\":\"0x715c5211361bd469a9ec916710611536d087ae5630a3fc3f80e9802ec43c4596\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://c61433f7de82ac5fbd752470aa1b9358dc70455ba85be87a9056509188f5db21\",\"dweb:/ipfs/QmaGvPxe4xpqkVMdq9mo2moJyBHB9f8wTkcxZotk7tevVH\"]},\"lib/rain.orderbook.interface/src/interface/IOrderBookV4OrderTaker.sol\":{\"keccak256\":\"0x7d197bd91214d318ce6a9ee388228494606ba7bdae36bbc6ec6ed1681ff60bd8\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://73caf415d34e06a83d104cbccf98ae76ccd522e5ae1fb32c2bb18af9bae7ccaa\",\"dweb:/ipfs/QmYbiDgjfjpX6pvjawqhtQpiTkUuX24ncHodheJPtSg4d7\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v2/IOrderBookV2.sol\":{\"keccak256\":\"0x30c528f1772e9593b5329f1458cab4cce3510a2ccca01696b506af177fffd786\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://9f53c14e5aaab2cd2fbf5b39d07c59acfdc09aff3476345816c2635de2cdd5d3\",\"dweb:/ipfs/QmaomXfmDKdoeYwbMe9cy5anx4fDEMtP4W9Rre5s5DZVE6\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v3/IOrderBookV3.sol\":{\"keccak256\":\"0xdca3fd0c6106ab98d08682e63e433b74250d1f01e646a5908c97183d9b25130b\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0f986a8388275a4144068981aa628e46bff221c2d27a3ad597a9c5fc2d4fcb09\",\"dweb:/ipfs/QmR2pxkpY4ddhLb7jdoNAVSJwYHokyGpn5Tzg3Q7YnGYgW\"]},\"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/IOrderBookV4ArbOrderTakerV2.sol\":{\"keccak256\":\"0x271d4a0fdeddc07a88b18fa52f39c840515e572d62a755f7710bbd1b20ebe389\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://64000bb3455809c1eb2a8789023286ad9ccaa2cdfe014cff480e96bb1b7ad6a3\",\"dweb:/ipfs/QmRDgNHR4mYjxvHJUNMaaDZdAnxZ7yDF9kCL3aaSYip6AH\"]},\"lib/sushixswap-v2/src/interfaces/IRouteProcessor.sol\":{\"keccak256\":\"0x5b2289c992f34dd25943db3cbc27ece8b0a1addeb2631f812e7834b7ae3eac37\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://f21522058b7fe3c18d2353b06a5ddbf2b62d2aceebf7dd6dfdc51b081452bb3f\",\"dweb:/ipfs/QmVkicGnNWgnX1RfXJWPpQaAPbiAQfFwGWigbPi1wu2WiT\"]},\"src/abstract/OrderBookV4ArbCommon.sol\":{\"keccak256\":\"0xe24cce13b3e21ae36c0aae11380128c5f0ddf542a0298f1a1845a39845e10576\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://5f5d04c151a7e9fe4a659cef55abc4a626bc2ba0e58edbd714dcbadb52f4b396\",\"dweb:/ipfs/QmZHQiYBNdxMJWoMjHnsqoj2YszvFMWrGYqDcodKpwyv98\"]},\"src/abstract/OrderBookV4ArbOrderTaker.sol\":{\"keccak256\":\"0xa419a3d91a8c362dad1bea2761e6e0218c96ff295064aad1f5548444977d7896\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0995be2430baeccbf24ead130e100f6d19a354b2703d65a3544a9bf516ff4c6c\",\"dweb:/ipfs/QmVaKDPVFe8U4MxnR3vwr7yLPrxo6hzYEud4XZzkHShsMu\"]},\"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol\":{\"keccak256\":\"0x2cd70a0a532aabe6b5df682078bb2bc60afb519c05502389e2ca334ef95131ca\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://172cd3ad61d01b30127a129bbf1ab8091e664ef66e7514ff3651189022f2917e\",\"dweb:/ipfs/QmS7SigcghYoJuzXoKEY89hx7gGSCWsBBZ1qf7tkNACjN9\"]},\"src/lib/LibOrderBook.sol\":{\"keccak256\":\"0xa33a7731cde01162cc5d5a1d28b96a17626a6919971620850f92cc32a20342cf\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://9bcbc37dd34292bca2ebdc620b418fbfd8b65039a3d040512f9c8d091ed1f2bf\",\"dweb:/ipfs/QmQEBw7n6QKuzF1BMtxyYcZTk8eK4Hed8QVEwuQtUUJ4AM\"]},\"src/lib/LibOrderBookArb.sol\":{\"keccak256\":\"0xe6ba0ae436fbb48193585beaaac8fc9b367ec9f511281b55e6cbc354c7faae90\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://2b69af34b0acdabe929170984243f7a04581df75010d790147b86f72bc6411c2\",\"dweb:/ipfs/QmZAYyTLrfB5w3uintmQp1Au32YyVrknfqcd6hLLvf1RKk\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.25+commit.b61c2a91"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"struct OrderBookV4ArbConfigV2","name":"config","type":"tuple","components":[{"internalType":"address","name":"orderBook","type":"address"},{"internalType":"struct TaskV1","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","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":"uint256[]","name":"context","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]},{"internalType":"bytes","name":"implementationData","type":"bytes"}]}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"type":"error","name":"InvalidSignature"},{"inputs":[],"type":"error","name":"NoOrders"},{"inputs":[],"type":"error","name":"WrongTask"},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"struct OrderBookV4ArbConfigV2","name":"config","type":"tuple","components":[{"internalType":"address","name":"orderBook","type":"address"},{"internalType":"struct TaskV1","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","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":"uint256[]","name":"context","type":"uint256[]"},{"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 IOrderBookV4","name":"orderBook","type":"address"},{"internalType":"struct TakeOrdersConfigV3","name":"takeOrders","type":"tuple","components":[{"internalType":"uint256","name":"minimumInput","type":"uint256"},{"internalType":"uint256","name":"maximumInput","type":"uint256"},{"internalType":"uint256","name":"maximumIORatio","type":"uint256"},{"internalType":"struct TakeOrderConfigV3[]","name":"orders","type":"tuple[]","components":[{"internalType":"struct OrderV3","name":"order","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IO[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"vaultId","type":"uint256"}]},{"internalType":"struct IO[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"vaultId","type":"uint256"}]},{"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":"uint256[]","name":"context","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]},{"internalType":"bytes","name":"data","type":"bytes"}]},{"internalType":"struct TaskV1","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","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":"uint256[]","name":"context","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]}],"stateMutability":"payable","type":"function","name":"arb3"},{"inputs":[],"stateMutability":"view","type":"function","name":"iTaskHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"inputAmountSent","type":"uint256"},{"internalType":"uint256","name":"totalOutputAmount","type":"uint256"},{"internalType":"bytes","name":"takeOrdersData","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"onTakeOrders"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"stateMutability":"view","type":"function","name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"stateMutability":"payable","type":"function","name":"x"}],"devdoc":{"kind":"dev","methods":{"onTakeOrders(address,address,uint256,uint256,bytes)":{"params":{"inputAmountSent":"The amount of `inputToken` that was sent to `IOrderBookV4OrderTaker`.","inputToken":"The token that was sent to `IOrderBookV4OrderTaker`.","outputToken":"The token that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns.","takeOrdersData":"The data passed to `takeOrders` by the caller.","totalOutputAmount":"The total amount of `outputToken` that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns."}},"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[EIP 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":{"onTakeOrders(address,address,uint256,uint256,bytes)":{"notice":"Called by `IOrderBookV4` when `takeOrders` is called with non-zero data, if it caused a non-zero input amount. I.e. if the order(s) taker received some tokens. Input and output directions are relative to the `IOrderBookV4OrderTaker` contract. If the order(s) taker had an active debt from a flash loan then that debt will be paid _before_ calculating any input amounts sent. i.e. the debt is deducted from the input amount before this callback is called."}},"version":1}},"settings":{"remappings":["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.interpreter.interface/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/","integrity/=lib/rain.interpreter/src/lib/integrity/","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/","openzeppelin/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/","parse/=lib/rain.interpreter/src/lib/parse/","prb-math/=lib/rain.interpreter/lib/prb-math/src/","rain.datacontract/=lib/rain.interpreter/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.sol.codegen/lib/rain.math.binary/src/","rain.math.fixedpoint/=lib/rain.interpreter/lib/rain.math.fixedpoint/src/","rain.math.saturating/=lib/rain.interpreter/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.binmaskflag/=lib/rain.interpreter/lib/rain.sol.binmaskflag/src/","rain.sol.codegen/=lib/rain.interpreter/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.math.fixedpoint/lib/rain.string/src/","state/=lib/rain.interpreter/src/lib/state/","sushixswap-v2/=lib/sushixswap-v2/"],"optimizer":{"enabled":true,"runs":9000},"metadata":{"bytecodeHash":"none","appendCBOR":false},"compilationTarget":{"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol":"BalancerRouterOrderBookV4ArbOrderTaker"},"evmVersion":"paris","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.math.fixedpoint/src/error/ErrScale.sol":{"keccak256":"0xf078f93e8cf6360008743854983c2c98a43f7f78b95a527473089a22b81c55a0","urls":["bzz-raw://580c4ad750f0ebebdf77f87feb52bce41f2d72fa4bf9221fbe3977837eb6a4d9","dweb:/ipfs/QmeYydyLSLqFT5DfFDgJBEBBeBEhwvsMi3oQ4USXXrQudF"],"license":"LicenseRef-DCL-1.0"},"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/FixedPointDecimalConstants.sol":{"keccak256":"0x9299cb9b7aeeaa2a60c6e248928bc173750c5361df4fc0e4d9ea94a778fcd6e6","urls":["bzz-raw://3a65a4f0f3b7462cb0b0b6d165d3868010ff19192f53a8133e3e93be3d811d81","dweb:/ipfs/QmSFWpSUH2cAcw7ph2c5rwvqcKWXTJgvabaRjk2P8ZMzcP"],"license":"LicenseRef-DCL-1.0"},"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/LibFixedPointDecimalScale.sol":{"keccak256":"0xef9a2b240ba686ee4b31c37edfbbab1a3b276db3ad269688fa2c0d1beced6c0b","urls":["bzz-raw://a4e115922faa62d4c3f64c466b9e3d27f53d611c92422828c1920c37bc51acfa","dweb:/ipfs/QmPa5cnqmk8eHjkdSPzegHDN9Q4jWbNV1DHeFKh5LZ6XVk"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol":{"keccak256":"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544","urls":["bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e","dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol":{"keccak256":"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1","urls":["bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34","dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305","urls":["bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5","dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca","urls":["bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd","dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"keccak256":"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69","urls":["bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71","dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1","urls":["bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68","dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa","urls":["bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931","dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0","urls":["bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f","dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"keccak256":"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58","urls":["bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2","dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol":{"keccak256":"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80","urls":["bzz-raw://77d1f1cf302cd5e1dfbbb4ce3b281b28e8c52942d4319fce43df2e1b6f02a52d","dweb:/ipfs/QmT6ZXStmK3Knhh9BokeVHQ9HXTBZNgL3Eb1ar1cYg1hWy"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","urls":["bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d","dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","urls":["bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f","dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3","urls":["bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c","dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc","urls":["bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7","dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrBytes.sol":{"keccak256":"0x82df8bd5b6a2343eb41c47f9b58f05adb2f8fd92b146ddb31c0ea697ebe3acd4","urls":["bzz-raw://f95976983e965460330e2a1d00f3ed0e2079e13a67f3364f1175723cd97b6a07","dweb:/ipfs/QmQKhYbVSesLuomYv4XPapPMvLmXNLgSx2QtgK5EJhww5c"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol":{"keccak256":"0xfc1739c5c406f71e1f52ebfd163162087e9025b02444ca12ae8844c71dcd1cf5","urls":["bzz-raw://ae2e95f1e6260b18105369c7216e1ebc6a251ffe3548d27ce180f7885c3f6906","dweb:/ipfs/QmPQEzZmQDuzp8R5rp6ABmzGD243qu8R5GX4FbHc8G4CUC"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes.sol":{"keccak256":"0x46f53ecd0554926ed6ef781485f9c3d3dfe08fa5503021aac7476c28df364f30","urls":["bzz-raw://d6841328d12c44dfc3e966d2372b841f27659b592556411bcb2889ed1a8db6b2","dweb:/ipfs/QmQHUvQre6Jb5VtiKDvwQiff3eLSCPxRkAs8Jy81dnPbdD"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibMemCpy.sol":{"keccak256":"0x58be272366c53e5db26413754881238127a5ccedc69439d50afbb4c4f9769006","urls":["bzz-raw://49d241b4acc8462d0289eafe645c20493a615c9bef629dab4f049599373df1c7","dweb:/ipfs/QmYLK8fhzz5kjdaQY29yrcgEcGv31gUABvC7eHoChgYwV7"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol":{"keccak256":"0xdadaac57081823b3a4162aeda93195d1dbe98caf1141f6d9113302909c851307","urls":["bzz-raw://fa6026d3853dd4a58faa0c9ac2dda867c200963a052a4d62e8797cd3a0e29250","dweb:/ipfs/QmPRKmE5tpJKwCpy3rumAMjCqDdGK8UC2r2soB1CNQwfmJ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol":{"keccak256":"0xbfea88bec2894f0ff0b3f8b3088f4a45f561aff1bc439165bcdb0e15fa0124ea","urls":["bzz-raw://3ef8c1cf899aa39585cded6e6510e637fa5e60f40dae9e39688ecacd41ef9c41","dweb:/ipfs/Qme4nJr2tCfkY9DDiMhcGjuvjy6jFGZvNgCeMD81YACEKR"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/error/ErrBytecode.sol":{"keccak256":"0x56d9f7a498877655b507ddb4683f4cdbb961bf38375d85c80ab66f8cf0aa9d03","urls":["bzz-raw://0206c9b5a55818d20b2a644c2da0a5cfbbfffb82d4e49bbd0ddd5d60df19ecb8","dweb:/ipfs/QmZuMWg8zqPFDVSWKZnRxrmDpr3YQE7ERSjAFLWnK4iDyd"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterCallerV3.sol":{"keccak256":"0x17a433a06d82d1fbaa497ab0ab0a3c698f86dcdbf9b3dc6814d2f64b1592bc32","urls":["bzz-raw://eb06d882eab9261c1561a3f087b4eb6b29bbf919f6902859a3464d7ecd738315","dweb:/ipfs/QmacaaExc2aL4xokmcBxKy2nhRYKWkEhb2DV2KNJQbMHxK"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol":{"keccak256":"0xd3fe133132e9688f0590f273b1a9851d17b794d7ed85d5cc7a4cf961220359f3","urls":["bzz-raw://bd74c48f247d80804a1fcaa664b4771cbca471cb5bc29307e585d60fb4162bf1","dweb:/ipfs/QmX8PF8aVeXbKsuaBnvLpsgcyjqxHUZK2wgogmNDzQC8mr"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterV3.sol":{"keccak256":"0x152209b9afda8a9fbba404563d67566584b95f49f57f321538d66995b81de300","urls":["bzz-raw://84a09751006cd68411da9684379919e6f0a6b7606050392633146374b7d10141","dweb:/ipfs/QmWoST14FWQr8MqGZXruDvJn5FeQrTkKZomSjazcp6msdm"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IParserV2.sol":{"keccak256":"0x9893dfb4e05bfbf088921c5cca38265388de5ef9e127ec8674a2ce6356152725","urls":["bzz-raw://19bac62db62ad9cb20a9b9790208e124bcfdf89f7deeae25b3cb30f11f680724","dweb:/ipfs/QmUvj4Zcj3b6ACRjcAHRW9geoLfLUXuKydcbMakaxRFPTa"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV1.sol":{"keccak256":"0x933cbfee07ddc43390326f87034613216352250472577bd890e9589e6206fad4","urls":["bzz-raw://d0f947ca6eb86ae9c03806430f5c3a946882daee9f82e436067b1c42ff554595","dweb:/ipfs/QmV7jK8dK6de1HDsUjKDGfEPwVdNEzDHgVHmVZKyfGv6MQ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV2.sol":{"keccak256":"0x3f03703392207a285d41b2871c2d83df103425c1984750cc303628269e6258e5","urls":["bzz-raw://a9bc96c0f288ab7b6ec1a14a42e426ec745f0b1c7fcde9d7052380c64e61c8da","dweb:/ipfs/QmYBobAFw36Jd2VtFtoWNqE8HxJhy3n9Eho1fsK3uBCbwc"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV3.sol":{"keccak256":"0x231a50d32c6f910d7ae13ae1d83a221ba55eb7962380572c9c354c8a3c5c52bf","urls":["bzz-raw://74b19a6c17ac7fab6edee53218a35154c5fe9ad3769ce8e22bac682dd32df0e8","dweb:/ipfs/QmYiG7i4tNfA4eTynoQVbNixvGepqoAedVz2isiMfxRF8D"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV1.sol":{"keccak256":"0x20aebc5f73ffd790da90b8e88d6412f9c3a11041239c669c03e188d0a6be1e3e","urls":["bzz-raw://24f85bcb1d9f52ae01f7127274100ef68640a823bf2b981f267faf71192d8235","dweb:/ipfs/QmPmz7q4rsy9vWXixdG9qBB8fLb1Wjj8LWyq6wyuFQR2HK"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV2.sol":{"keccak256":"0x8ae6f8b21d5fba09db20a979e797339d4cc385450d4da8cb4de2331db638caee","urls":["bzz-raw://162b488b86df5c57c8cecd6c02172122ab9d30d70dd135ea151db5d56bf06f62","dweb:/ipfs/Qmf9Kd89mH6PE5hoQ6ahV1Dsi28AFbakeUUw12W9Dp3sHW"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol":{"keccak256":"0xe03c065839e972fde62d73c45acf6fc2e88f42e3a07f4255ef5bfdcd30d3b1f1","urls":["bzz-raw://e766d9cfe9464f722e02320c3936fb0b98b9417663fefba6bac3dbb21007ce82","dweb:/ipfs/QmX88DnazhZw7B3Fxp1iDZXogi2k6dyMPvh2vXpXep11oQ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol":{"keccak256":"0x8986cb9ba93034751b21245398bc1ef7a55fe10d34b5d4cc4207ee9d39a3e616","urls":["bzz-raw://dc7d8e706e96f0d0e53599582fadd591581484ac36921b0e4c6454c54b568c2b","dweb:/ipfs/QmNczMgGQKWJiDhXVbtXeBjUEtzFtr7k41uPjiU8P6BrHT"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV2.sol":{"keccak256":"0x0a9223e817a36a9717b91f977a9fce5e698afd393aa2405979baf53a12339805","urls":["bzz-raw://1537576666b7462485e898ddbd36848be401b3c1e3f8317eca4112d1b21d4e74","dweb:/ipfs/QmZYRLbnctnMKEZ4UYz9oZ9MFoqQy1hex29HrXPVBX5U1g"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IParserV1.sol":{"keccak256":"0x19e1a217e8c67c671e319dd0e5608d7c496fbfc02363fbb2d08626715625dd55","urls":["bzz-raw://603b3234a5c084acb12d0b7e3909503869f9a6d860f91d86692e007f67aba25b","dweb:/ipfs/QmU7i9uyr9qWFzD2xjn1qjgiPjb8vUjuXA6dHEuGLVkmPj"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/bytecode/LibBytecode.sol":{"keccak256":"0xdebdca9d3d2a6c1be927f6fa1f28550cd7885aa52abd378ddb65e5f6495ef87c","urls":["bzz-raw://5ca7fe490fe2b1287c3c231ec34daa504b3b36fa6c3e69aacda9737db1e1b548","dweb:/ipfs/QmQozWFz6qFJDiRFS1YgPWCsRZgCCQ3yEzmwTVyiCs7SxY"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibContext.sol":{"keccak256":"0xd2cfeec3582d7b0b2a09573e258230ec4a6de169e60d9078f674a7a09d0c7b2d","urls":["bzz-raw://cf266d36372575856000331ebb8dca7d6025db6365d14f4c876ab55305090aba","dweb:/ipfs/QmYyoYFXryPM2SRMafgUgsBbAXPeCmzLFvzhHGR3i47zHy"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibEvaluable.sol":{"keccak256":"0x922f6df3f98bc94869b9c244ae349e4ecfe0f250937414af7f3699e016b9f57e","urls":["bzz-raw://e4fd2f59466c83a6e5dfe843951880d3f1dbe98cf559746242d942ab20962166","dweb:/ipfs/QmTTD9vj8ph7ocmWFAjPb4D4UiwusCg7iZEPWoRfVtEEu1"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/deprecated/caller/LibEncodedDispatch.sol":{"keccak256":"0x0d9b888a01c5d508dd3cdfd53823ad56c6e16e06d18ca8b2ac68e82b102cc60a","urls":["bzz-raw://6f854a3243d04aa76169367843a97bec51574f01ddb1e31b271f8aa93e184dce","dweb:/ipfs/QmRc85MSQBbqvCvdcZBHvBrA8FFfVbxYWHbNV2vshmLF95"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/ns/LibNamespace.sol":{"keccak256":"0x5e1f5a0e05fbadf8acfad550ed59d960dd05ebc1d74cfa676f22a26644cc0ee5","urls":["bzz-raw://ee31bfc695ae5dc841379c3164b345bb0951b8b10fd94f300d5bb2de51dd7a1e","dweb:/ipfs/QmT1CqR7Lpj2bEJADgEPgY9cmTqgKLEZm1QLbZxfHEd8PY"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/IOrderBookV4.sol":{"keccak256":"0x715c5211361bd469a9ec916710611536d087ae5630a3fc3f80e9802ec43c4596","urls":["bzz-raw://c61433f7de82ac5fbd752470aa1b9358dc70455ba85be87a9056509188f5db21","dweb:/ipfs/QmaGvPxe4xpqkVMdq9mo2moJyBHB9f8wTkcxZotk7tevVH"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/IOrderBookV4OrderTaker.sol":{"keccak256":"0x7d197bd91214d318ce6a9ee388228494606ba7bdae36bbc6ec6ed1681ff60bd8","urls":["bzz-raw://73caf415d34e06a83d104cbccf98ae76ccd522e5ae1fb32c2bb18af9bae7ccaa","dweb:/ipfs/QmYbiDgjfjpX6pvjawqhtQpiTkUuX24ncHodheJPtSg4d7"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v2/IOrderBookV2.sol":{"keccak256":"0x30c528f1772e9593b5329f1458cab4cce3510a2ccca01696b506af177fffd786","urls":["bzz-raw://9f53c14e5aaab2cd2fbf5b39d07c59acfdc09aff3476345816c2635de2cdd5d3","dweb:/ipfs/QmaomXfmDKdoeYwbMe9cy5anx4fDEMtP4W9Rre5s5DZVE6"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v3/IOrderBookV3.sol":{"keccak256":"0xdca3fd0c6106ab98d08682e63e433b74250d1f01e646a5908c97183d9b25130b","urls":["bzz-raw://0f986a8388275a4144068981aa628e46bff221c2d27a3ad597a9c5fc2d4fcb09","dweb:/ipfs/QmR2pxkpY4ddhLb7jdoNAVSJwYHokyGpn5Tzg3Q7YnGYgW"],"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/IOrderBookV4ArbOrderTakerV2.sol":{"keccak256":"0x271d4a0fdeddc07a88b18fa52f39c840515e572d62a755f7710bbd1b20ebe389","urls":["bzz-raw://64000bb3455809c1eb2a8789023286ad9ccaa2cdfe014cff480e96bb1b7ad6a3","dweb:/ipfs/QmRDgNHR4mYjxvHJUNMaaDZdAnxZ7yDF9kCL3aaSYip6AH"],"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/OrderBookV4ArbCommon.sol":{"keccak256":"0xe24cce13b3e21ae36c0aae11380128c5f0ddf542a0298f1a1845a39845e10576","urls":["bzz-raw://5f5d04c151a7e9fe4a659cef55abc4a626bc2ba0e58edbd714dcbadb52f4b396","dweb:/ipfs/QmZHQiYBNdxMJWoMjHnsqoj2YszvFMWrGYqDcodKpwyv98"],"license":"LicenseRef-DCL-1.0"},"src/abstract/OrderBookV4ArbOrderTaker.sol":{"keccak256":"0xa419a3d91a8c362dad1bea2761e6e0218c96ff295064aad1f5548444977d7896","urls":["bzz-raw://0995be2430baeccbf24ead130e100f6d19a354b2703d65a3544a9bf516ff4c6c","dweb:/ipfs/QmVaKDPVFe8U4MxnR3vwr7yLPrxo6hzYEud4XZzkHShsMu"],"license":"LicenseRef-DCL-1.0"},"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol":{"keccak256":"0x2cd70a0a532aabe6b5df682078bb2bc60afb519c05502389e2ca334ef95131ca","urls":["bzz-raw://172cd3ad61d01b30127a129bbf1ab8091e664ef66e7514ff3651189022f2917e","dweb:/ipfs/QmS7SigcghYoJuzXoKEY89hx7gGSCWsBBZ1qf7tkNACjN9"],"license":"LicenseRef-DCL-1.0"},"src/lib/LibOrderBook.sol":{"keccak256":"0xa33a7731cde01162cc5d5a1d28b96a17626a6919971620850f92cc32a20342cf","urls":["bzz-raw://9bcbc37dd34292bca2ebdc620b418fbfd8b65039a3d040512f9c8d091ed1f2bf","dweb:/ipfs/QmQEBw7n6QKuzF1BMtxyYcZTk8eK4Hed8QVEwuQtUUJ4AM"],"license":"LicenseRef-DCL-1.0"},"src/lib/LibOrderBookArb.sol":{"keccak256":"0xe6ba0ae436fbb48193585beaaac8fc9b367ec9f511281b55e6cbc354c7faae90","urls":["bzz-raw://2b69af34b0acdabe929170984243f7a04581df75010d790147b86f72bc6411c2","dweb:/ipfs/QmZAYyTLrfB5w3uintmQp1Au32YyVrknfqcd6hLLvf1RKk"],"license":"LicenseRef-DCL-1.0"}},"version":1},"id":53} \ No newline at end of file +{"abi":[{"type":"constructor","inputs":[{"name":"config","type":"tuple","internalType":"struct OrderBookV4ArbConfigV2","components":[{"name":"orderBook","type":"address","internalType":"address"},{"name":"task","type":"tuple","internalType":"struct TaskV1","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"uint256[]","internalType":"uint256[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"implementationData","type":"bytes","internalType":"bytes"}]}],"stateMutability":"nonpayable"},{"type":"fallback","stateMutability":"nonpayable"},{"type":"function","name":"arb3","inputs":[{"name":"orderBook","type":"address","internalType":"contract IOrderBookV4"},{"name":"takeOrders","type":"tuple","internalType":"struct TakeOrdersConfigV3","components":[{"name":"minimumInput","type":"uint256","internalType":"uint256"},{"name":"maximumInput","type":"uint256","internalType":"uint256"},{"name":"maximumIORatio","type":"uint256","internalType":"uint256"},{"name":"orders","type":"tuple[]","internalType":"struct TakeOrderConfigV3[]","components":[{"name":"order","type":"tuple","internalType":"struct OrderV3","components":[{"name":"owner","type":"address","internalType":"address"},{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"validInputs","type":"tuple[]","internalType":"struct IO[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"decimals","type":"uint8","internalType":"uint8"},{"name":"vaultId","type":"uint256","internalType":"uint256"}]},{"name":"validOutputs","type":"tuple[]","internalType":"struct IO[]","components":[{"name":"token","type":"address","internalType":"address"},{"name":"decimals","type":"uint8","internalType":"uint8"},{"name":"vaultId","type":"uint256","internalType":"uint256"}]},{"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":"uint256[]","internalType":"uint256[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"data","type":"bytes","internalType":"bytes"}]},{"name":"task","type":"tuple","internalType":"struct TaskV1","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"uint256[]","internalType":"uint256[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"iPermit2","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IPermit2"}],"stateMutability":"view"},{"type":"function","name":"iTaskHash","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"onTakeOrders","inputs":[{"name":"inputToken","type":"address","internalType":"address"},{"name":"outputToken","type":"address","internalType":"address"},{"name":"inputAmountSent","type":"uint256","internalType":"uint256"},{"name":"totalOutputAmount","type":"uint256","internalType":"uint256"},{"name":"takeOrdersData","type":"bytes","internalType":"bytes"}],"outputs":[],"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 OrderBookV4ArbConfigV2","components":[{"name":"orderBook","type":"address","internalType":"address"},{"name":"task","type":"tuple","internalType":"struct TaskV1","components":[{"name":"evaluable","type":"tuple","internalType":"struct EvaluableV3","components":[{"name":"interpreter","type":"address","internalType":"contract IInterpreterV3"},{"name":"store","type":"address","internalType":"contract IInterpreterStoreV2"},{"name":"bytecode","type":"bytes","internalType":"bytes"}]},{"name":"signedContext","type":"tuple[]","internalType":"struct SignedContextV1[]","components":[{"name":"signer","type":"address","internalType":"address"},{"name":"context","type":"uint256[]","internalType":"uint256[]"},{"name":"signature","type":"bytes","internalType":"bytes"}]}]},{"name":"implementationData","type":"bytes","internalType":"bytes"}]}],"anonymous":false},{"type":"error","name":"InvalidSignature","inputs":[{"name":"i","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"NoOrders","inputs":[]},{"type":"error","name":"WrongTask","inputs":[]}],"bytecode":{"object":"0x60c060405260006080526e22d473030f116ddee9f6b43ac78ba360a05234801561002857600080fd5b50604051613a1a380380613a1a83398101604081905261004791610381565b808060016000819055507f584f220334313e589a42a75ac60d4fa6ed5b02329a7255af822a0e4ac9cd5f1d33826040516100829291906105fa565b60405180910390a16020810151516040015151156100c9576020808201516040516100ad920161065a565b60408051601f1981840301815291905280516020909101206080525b505050610674565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715610109576101096100d1565b60405290565b604080519081016001600160401b0381118282101715610109576101096100d1565b604051601f8201601f191681016001600160401b0381118282101715610159576101596100d1565b604052919050565b6001600160a01b038116811461017657600080fd5b50565b60005b8381101561019457818101518382015260200161017c565b50506000910152565b600082601f8301126101ae57600080fd5b81516001600160401b038111156101c7576101c76100d1565b6101da601f8201601f1916602001610131565b8181528460208386010111156101ef57600080fd5b610200826020830160208701610179565b949350505050565b60006001600160401b03821115610221576102216100d1565b5060051b60200190565b600082601f83011261023c57600080fd5b8151602061025161024c83610208565b610131565b82815260059290921b8401810191818101908684111561027057600080fd5b8286015b848110156103765780516001600160401b038082111561029357600080fd5b908801906060828b03601f190112156102ac5760008081fd5b6102b46100e7565b868301516102c181610161565b8152604083810151838111156102d75760008081fd5b8401603f81018d136102e95760008081fd5b888101516102f961024c82610208565b81815260059190911b82018301908a8101908f8311156103195760008081fd5b928401925b828410156103375783518252928b0192908b019061031e565b858c01525050506060840151838111156103515760008081fd5b61035f8d8a8388010161019d565b918301919091525085525050918301918301610274565b509695505050505050565b6000602080838503121561039457600080fd5b82516001600160401b03808211156103ab57600080fd5b90840190606082870312156103bf57600080fd5b6103c76100e7565b82516103d281610161565b815282840151828111156103e557600080fd5b8301604081890312156103f757600080fd5b6103ff61010f565b81518481111561040e57600080fd5b82016060818b03121561042057600080fd5b6104286100e7565b815161043381610161565b81528188015161044281610161565b8189015260408201518681111561045857600080fd5b6104648c82850161019d565b604083015250825250818601518481111561047e57600080fd5b61048a8a82850161022b565b87830152508086840152505060408301519350818411156104aa57600080fd5b6104b68785850161019d565b60408201529695505050505050565b600081518084526104dd816020860160208601610179565b601f01601f19169290920160200192915050565b6000604082516040855260018060a01b03808251166040870152602080830151606083821660608a015260408501519450606060808a015261053660a08a01866104c5565b888401518a82038b86015280518083529196508401925083860190600581901b870185016000805b838110156105e857898303601f19018552865180518a168452888101518985018890528051888601819052908a0190849060808701905b808310156105b55783518252928c019260019290920191908c0190610595565b508e84015193508681038f8801526105cd81856104c5565b9650505050508787019650878501945060018101905061055e565b50909c9b505050505050505050505050565b6001600160a01b0383811682526040602080840182905284519092169083015282015160608083015260009061063360a08401826104f1565b90506040840151603f1984830301608085015261065082826104c5565b9695505050505050565b60208152600061066d60208301846104f1565b9392505050565b60805160a05161335f6106bb6000396000818160cf0152818161029c0152818161037c01526106a001526000818161013b015281816107480152610799015261335f6000f3fe60806040526004361061005a5760003560e01c806369e5049b1161004357806369e5049b146100bd5780637ea0b76a1461011657806393be095e146101295761005a565b806301ffc9a714610068578063059bebe61461009d575b34801561006657600080fd5b005b34801561007457600080fd5b50610088610083366004611ef8565b61016b565b60405190151581526020015b60405180910390f35b3480156100a957600080fd5b506100666100b8366004611f5f565b610250565b3480156100c957600080fd5b506100f17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b610066610124366004612009565b610735565b34801561013557600080fd5b5061015d7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610094565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f059bebe60000000000000000000000000000000000000000000000000000000014806101fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f7ea0b76a00000000000000000000000000000000000000000000000000000000145b8061024a57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60008061025f8385018561218f565b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015260001960248301529294509092509089169063095ea7b3906044016020604051808303816000875af11580156102fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061032091906122da565b506040517f87517c4500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8981166004830152838116602483015260448201819052600060648301527f000000000000000000000000000000000000000000000000000000000000000016906387517c4590608401600060405180830381600087803b1580156103c057600080fd5b505af11580156103d4573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614610476576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496e76616c696420696e70757420746f6b656e0000000000000000000000000060448201526064015b60405180910390fd5b6020810151805173ffffffffffffffffffffffffffffffffffffffff891691906104a290600190612326565b815181106104b2576104b2612339565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff161461053b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c6964206f757470757420746f6b656e000000000000000000000000604482015260640161046d565b60408181018790526060820186905280516001808252818301909252839160009190816020015b6105a36040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016060815260200160008152602001600081525090565b81526020019060019003908161056257905050905082816000815181106105cc576105cc612339565b602002602001018190525060008060008473ffffffffffffffffffffffffffffffffffffffff1663286f580d8560001960006040518463ffffffff1660e01b815260040161061c93929190612368565b6000604051808303816000875af115801561063b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106639190810190612526565b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152600060248301529396509194509250908e169063095ea7b3906044016020604051808303816000875af1158015610701573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072591906122da565b5050505050505050505050505050565b61073d610a9d565b610746816127c3565b7f0000000000000000000000000000000000000000000000000000000000000000158015906107bb5750806040516020016107819190612911565b604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000014155b156107f2576040517f8812562900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107ff60608401846129fe565b905060000361083a576040517f9c95219f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061084960608501856129fe565b600081811061085a5761085a612339565b905060200281019061086c9190612a48565b6108769080612a86565b610884906040810190612aba565b61089160608701876129fe565b60008181106108a2576108a2612339565b90506020028101906108b49190612a48565b602001358181106108c7576108c7612339565b6108dd9260206060909202019081019150612b03565b905060006108ee60608601866129fe565b60008181106108ff576108ff612339565b90506020028101906109119190612a48565b61091b9080612a86565b610929906060810190612aba565b61093660608801886129fe565b600081811061094757610947612339565b90506020028101906109599190612a48565b6040013581811061096c5761096c612339565b6109829260206060909202019081019150612b03565b90506109a673ffffffffffffffffffffffffffffffffffffffff8316876000610b10565b6109c973ffffffffffffffffffffffffffffffffffffffff831687600019610b10565b6000808773ffffffffffffffffffffffffffffffffffffffff16630997c4a0886040518263ffffffff1660e01b8152600401610a059190612dd1565b60408051808303816000875af1158015610a23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a479190613035565b9092509050610a6e73ffffffffffffffffffffffffffffffffffffffff8516896000610b10565b610a81610a7a876127c3565b8585610cf2565b5050505050610a906001600055565b505050565b505050505050565b600260005403610b09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161046d565b6002600055565b801580610bb057506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015610b8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bae9190613059565b155b610c3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840161046d565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a909084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526110ca565b604080516001808252818301909252600091816020015b6060815260200190600190039081610d09575050604080516003808252608082019092529192506000919060208201606080368337019050506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610db2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd69190613059565b90508015610dff57610dff73ffffffffffffffffffffffffffffffffffffffff861633836111d9565b60008573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e709190613072565b60ff169050610e818282600061122f565b83600081518110610e9457610e94612339565b602090810291909101015250506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015610f0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f329190613059565b90508015610f5b57610f5b73ffffffffffffffffffffffffffffffffffffffff851633836111d9565b60008473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcc9190613072565b60ff169050610fdd8282600061122f565b83600181518110610ff057610ff0612339565b60209081029190910101525047905061100933826112b7565b808260028151811061101d5761101d612339565b60200260200101818152505050808260008151811061103e5761103e612339565b6020908102919091010152604080516001808252818301909252600091816020015b6040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915281526020019060019003908161106057905050905085816000815181106110b5576110b5612339565b6020026020010181905250610a958382611411565b600061112c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661160a9092919063ffffffff16565b905080516000148061114d57508080602001905181019061114d91906122da565b610a90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161046d565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a909084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610c8e565b60008260121115611264576012839003600283161561125a576112528582611621565b9150506112b0565b6112528582611672565b60128311156112ad577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee830160018316156112a35761125285826116aa565b61125285826116f8565b50825b9392505050565b80471015611321576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161046d565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461137b576040519150601f19603f3d011682016040523d82523d6000602084013e611380565b606091505b5050905080610a90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161046d565b336114446040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915290565b60005b83518110156116035783818151811061146257611462612339565b6020026020010151915060008260000151604001515111156115fb578151805160209182015160008681523090935260408320839273ffffffffffffffffffffffffffffffffffffffff169163d6e3357a9187600001516040015160006114cd8d8b6020015161171b565b604080516000815260208101918290527fffffffff0000000000000000000000000000000000000000000000000000000060e089901b169091526115199594939291906024810161308f565b600060405180830381865afa158015611536573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261155e919081019061313f565b80519193509150156115f8578351602001516040517f946aadc600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063946aadc6906115c590889085906004016131a3565b600060405180830381600087803b1580156115df57600080fd5b505af11580156115f3573d6000803e3d6000fd5b505050505b50505b600101611447565b5050505050565b60606116198484600085611a2b565b949350505050565b6000604e82106116435782156116395760001961163c565b60005b905061024a565b50600a81900a828102908381838161165d5761165d6131bc565b041461166b57600019611619565b5092915050565b600a81900a61168181846131eb565b9050604e821061024a5782156116a15761169c82600a6132e6565b6112b0565b60009392505050565b6000604e82106116ce5782156116c15760016116c4565b60005b60ff16905061024a565b600a82900a8084816116e2576116e26131bc565b049150808202841461166b575060010192915050565b6000604e8210156116a15781600a0a8381611715576117156131bc565b046112b0565b60606000825167ffffffffffffffff8111156117395761173961208e565b604051908082528060200260200182016040528015611762578160200160208202803683370190505b50905060008084511161177657600061177c565b83516001015b855160010101905060008167ffffffffffffffff81111561179f5761179f61208e565b6040519080825280602002602001820160405280156117d257816020015b60608152602001906001900390816117bd5790505b50905060006117f7604080516002815233602082015230818301526060810190915290565b82828151811061180957611809612339565b602002602001018190525060005b875181101561186757818060010192505087818151811061183a5761183a612339565b602002602001015183838151811061185457611854612339565b6020908102919091010152600101611817565b50855115611a215780806001019150508382828151811061188a5761188a612339565b602002602001018190525060005b8651811015611a1f576119498782815181106118b6576118b6612339565b6020026020010151600001516119266118f38a85815181106118da576118da612339565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b89848151811061193857611938612339565b602002602001015160400151611b44565b611982576040517f52bf98480000000000000000000000000000000000000000000000000000000081526004810182905260240161046d565b86818151811061199457611994612339565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168582815181106119c8576119c8612339565b60200260200101818152505081806001019250508681815181106119ee576119ee612339565b602002602001015160200151838381518110611a0c57611a0c612339565b6020908102919091010152600101611898565b505b5095945050505050565b606082471015611abd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046d565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ae691906132f2565b60006040518083038185875af1925050503d8060008114611b23576040519150601f19603f3d011682016040523d82523d6000602084013e611b28565b606091505b5091509150611b3987838387611bbf565b979650505050505050565b6000806000611b538585611c5f565b90925090506000816004811115611b6c57611b6c613304565b148015611ba457508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611bb55750611bb5868686611ca4565b9695505050505050565b60608315611c55578251600003611c4e5773ffffffffffffffffffffffffffffffffffffffff85163b611c4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046d565b5081611619565b6116198383611de3565b6000808251604103611c955760208301516040840151606085015160001a611c8987828585611e27565b94509450505050611c9d565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611cdb929190613333565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611d4691906132f2565b600060405180830381855afa9150503d8060008114611d81576040519150601f19603f3d011682016040523d82523d6000602084013e611d86565b606091505b5091509150818015611d9a57506020815110155b8015611bb5575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611dd89083016020908101908401613059565b149695505050505050565b815115611df35781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046d919061334c565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611e5e5750600090506003611eef565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611eb2573d6000803e3d6000fd5b5050604051601f19015191505073ffffffffffffffffffffffffffffffffffffffff8116611ee857600060019250925050611eef565b9150600090505b94509492505050565b600060208284031215611f0a57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146112b057600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611f5c57600080fd5b50565b60008060008060008060a08789031215611f7857600080fd5b8635611f8381611f3a565b95506020870135611f9381611f3a565b94506040870135935060608701359250608087013567ffffffffffffffff80821115611fbe57600080fd5b818901915089601f830112611fd257600080fd5b813581811115611fe157600080fd5b8a6020828501011115611ff357600080fd5b6020830194508093505050509295509295509295565b60008060006060848603121561201e57600080fd5b833561202981611f3a565b9250602084013567ffffffffffffffff8082111561204657600080fd5b9085019060a0828803121561205a57600080fd5b9092506040850135908082111561207057600080fd5b5084016040818703121561208357600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff811182821017156120e0576120e061208e565b60405290565b6040516060810167ffffffffffffffff811182821017156120e0576120e061208e565b6040805190810167ffffffffffffffff811182821017156120e0576120e061208e565b604051601f8201601f1916810167ffffffffffffffff811182821017156121555761215561208e565b604052919050565b600067ffffffffffffffff8211156121775761217761208e565b5060051b60200190565b8015158114611f5c57600080fd5b60008060408084860312156121a357600080fd5b83356121ae81611f3a565b925060208481013567ffffffffffffffff808211156121cc57600080fd5b90860190608082890312156121e057600080fd5b6121e86120bd565b82356121f381611f3a565b8152828401358281111561220657600080fd5b83019150601f8201891361221957600080fd5b813561222c6122278261215d565b61212c565b8181526060918202840186019186820191908c84111561224b57600080fd5b948701945b838610156122ae5780868e0312156122685760008081fd5b6122706120e6565b863561227b81611f3a565b81528689013561228a81611f3a565b818a0152868a013561229b81612181565b818b015283529485019491870191612250565b508087850152505050604083013560408201526060830135606082015280955050505050509250929050565b6000602082840312156122ec57600080fd5b81516112b081612181565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561024a5761024a6122f7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060808083016080845280875180835260a0925060a08601915060a08160051b8701016020808b016000805b85811015612468578a85037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600187528251805173ffffffffffffffffffffffffffffffffffffffff9081168752858201518688018c905280518c8901819052908701919085908c8a01905b8083101561243c5784518051851683528a81015185168b8401526040908101511515908301529389019360019290920191606090910190612400565b50604085810151908b015260609485015194909901939093525050509583019591830191600101612395565b505050870189905287151560408801528681036060880152600281527f30780000000000000000000000000000000000000000000000000000000000006020820152604081019a9950505050505050505050565b600082601f8301126124cd57600080fd5b815160206124dd6122278361215d565b8083825260208201915060208460051b8701019350868411156124ff57600080fd5b602086015b8481101561251b5780518352918301918301612504565b509695505050505050565b60008060006060848603121561253b57600080fd5b835167ffffffffffffffff8082111561255357600080fd5b61255f878388016124bc565b945060209150818601518181111561257657600080fd5b8601601f8101881361258757600080fd5b80516125956122278261215d565b81815260059190911b8201840190848101908a8311156125b457600080fd5b928501925b828410156125db5783516125cc81611f3a565b825292850192908501906125b9565b60408a01519097509450505050808211156125f557600080fd5b50612602868287016124bc565b9150509250925092565b600082601f83011261261d57600080fd5b813567ffffffffffffffff8111156126375761263761208e565b61264a6020601f19601f8401160161212c565b81815284602083860101111561265f57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261268d57600080fd5b8135602061269d6122278361215d565b82815260059290921b840181019181810190868411156126bc57600080fd5b8286015b8481101561251b57803567ffffffffffffffff808211156126e057600080fd5b908801906060828b03601f190112156126f95760008081fd5b6127016120e6565b8683013561270e81611f3a565b8152604083810135838111156127245760008081fd5b8401603f81018d136127365760008081fd5b888101356127466122278261215d565b81815260059190911b82018301908a8101908f8311156127665760008081fd5b928401925b828410156127845783358252928b0192908b019061276b565b858c015250505060608401358381111561279e5760008081fd5b6127ac8d8a8388010161260c565b9183019190915250855250509183019183016126c0565b6000604082360312156127d557600080fd5b6127dd612109565b823567ffffffffffffffff808211156127f557600080fd5b81850191506060823603121561280a57600080fd5b6128126120e6565b823561281d81611f3a565b8152602083013561282d81611f3a565b602082015260408301358281111561284457600080fd5b6128503682860161260c565b6040830152508352602085013591508082111561286c57600080fd5b506128793682860161267c565b60208301525092915050565b60005b838110156128a0578181015183820152602001612888565b50506000910152565b600081518084526128c1816020860160208601612885565b601f01601f19169290920160200192915050565b60008151808452602080850194506020840160005b83811015612906578151875295820195908201906001016128ea565b509495945050505050565b60006020808352606084516040808487015273ffffffffffffffffffffffffffffffffffffffff808351166060880152808584015116608088015260408301519250606060a088015261296760c08801846128a9565b925084880151601f19808986030160408a01528482518087528887019150888160051b880101898501945060005b828110156129ed578489830301845285518781511683528b8101518b8d8501526129c18c8501826128d5565b918a0151848303858c01529190506129d981836128a9565b978d0197958d019593505050600101612995565b509c9b505050505050505050505050565b6000808335601e19843603018112612a1557600080fd5b83018035915067ffffffffffffffff821115612a3057600080fd5b6020019150600581901b3603821315611c9d57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612a7c57600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61833603018112612a7c57600080fd5b6000808335601e19843603018112612ad157600080fd5b83018035915067ffffffffffffffff821115612aec57600080fd5b6020019150606081023603821315611c9d57600080fd5b600060208284031215612b1557600080fd5b81356112b081611f3a565b6000808335601e19843603018112612b3757600080fd5b830160208101925035905067ffffffffffffffff811115612b5757600080fd5b8060051b3603821315611c9d57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112612b9d57600080fd5b90910192915050565b6000808335601e19843603018112612bbd57600080fd5b830160208101925035905067ffffffffffffffff811115612bdd57600080fd5b803603821315611c9d57600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6000808335601e19843603018112612c2e57600080fd5b830160208101925035905067ffffffffffffffff811115612c4e57600080fd5b606081023603821315611c9d57600080fd5b60ff81168114611f5c57600080fd5b8183526000602080850194508260005b85811015612906578135612c9281611f3a565b73ffffffffffffffffffffffffffffffffffffffff16875281830135612cb781612c60565b60ff16878401526040828101359088015260609687019690910190600101612c7f565b818352602080840193600091600585811b830182018585805b89811015612dc257601f19878503018b52612d0e838a612b69565b60608135612d1b81611f3a565b73ffffffffffffffffffffffffffffffffffffffff168652612d3f82890183612b20565b828a8901528083890152608092507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612d79578586fd5b881b808289850137870190506040612d9384820185612ba6565b94508389840301828a0152612dab8484018683612bec565b9f8b019f9850505094880194505050600101612cf3565b50919998505050505050505050565b6000602080835260c083018435828501526040828601358186015260608187013581870152612e0281880188612b20565b60a060808901528481865260e08901905060e08260051b8a010195508260005b83811015613008577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff208b890301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81863603018112612e8357600080fd5b85018035368290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61018112612eb857600080fd5b60808a5281018035612ec981611f3a565b73ffffffffffffffffffffffffffffffffffffffff80821660808d0152612ef28d840184612b69565b915060a0808d01528135612f0581611f3a565b81166101208d0152818d0135612f1a81611f3a565b166101408c0152612f2d818b0182612ba6565b9150896101608d0152612f456101808d018383612bec565b915050612f548a830183612c17565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808e85030160c08f0152612f8a848385612c6f565b9350612f988c860186612c17565b93509150808e85030160e08f015250612fb2838383612c6f565b9250505060808201356101008c01528b8301358c8c0152898301358a8c0152612fdd89840184612b20565b935091508a8103898c0152612ff3818484612cda565b9a505050928901925090880190600101612e22565b5050505050505061301c6080860186612ba6565b9250601f198583030160a0860152611bb5828483612bec565b6000806040838503121561304857600080fd5b505080516020909101519092909150565b60006020828403121561306b57600080fd5b5051919050565b60006020828403121561308457600080fd5b81516112b081612c60565b73ffffffffffffffffffffffffffffffffffffffff8716815260006020878184015260c060408401526130c560c08401886128a9565b86606085015283810360808501528086518083528383019150838160051b84010184890160005b8381101561311a57601f198684030185526131088383516128d5565b948701949250908601906001016130ec565b505086810360a088015261312e81896128d5565b9d9c50505050505050505050505050565b6000806040838503121561315257600080fd5b825167ffffffffffffffff8082111561316a57600080fd5b613176868387016124bc565b9350602085015191508082111561318c57600080fd5b50613199858286016124bc565b9150509250929050565b82815260406020820152600061161960408301846128d5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b808202811582820484141761024a5761024a6122f7565b600181815b8085111561323d578160001904821115613223576132236122f7565b8085161561323057918102915b93841c9390800290613207565b509250929050565b6000826132545750600161024a565b816132615750600061024a565b816001811461327757600281146132815761329d565b600191505061024a565b60ff841115613292576132926122f7565b50506001821b61024a565b5060208310610133831016604e8410600b84101617156132c0575081810a61024a565b6132ca8383613202565b80600019048211156132de576132de6122f7565b029392505050565b60006112b08383613245565b60008251612a7c818460208701612885565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061161960408301846128a9565b6020815260006112b060208301846128a956","sourceMap":"2371:2001:53:-:0;;;1597:1:51;1560:38;;2616:42:53;2570:89;;2666:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2741:6;2489::52;1716:1:5;1821:7;:22;;;;1729:29:51;1739:10;1751:6;1729:29;;;;;;;:::i;:::-;;;;;;;;1773:11;;;;:21;:30;;;:37;:42;1769:119;;1864:11;;;;;1853:23;;;;;;:::i;:::-;;;;-1:-1:-1;;1853:23:51;;;;;;;;;1843:34;;1853:23;1843:34;;;;1831:46;;1769:119;1605:289;2418:81:52;2666:85:53;2371:2001;;14:127:56;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:56;;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:56;;576:22;;;537:62;534:88;;;602:18;;:::i;666:275::-;737:2;731:9;802:2;783:13;;-1:-1:-1;;779:27:56;767:40;;-1:-1:-1;;;;;822:34:56;;858:22;;;819:62;816:88;;;884:18;;:::i;:::-;920:2;913:22;666:275;;-1:-1:-1;666:275:56:o;946:131::-;-1:-1:-1;;;;;1021:31:56;;1011:42;;1001:70;;1067:1;1064;1057:12;1001:70;946:131;:::o;1082:250::-;1167:1;1177:113;1191:6;1188:1;1185:13;1177:113;;;1267:11;;;1261:18;1248:11;;;1241:39;1213:2;1206:10;1177:113;;;-1:-1:-1;;1324:1:56;1306:16;;1299:27;1082:250::o;1337:509::-;1390:5;1443:3;1436:4;1428:6;1424:17;1420:27;1410:55;;1461:1;1458;1451:12;1410:55;1484:13;;-1:-1:-1;;;;;1509:26:56;;1506:52;;;1538:18;;:::i;:::-;1582:55;1625:2;1606:13;;-1:-1:-1;;1602:27:56;1631:4;1598:38;1582:55;:::i;:::-;1662:2;1653:7;1646:19;1708:3;1701:4;1696:2;1688:6;1684:15;1680:26;1677:35;1674:55;;;1725:1;1722;1715:12;1674:55;1738:77;1812:2;1805:4;1796:7;1792:18;1785:4;1777:6;1773:17;1738:77;:::i;:::-;1833:7;1337:509;-1:-1:-1;;;;1337:509:56:o;1851:198::-;1926:4;-1:-1:-1;;;;;1948:30:56;;1945:56;;;1981:18;;:::i;:::-;-1:-1:-1;2026:1:56;2022:14;2038:4;2018:25;;1851:198::o;2054:2494::-;2134:5;2187:3;2180:4;2172:6;2168:17;2164:27;2154:55;;2205:1;2202;2195:12;2154:55;2234:6;2228:13;2260:4;2284:75;2300:58;2355:2;2300:58;:::i;:::-;2284:75;:::i;:::-;2393:15;;;2479:1;2475:10;;;;2463:23;;2459:32;;;2424:12;;;;2503:15;;;2500:35;;;2531:1;2528;2521:12;2500:35;2567:2;2559:6;2555:15;2579:1940;2595:6;2590:3;2587:15;2579:1940;;;2668:10;;-1:-1:-1;;;;;2735:19:56;;;2732:39;;;2767:1;2764;2757:12;2732:39;2794:24;;;;2866:4;2842:12;;;-1:-1:-1;;2838:26:56;2834:37;2831:127;;;2912:1;2941:2;2937;2930:14;2831:127;2984:22;;:::i;:::-;3048:2;3044;3040:11;3034:18;3065:33;3090:7;3065:33;:::i;:::-;3111:22;;3156:2;3193:11;;;3187:18;3221:16;;;3218:106;;;3278:1;3307:2;3303;3296:14;3218:106;3347:17;;3399:2;3391:11;;3387:21;-1:-1:-1;3377:119:56;;3450:1;3479:2;3475;3468:14;3377:119;3534:2;3530;3526:11;3520:18;3564:76;3580:59;3635:3;3580:59;:::i;3564:76::-;3684:18;;;3783:1;3779:11;;;;3771:20;;3767:29;;;3724:14;;;;3812:17;;;3809:110;;;3871:1;3901:3;3896;3889:16;3809:110;3945:11;;;;3969:167;3987:8;3980:5;3977:19;3969:167;;;4069:12;;4055:27;;4008:14;;;;4108;;;;3969:167;;;4156:14;;;4149:29;-1:-1:-1;;;4221:4:56;4213:13;;4207:20;4243:16;;;4240:109;;;4301:1;4331:3;4326;4319:16;4240:109;4385:60;4441:3;4436:2;4425:8;4421:2;4417:17;4413:26;4385:60;:::i;:::-;4369:14;;;4362:84;;;;-1:-1:-1;4459:18:56;;-1:-1:-1;;4497:12:56;;;;2612;;2579:1940;;;-1:-1:-1;4537:5:56;2054:2494;-1:-1:-1;;;;;;2054:2494:56:o;4553:1917::-;4663:6;4694:2;4737;4725:9;4716:7;4712:23;4708:32;4705:52;;;4753:1;4750;4743:12;4705:52;4780:16;;-1:-1:-1;;;;;4845:14:56;;;4842:34;;;4872:1;4869;4862:12;4842:34;4895:22;;;;4951:4;4933:16;;;4929:27;4926:47;;;4969:1;4966;4959:12;4926:47;4995:22;;:::i;:::-;5047:2;5041:9;5059:33;5084:7;5059:33;:::i;:::-;5101:22;;5154:11;;;5148:18;5178:16;;;5175:36;;;5207:1;5204;5197:12;5175:36;5230:17;;5281:4;5263:16;;;5259:27;5256:47;;;5299:1;5296;5289:12;5256:47;5327:22;;:::i;:::-;5380:2;5374:9;5408:2;5398:8;5395:16;5392:36;;;5424:1;5421;5414:12;5392:36;5447:17;;5498:4;5480:16;;;5476:27;5473:47;;;5516:1;5513;5506:12;5473:47;5544:22;;:::i;:::-;5596:2;5590:9;5608:33;5633:7;5608:33;:::i;:::-;5650:24;;5704:11;;;5698:18;5725:33;5698:18;5725:33;:::i;:::-;5774:16;;;5767:33;5839:4;5831:13;;5825:20;5857:16;;;5854:36;;;5886:1;5883;5876:12;5854:36;5926:55;5973:7;5962:8;5958:2;5954:17;5926:55;:::i;:::-;5919:4;5906:18;;5899:83;-1:-1:-1;5991:24:56;;-1:-1:-1;6046:11:56;;;6040:18;6070:16;;;6067:36;;;6099:1;6096;6089:12;6067:36;6137:82;6211:7;6200:8;6196:2;6192:17;6137:82;:::i;:::-;6132:2;6123:7;6119:16;6112:108;;6252:7;6247:2;6240:5;6236:14;6229:31;;;6299:4;6295:2;6291:13;6285:20;6269:36;;6330:2;6320:8;6317:16;6314:36;;;6346:1;6343;6336:12;6314:36;6384:55;6431:7;6420:8;6416:2;6412:17;6384:55;:::i;:::-;6377:4;6366:16;;6359:81;6370:5;4553:1917;-1:-1:-1;;;;;;4553:1917:56:o;6475:270::-;6516:3;6554:5;6548:12;6581:6;6576:3;6569:19;6597:76;6666:6;6659:4;6654:3;6650:14;6643:4;6636:5;6632:16;6597:76;:::i;:::-;6727:2;6706:15;-1:-1:-1;;6702:29:56;6693:39;;;;6734:4;6689:50;;6475:270;-1:-1:-1;;6475:270:56:o;6750:2011::-;6799:3;6827:4;6866:5;6860:12;6893:4;6888:3;6881:17;6934:1;6930;6925:3;6921:11;6917:19;6993:2;6978:12;6972:19;6968:28;6961:4;6956:3;6952:14;6945:52;7016:4;7075:2;7061:12;7057:21;7051:28;7098:4;7154:2;7138:14;7134:23;7127:4;7122:3;7118:14;7111:47;7213:4;7199:12;7195:23;7189:30;7167:52;;7250:4;7244:3;7239;7235:13;7228:27;7277:47;7319:3;7314;7310:13;7294:14;7277:47;:::i;:::-;7361:14;;;7355:21;7406:15;;;7392:12;;;7385:37;7472:21;;7502;;;7264:60;;-1:-1:-1;7634:23:56;;;-1:-1:-1;7541:14:56;;;;7595:1;7591:14;;;7580:26;;7576:35;;7675:1;;7706:1029;7722:6;7717:3;7714:15;7706:1029;;;7793:16;;;-1:-1:-1;;7789:30:56;7775:45;;7843:13;;7926:9;;7922:18;;7909:32;;7982:11;;;7976:18;8014:13;;;8007:25;;;8093:21;;7883:13;;;8127:24;;;8216:23;;;;8263:1;;8183:3;8173:14;;;8277:209;8293:8;8288:3;8285:17;8277:209;;;8370:15;;8356:30;;8455:17;;;;8321:1;8312:11;;;;;8412:14;;;;8277:209;;;8281:3;8535:2;8531;8527:11;8521:18;8499:40;;8585:4;8578:5;8574:16;8569:2;8563:4;8559:13;8552:39;8612;8645:5;8629:14;8612:39;:::i;:::-;8604:47;;;;;;8686:2;8678:6;8674:15;8664:25;;8722:2;8715:5;8711:14;8702:23;;7748:1;7743:3;7739:11;7732:18;;7706:1029;;;-1:-1:-1;8751:4:56;;6750:2011;-1:-1:-1;;;;;;;;;;;;6750:2011:56:o;8766:755::-;-1:-1:-1;;;;;9041:15:56;;;9023:34;;9093:2;9088;9073:18;;;9066:30;;;9136:13;;9132:22;;;9112:18;;;9105:50;9190:15;;9184:22;9244:4;9222:20;;;9215:34;8966:4;;9272:59;9003:3;9311:19;;9184:22;9272:59;:::i;:::-;9258:73;;9380:2;9372:6;9368:15;9362:22;9453:2;9449:7;9437:9;9429:6;9425:22;9421:36;9415:3;9404:9;9400:19;9393:65;9475:40;9508:6;9492:14;9475:40;:::i;:::-;9467:48;8766:755;-1:-1:-1;;;;;;8766:755:56:o;9526:255::-;9703:2;9692:9;9685:21;9666:4;9723:52;9771:2;9760:9;9756:18;9748:6;9723:52;:::i;:::-;9715:60;9526:255;-1:-1:-1;;;9526:255:56:o;:::-;2371:2001:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x60806040526004361061005a5760003560e01c806369e5049b1161004357806369e5049b146100bd5780637ea0b76a1461011657806393be095e146101295761005a565b806301ffc9a714610068578063059bebe61461009d575b34801561006657600080fd5b005b34801561007457600080fd5b50610088610083366004611ef8565b61016b565b60405190151581526020015b60405180910390f35b3480156100a957600080fd5b506100666100b8366004611f5f565b610250565b3480156100c957600080fd5b506100f17f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610094565b610066610124366004612009565b610735565b34801561013557600080fd5b5061015d7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610094565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f059bebe60000000000000000000000000000000000000000000000000000000014806101fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f7ea0b76a00000000000000000000000000000000000000000000000000000000145b8061024a57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60008061025f8385018561218f565b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015260001960248301529294509092509089169063095ea7b3906044016020604051808303816000875af11580156102fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061032091906122da565b506040517f87517c4500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8981166004830152838116602483015260448201819052600060648301527f000000000000000000000000000000000000000000000000000000000000000016906387517c4590608401600060405180830381600087803b1580156103c057600080fd5b505af11580156103d4573d6000803e3d6000fd5b505050508773ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614610476576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496e76616c696420696e70757420746f6b656e0000000000000000000000000060448201526064015b60405180910390fd5b6020810151805173ffffffffffffffffffffffffffffffffffffffff891691906104a290600190612326565b815181106104b2576104b2612339565b60200260200101516020015173ffffffffffffffffffffffffffffffffffffffff161461053b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c6964206f757470757420746f6b656e000000000000000000000000604482015260640161046d565b60408181018790526060820186905280516001808252818301909252839160009190816020015b6105a36040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016060815260200160008152602001600081525090565b81526020019060019003908161056257905050905082816000815181106105cc576105cc612339565b602002602001018190525060008060008473ffffffffffffffffffffffffffffffffffffffff1663286f580d8560001960006040518463ffffffff1660e01b815260040161061c93929190612368565b6000604051808303816000875af115801561063b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106639190810190612526565b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152600060248301529396509194509250908e169063095ea7b3906044016020604051808303816000875af1158015610701573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072591906122da565b5050505050505050505050505050565b61073d610a9d565b610746816127c3565b7f0000000000000000000000000000000000000000000000000000000000000000158015906107bb5750806040516020016107819190612911565b604051602081830303815290604052805190602001207f000000000000000000000000000000000000000000000000000000000000000014155b156107f2576040517f8812562900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107ff60608401846129fe565b905060000361083a576040517f9c95219f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061084960608501856129fe565b600081811061085a5761085a612339565b905060200281019061086c9190612a48565b6108769080612a86565b610884906040810190612aba565b61089160608701876129fe565b60008181106108a2576108a2612339565b90506020028101906108b49190612a48565b602001358181106108c7576108c7612339565b6108dd9260206060909202019081019150612b03565b905060006108ee60608601866129fe565b60008181106108ff576108ff612339565b90506020028101906109119190612a48565b61091b9080612a86565b610929906060810190612aba565b61093660608801886129fe565b600081811061094757610947612339565b90506020028101906109599190612a48565b6040013581811061096c5761096c612339565b6109829260206060909202019081019150612b03565b90506109a673ffffffffffffffffffffffffffffffffffffffff8316876000610b10565b6109c973ffffffffffffffffffffffffffffffffffffffff831687600019610b10565b6000808773ffffffffffffffffffffffffffffffffffffffff16630997c4a0886040518263ffffffff1660e01b8152600401610a059190612dd1565b60408051808303816000875af1158015610a23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a479190613035565b9092509050610a6e73ffffffffffffffffffffffffffffffffffffffff8516896000610b10565b610a81610a7a876127c3565b8585610cf2565b5050505050610a906001600055565b505050565b505050505050565b600260005403610b09576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161046d565b6002600055565b801580610bb057506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015610b8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bae9190613059565b155b610c3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840161046d565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a909084907f095ea7b300000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526110ca565b604080516001808252818301909252600091816020015b6060815260200190600190039081610d09575050604080516003808252608082019092529192506000919060208201606080368337019050506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915060009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610db2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd69190613059565b90508015610dff57610dff73ffffffffffffffffffffffffffffffffffffffff861633836111d9565b60008573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e709190613072565b60ff169050610e818282600061122f565b83600081518110610e9457610e94612339565b602090810291909101015250506040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015610f0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f329190613059565b90508015610f5b57610f5b73ffffffffffffffffffffffffffffffffffffffff851633836111d9565b60008473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fa8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcc9190613072565b60ff169050610fdd8282600061122f565b83600181518110610ff057610ff0612339565b60209081029190910101525047905061100933826112b7565b808260028151811061101d5761101d612339565b60200260200101818152505050808260008151811061103e5761103e612339565b6020908102919091010152604080516001808252818301909252600091816020015b6040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915281526020019060019003908161106057905050905085816000815181106110b5576110b5612339565b6020026020010181905250610a958382611411565b600061112c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661160a9092919063ffffffff16565b905080516000148061114d57508080602001905181019061114d91906122da565b610a90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161046d565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a909084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401610c8e565b60008260121115611264576012839003600283161561125a576112528582611621565b9150506112b0565b6112528582611672565b60128311156112ad577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee830160018316156112a35761125285826116aa565b61125285826116f8565b50825b9392505050565b80471015611321576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161046d565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461137b576040519150601f19603f3d011682016040523d82523d6000602084013e611380565b606091505b5050905080610a90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161046d565b336114446040805160a0810182526000918101828152606080830193909352608082018390528152602081019190915290565b60005b83518110156116035783818151811061146257611462612339565b6020026020010151915060008260000151604001515111156115fb578151805160209182015160008681523090935260408320839273ffffffffffffffffffffffffffffffffffffffff169163d6e3357a9187600001516040015160006114cd8d8b6020015161171b565b604080516000815260208101918290527fffffffff0000000000000000000000000000000000000000000000000000000060e089901b169091526115199594939291906024810161308f565b600060405180830381865afa158015611536573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261155e919081019061313f565b80519193509150156115f8578351602001516040517f946aadc600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063946aadc6906115c590889085906004016131a3565b600060405180830381600087803b1580156115df57600080fd5b505af11580156115f3573d6000803e3d6000fd5b505050505b50505b600101611447565b5050505050565b60606116198484600085611a2b565b949350505050565b6000604e82106116435782156116395760001961163c565b60005b905061024a565b50600a81900a828102908381838161165d5761165d6131bc565b041461166b57600019611619565b5092915050565b600a81900a61168181846131eb565b9050604e821061024a5782156116a15761169c82600a6132e6565b6112b0565b60009392505050565b6000604e82106116ce5782156116c15760016116c4565b60005b60ff16905061024a565b600a82900a8084816116e2576116e26131bc565b049150808202841461166b575060010192915050565b6000604e8210156116a15781600a0a8381611715576117156131bc565b046112b0565b60606000825167ffffffffffffffff8111156117395761173961208e565b604051908082528060200260200182016040528015611762578160200160208202803683370190505b50905060008084511161177657600061177c565b83516001015b855160010101905060008167ffffffffffffffff81111561179f5761179f61208e565b6040519080825280602002602001820160405280156117d257816020015b60608152602001906001900390816117bd5790505b50905060006117f7604080516002815233602082015230818301526060810190915290565b82828151811061180957611809612339565b602002602001018190525060005b875181101561186757818060010192505087818151811061183a5761183a612339565b602002602001015183838151811061185457611854612339565b6020908102919091010152600101611817565b50855115611a215780806001019150508382828151811061188a5761188a612339565b602002602001018190525060005b8651811015611a1f576119498782815181106118b6576118b6612339565b6020026020010151600001516119266118f38a85815181106118da576118da612339565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b89848151811061193857611938612339565b602002602001015160400151611b44565b611982576040517f52bf98480000000000000000000000000000000000000000000000000000000081526004810182905260240161046d565b86818151811061199457611994612339565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168582815181106119c8576119c8612339565b60200260200101818152505081806001019250508681815181106119ee576119ee612339565b602002602001015160200151838381518110611a0c57611a0c612339565b6020908102919091010152600101611898565b505b5095945050505050565b606082471015611abd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161046d565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611ae691906132f2565b60006040518083038185875af1925050503d8060008114611b23576040519150601f19603f3d011682016040523d82523d6000602084013e611b28565b606091505b5091509150611b3987838387611bbf565b979650505050505050565b6000806000611b538585611c5f565b90925090506000816004811115611b6c57611b6c613304565b148015611ba457508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611bb55750611bb5868686611ca4565b9695505050505050565b60608315611c55578251600003611c4e5773ffffffffffffffffffffffffffffffffffffffff85163b611c4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161046d565b5081611619565b6116198383611de3565b6000808251604103611c955760208301516040840151606085015160001a611c8987828585611e27565b94509450505050611c9d565b506000905060025b9250929050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401611cdb929190613333565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611d4691906132f2565b600060405180830381855afa9150503d8060008114611d81576040519150601f19603f3d011682016040523d82523d6000602084013e611d86565b606091505b5091509150818015611d9a57506020815110155b8015611bb5575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090611dd89083016020908101908401613059565b149695505050505050565b815115611df35781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046d919061334c565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611e5e5750600090506003611eef565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611eb2573d6000803e3d6000fd5b5050604051601f19015191505073ffffffffffffffffffffffffffffffffffffffff8116611ee857600060019250925050611eef565b9150600090505b94509492505050565b600060208284031215611f0a57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146112b057600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611f5c57600080fd5b50565b60008060008060008060a08789031215611f7857600080fd5b8635611f8381611f3a565b95506020870135611f9381611f3a565b94506040870135935060608701359250608087013567ffffffffffffffff80821115611fbe57600080fd5b818901915089601f830112611fd257600080fd5b813581811115611fe157600080fd5b8a6020828501011115611ff357600080fd5b6020830194508093505050509295509295509295565b60008060006060848603121561201e57600080fd5b833561202981611f3a565b9250602084013567ffffffffffffffff8082111561204657600080fd5b9085019060a0828803121561205a57600080fd5b9092506040850135908082111561207057600080fd5b5084016040818703121561208357600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff811182821017156120e0576120e061208e565b60405290565b6040516060810167ffffffffffffffff811182821017156120e0576120e061208e565b6040805190810167ffffffffffffffff811182821017156120e0576120e061208e565b604051601f8201601f1916810167ffffffffffffffff811182821017156121555761215561208e565b604052919050565b600067ffffffffffffffff8211156121775761217761208e565b5060051b60200190565b8015158114611f5c57600080fd5b60008060408084860312156121a357600080fd5b83356121ae81611f3a565b925060208481013567ffffffffffffffff808211156121cc57600080fd5b90860190608082890312156121e057600080fd5b6121e86120bd565b82356121f381611f3a565b8152828401358281111561220657600080fd5b83019150601f8201891361221957600080fd5b813561222c6122278261215d565b61212c565b8181526060918202840186019186820191908c84111561224b57600080fd5b948701945b838610156122ae5780868e0312156122685760008081fd5b6122706120e6565b863561227b81611f3a565b81528689013561228a81611f3a565b818a0152868a013561229b81612181565b818b015283529485019491870191612250565b508087850152505050604083013560408201526060830135606082015280955050505050509250929050565b6000602082840312156122ec57600080fd5b81516112b081612181565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561024a5761024a6122f7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060808083016080845280875180835260a0925060a08601915060a08160051b8701016020808b016000805b85811015612468578a85037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600187528251805173ffffffffffffffffffffffffffffffffffffffff9081168752858201518688018c905280518c8901819052908701919085908c8a01905b8083101561243c5784518051851683528a81015185168b8401526040908101511515908301529389019360019290920191606090910190612400565b50604085810151908b015260609485015194909901939093525050509583019591830191600101612395565b505050870189905287151560408801528681036060880152600281527f30780000000000000000000000000000000000000000000000000000000000006020820152604081019a9950505050505050505050565b600082601f8301126124cd57600080fd5b815160206124dd6122278361215d565b8083825260208201915060208460051b8701019350868411156124ff57600080fd5b602086015b8481101561251b5780518352918301918301612504565b509695505050505050565b60008060006060848603121561253b57600080fd5b835167ffffffffffffffff8082111561255357600080fd5b61255f878388016124bc565b945060209150818601518181111561257657600080fd5b8601601f8101881361258757600080fd5b80516125956122278261215d565b81815260059190911b8201840190848101908a8311156125b457600080fd5b928501925b828410156125db5783516125cc81611f3a565b825292850192908501906125b9565b60408a01519097509450505050808211156125f557600080fd5b50612602868287016124bc565b9150509250925092565b600082601f83011261261d57600080fd5b813567ffffffffffffffff8111156126375761263761208e565b61264a6020601f19601f8401160161212c565b81815284602083860101111561265f57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261268d57600080fd5b8135602061269d6122278361215d565b82815260059290921b840181019181810190868411156126bc57600080fd5b8286015b8481101561251b57803567ffffffffffffffff808211156126e057600080fd5b908801906060828b03601f190112156126f95760008081fd5b6127016120e6565b8683013561270e81611f3a565b8152604083810135838111156127245760008081fd5b8401603f81018d136127365760008081fd5b888101356127466122278261215d565b81815260059190911b82018301908a8101908f8311156127665760008081fd5b928401925b828410156127845783358252928b0192908b019061276b565b858c015250505060608401358381111561279e5760008081fd5b6127ac8d8a8388010161260c565b9183019190915250855250509183019183016126c0565b6000604082360312156127d557600080fd5b6127dd612109565b823567ffffffffffffffff808211156127f557600080fd5b81850191506060823603121561280a57600080fd5b6128126120e6565b823561281d81611f3a565b8152602083013561282d81611f3a565b602082015260408301358281111561284457600080fd5b6128503682860161260c565b6040830152508352602085013591508082111561286c57600080fd5b506128793682860161267c565b60208301525092915050565b60005b838110156128a0578181015183820152602001612888565b50506000910152565b600081518084526128c1816020860160208601612885565b601f01601f19169290920160200192915050565b60008151808452602080850194506020840160005b83811015612906578151875295820195908201906001016128ea565b509495945050505050565b60006020808352606084516040808487015273ffffffffffffffffffffffffffffffffffffffff808351166060880152808584015116608088015260408301519250606060a088015261296760c08801846128a9565b925084880151601f19808986030160408a01528482518087528887019150888160051b880101898501945060005b828110156129ed578489830301845285518781511683528b8101518b8d8501526129c18c8501826128d5565b918a0151848303858c01529190506129d981836128a9565b978d0197958d019593505050600101612995565b509c9b505050505050505050505050565b6000808335601e19843603018112612a1557600080fd5b83018035915067ffffffffffffffff821115612a3057600080fd5b6020019150600581901b3603821315611c9d57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612a7c57600080fd5b9190910192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61833603018112612a7c57600080fd5b6000808335601e19843603018112612ad157600080fd5b83018035915067ffffffffffffffff821115612aec57600080fd5b6020019150606081023603821315611c9d57600080fd5b600060208284031215612b1557600080fd5b81356112b081611f3a565b6000808335601e19843603018112612b3757600080fd5b830160208101925035905067ffffffffffffffff811115612b5757600080fd5b8060051b3603821315611c9d57600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112612b9d57600080fd5b90910192915050565b6000808335601e19843603018112612bbd57600080fd5b830160208101925035905067ffffffffffffffff811115612bdd57600080fd5b803603821315611c9d57600080fd5b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6000808335601e19843603018112612c2e57600080fd5b830160208101925035905067ffffffffffffffff811115612c4e57600080fd5b606081023603821315611c9d57600080fd5b60ff81168114611f5c57600080fd5b8183526000602080850194508260005b85811015612906578135612c9281611f3a565b73ffffffffffffffffffffffffffffffffffffffff16875281830135612cb781612c60565b60ff16878401526040828101359088015260609687019690910190600101612c7f565b818352602080840193600091600585811b830182018585805b89811015612dc257601f19878503018b52612d0e838a612b69565b60608135612d1b81611f3a565b73ffffffffffffffffffffffffffffffffffffffff168652612d3f82890183612b20565b828a8901528083890152608092507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115612d79578586fd5b881b808289850137870190506040612d9384820185612ba6565b94508389840301828a0152612dab8484018683612bec565b9f8b019f9850505094880194505050600101612cf3565b50919998505050505050505050565b6000602080835260c083018435828501526040828601358186015260608187013581870152612e0281880188612b20565b60a060808901528481865260e08901905060e08260051b8a010195508260005b83811015613008577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff208b890301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81863603018112612e8357600080fd5b85018035368290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61018112612eb857600080fd5b60808a5281018035612ec981611f3a565b73ffffffffffffffffffffffffffffffffffffffff80821660808d0152612ef28d840184612b69565b915060a0808d01528135612f0581611f3a565b81166101208d0152818d0135612f1a81611f3a565b166101408c0152612f2d818b0182612ba6565b9150896101608d0152612f456101808d018383612bec565b915050612f548a830183612c17565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808e85030160c08f0152612f8a848385612c6f565b9350612f988c860186612c17565b93509150808e85030160e08f015250612fb2838383612c6f565b9250505060808201356101008c01528b8301358c8c0152898301358a8c0152612fdd89840184612b20565b935091508a8103898c0152612ff3818484612cda565b9a505050928901925090880190600101612e22565b5050505050505061301c6080860186612ba6565b9250601f198583030160a0860152611bb5828483612bec565b6000806040838503121561304857600080fd5b505080516020909101519092909150565b60006020828403121561306b57600080fd5b5051919050565b60006020828403121561308457600080fd5b81516112b081612c60565b73ffffffffffffffffffffffffffffffffffffffff8716815260006020878184015260c060408401526130c560c08401886128a9565b86606085015283810360808501528086518083528383019150838160051b84010184890160005b8381101561311a57601f198684030185526131088383516128d5565b948701949250908601906001016130ec565b505086810360a088015261312e81896128d5565b9d9c50505050505050505050505050565b6000806040838503121561315257600080fd5b825167ffffffffffffffff8082111561316a57600080fd5b613176868387016124bc565b9350602085015191508082111561318c57600080fd5b50613199858286016124bc565b9150509250929050565b82815260406020820152600061161960408301846128d5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b808202811582820484141761024a5761024a6122f7565b600181815b8085111561323d578160001904821115613223576132236122f7565b8085161561323057918102915b93841c9390800290613207565b509250929050565b6000826132545750600161024a565b816132615750600061024a565b816001811461327757600281146132815761329d565b600191505061024a565b60ff841115613292576132926122f7565b50506001821b61024a565b5060208310610133831016604e8410600b84101617156132c0575081810a61024a565b6132ca8383613202565b80600019048211156132de576132de6122f7565b029392505050565b60006112b08383613245565b60008251612a7c818460208701612885565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b82815260406020820152600061161960408301846128a9565b6020815260006112b060208301846128a956","sourceMap":"2371:2001:53:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2533:290:52;;;;;;;;;;-1:-1:-1;2533:290:52;;;;;:::i;:::-;;:::i;:::-;;;612:14:56;;605:22;587:41;;575:2;560:18;2533:290:52;;;;;;;;2802:1511:53;;;;;;;;;;-1:-1:-1;2802:1511:53;;;;;:::i;:::-;;:::i;2570:89::-;;;;;;;;;;;;;;;;;;2001:42:56;1989:55;;;1971:74;;1959:2;1944:18;2570:89:53;1808:243:56;2877:1011:52;;;;;;:::i;:::-;;:::i;1560:38:51:-;;;;;;;;;;;;;;;;;;3045:25:56;;;3033:2;3018:18;1560:38:51;2899:177:56;2533:290:52;2618:4;2642:55;;;2657:40;2642:55;;2641:135;;-1:-1:-1;2715:60:52;;;2730:45;2715:60;2641:135;:175;;;-1:-1:-1;952:25:14;937:40;;;;2780:36:52;2634:182;2533:290;-1:-1:-1;;2533:290:52:o;2802:1511:53:-;3134:23;;3197:94;;;;3221:14;3197:94;:::i;:::-;3357:64;;;;;:26;3392:8;7135:55:56;;3357:64:53;;;7117:74:56;-1:-1:-1;;7207:18:56;;;7200:34;3133:158:53;;-1:-1:-1;3133:158:53;;-1:-1:-1;3357:26:53;;;;;;7090:18:56;;3357:64:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;3431:67:53;;;;;:16;7812:15:56;;;3431:67:53;;;7794:34:56;7864:15;;;7844:18;;;7837:43;7896:18;;;7889:43;;;3496:1:53;7948:18:56;;;7941:55;3431:8:53;:16;;;;7705:19:56;;3431:67:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3615:10;3589:36;;3597:5;:13;;;3589:36;;;3581:68;;;;;;;8209:2:56;3581:68:53;;;8191:21:56;8248:2;8228:18;;;8221:30;8287:21;8267:18;;;8260:49;8326:18;;3581:68:53;;;;;;;;;3675:11;;;;3687:18;;3667:68;;;;3675:11;3687:22;;3708:1;;3687:22;:::i;:::-;3675:35;;;;;;;;:::i;:::-;;;;;;;:44;;;3667:68;;;3659:101;;;;;;;9068:2:56;3659:101:53;;;9050:21:56;9107:2;9087:18;;;9080:30;9146:22;9126:18;;;9119:50;9186:18;;3659:101:53;8866:344:56;3659:101:53;3839:19;;;;:37;;;3886:18;;;:38;;;3973:30;;4001:1;3973:30;;;;;;;;;3812:15;;-1:-1:-1;;3973:30:53;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3973:30:53;;;;;;;;;;;;;;;;3934:69;;4024:5;4013;4019:1;4013:8;;;;;;;;:::i;:::-;;;;;;:16;;;;4041:31;4074:26;4102:27;4133:14;:26;;;4160:5;-1:-1:-1;;4186:5:53;4133:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4133:65:53;;;;;;;;;;;;:::i;:::-;4258:48;;;;;:26;4293:8;7135:55:56;;4258:48:53;;;7117:74:56;-1:-1:-1;7207:18:56;;;7200:34;4040:158:53;;-1:-1:-1;4040:158:53;;-1:-1:-1;4040:158:53;-1:-1:-1;4258:26:53;;;;;;7090:18:56;;4258:48:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3018:1295;;;;;;;2802:1511;;;;;;:::o;2877:1011:52:-;2261:21:5;:19;:21::i;:::-;1900:186:51::1;3053:4:52::0;1900:186:51::1;:::i;:::-;1957:9;:23:::0;;::::1;::::0;:67:::1;;;2018:4;2007:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;1997:27;;;;;;1984:9;:40;;1957:67;1953:116;;;2047:11;;;;;;;;;;;;;;1953:116;3146:17:52::2;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;:24;;3174:1;3146:29:::0;3142:77:::2;;3198:10;;;;;;;;;;;;;;3142:77;3229:24;3256:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3274:1;3256:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:26;::::0;;::::2;:::i;:::-;:38;::::0;::::2;::::0;::::2;::::0;::::2;:::i;:::-;3295:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3313:1;3295:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:33;;;3256:73;;;;;;;:::i;:::-;:79;::::0;::::2;:73;::::0;;::::2;;:79:::0;;::::2;::::0;-1:-1:-1;3256:79:52::2;:::i;:::-;3229:106:::0;-1:-1:-1;3345:25:52::2;3373:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3391:1;3373:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:26;::::0;;::::2;:::i;:::-;:39;::::0;::::2;::::0;::::2;::::0;::::2;:::i;:::-;3413:17;;::::0;::::2;:10:::0;:17:::2;:::i;:::-;3431:1;3413:20;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:34;;;3373:75;;;;;;;:::i;:::-;:81;::::0;::::2;:75;::::0;;::::2;;:81:::0;;::::2;::::0;-1:-1:-1;3373:81:52::2;:::i;:::-;3345:109:::0;-1:-1:-1;3465:59:52::2;:36;::::0;::::2;3510:9:::0;3522:1:::2;3465:36;:59::i;:::-;3534:75;:36;::::0;::::2;3579:9:::0;-1:-1:-1;;3534:36:52::2;:75::i;:::-;3620:18;3640:19:::0;3663:9:::2;:21;;;3685:10;3663:33;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3619:77:::0;;-1:-1:-1;3619:77:52;-1:-1:-1;3741:59:52::2;:36;::::0;::::2;3786:9:::0;3798:1:::2;3741:36;:59::i;:::-;3811:70;;3839:4:::0;3811:70:::2;:::i;:::-;3845:16;3863:17;3811:27;:70::i;:::-;3063:825;;;;2292:1:5::1;2303:20:::0;1716:1;2809:7;:22;2629:209;2303:20;2877:1011:52;;;:::o;3937:100::-;;;;;;;:::o;2336:287:5:-;1759:1;2468:7;;:19;2460:63;;;;;;;33666:2:56;2460:63:5;;;33648:21:56;33705:2;33685:18;;;33678:30;33744:33;33724:18;;;33717:61;33795:18;;2460:63:5;33464:355:56;2460:63:5;1759:1;2598:7;:18;2336:287::o;1818:573:9:-;2143:10;;;2142:62;;-1:-1:-1;2159:39:9;;;;;2183:4;2159:39;;;34059:34:56;2159:15:9;34129::56;;;34109:18;;;34102:43;2159:15:9;;;;;33971:18:56;;2159:39:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;2142:62;2121:163;;;;;;;34547:2:56;2121:163:9;;;34529:21:56;34586:2;34566:18;;;34559:30;34625:34;34605:18;;;34598:62;34696:24;34676:18;;;34669:52;34738:19;;2121:163:9;34345:418:56;2121:163:9;2321:62;;7147:42:56;7135:55;;2321:62:9;;;7117:74:56;7207:18;;;7200:34;;;2294:90:9;;2314:5;;2344:22;;7090:18:56;;2321:62:9;;;;-1:-1:-1;;2321:62:9;;;;;;;;;;;;;;;;;;;;;;;;;;;2294:19;:90::i;1058:2206:55:-;1200:18;;;1216:1;1200:18;;;;;;;;;1171:26;;1200:18;;;;;;;;;;;;;;;;;-1:-1:-1;;1251:16:55;;;1265:1;1251:16;;;;;;;;;1171:47;;-1:-1:-1;1228:20:55;;1251:16;;;;;;;;;;;-1:-1:-1;;1375:49:55;;;;;1418:4;1375:49;;;1971:74:56;1228:39:55;;-1:-1:-1;1352:20:55;;1375:34;;;;;;1944:18:56;;1375:49:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1352:72;-1:-1:-1;1442:16:55;;1438:118;;1478:63;:37;;;1516:10;1528:12;1478:37;:63::i;:::-;1569:21;1608:16;1593:41;;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1569:67;;;;1659:214;1710:12;1740:13;1858:1;1659:33;:214::i;:::-;1650:3;1654:1;1650:6;;;;;;;;:::i;:::-;;;;;;;;;;:223;-1:-1:-1;;1993:50:55;;;;;2037:4;1993:50;;;1971:74:56;1969:21:55;;1993:35;;;;;;1944:18:56;;1993:50:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1969:74;-1:-1:-1;2061:17:55;;2057:121;;2098:65;:38;;;2137:10;2149:13;2098:38;:65::i;:::-;2192:22;2232:17;2217:42;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2192:69;;;;2284:216;2335:13;2366:14;2485:1;2284:33;:216::i;:::-;2275:3;2279:1;2275:6;;;;;;;;:::i;:::-;;;;;;;;;;:225;-1:-1:-1;2985:21:55;;-1:-1:-1;3020:50:55;3046:10;2985:21;3020:17;:50::i;:::-;3093:10;3084:3;3088:1;3084:6;;;;;;;;:::i;:::-;;;;;;:19;;;;;2521:593;3137:3;3124:7;3132:1;3124:10;;;;;;;;:::i;:::-;;;;;;;;;;:16;3174:15;;;3187:1;3174:15;;;;;;;;;3151:20;;3174:15;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3174:15:55;;;;;;;;;;;;;;;3151:38;;3209:4;3199;3204:1;3199:7;;;;;;;;:::i;:::-;;;;;;:14;;;;3223:34;3243:7;3252:4;3223:19;:34::i;5196:642:9:-;5615:23;5641:69;5669:4;5641:69;;;;;;;;;;;;;;;;;5649:5;5641:27;;;;:69;;;;;:::i;:::-;5615:95;;5728:10;:17;5749:1;5728:22;:56;;;;5765:10;5754:30;;;;;;;;;;;;:::i;:::-;5720:111;;;;;;;35453:2:56;5720:111:9;;;35435:21:56;35492:2;35472:18;;;35465:30;35531:34;35511:18;;;35504:62;35602:12;35582:18;;;35575:40;35632:19;;5720:111:9;35251:406:56;941:175:9;1050:58;;7147:42:56;7135:55;;1050:58:9;;;7117:74:56;7207:18;;;7200:34;;;1023:86:9;;1043:5;;1073:23;;7090:18:56;;1050:58:9;6943:297:56;6376:849:3;6460:7;6530:8;344:2:2;6507:31:3;6503:706;;;344:2:2;6578:31:3;;;594:6:2;6631:21:3;;:25;6627:185;;6687:31;6705:1;6708:9;6687:17;:31::i;:::-;6680:38;;;;;6627:185;6772:21;6780:1;6783:9;6772:7;:21::i;6503:706::-;344:2:2;6836:8:3;:31;6832:377;;;6909:31;;;507:1:2;6962:21:3;;:25;6958:190;;7018:32;7035:1;7038:11;7018:16;:32::i;6958:190::-;7104:25;7114:1;7117:11;7104:9;:25::i;6832:377::-;-1:-1:-1;7193:1:3;6832:377;6376:849;;;;;:::o;2647:312:10:-;2761:6;2736:21;:31;;2728:73;;;;;;;35864:2:56;2728:73:10;;;35846:21:56;35903:2;35883:18;;;35876:30;35942:31;35922:18;;;35915:59;35991:18;;2728:73:10;35662:353:56;2728:73:10;2813:12;2831:9;:14;;2853:6;2831:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2812:52;;;2882:7;2874:78;;;;;;;36432:2:56;2874:78:10;;;36414:21:56;36471:2;36451:18;;;36444:30;36510:34;36490:18;;;36483:62;36581:28;36561:18;;;36554:56;36627:19;;2874:78:10;36230:422:56;4688:935:54;4836:10;4859:18;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4859:18:54;4892:9;4887:730;4911:4;:11;4907:1;:15;4887:730;;;4950:4;4955:1;4950:7;;;;;;;;:::i;:::-;;;;;;;4943:14;;5008:1;4975:4;:14;;;:23;;;:30;:34;4971:636;;;5081:14;;:26;;5135:20;;;;;5030:22;1218:25:42;;;5226:4:54;1256:20:42;;;1324:4;1311:18;;5030:22:54;;5081:32;;;;;5254:4;:14;;;:23;;;5318:1;5342:45;5359:7;5368:4;:18;;;5342:16;:45::i;:::-;5409:16;;;5423:1;5409:16;;;;;;;;;5081:362;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5081:362:54;;;;;;;;;;;;:::i;:::-;5490:13;;5029:414;;-1:-1:-1;5029:414:54;-1:-1:-1;5490:17:54;5486:107;;5531:14;;:20;;;:43;;;;;:24;;;;;;;:43;;5556:9;;5567:6;;5531:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5486:107;5011:596;;4971:636;4924:3;;4887:730;;;;4763:860;;4688:935;;:::o;4108:223:10:-;4241:12;4272:52;4294:6;4302:4;4308:1;4311:12;4272:21;:52::i;:::-;4265:59;4108:223;-1:-1:-1;;;;4108:223:10:o;3853:689:3:-;3933:9;817:2:2;3982:9:3;:34;3978:548;;4040:6;;:30;;-1:-1:-1;;4040:30:3;;;4049:1;4040:30;4036:34;;3978:548;;;-1:-1:-1;4252:2:3;:15;;;4289:6;;;;:1;4252:15;4289:6;4252:15;4476:6;;;;:::i;:::-;;:11;:35;;-1:-1:-1;;4476:35:3;;;-1:-1:-1;4490:1:3;4472:39;-1:-1:-1;;3853:689:3:o;2909:688::-;3084:2;:15;;;3123:5;3084:15;3123:1;:5;:::i;:::-;3119:9;;817:2:2;3498:9:3;:34;3494:97;;3552:6;;:28;;3565:15;3571:9;3565:2;:15;:::i;:::-;3552:28;;;3561:1;3548:32;2909:688;-1:-1:-1;;;2909:688:3:o;5491:598::-;5572:9;817:2:2;5621:11:3;:36;5617:456;;5681:6;;:14;;5694:1;5681:14;;;5690:1;5681:14;5677:18;;;;5617:456;;;5746:2;:17;;;;5785:1;5746:17;5785:5;;;;:::i;:::-;;5781:9;;6009:1;6005;:5;6000:1;:10;5996:63;;-1:-1:-1;6039:1:3;6034:6;;5491:598;-1:-1:-1;;5491:598:3:o;4915:207::-;4989:7;817:2:2;5039:11:3;:36;;:66;;5093:11;5087:2;:17;5082:1;:23;;;;;:::i;:::-;;5039:66;;7619:2290:39;7754:18;7812:24;7853:14;:21;7839:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7839:36:39;;7812:63;;8024:21;8098:1;8074:14;:21;:25;:57;;8130:1;8074:57;;;8102:14;:21;8126:1;8102:25;8074:57;8052:11;:18;8048:1;:22;:84;8024:108;;8147:26;8192:13;8176:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8147:59;;8220:14;8270:17;3181:4:23;3175:11;;3213:1;3199:16;;2741:10:39;3246:4:23;3235:16;;3228:27;2779:4:39;3275:16:23;;;3268:27;2664:16:39;3321::23;;3308:30;;;3175:11;2625:169:39;8270:17;8252:7;8260:6;8252:15;;;;;;;;:::i;:::-;;;;;;:35;;;;8307:9;8302:140;8326:11;:18;8322:1;:22;8302:140;;;8369:8;;;;;;;8413:11;8425:1;8413:14;;;;;;;;:::i;:::-;;;;;;;8395:7;8403:6;8395:15;;;;;;;;:::i;:::-;;;;;;;;;;:32;8346:3;;8302:140;;;-1:-1:-1;8460:21:39;;:25;8456:1408;;8505:8;;;;;;;8549:7;8531;8539:6;8531:15;;;;;;;;:::i;:::-;;;;;;:25;;;;8580:9;8575:1275;8599:14;:21;8595:1;:25;8575:1275;;;9277:284;9343:14;9358:1;9343:17;;;;;;;;:::i;:::-;;;;;;;:24;;;9397:81;9426:51;9451:14;9466:1;9451:17;;;;;;;;:::i;:::-;;;;;;;:25;;;4172:13:0;;4187:4;4168:24;;;4149:17;;4139:54;;3999:210;9426:51:39;7389:34:12;7189:15;7376:48;;;7444:4;7437:18;;;;7495:4;7479:21;;;7120:396;9397:81:39;9508:14;9523:1;9508:17;;;;;;;;:::i;:::-;;;;;;;:27;;;9277:36;:284::i;:::-;8649:1010;;9617:19;;;;;;;;3045:25:56;;;3018:18;;9617:19:39;2899:177:56;8649:1010:39;9710:14;9725:1;9710:17;;;;;;;;:::i;:::-;;;;;;;:24;;;9694:42;;9681:7;9689:1;9681:10;;;;;;;;:::i;:::-;;;;;;:55;;;;;9758:8;;;;;;;9806:14;9821:1;9806:17;;;;;;;;:::i;:::-;;;;;;;:25;;;9788:7;9796:6;9788:15;;;;;;;;:::i;:::-;;;;;;;;;;:43;8622:3;;8575:1275;;;;8456:1408;-1:-1:-1;9885:7:39;7619:2290;-1:-1:-1;;;;;7619:2290:39:o;5165:446:10:-;5330:12;5387:5;5362:21;:30;;5354:81;;;;;;;41459:2:56;5354:81:10;;;41441:21:56;41498:2;41478:18;;;41471:30;41537:34;41517:18;;;41510:62;41608:8;41588:18;;;41581:36;41634:19;;5354:81:10;41257:402:56;5354:81:10;5446:12;5460:23;5487:6;:11;;5506:5;5513:4;5487:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5445:73;;;;5535:69;5562:6;5570:7;5579:10;5591:12;5535:26;:69::i;:::-;5528:76;5165:446;-1:-1:-1;;;;;;;5165:446:10:o;1014:366:13:-;1120:4;1137:17;1156:24;1184:33;1201:4;1207:9;1184:16;:33::i;:::-;1136:81;;-1:-1:-1;1136:81:13;-1:-1:-1;1256:26:13;1247:5;:35;;;;;;;;:::i;:::-;;:58;;;;;1299:6;1286:19;;:9;:19;;;1247:58;1246:127;;;;1322:51;1349:6;1357:4;1363:9;1322:26;:51::i;:::-;1227:146;1014:366;-1:-1:-1;;;;;;1014:366:13:o;7671:628:10:-;7851:12;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;1702:19;;;;8113:60;;;;;;;42347:2:56;8113:60:10;;;42329:21:56;42386:2;42366:18;;;42359:30;42425:31;42405:18;;;42398:59;42474:18;;8113:60:10;42145:353:56;8113:60:10;-1:-1:-1;8208:10:10;8201:17;;7875:418;8249:33;8257:10;8269:12;8249:7;:33::i;2145:730:12:-;2226:7;2235:12;2263:9;:16;2283:2;2263:22;2259:610;;2599:4;2584:20;;2578:27;2648:4;2633:20;;2627:27;2705:4;2690:20;;2684:27;2301:9;2676:36;2746:25;2757:4;2676:36;2578:27;2627;2746:10;:25::i;:::-;2739:32;;;;;;;;;2259:610;-1:-1:-1;2818:1:12;;-1:-1:-1;2822:35:12;2259:610;2145:730;;;;;:::o;1786:473:13:-;1929:4;1946:12;1960:19;1983:6;:17;;2037:34;;;2073:4;2079:9;2014:75;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;2014:75:13;;;;;;;;;;;;;;;;;;;;;;;;;;;1983:116;;;;2014:75;1983:116;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1945:154;;;;2117:7;:42;;;;;2157:2;2140:6;:13;:19;;2117:42;:134;;;;-1:-1:-1;2175:29:13;;2216:34;;2175:29;;;;;;;;;;;;:::i;:::-;:76;;1786:473;-1:-1:-1;;;;;;1786:473:13:o;8821:540:10:-;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;;;;;;;;;;:::i;5009:1456:12:-;5097:7;;6021:66;6008:79;;6004:161;;;-1:-1:-1;6119:1:12;;-1:-1:-1;6123:30:12;6103:51;;6004:161;6276:24;;;6259:14;6276:24;;;;;;;;;43436:25:56;;;43509:4;43497:17;;43477:18;;;43470:45;;;;43531:18;;;43524:34;;;43574:18;;;43567:34;;;6276:24:12;;43408:19:56;;6276:24:12;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6276:24:12;;-1:-1:-1;;6276:24:12;;;-1:-1:-1;;6314:20:12;;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;-1:-1:-1;6437:20:12;;-1:-1:-1;5009:1456:12;;;;;;;;:::o;14:332:56:-;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;639:154;725:42;718:5;714:54;707:5;704:65;694:93;;783:1;780;773:12;694:93;639:154;:::o;798:1005::-;904:6;912;920;928;936;944;997:3;985:9;976:7;972:23;968:33;965:53;;;1014:1;1011;1004:12;965:53;1053:9;1040:23;1072:31;1097:5;1072:31;:::i;:::-;1122:5;-1:-1:-1;1179:2:56;1164:18;;1151:32;1192:33;1151:32;1192:33;:::i;:::-;1244:7;-1:-1:-1;1298:2:56;1283:18;;1270:32;;-1:-1:-1;1349:2:56;1334:18;;1321:32;;-1:-1:-1;1404:3:56;1389:19;;1376:33;1428:18;1458:14;;;1455:34;;;1485:1;1482;1475:12;1455:34;1523:6;1512:9;1508:22;1498:32;;1568:7;1561:4;1557:2;1553:13;1549:27;1539:55;;1590:1;1587;1580:12;1539:55;1630:2;1617:16;1656:2;1648:6;1645:14;1642:34;;;1672:1;1669;1662:12;1642:34;1717:7;1712:2;1703:6;1699:2;1695:15;1691:24;1688:37;1685:57;;;1738:1;1735;1728:12;1685:57;1769:2;1765;1761:11;1751:21;;1791:6;1781:16;;;;;798:1005;;;;;;;;:::o;2056:838::-;2218:6;2226;2234;2287:2;2275:9;2266:7;2262:23;2258:32;2255:52;;;2303:1;2300;2293:12;2255:52;2342:9;2329:23;2361:31;2386:5;2361:31;:::i;:::-;2411:5;-1:-1:-1;2467:2:56;2452:18;;2439:32;2490:18;2520:14;;;2517:34;;;2547:1;2544;2537:12;2517:34;2570:22;;;;2626:3;2608:16;;;2604:26;2601:46;;;2643:1;2640;2633:12;2601:46;2666:2;;-1:-1:-1;2721:2:56;2706:18;;2693:32;;2737:16;;;2734:36;;;2766:1;2763;2756:12;2734:36;-1:-1:-1;2789:24:56;;2847:2;2829:16;;;2825:25;2822:45;;;2863:1;2860;2853:12;2822:45;2886:2;2876:12;;;2056:838;;;;;:::o;3081:184::-;3133:77;3130:1;3123:88;3230:4;3227:1;3220:15;3254:4;3251:1;3244:15;3270:253;3342:2;3336:9;3384:4;3372:17;;3419:18;3404:34;;3440:22;;;3401:62;3398:88;;;3466:18;;:::i;:::-;3502:2;3495:22;3270:253;:::o;3528:::-;3600:2;3594:9;3642:4;3630:17;;3677:18;3662:34;;3698:22;;;3659:62;3656:88;;;3724:18;;:::i;3786:257::-;3858:4;3852:11;;;3890:17;;3937:18;3922:34;;3958:22;;;3919:62;3916:88;;;3984:18;;:::i;4048:334::-;4119:2;4113:9;4175:2;4165:13;;-1:-1:-1;;4161:86:56;4149:99;;4278:18;4263:34;;4299:22;;;4260:62;4257:88;;;4325:18;;:::i;:::-;4361:2;4354:22;4048:334;;-1:-1:-1;4048:334:56:o;4387:195::-;4459:4;4492:18;4484:6;4481:30;4478:56;;;4514:18;;:::i;:::-;-1:-1:-1;4559:1:56;4555:14;4571:4;4551:25;;4387:195::o;4587:118::-;4673:5;4666:13;4659:21;4652:5;4649:32;4639:60;;4695:1;4692;4685:12;4710:2228;4825:6;4833;4864:2;4907;4895:9;4886:7;4882:23;4878:32;4875:52;;;4923:1;4920;4913:12;4875:52;4962:9;4949:23;4981:31;5006:5;4981:31;:::i;:::-;5031:5;-1:-1:-1;5055:2:56;5093:18;;;5080:32;5131:18;5161:14;;;5158:34;;;5188:1;5185;5178:12;5158:34;5211:22;;;;5267:4;5249:16;;;5245:27;5242:47;;;5285:1;5282;5275:12;5242:47;5313:22;;:::i;:::-;5372:2;5359:16;5384:33;5409:7;5384:33;:::i;:::-;5426:24;;5488:11;;;5475:25;5512:16;;;5509:36;;;5541:1;5538;5531:12;5509:36;5564:17;;;-1:-1:-1;5612:4:56;5604:13;;5600:27;-1:-1:-1;5590:55:56;;5641:1;5638;5631:12;5590:55;5677:2;5664:16;5700:72;5716:55;5768:2;5716:55;:::i;:::-;5700:72;:::i;:::-;5806:15;;;5868:4;5907:13;;;5899:22;;5895:31;;;5837:12;;;;5794:3;5938:19;;;5935:39;;;5970:1;5967;5960:12;5935:39;5994:11;;;;6014:728;6030:6;6025:3;6022:15;6014:728;;;6110:2;6104:3;6095:7;6091:17;6087:26;6084:116;;;6154:1;6183:2;6179;6172:14;6084:116;6228:22;;:::i;:::-;6291:3;6278:17;6308:33;6333:7;6308:33;:::i;:::-;6354:24;;6419:12;;;6406:26;6445:33;6406:26;6445:33;:::i;:::-;6498:16;;;6491:33;6565:12;;;6552:26;6591:30;6552:26;6591:30;:::i;:::-;6641:16;;;6634:33;6680:20;;6047:12;;;;6720;;;;6014:728;;;6018:3;6776:5;6771:2;6762:7;6758:16;6751:31;;;;6837:2;6833;6829:11;6816:25;6811:2;6802:7;6798:16;6791:51;6899:4;6895:2;6891:13;6878:27;6871:4;6862:7;6858:18;6851:55;6925:7;6915:17;;;;;;;4710:2228;;;;;:::o;7245:245::-;7312:6;7365:2;7353:9;7344:7;7340:23;7336:32;7333:52;;;7381:1;7378;7371:12;7333:52;7413:9;7407:16;7432:28;7454:5;7432:28;:::i;8355:184::-;8407:77;8404:1;8397:88;8504:4;8501:1;8494:15;8528:4;8525:1;8518:15;8544:128;8611:9;;;8632:11;;;8629:37;;;8646:18;;:::i;8677:184::-;8729:77;8726:1;8719:88;8826:4;8823:1;8816:15;8850:4;8847:1;8840:15;9370:2420;9740:4;9769:3;9810;9799:9;9795:19;9841:3;9830:9;9823:22;9865:6;9900;9894:13;9931:6;9923;9916:22;9957:3;9947:13;;9991:3;9980:9;9976:19;9969:26;;10054:3;10044:6;10041:1;10037:14;10026:9;10022:30;10018:40;10077:4;10116:2;10108:6;10104:15;10137:1;10158;10168:1404;10184:6;10179:3;10176:15;10168:1404;;;10253:22;;;10277:66;10249:95;10237:108;;10368:13;;10520:9;;10446:42;10516:18;;;10501:34;;10574:11;;;10568:18;10606:15;;;10599:27;;;10687:19;;10408:15;;;10719:24;;;10809:21;;;;10446:42;10854:1;;10765:15;;;;10868:430;10884:8;10879:3;10876:17;10868:430;;;10957:15;;11007:9;;11003:18;;10989:33;;11072:11;;;11066:18;11062:27;;11046:14;;;11039:51;11117:4;11181:11;;;11175:18;11168:26;11161:34;11145:14;;;11138:58;11267:17;;;;10912:1;10903:11;;;;;11233:4;11222:16;;;;10868:430;;;-1:-1:-1;11321:4:56;11368:11;;;11362:18;11345:15;;;11338:43;11404:4;11451:11;;;11445:18;11428:15;;;;11421:43;;;;-1:-1:-1;;;11550:12:56;;;;11515:15;;;;10210:1;10201:11;10168:1404;;;-1:-1:-1;;;11588:18:56;;11581:34;;;421:13;;414:21;11663:4;11648:20;;402:34;11707:22;;;11700:4;11685:20;;11678:52;9292:1;9280:14;;9326:4;9319;9310:14;;9303:28;9356:2;9347:12;;11739:45;9370:2420;-1:-1:-1;;;;;;;;;;9370:2420:56:o;11795:677::-;11860:5;11913:3;11906:4;11898:6;11894:17;11890:27;11880:55;;11931:1;11928;11921:12;11880:55;11960:6;11954:13;11986:4;12010:72;12026:55;12078:2;12026:55;:::i;12010:72::-;12104:3;12128:2;12123:3;12116:15;12156:4;12151:3;12147:14;12140:21;;12213:4;12207:2;12204:1;12200:10;12192:6;12188:23;12184:34;12170:48;;12241:3;12233:6;12230:15;12227:35;;;12258:1;12255;12248:12;12227:35;12294:4;12286:6;12282:17;12308:135;12324:6;12319:3;12316:15;12308:135;;;12390:10;;12378:23;;12421:12;;;;12341;;12308:135;;;-1:-1:-1;12461:5:56;11795:677;-1:-1:-1;;;;;;11795:677:56:o;12477:1449::-;12640:6;12648;12656;12709:2;12697:9;12688:7;12684:23;12680:32;12677:52;;;12725:1;12722;12715:12;12677:52;12758:9;12752:16;12787:18;12828:2;12820:6;12817:14;12814:34;;;12844:1;12841;12834:12;12814:34;12867:72;12931:7;12922:6;12911:9;12907:22;12867:72;:::i;:::-;12857:82;;12958:2;12948:12;;13006:2;12995:9;12991:18;12985:25;13035:2;13025:8;13022:16;13019:36;;;13051:1;13048;13041:12;13019:36;13074:24;;13129:4;13121:13;;13117:27;-1:-1:-1;13107:55:56;;13158:1;13155;13148:12;13107:55;13187:2;13181:9;13210:72;13226:55;13278:2;13226:55;:::i;13210:72::-;13316:15;;;13398:1;13394:10;;;;13386:19;;13382:28;;;13347:12;;;;13422:19;;;13419:39;;;13454:1;13451;13444:12;13419:39;13478:11;;;;13498:210;13514:6;13509:3;13506:15;13498:210;;;13587:3;13581:10;13604:31;13629:5;13604:31;:::i;:::-;13648:18;;13531:12;;;;13686;;;;13498:210;;;13778:2;13763:18;;13757:25;13727:5;;-1:-1:-1;13757:25:56;-1:-1:-1;;;;13794:16:56;;;13791:36;;;13823:1;13820;13813:12;13791:36;;13846:74;13912:7;13901:8;13890:9;13886:24;13846:74;:::i;:::-;13836:84;;;12477:1449;;;;;:::o;14241:589::-;14283:5;14336:3;14329:4;14321:6;14317:17;14313:27;14303:55;;14354:1;14351;14344:12;14303:55;14390:6;14377:20;14416:18;14412:2;14409:26;14406:52;;;14438:18;;:::i;:::-;14482:114;14590:4;-1:-1:-1;;14514:4:56;14510:2;14506:13;14502:86;14498:97;14482:114;:::i;:::-;14621:2;14612:7;14605:19;14667:3;14660:4;14655:2;14647:6;14643:15;14639:26;14636:35;14633:55;;;14684:1;14681;14674:12;14633:55;14749:2;14742:4;14734:6;14730:17;14723:4;14714:7;14710:18;14697:55;14797:1;14772:16;;;14790:4;14768:27;14761:38;;;;14776:7;14241:589;-1:-1:-1;;;14241:589:56:o;14835:2574::-;14904:5;14957:3;14950:4;14942:6;14938:17;14934:27;14924:55;;14975:1;14972;14965:12;14924:55;15011:6;14998:20;15037:4;15061:72;15077:55;15129:2;15077:55;:::i;15061:72::-;15167:15;;;15253:1;15249:10;;;;15237:23;;15233:32;;;15198:12;;;;15277:15;;;15274:35;;;15305:1;15302;15295:12;15274:35;15341:2;15333:6;15329:15;15353:2027;15369:6;15364:3;15361:15;15353:2027;;;15455:3;15442:17;15482:18;15532:2;15519:11;15516:19;15513:39;;;15548:1;15545;15538:12;15513:39;15575:24;;;;15706:4;15623:12;;;-1:-1:-1;;15619:85:56;15615:96;15612:186;;;15752:1;15781:2;15777;15770:14;15612:186;15824:22;;:::i;:::-;15895:2;15891;15887:11;15874:25;15912:33;15937:7;15912:33;:::i;:::-;15958:22;;16003:2;16047:11;;;16034:25;16075:16;;;16072:106;;;16132:1;16161:2;16157;16150:14;16072:106;16201:17;;16253:2;16245:11;;16241:21;-1:-1:-1;16231:119:56;;16304:1;16333:2;16329;16322:14;16231:119;16395:2;16391;16387:11;16374:25;16425:73;16441:56;16493:3;16441:56;:::i;16425:73::-;16542:18;;;16641:1;16637:11;;;;16629:20;;16625:29;;;16582:14;;;;16670:17;;;16667:110;;;16729:1;16759:3;16754;16747:16;16667:110;16803:11;;;;16827:174;16845:8;16838:5;16835:19;16827:174;;;16927:19;;16913:34;;16866:14;;;;16973;;;;16827:174;;;17021:14;;;17014:29;-1:-1:-1;;;17093:4:56;17085:13;;17072:27;17115:16;;;17112:109;;;17173:1;17203:3;17198;17191:16;17112:109;17257:49;17302:3;17297:2;17286:8;17282:2;17278:17;17274:26;17257:49;:::i;:::-;17241:14;;;17234:73;;;;-1:-1:-1;17320:18:56;;-1:-1:-1;;17358:12:56;;;;15386;;15353:2027;;17414:1210;17514:9;17573:4;17565:5;17549:14;17545:26;17541:37;17538:57;;;17591:1;17588;17581:12;17538:57;17619:22;;:::i;:::-;17677:5;17664:19;17702:18;17743:2;17735:6;17732:14;17729:34;;;17759:1;17756;17749:12;17729:34;17793:6;17786:5;17782:18;17772:28;;17841:4;17836:2;17820:14;17816:23;17812:34;17809:54;;;17859:1;17856;17849:12;17809:54;17887:22;;:::i;:::-;17946:2;17933:16;17958:33;17983:7;17958:33;:::i;:::-;18000:24;;18069:2;18061:11;;18048:25;18082:33;18048:25;18082:33;:::i;:::-;18144:2;18131:16;;18124:33;18203:4;18195:13;;18182:27;18221:16;;;18218:36;;;18250:1;18247;18240:12;18218:36;18290:51;18326:14;18315:8;18311:2;18307:17;18290:51;:::i;:::-;18283:4;18270:18;;18263:79;-1:-1:-1;18351:24:56;;18424:2;18413:14;;18400:28;;-1:-1:-1;18440:16:56;;;18437:36;;;18469:1;18466;18459:12;18437:36;;18507:81;18573:14;18562:8;18555:5;18551:20;18507:81;:::i;:::-;18502:2;18489:16;;18482:107;-1:-1:-1;18493:7:56;17414:1210;-1:-1:-1;;17414:1210:56:o;18629:250::-;18714:1;18724:113;18738:6;18735:1;18732:13;18724:113;;;18814:11;;;18808:18;18795:11;;;18788:39;18760:2;18753:10;18724:113;;;-1:-1:-1;;18871:1:56;18853:16;;18846:27;18629:250::o;18884:329::-;18925:3;18963:5;18957:12;18990:6;18985:3;18978:19;19006:76;19075:6;19068:4;19063:3;19059:14;19052:4;19045:5;19041:16;19006:76;:::i;:::-;19127:2;19115:15;-1:-1:-1;;19111:88:56;19102:98;;;;19202:4;19098:109;;18884:329;-1:-1:-1;;18884:329:56:o;19218:439::-;19271:3;19309:5;19303:12;19336:6;19331:3;19324:19;19362:4;19391;19386:3;19382:14;19375:21;;19430:4;19423:5;19419:16;19453:1;19463:169;19477:6;19474:1;19471:13;19463:169;;;19538:13;;19526:26;;19572:12;;;;19607:15;;;;19499:1;19492:9;19463:169;;;-1:-1:-1;19648:3:56;;19218:439;-1:-1:-1;;;;;19218:439:56:o;19662:1808::-;19802:4;19831:2;19860;19849:9;19842:21;19882:2;19919:6;19913:13;19945:4;19985;19980:2;19969:9;19965:18;19958:32;20009:42;20112:2;20097:12;20091:19;20087:28;20082:2;20071:9;20067:18;20060:56;20187:2;20181;20167:12;20163:21;20157:28;20153:37;20147:3;20136:9;20132:19;20125:66;20246:4;20232:12;20228:23;20222:30;20200:52;;20289:2;20283:3;20272:9;20268:19;20261:31;20312:53;20360:3;20349:9;20345:19;20329:14;20312:53;:::i;:::-;20301:64;;20414:2;20406:6;20402:15;20396:22;-1:-1:-1;;20566:2:56;20554:9;20549:3;20545:19;20541:28;20534:4;20523:9;20519:20;20512:58;20590:3;20622:14;20616:21;20658:6;20653:3;20646:19;20690:2;20685:3;20681:12;20674:19;;20746:2;20736:6;20733:1;20729:14;20724:3;20720:24;20716:33;20792:2;20776:14;20772:23;20758:37;;20813:1;20823:618;20837:6;20834:1;20831:13;20823:618;;;20920:2;20914:3;20906:6;20902:16;20898:25;20893:3;20886:38;20953:6;20947:13;21003:2;20998;20992:9;20988:18;20980:6;20973:34;21056:2;21052;21048:11;21042:18;21097:2;21092;21084:6;21080:15;21073:27;21127:61;21184:2;21176:6;21172:15;21156:14;21127:61;:::i;:::-;21229:11;;;21223:18;21278:19;;;21261:15;;;21254:44;21223:18;21113:75;-1:-1:-1;21321:40:56;21113:75;21223:18;21321:40;:::i;:::-;21384:15;;;;21419:12;;;;21311:50;-1:-1:-1;;;20859:1:56;20852:9;20823:618;;;-1:-1:-1;21458:6:56;19662:1808;-1:-1:-1;;;;;;;;;;;;19662:1808:56:o;21475:641::-;21605:4;21611:6;21671:11;21658:25;-1:-1:-1;;21750:8:56;21734:14;21730:29;21726:102;21706:18;21702:127;21692:155;;21843:1;21840;21833:12;21692:155;21870:33;;21922:20;;;-1:-1:-1;21965:18:56;21954:30;;21951:50;;;21997:1;21994;21987:12;21951:50;22030:4;22018:17;;-1:-1:-1;22081:1:56;22077:14;;;22061;22057:35;22047:46;;22044:66;;;22106:1;22103;22096:12;22121:393;22224:4;22282:11;22269:25;22372:66;22361:8;22345:14;22341:29;22337:102;22317:18;22313:127;22303:155;;22454:1;22451;22444:12;22303:155;22475:33;;;;;22121:393;-1:-1:-1;;22121:393:56:o;22519:383::-;22612:4;22670:11;22657:25;22760:66;22749:8;22733:14;22729:29;22725:102;22705:18;22701:127;22691:155;;22842:1;22839;22832:12;22907:629;23022:4;23028:6;23088:11;23075:25;-1:-1:-1;;23167:8:56;23151:14;23147:29;23143:102;23123:18;23119:127;23109:155;;23260:1;23257;23250:12;23109:155;23287:33;;23339:20;;;-1:-1:-1;23382:18:56;23371:30;;23368:50;;;23414:1;23411;23404:12;23368:50;23447:4;23435:17;;-1:-1:-1;23506:4:56;23494:17;;23478:14;23474:38;23464:49;;23461:69;;;23526:1;23523;23516:12;23541:247;23600:6;23653:2;23641:9;23632:7;23628:23;23624:32;23621:52;;;23669:1;23666;23659:12;23621:52;23708:9;23695:23;23727:31;23752:5;23727:31;:::i;23793:605::-;23889:5;23896:6;23956:3;23943:17;-1:-1:-1;;24027:8:56;24011:14;24007:29;24003:102;23983:18;23979:127;23969:155;;24120:1;24117;24110:12;23969:155;24148:33;;24252:4;24239:18;;;-1:-1:-1;24200:21:56;;-1:-1:-1;24280:18:56;24269:30;;24266:50;;;24312:1;24309;24302:12;24266:50;24366:6;24363:1;24359:14;24343;24339:35;24332:5;24328:47;24325:67;;;24388:1;24385;24378:12;24403:355;24474:5;24533:3;24520:17;24615:66;24604:8;24588:14;24584:29;24580:102;24560:18;24556:127;24546:155;;24697:1;24694;24687:12;24546:155;24719:33;;;;24403:355;-1:-1:-1;;24403:355:56:o;24763:559::-;24821:5;24828:6;24888:3;24875:17;-1:-1:-1;;24959:8:56;24943:14;24939:29;24935:102;24915:18;24911:127;24901:155;;25052:1;25049;25042:12;24901:155;25080:33;;25184:4;25171:18;;;-1:-1:-1;25132:21:56;;-1:-1:-1;25212:18:56;25201:30;;25198:50;;;25244:1;25241;25234:12;25198:50;25291:6;25275:14;25271:27;25264:5;25260:39;25257:59;;;25312:1;25309;25302:12;25327:325;25415:6;25410:3;25403:19;25467:6;25460:5;25453:4;25448:3;25444:14;25431:43;;25519:1;25512:4;25503:6;25498:3;25494:16;25490:27;25483:38;25385:3;25641:4;-1:-1:-1;;25566:2:56;25558:6;25554:15;25550:88;25545:3;25541:98;25537:109;25530:116;;25327:325;;;;:::o;25657:593::-;25738:5;25745:6;25805:3;25792:17;-1:-1:-1;;25876:8:56;25860:14;25856:29;25852:102;25832:18;25828:127;25818:155;;25969:1;25966;25959:12;25818:155;25997:33;;26101:4;26088:18;;;-1:-1:-1;26049:21:56;;-1:-1:-1;26129:18:56;26118:30;;26115:50;;;26161:1;26158;26151:12;26115:50;26220:4;26212:6;26208:17;26192:14;26188:38;26181:5;26177:50;26174:70;;;26240:1;26237;26230:12;26255:114;26339:4;26332:5;26328:16;26321:5;26318:27;26308:55;;26359:1;26356;26349:12;26374:830;26485:6;26480:3;26473:19;26455:3;26511:4;26540;26535:3;26531:14;26524:21;;26568:5;26591:1;26601:578;26615:6;26612:1;26609:13;26601:578;;;26692:6;26679:20;26712:33;26737:7;26712:33;:::i;:::-;26783:42;26770:56;26758:69;;26868:15;;;26855:29;26897:31;26855:29;26897:31;:::i;:::-;26975:4;26962:18;26948:12;;;26941:40;27004:4;27055:15;;;27042:29;27028:12;;;27021:51;27095:4;27119:12;;;;27154:15;;;;26637:1;26630:9;26601:578;;27209:1709;27346:19;;;27384:4;27404:12;;;;27303:3;;27435:1;27472:14;;;27461:26;;27457:35;;27515:5;27303:3;;27569:1323;27585:6;27580:3;27577:15;27569:1323;;;-1:-1:-1;;27664:5:56;27658:4;27654:16;27650:89;27645:3;27638:102;27763:58;27814:6;27807:5;27763:58;:::i;:::-;27844:4;27889:2;27876:16;27905:33;27930:7;27905:33;:::i;:::-;27977:42;27964:56;27951:70;;28068:85;28141:11;;;28145:2;28068:85;:::i;:::-;28188:2;28183;28177:4;28173:13;28166:25;28226:12;28221:2;28215:4;28211:13;28204:35;28262:3;28252:13;;28298:66;28284:12;28281:84;28278:104;;;28378:1;28375;28368:12;28278:104;28411:21;;;28473:12;28458:13;;;28445:51;28519:19;;;-1:-1:-1;28561:4:56;28616:47;28651:11;;;28655:2;28616:47;:::i;:::-;28578:85;;28717:2;28710:4;28706:2;28702:13;28698:22;28693:2;28687:4;28683:13;28676:45;28742:70;28808:2;28804;28800:11;28784:14;28768;28742:70;:::i;:::-;28870:12;;;;28734:78;-1:-1:-1;;;28835:15:56;;;;-1:-1:-1;;;27611:1:56;27602:11;27569:1323;;;-1:-1:-1;28908:4:56;;27209:1709;-1:-1:-1;;;;;;;;;27209:1709:56:o;28923:4286::-;29089:4;29118:2;29147;29136:9;29129:21;29188:3;29177:9;29173:19;29241:6;29228:20;29223:2;29212:9;29208:18;29201:48;29268:2;29331;29323:6;29319:15;29306:29;29301:2;29290:9;29286:18;29279:57;29355:2;29418;29410:6;29406:15;29393:29;29388:2;29377:9;29373:18;29366:57;29466:93;29555:2;29547:6;29543:15;29535:6;29466:93;:::i;:::-;29596:4;29590:3;29579:9;29575:19;29568:33;29621:6;29651:12;29643:6;29636:28;29695:3;29684:9;29680:19;29673:26;;29764:3;29748:12;29745:1;29741:20;29730:9;29726:36;29722:46;29708:60;;29791:12;29821:1;29831:3053;29845:12;29842:1;29839:19;29831:3053;;;29940:66;29928:9;29920:6;29916:22;29912:95;29907:3;29900:108;30060:6;30047:20;30153:66;30138:12;30122:14;30118:33;30114:106;30094:18;30090:131;30080:159;;30235:1;30232;30225:12;30080:159;30265:37;;30343:19;;30419:14;30415:26;;;30443:66;30411:99;30385:126;;30375:154;;30525:1;30522;30515:12;30375:154;30617:3;30602:19;;30557:32;;30649:21;;30683:33;30649:21;30683:33;:::i;:::-;30739:42;30832:2;30823:7;30819:16;30813:3;30805:6;30801:16;30794:42;30871:70;30937:2;30928:7;30924:16;30915:7;30871:70;:::i;:::-;30849:92;;30980:4;30973;30965:6;30961:17;30954:31;31026:14;31013:28;31054:33;31079:7;31054:33;:::i;:::-;31125:16;;31119:3;31107:16;;31100:42;31183:23;;;31170:37;31220:33;31170:37;31220:33;:::i;:::-;31291:16;31285:3;31273:16;;31266:42;31359:71;31406:23;;;31410:14;31359:71;:::i;:::-;31321:109;;31468:2;31462:3;31454:6;31450:16;31443:28;31495:75;31565:3;31557:6;31553:16;31537:14;31521;31495:75;:::i;:::-;31484:86;;;31621:80;31697:2;31688:7;31684:16;31675:7;31621:80;:::i;:::-;31724:66;31850:2;31841:6;31836:3;31832:16;31828:25;31822:3;31814:6;31810:16;31803:51;31881:85;31962:3;31946:14;31930;31881:85;:::i;:::-;31867:99;;32017:80;32093:2;32084:7;32080:16;32071:7;32017:80;:::i;:::-;31979:118;;;;32160:2;32151:6;32143;32139:19;32135:28;32129:3;32121:6;32117:16;32110:54;;32191:88;32272:6;32256:14;32240;32191:88;:::i;:::-;32177:102;;;;32343:3;32334:7;32330:17;32317:31;32311:3;32303:6;32299:16;32292:57;32410:2;32403:5;32399:14;32386:28;32381:2;32373:6;32369:15;32362:53;32476:2;32469:5;32465:14;32452:28;32447:2;32439:6;32435:15;32428:53;32532:91;32619:2;32612:5;32608:14;32601:5;32532:91;:::i;:::-;32494:129;;;;32672:6;32664;32660:19;32655:2;32647:6;32643:15;32636:44;32703:101;32797:6;32781:14;32765;32703:101;:::i;:::-;32693:111;-1:-1:-1;;;32862:12:56;;;;-1:-1:-1;32827:15:56;;;;29873:1;29866:9;29831:3053;;;29835:3;;;;;;;32931:56;32982:3;32974:6;32970:16;32962:6;32931:56;:::i;:::-;32893:94;;-1:-1:-1;;33041:9:56;33033:6;33029:22;33025:95;33018:4;33007:9;33003:20;32996:125;33138:65;33196:6;33180:14;33164;33138:65;:::i;33214:245::-;33293:6;33301;33354:2;33342:9;33333:7;33329:23;33325:32;33322:52;;;33370:1;33367;33360:12;33322:52;-1:-1:-1;;33393:16:56;;33449:2;33434:18;;;33428:25;33393:16;;33428:25;;-1:-1:-1;33214:245:56:o;34156:184::-;34226:6;34279:2;34267:9;34258:7;34254:23;34250:32;34247:52;;;34295:1;34292;34285:12;34247:52;-1:-1:-1;34318:16:56;;34156:184;-1:-1:-1;34156:184:56:o;34999:247::-;35067:6;35120:2;35108:9;35099:7;35095:23;35091:32;35088:52;;;35136:1;35133;35126:12;35088:52;35168:9;35162:16;35187:29;35210:5;35187:29;:::i;36657:1572::-;37212:42;37204:6;37200:55;37189:9;37182:74;37163:4;37275:2;37313:6;37308:2;37297:9;37293:18;37286:34;37356:3;37351:2;37340:9;37336:18;37329:31;37383:45;37423:3;37412:9;37408:19;37400:6;37383:45;:::i;:::-;37464:6;37459:2;37448:9;37444:18;37437:34;37520:9;37512:6;37508:22;37502:3;37491:9;37487:19;37480:51;37551:6;37586;37580:13;37617:6;37609;37602:22;37652:2;37644:6;37640:15;37633:22;;37711:2;37701:6;37698:1;37694:14;37686:6;37682:27;37678:36;37749:2;37741:6;37737:15;37770:1;37780:322;37794:6;37791:1;37788:13;37780:322;;;-1:-1:-1;;37871:6:56;37863;37859:19;37855:92;37850:3;37843:105;37971:51;38015:6;38006;38000:13;37971:51;:::i;:::-;38080:12;;;;37961:61;-1:-1:-1;38045:15:56;;;;37816:1;37809:9;37780:322;;;37784:3;;38151:9;38143:6;38139:22;38133:3;38122:9;38118:19;38111:51;38179:44;38216:6;38208;38179:44;:::i;:::-;38171:52;36657:1572;-1:-1:-1;;;;;;;;;;;;;36657:1572:56:o;38234:614::-;38363:6;38371;38424:2;38412:9;38403:7;38399:23;38395:32;38392:52;;;38440:1;38437;38430:12;38392:52;38473:9;38467:16;38502:18;38543:2;38535:6;38532:14;38529:34;;;38559:1;38556;38549:12;38529:34;38582:72;38646:7;38637:6;38626:9;38622:22;38582:72;:::i;:::-;38572:82;;38700:2;38689:9;38685:18;38679:25;38663:41;;38729:2;38719:8;38716:16;38713:36;;;38745:1;38742;38735:12;38713:36;;38768:74;38834:7;38823:8;38812:9;38808:24;38768:74;:::i;:::-;38758:84;;;38234:614;;;;;:::o;38853:367::-;39095:6;39084:9;39077:25;39138:2;39133;39122:9;39118:18;39111:30;39058:4;39158:56;39210:2;39199:9;39195:18;39187:6;39158:56;:::i;39225:184::-;39277:77;39274:1;39267:88;39374:4;39371:1;39364:15;39398:4;39395:1;39388:15;39414:168;39487:9;;;39518;;39535:15;;;39529:22;;39515:37;39505:71;;39556:18;;:::i;39587:476::-;39676:1;39713:5;39676:1;39727:330;39748:7;39738:8;39735:21;39727:330;;;39867:4;-1:-1:-1;;39795:77:56;39789:4;39786:87;39783:113;;;39876:18;;:::i;:::-;39926:7;39916:8;39912:22;39909:55;;;39946:16;;;;39909:55;40025:22;;;;39985:15;;;;39727:330;;;39731:3;39587:476;;;;;:::o;40068:866::-;40117:5;40147:8;40137:80;;-1:-1:-1;40188:1:56;40202:5;;40137:80;40236:4;40226:76;;-1:-1:-1;40273:1:56;40287:5;;40226:76;40318:4;40336:1;40331:59;;;;40404:1;40399:130;;;;40311:218;;40331:59;40361:1;40352:10;;40375:5;;;40399:130;40436:3;40426:8;40423:17;40420:43;;;40443:18;;:::i;:::-;-1:-1:-1;;40499:1:56;40485:16;;40514:5;;40311:218;;40613:2;40603:8;40600:16;40594:3;40588:4;40585:13;40581:36;40575:2;40565:8;40562:16;40557:2;40551:4;40548:12;40544:35;40541:77;40538:159;;;-1:-1:-1;40650:19:56;;;40682:5;;40538:159;40729:34;40754:8;40748:4;40729:34;:::i;:::-;40859:6;-1:-1:-1;;40787:79:56;40778:7;40775:92;40772:118;;;40870:18;;:::i;:::-;40908:20;;40068:866;-1:-1:-1;;;40068:866:56:o;40939:131::-;40999:5;41028:36;41055:8;41049:4;41028:36;:::i;41664:287::-;41793:3;41831:6;41825:13;41847:66;41906:6;41901:3;41894:4;41886:6;41882:17;41847:66;:::i;41956:184::-;42008:77;42005:1;41998:88;42105:4;42102:1;42095:15;42129:4;42126:1;42119:15;42503:288;42678:6;42667:9;42660:25;42721:2;42716;42705:9;42701:18;42694:30;42641:4;42741:44;42781:2;42770:9;42766:18;42758:6;42741:44;:::i;42985:219::-;43134:2;43123:9;43116:21;43097:4;43154:44;43194:2;43183:9;43179:18;43171:6;43154:44;:::i","linkReferences":{},"immutableReferences":{"6454":[{"start":315,"length":32},{"start":1864,"length":32},{"start":1945,"length":32}],"6850":[{"start":207,"length":32},{"start":668,"length":32},{"start":892,"length":32},{"start":1696,"length":32}]}},"methodIdentifiers":{"arb3(address,(uint256,uint256,uint256,((address,(address,address,bytes),(address,uint8,uint256)[],(address,uint8,uint256)[],bytes32),uint256,uint256,(address,uint256[],bytes)[])[],bytes),((address,address,bytes),(address,uint256[],bytes)[]))":"7ea0b76a","iPermit2()":"69e5049b","iTaskHash()":"93be095e","onTakeOrders(address,address,uint256,uint256,bytes)":"059bebe6","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 IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV1\",\"name\":\"task\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"implementationData\",\"type\":\"bytes\"}],\"internalType\":\"struct OrderBookV4ArbConfigV2\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoOrders\",\"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 IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV1\",\"name\":\"task\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"implementationData\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"struct OrderBookV4ArbConfigV2\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"Construct\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[{\"internalType\":\"contract IOrderBookV4\",\"name\":\"orderBook\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"minimumInput\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumInput\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumIORatio\",\"type\":\"uint256\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"vaultId\",\"type\":\"uint256\"}],\"internalType\":\"struct IO[]\",\"name\":\"validInputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"vaultId\",\"type\":\"uint256\"}],\"internalType\":\"struct IO[]\",\"name\":\"validOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"nonce\",\"type\":\"bytes32\"}],\"internalType\":\"struct OrderV3\",\"name\":\"order\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"inputIOIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"outputIOIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TakeOrderConfigV3[]\",\"name\":\"orders\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct TakeOrdersConfigV3\",\"name\":\"takeOrders\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"contract IInterpreterV3\",\"name\":\"interpreter\",\"type\":\"address\"},{\"internalType\":\"contract IInterpreterStoreV2\",\"name\":\"store\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"internalType\":\"struct EvaluableV3\",\"name\":\"evaluable\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"context\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct SignedContextV1[]\",\"name\":\"signedContext\",\"type\":\"tuple[]\"}],\"internalType\":\"struct TaskV1\",\"name\":\"task\",\"type\":\"tuple\"}],\"name\":\"arb3\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"iPermit2\",\"outputs\":[{\"internalType\":\"contract IPermit2\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"iTaskHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"inputToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"outputToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"inputAmountSent\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalOutputAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"takeOrdersData\",\"type\":\"bytes\"}],\"name\":\"onTakeOrders\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"onTakeOrders(address,address,uint256,uint256,bytes)\":{\"params\":{\"inputAmountSent\":\"The amount of `inputToken` that was sent to `IOrderBookV4OrderTaker`.\",\"inputToken\":\"The token that was sent to `IOrderBookV4OrderTaker`.\",\"outputToken\":\"The token that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns.\",\"takeOrdersData\":\"The data passed to `takeOrders` by the caller.\",\"totalOutputAmount\":\"The total amount of `outputToken` that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns.\"}},\"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[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"errors\":{\"InvalidSignature(uint256)\":[{\"notice\":\"Thrown when the ith signature from a list of signed contexts is invalid.\"}],\"NoOrders()\":[{\"notice\":\"Thrown when take orders is called with no orders.\"}],\"WrongTask()\":[{\"notice\":\"Thrown when the task does not match the expected hash.\"}]},\"kind\":\"user\",\"methods\":{\"onTakeOrders(address,address,uint256,uint256,bytes)\":{\"notice\":\"Called by `IOrderBookV4` when `takeOrders` is called with non-zero data, if it caused a non-zero input amount. I.e. if the order(s) taker received some tokens. Input and output directions are relative to the `IOrderBookV4OrderTaker` contract. If the order(s) taker had an active debt from a flash loan then that debt will be paid _before_ calculating any input amounts sent. i.e. the debt is deducted from the input amount before this callback is called.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol\":\"BalancerRouterOrderBookV4ArbOrderTaker\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"appendCBOR\":false,\"bytecodeHash\":\"none\"},\"optimizer\":{\"enabled\":true,\"runs\":9000},\"remappings\":[\":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.interpreter.interface/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/\",\":integrity/=lib/rain.interpreter/src/lib/integrity/\",\":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/\",\":openzeppelin/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/\",\":parse/=lib/rain.interpreter/src/lib/parse/\",\":prb-math/=lib/rain.interpreter/lib/prb-math/src/\",\":rain.datacontract/=lib/rain.interpreter/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.sol.codegen/lib/rain.math.binary/src/\",\":rain.math.fixedpoint/=lib/rain.interpreter/lib/rain.math.fixedpoint/src/\",\":rain.math.saturating/=lib/rain.interpreter/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.binmaskflag/=lib/rain.interpreter/lib/rain.sol.binmaskflag/src/\",\":rain.sol.codegen/=lib/rain.interpreter/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.math.fixedpoint/lib/rain.string/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.math.fixedpoint/src/error/ErrScale.sol\":{\"keccak256\":\"0xf078f93e8cf6360008743854983c2c98a43f7f78b95a527473089a22b81c55a0\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://580c4ad750f0ebebdf77f87feb52bce41f2d72fa4bf9221fbe3977837eb6a4d9\",\"dweb:/ipfs/QmeYydyLSLqFT5DfFDgJBEBBeBEhwvsMi3oQ4USXXrQudF\"]},\"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/FixedPointDecimalConstants.sol\":{\"keccak256\":\"0x9299cb9b7aeeaa2a60c6e248928bc173750c5361df4fc0e4d9ea94a778fcd6e6\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://3a65a4f0f3b7462cb0b0b6d165d3868010ff19192f53a8133e3e93be3d811d81\",\"dweb:/ipfs/QmSFWpSUH2cAcw7ph2c5rwvqcKWXTJgvabaRjk2P8ZMzcP\"]},\"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/LibFixedPointDecimalScale.sol\":{\"keccak256\":\"0xef9a2b240ba686ee4b31c37edfbbab1a3b276db3ad269688fa2c0d1beced6c0b\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://a4e115922faa62d4c3f64c466b9e3d27f53d611c92422828c1920c37bc51acfa\",\"dweb:/ipfs/QmPa5cnqmk8eHjkdSPzegHDN9Q4jWbNV1DHeFKh5LZ6XVk\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol\":{\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e\",\"dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34\",\"dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5\",\"dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71\",\"dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68\",\"dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931\",\"dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Strings.sol\":{\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f\",\"dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\":{\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2\",\"dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol\":{\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://77d1f1cf302cd5e1dfbbb4ce3b281b28e8c52942d4319fce43df2e1b6f02a52d\",\"dweb:/ipfs/QmT6ZXStmK3Knhh9BokeVHQ9HXTBZNgL3Eb1ar1cYg1hWy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\":{\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d\",\"dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c\",\"dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol\":{\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7\",\"dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrBytes.sol\":{\"keccak256\":\"0x82df8bd5b6a2343eb41c47f9b58f05adb2f8fd92b146ddb31c0ea697ebe3acd4\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://f95976983e965460330e2a1d00f3ed0e2079e13a67f3364f1175723cd97b6a07\",\"dweb:/ipfs/QmQKhYbVSesLuomYv4XPapPMvLmXNLgSx2QtgK5EJhww5c\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol\":{\"keccak256\":\"0xfc1739c5c406f71e1f52ebfd163162087e9025b02444ca12ae8844c71dcd1cf5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://ae2e95f1e6260b18105369c7216e1ebc6a251ffe3548d27ce180f7885c3f6906\",\"dweb:/ipfs/QmPQEzZmQDuzp8R5rp6ABmzGD243qu8R5GX4FbHc8G4CUC\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes.sol\":{\"keccak256\":\"0x46f53ecd0554926ed6ef781485f9c3d3dfe08fa5503021aac7476c28df364f30\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://d6841328d12c44dfc3e966d2372b841f27659b592556411bcb2889ed1a8db6b2\",\"dweb:/ipfs/QmQHUvQre6Jb5VtiKDvwQiff3eLSCPxRkAs8Jy81dnPbdD\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibMemCpy.sol\":{\"keccak256\":\"0x58be272366c53e5db26413754881238127a5ccedc69439d50afbb4c4f9769006\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://49d241b4acc8462d0289eafe645c20493a615c9bef629dab4f049599373df1c7\",\"dweb:/ipfs/QmYLK8fhzz5kjdaQY29yrcgEcGv31gUABvC7eHoChgYwV7\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol\":{\"keccak256\":\"0xdadaac57081823b3a4162aeda93195d1dbe98caf1141f6d9113302909c851307\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://fa6026d3853dd4a58faa0c9ac2dda867c200963a052a4d62e8797cd3a0e29250\",\"dweb:/ipfs/QmPRKmE5tpJKwCpy3rumAMjCqDdGK8UC2r2soB1CNQwfmJ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol\":{\"keccak256\":\"0xbfea88bec2894f0ff0b3f8b3088f4a45f561aff1bc439165bcdb0e15fa0124ea\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://3ef8c1cf899aa39585cded6e6510e637fa5e60f40dae9e39688ecacd41ef9c41\",\"dweb:/ipfs/Qme4nJr2tCfkY9DDiMhcGjuvjy6jFGZvNgCeMD81YACEKR\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/error/ErrBytecode.sol\":{\"keccak256\":\"0x56d9f7a498877655b507ddb4683f4cdbb961bf38375d85c80ab66f8cf0aa9d03\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0206c9b5a55818d20b2a644c2da0a5cfbbfffb82d4e49bbd0ddd5d60df19ecb8\",\"dweb:/ipfs/QmZuMWg8zqPFDVSWKZnRxrmDpr3YQE7ERSjAFLWnK4iDyd\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterCallerV3.sol\":{\"keccak256\":\"0x17a433a06d82d1fbaa497ab0ab0a3c698f86dcdbf9b3dc6814d2f64b1592bc32\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://eb06d882eab9261c1561a3f087b4eb6b29bbf919f6902859a3464d7ecd738315\",\"dweb:/ipfs/QmacaaExc2aL4xokmcBxKy2nhRYKWkEhb2DV2KNJQbMHxK\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol\":{\"keccak256\":\"0xd3fe133132e9688f0590f273b1a9851d17b794d7ed85d5cc7a4cf961220359f3\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://bd74c48f247d80804a1fcaa664b4771cbca471cb5bc29307e585d60fb4162bf1\",\"dweb:/ipfs/QmX8PF8aVeXbKsuaBnvLpsgcyjqxHUZK2wgogmNDzQC8mr\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterV3.sol\":{\"keccak256\":\"0x152209b9afda8a9fbba404563d67566584b95f49f57f321538d66995b81de300\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://84a09751006cd68411da9684379919e6f0a6b7606050392633146374b7d10141\",\"dweb:/ipfs/QmWoST14FWQr8MqGZXruDvJn5FeQrTkKZomSjazcp6msdm\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IParserV2.sol\":{\"keccak256\":\"0x9893dfb4e05bfbf088921c5cca38265388de5ef9e127ec8674a2ce6356152725\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://19bac62db62ad9cb20a9b9790208e124bcfdf89f7deeae25b3cb30f11f680724\",\"dweb:/ipfs/QmUvj4Zcj3b6ACRjcAHRW9geoLfLUXuKydcbMakaxRFPTa\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV1.sol\":{\"keccak256\":\"0x933cbfee07ddc43390326f87034613216352250472577bd890e9589e6206fad4\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://d0f947ca6eb86ae9c03806430f5c3a946882daee9f82e436067b1c42ff554595\",\"dweb:/ipfs/QmV7jK8dK6de1HDsUjKDGfEPwVdNEzDHgVHmVZKyfGv6MQ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV2.sol\":{\"keccak256\":\"0x3f03703392207a285d41b2871c2d83df103425c1984750cc303628269e6258e5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://a9bc96c0f288ab7b6ec1a14a42e426ec745f0b1c7fcde9d7052380c64e61c8da\",\"dweb:/ipfs/QmYBobAFw36Jd2VtFtoWNqE8HxJhy3n9Eho1fsK3uBCbwc\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV3.sol\":{\"keccak256\":\"0x231a50d32c6f910d7ae13ae1d83a221ba55eb7962380572c9c354c8a3c5c52bf\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://74b19a6c17ac7fab6edee53218a35154c5fe9ad3769ce8e22bac682dd32df0e8\",\"dweb:/ipfs/QmYiG7i4tNfA4eTynoQVbNixvGepqoAedVz2isiMfxRF8D\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV1.sol\":{\"keccak256\":\"0x20aebc5f73ffd790da90b8e88d6412f9c3a11041239c669c03e188d0a6be1e3e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://24f85bcb1d9f52ae01f7127274100ef68640a823bf2b981f267faf71192d8235\",\"dweb:/ipfs/QmPmz7q4rsy9vWXixdG9qBB8fLb1Wjj8LWyq6wyuFQR2HK\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV2.sol\":{\"keccak256\":\"0x8ae6f8b21d5fba09db20a979e797339d4cc385450d4da8cb4de2331db638caee\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://162b488b86df5c57c8cecd6c02172122ab9d30d70dd135ea151db5d56bf06f62\",\"dweb:/ipfs/Qmf9Kd89mH6PE5hoQ6ahV1Dsi28AFbakeUUw12W9Dp3sHW\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol\":{\"keccak256\":\"0xe03c065839e972fde62d73c45acf6fc2e88f42e3a07f4255ef5bfdcd30d3b1f1\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e766d9cfe9464f722e02320c3936fb0b98b9417663fefba6bac3dbb21007ce82\",\"dweb:/ipfs/QmX88DnazhZw7B3Fxp1iDZXogi2k6dyMPvh2vXpXep11oQ\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol\":{\"keccak256\":\"0x8986cb9ba93034751b21245398bc1ef7a55fe10d34b5d4cc4207ee9d39a3e616\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://dc7d8e706e96f0d0e53599582fadd591581484ac36921b0e4c6454c54b568c2b\",\"dweb:/ipfs/QmNczMgGQKWJiDhXVbtXeBjUEtzFtr7k41uPjiU8P6BrHT\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV2.sol\":{\"keccak256\":\"0x0a9223e817a36a9717b91f977a9fce5e698afd393aa2405979baf53a12339805\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://1537576666b7462485e898ddbd36848be401b3c1e3f8317eca4112d1b21d4e74\",\"dweb:/ipfs/QmZYRLbnctnMKEZ4UYz9oZ9MFoqQy1hex29HrXPVBX5U1g\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IParserV1.sol\":{\"keccak256\":\"0x19e1a217e8c67c671e319dd0e5608d7c496fbfc02363fbb2d08626715625dd55\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://603b3234a5c084acb12d0b7e3909503869f9a6d860f91d86692e007f67aba25b\",\"dweb:/ipfs/QmU7i9uyr9qWFzD2xjn1qjgiPjb8vUjuXA6dHEuGLVkmPj\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/bytecode/LibBytecode.sol\":{\"keccak256\":\"0xdebdca9d3d2a6c1be927f6fa1f28550cd7885aa52abd378ddb65e5f6495ef87c\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://5ca7fe490fe2b1287c3c231ec34daa504b3b36fa6c3e69aacda9737db1e1b548\",\"dweb:/ipfs/QmQozWFz6qFJDiRFS1YgPWCsRZgCCQ3yEzmwTVyiCs7SxY\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibContext.sol\":{\"keccak256\":\"0xd2cfeec3582d7b0b2a09573e258230ec4a6de169e60d9078f674a7a09d0c7b2d\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://cf266d36372575856000331ebb8dca7d6025db6365d14f4c876ab55305090aba\",\"dweb:/ipfs/QmYyoYFXryPM2SRMafgUgsBbAXPeCmzLFvzhHGR3i47zHy\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibEvaluable.sol\":{\"keccak256\":\"0x922f6df3f98bc94869b9c244ae349e4ecfe0f250937414af7f3699e016b9f57e\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://e4fd2f59466c83a6e5dfe843951880d3f1dbe98cf559746242d942ab20962166\",\"dweb:/ipfs/QmTTD9vj8ph7ocmWFAjPb4D4UiwusCg7iZEPWoRfVtEEu1\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/deprecated/caller/LibEncodedDispatch.sol\":{\"keccak256\":\"0x0d9b888a01c5d508dd3cdfd53823ad56c6e16e06d18ca8b2ac68e82b102cc60a\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://6f854a3243d04aa76169367843a97bec51574f01ddb1e31b271f8aa93e184dce\",\"dweb:/ipfs/QmRc85MSQBbqvCvdcZBHvBrA8FFfVbxYWHbNV2vshmLF95\"]},\"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/ns/LibNamespace.sol\":{\"keccak256\":\"0x5e1f5a0e05fbadf8acfad550ed59d960dd05ebc1d74cfa676f22a26644cc0ee5\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://ee31bfc695ae5dc841379c3164b345bb0951b8b10fd94f300d5bb2de51dd7a1e\",\"dweb:/ipfs/QmT1CqR7Lpj2bEJADgEPgY9cmTqgKLEZm1QLbZxfHEd8PY\"]},\"lib/rain.orderbook.interface/src/interface/IOrderBookV4.sol\":{\"keccak256\":\"0x715c5211361bd469a9ec916710611536d087ae5630a3fc3f80e9802ec43c4596\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://c61433f7de82ac5fbd752470aa1b9358dc70455ba85be87a9056509188f5db21\",\"dweb:/ipfs/QmaGvPxe4xpqkVMdq9mo2moJyBHB9f8wTkcxZotk7tevVH\"]},\"lib/rain.orderbook.interface/src/interface/IOrderBookV4OrderTaker.sol\":{\"keccak256\":\"0x7d197bd91214d318ce6a9ee388228494606ba7bdae36bbc6ec6ed1681ff60bd8\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://73caf415d34e06a83d104cbccf98ae76ccd522e5ae1fb32c2bb18af9bae7ccaa\",\"dweb:/ipfs/QmYbiDgjfjpX6pvjawqhtQpiTkUuX24ncHodheJPtSg4d7\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v2/IOrderBookV2.sol\":{\"keccak256\":\"0x30c528f1772e9593b5329f1458cab4cce3510a2ccca01696b506af177fffd786\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://9f53c14e5aaab2cd2fbf5b39d07c59acfdc09aff3476345816c2635de2cdd5d3\",\"dweb:/ipfs/QmaomXfmDKdoeYwbMe9cy5anx4fDEMtP4W9Rre5s5DZVE6\"]},\"lib/rain.orderbook.interface/src/interface/deprecated/v3/IOrderBookV3.sol\":{\"keccak256\":\"0xdca3fd0c6106ab98d08682e63e433b74250d1f01e646a5908c97183d9b25130b\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0f986a8388275a4144068981aa628e46bff221c2d27a3ad597a9c5fc2d4fcb09\",\"dweb:/ipfs/QmR2pxkpY4ddhLb7jdoNAVSJwYHokyGpn5Tzg3Q7YnGYgW\"]},\"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/IOrderBookV4ArbOrderTakerV2.sol\":{\"keccak256\":\"0x271d4a0fdeddc07a88b18fa52f39c840515e572d62a755f7710bbd1b20ebe389\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://64000bb3455809c1eb2a8789023286ad9ccaa2cdfe014cff480e96bb1b7ad6a3\",\"dweb:/ipfs/QmRDgNHR4mYjxvHJUNMaaDZdAnxZ7yDF9kCL3aaSYip6AH\"]},\"lib/sushixswap-v2/src/interfaces/IRouteProcessor.sol\":{\"keccak256\":\"0x5b2289c992f34dd25943db3cbc27ece8b0a1addeb2631f812e7834b7ae3eac37\",\"license\":\"GPL-3.0-or-later\",\"urls\":[\"bzz-raw://f21522058b7fe3c18d2353b06a5ddbf2b62d2aceebf7dd6dfdc51b081452bb3f\",\"dweb:/ipfs/QmVkicGnNWgnX1RfXJWPpQaAPbiAQfFwGWigbPi1wu2WiT\"]},\"src/abstract/OrderBookV4ArbCommon.sol\":{\"keccak256\":\"0xe24cce13b3e21ae36c0aae11380128c5f0ddf542a0298f1a1845a39845e10576\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://5f5d04c151a7e9fe4a659cef55abc4a626bc2ba0e58edbd714dcbadb52f4b396\",\"dweb:/ipfs/QmZHQiYBNdxMJWoMjHnsqoj2YszvFMWrGYqDcodKpwyv98\"]},\"src/abstract/OrderBookV4ArbOrderTaker.sol\":{\"keccak256\":\"0xa419a3d91a8c362dad1bea2761e6e0218c96ff295064aad1f5548444977d7896\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://0995be2430baeccbf24ead130e100f6d19a354b2703d65a3544a9bf516ff4c6c\",\"dweb:/ipfs/QmVaKDPVFe8U4MxnR3vwr7yLPrxo6hzYEud4XZzkHShsMu\"]},\"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol\":{\"keccak256\":\"0x2591b8fcde79fa4a27854fbbb09822d1aa504df69561233223d992d473e06cf2\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://4b2f128a405c55af13e0e5fa0e18db0a7aacc89a2439f3d73ed631eb16e9684b\",\"dweb:/ipfs/QmeQSZhZy49SRHRbtQHWahDo4GsAbUU1pQDv8vskJpao4n\"]},\"src/lib/LibOrderBook.sol\":{\"keccak256\":\"0xa33a7731cde01162cc5d5a1d28b96a17626a6919971620850f92cc32a20342cf\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://9bcbc37dd34292bca2ebdc620b418fbfd8b65039a3d040512f9c8d091ed1f2bf\",\"dweb:/ipfs/QmQEBw7n6QKuzF1BMtxyYcZTk8eK4Hed8QVEwuQtUUJ4AM\"]},\"src/lib/LibOrderBookArb.sol\":{\"keccak256\":\"0xe6ba0ae436fbb48193585beaaac8fc9b367ec9f511281b55e6cbc354c7faae90\",\"license\":\"LicenseRef-DCL-1.0\",\"urls\":[\"bzz-raw://2b69af34b0acdabe929170984243f7a04581df75010d790147b86f72bc6411c2\",\"dweb:/ipfs/QmZAYyTLrfB5w3uintmQp1Au32YyVrknfqcd6hLLvf1RKk\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.25+commit.b61c2a91"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"struct OrderBookV4ArbConfigV2","name":"config","type":"tuple","components":[{"internalType":"address","name":"orderBook","type":"address"},{"internalType":"struct TaskV1","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","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":"uint256[]","name":"context","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]},{"internalType":"bytes","name":"implementationData","type":"bytes"}]}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"type":"error","name":"InvalidSignature"},{"inputs":[],"type":"error","name":"NoOrders"},{"inputs":[],"type":"error","name":"WrongTask"},{"inputs":[{"internalType":"address","name":"sender","type":"address","indexed":false},{"internalType":"struct OrderBookV4ArbConfigV2","name":"config","type":"tuple","components":[{"internalType":"address","name":"orderBook","type":"address"},{"internalType":"struct TaskV1","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","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":"uint256[]","name":"context","type":"uint256[]"},{"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 IOrderBookV4","name":"orderBook","type":"address"},{"internalType":"struct TakeOrdersConfigV3","name":"takeOrders","type":"tuple","components":[{"internalType":"uint256","name":"minimumInput","type":"uint256"},{"internalType":"uint256","name":"maximumInput","type":"uint256"},{"internalType":"uint256","name":"maximumIORatio","type":"uint256"},{"internalType":"struct TakeOrderConfigV3[]","name":"orders","type":"tuple[]","components":[{"internalType":"struct OrderV3","name":"order","type":"tuple","components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","name":"store","type":"address"},{"internalType":"bytes","name":"bytecode","type":"bytes"}]},{"internalType":"struct IO[]","name":"validInputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"vaultId","type":"uint256"}]},{"internalType":"struct IO[]","name":"validOutputs","type":"tuple[]","components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"vaultId","type":"uint256"}]},{"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":"uint256[]","name":"context","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]},{"internalType":"bytes","name":"data","type":"bytes"}]},{"internalType":"struct TaskV1","name":"task","type":"tuple","components":[{"internalType":"struct EvaluableV3","name":"evaluable","type":"tuple","components":[{"internalType":"contract IInterpreterV3","name":"interpreter","type":"address"},{"internalType":"contract IInterpreterStoreV2","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":"uint256[]","name":"context","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}]}]}],"stateMutability":"payable","type":"function","name":"arb3"},{"inputs":[],"stateMutability":"view","type":"function","name":"iPermit2","outputs":[{"internalType":"contract IPermit2","name":"","type":"address"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"iTaskHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}]},{"inputs":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"inputAmountSent","type":"uint256"},{"internalType":"uint256","name":"totalOutputAmount","type":"uint256"},{"internalType":"bytes","name":"takeOrdersData","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"onTakeOrders"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"stateMutability":"view","type":"function","name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}]}],"devdoc":{"kind":"dev","methods":{"onTakeOrders(address,address,uint256,uint256,bytes)":{"params":{"inputAmountSent":"The amount of `inputToken` that was sent to `IOrderBookV4OrderTaker`.","inputToken":"The token that was sent to `IOrderBookV4OrderTaker`.","outputToken":"The token that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns.","takeOrdersData":"The data passed to `takeOrders` by the caller.","totalOutputAmount":"The total amount of `outputToken` that `IOrderBookV4` will attempt to pull from `IOrderBookV4OrderTaker` after this callback returns."}},"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[EIP 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":{"onTakeOrders(address,address,uint256,uint256,bytes)":{"notice":"Called by `IOrderBookV4` when `takeOrders` is called with non-zero data, if it caused a non-zero input amount. I.e. if the order(s) taker received some tokens. Input and output directions are relative to the `IOrderBookV4OrderTaker` contract. If the order(s) taker had an active debt from a flash loan then that debt will be paid _before_ calculating any input amounts sent. i.e. the debt is deducted from the input amount before this callback is called."}},"version":1}},"settings":{"remappings":["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.interpreter.interface/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/","integrity/=lib/rain.interpreter/src/lib/integrity/","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/","openzeppelin/=lib/rain.interpreter/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/","parse/=lib/rain.interpreter/src/lib/parse/","prb-math/=lib/rain.interpreter/lib/prb-math/src/","rain.datacontract/=lib/rain.interpreter/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.sol.codegen/lib/rain.math.binary/src/","rain.math.fixedpoint/=lib/rain.interpreter/lib/rain.math.fixedpoint/src/","rain.math.saturating/=lib/rain.interpreter/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.binmaskflag/=lib/rain.interpreter/lib/rain.sol.binmaskflag/src/","rain.sol.codegen/=lib/rain.interpreter/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.math.fixedpoint/lib/rain.string/src/","state/=lib/rain.interpreter/src/lib/state/","sushixswap-v2/=lib/sushixswap-v2/"],"optimizer":{"enabled":true,"runs":9000},"metadata":{"bytecodeHash":"none","appendCBOR":false},"compilationTarget":{"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol":"BalancerRouterOrderBookV4ArbOrderTaker"},"evmVersion":"paris","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.math.fixedpoint/src/error/ErrScale.sol":{"keccak256":"0xf078f93e8cf6360008743854983c2c98a43f7f78b95a527473089a22b81c55a0","urls":["bzz-raw://580c4ad750f0ebebdf77f87feb52bce41f2d72fa4bf9221fbe3977837eb6a4d9","dweb:/ipfs/QmeYydyLSLqFT5DfFDgJBEBBeBEhwvsMi3oQ4USXXrQudF"],"license":"LicenseRef-DCL-1.0"},"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/FixedPointDecimalConstants.sol":{"keccak256":"0x9299cb9b7aeeaa2a60c6e248928bc173750c5361df4fc0e4d9ea94a778fcd6e6","urls":["bzz-raw://3a65a4f0f3b7462cb0b0b6d165d3868010ff19192f53a8133e3e93be3d811d81","dweb:/ipfs/QmSFWpSUH2cAcw7ph2c5rwvqcKWXTJgvabaRjk2P8ZMzcP"],"license":"LicenseRef-DCL-1.0"},"lib/rain.interpreter/lib/rain.math.fixedpoint/src/lib/LibFixedPointDecimalScale.sol":{"keccak256":"0xef9a2b240ba686ee4b31c37edfbbab1a3b276db3ad269688fa2c0d1beced6c0b","urls":["bzz-raw://a4e115922faa62d4c3f64c466b9e3d27f53d611c92422828c1920c37bc51acfa","dweb:/ipfs/QmPa5cnqmk8eHjkdSPzegHDN9Q4jWbNV1DHeFKh5LZ6XVk"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol":{"keccak256":"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544","urls":["bzz-raw://c45b821ef9e882e57c256697a152e108f0f2ad6997609af8904cae99c9bd422e","dweb:/ipfs/QmRKCJW6jjzR5UYZcLpGnhEJ75UVbH6EHkEa49sWx2SKng"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol":{"keccak256":"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1","urls":["bzz-raw://41319e7f621f2dc3733511332c4fd032f8e32ad2aa7fd6f665c19741d9941a34","dweb:/ipfs/QmcYR3bd862GD1Bc7jwrU9bGxrhUu5na1oP964bDCu2id1"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305","urls":["bzz-raw://bd39944e8fc06be6dbe2dd1d8449b5336e23c6a7ba3e8e9ae5ae0f37f35283f5","dweb:/ipfs/QmPV3FGYjVwvKSgAXKUN3r9T9GwniZz83CxBpM7vyj2G53"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca","urls":["bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd","dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol":{"keccak256":"0xb264c03a3442eb37a68ad620cefd1182766b58bee6cec40343480392d6b14d69","urls":["bzz-raw://28879d01fd22c07b44f006612775f8577defbe459cb01685c5e25cd518c91a71","dweb:/ipfs/QmVgfkwv2Fxw6hhTcDUZhE7NkoSKjab3ipM7UaRbt6uXb5"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1","urls":["bzz-raw://9d213d3befca47da33f6db0310826bcdb148299805c10d77175ecfe1d06a9a68","dweb:/ipfs/QmRgCn6SP1hbBkExUADFuDo8xkT4UU47yjNF5FhCeRbQmS"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Address.sol":{"keccak256":"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa","urls":["bzz-raw://2455248c8ddd9cc6a7af76a13973cddf222072427e7b0e2a7d1aff345145e931","dweb:/ipfs/QmfYjnjRbWqYpuxurqveE6HtzsY1Xx323J428AKQgtBJZm"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/Strings.sol":{"keccak256":"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0","urls":["bzz-raw://b81d9ff6559ea5c47fc573e17ece6d9ba5d6839e213e6ebc3b4c5c8fe4199d7f","dweb:/ipfs/QmPCW1bFisUzJkyjroY3yipwfism9RRCigCcK1hbXtVM8n"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol":{"keccak256":"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58","urls":["bzz-raw://8b93a1e39a4a19eba1600b92c96f435442db88cac91e315c8291547a2a7bcfe2","dweb:/ipfs/QmTm34KVe6uZBZwq8dZDNWwPcm24qBJdxqL3rPxBJ4LrMv"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol":{"keccak256":"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80","urls":["bzz-raw://77d1f1cf302cd5e1dfbbb4ce3b281b28e8c52942d4319fce43df2e1b6f02a52d","dweb:/ipfs/QmT6ZXStmK3Knhh9BokeVHQ9HXTBZNgL3Eb1ar1cYg1hWy"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol":{"keccak256":"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b","urls":["bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d","dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1","urls":["bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f","dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3","urls":["bzz-raw://cc8841b3cd48ad125e2f46323c8bad3aa0e88e399ec62acb9e57efa7e7c8058c","dweb:/ipfs/QmSqE4mXHA2BXW58deDbXE8MTcsL5JSKNDbm23sVQxRLPS"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol":{"keccak256":"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc","urls":["bzz-raw://c50fcc459e49a9858b6d8ad5f911295cb7c9ab57567845a250bf0153f84a95c7","dweb:/ipfs/QmcEW85JRzvDkQggxiBBLVAasXWdkhEysqypj9EaB6H2g6"],"license":"MIT"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrBytes.sol":{"keccak256":"0x82df8bd5b6a2343eb41c47f9b58f05adb2f8fd92b146ddb31c0ea697ebe3acd4","urls":["bzz-raw://f95976983e965460330e2a1d00f3ed0e2079e13a67f3364f1175723cd97b6a07","dweb:/ipfs/QmQKhYbVSesLuomYv4XPapPMvLmXNLgSx2QtgK5EJhww5c"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol":{"keccak256":"0xfc1739c5c406f71e1f52ebfd163162087e9025b02444ca12ae8844c71dcd1cf5","urls":["bzz-raw://ae2e95f1e6260b18105369c7216e1ebc6a251ffe3548d27ce180f7885c3f6906","dweb:/ipfs/QmPQEzZmQDuzp8R5rp6ABmzGD243qu8R5GX4FbHc8G4CUC"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes.sol":{"keccak256":"0x46f53ecd0554926ed6ef781485f9c3d3dfe08fa5503021aac7476c28df364f30","urls":["bzz-raw://d6841328d12c44dfc3e966d2372b841f27659b592556411bcb2889ed1a8db6b2","dweb:/ipfs/QmQHUvQre6Jb5VtiKDvwQiff3eLSCPxRkAs8Jy81dnPbdD"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibMemCpy.sol":{"keccak256":"0x58be272366c53e5db26413754881238127a5ccedc69439d50afbb4c4f9769006","urls":["bzz-raw://49d241b4acc8462d0289eafe645c20493a615c9bef629dab4f049599373df1c7","dweb:/ipfs/QmYLK8fhzz5kjdaQY29yrcgEcGv31gUABvC7eHoChgYwV7"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol":{"keccak256":"0xdadaac57081823b3a4162aeda93195d1dbe98caf1141f6d9113302909c851307","urls":["bzz-raw://fa6026d3853dd4a58faa0c9ac2dda867c200963a052a4d62e8797cd3a0e29250","dweb:/ipfs/QmPRKmE5tpJKwCpy3rumAMjCqDdGK8UC2r2soB1CNQwfmJ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol":{"keccak256":"0xbfea88bec2894f0ff0b3f8b3088f4a45f561aff1bc439165bcdb0e15fa0124ea","urls":["bzz-raw://3ef8c1cf899aa39585cded6e6510e637fa5e60f40dae9e39688ecacd41ef9c41","dweb:/ipfs/Qme4nJr2tCfkY9DDiMhcGjuvjy6jFGZvNgCeMD81YACEKR"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/error/ErrBytecode.sol":{"keccak256":"0x56d9f7a498877655b507ddb4683f4cdbb961bf38375d85c80ab66f8cf0aa9d03","urls":["bzz-raw://0206c9b5a55818d20b2a644c2da0a5cfbbfffb82d4e49bbd0ddd5d60df19ecb8","dweb:/ipfs/QmZuMWg8zqPFDVSWKZnRxrmDpr3YQE7ERSjAFLWnK4iDyd"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterCallerV3.sol":{"keccak256":"0x17a433a06d82d1fbaa497ab0ab0a3c698f86dcdbf9b3dc6814d2f64b1592bc32","urls":["bzz-raw://eb06d882eab9261c1561a3f087b4eb6b29bbf919f6902859a3464d7ecd738315","dweb:/ipfs/QmacaaExc2aL4xokmcBxKy2nhRYKWkEhb2DV2KNJQbMHxK"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol":{"keccak256":"0xd3fe133132e9688f0590f273b1a9851d17b794d7ed85d5cc7a4cf961220359f3","urls":["bzz-raw://bd74c48f247d80804a1fcaa664b4771cbca471cb5bc29307e585d60fb4162bf1","dweb:/ipfs/QmX8PF8aVeXbKsuaBnvLpsgcyjqxHUZK2wgogmNDzQC8mr"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IInterpreterV3.sol":{"keccak256":"0x152209b9afda8a9fbba404563d67566584b95f49f57f321538d66995b81de300","urls":["bzz-raw://84a09751006cd68411da9684379919e6f0a6b7606050392633146374b7d10141","dweb:/ipfs/QmWoST14FWQr8MqGZXruDvJn5FeQrTkKZomSjazcp6msdm"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/IParserV2.sol":{"keccak256":"0x9893dfb4e05bfbf088921c5cca38265388de5ef9e127ec8674a2ce6356152725","urls":["bzz-raw://19bac62db62ad9cb20a9b9790208e124bcfdf89f7deeae25b3cb30f11f680724","dweb:/ipfs/QmUvj4Zcj3b6ACRjcAHRW9geoLfLUXuKydcbMakaxRFPTa"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV1.sol":{"keccak256":"0x933cbfee07ddc43390326f87034613216352250472577bd890e9589e6206fad4","urls":["bzz-raw://d0f947ca6eb86ae9c03806430f5c3a946882daee9f82e436067b1c42ff554595","dweb:/ipfs/QmV7jK8dK6de1HDsUjKDGfEPwVdNEzDHgVHmVZKyfGv6MQ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV2.sol":{"keccak256":"0x3f03703392207a285d41b2871c2d83df103425c1984750cc303628269e6258e5","urls":["bzz-raw://a9bc96c0f288ab7b6ec1a14a42e426ec745f0b1c7fcde9d7052380c64e61c8da","dweb:/ipfs/QmYBobAFw36Jd2VtFtoWNqE8HxJhy3n9Eho1fsK3uBCbwc"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IExpressionDeployerV3.sol":{"keccak256":"0x231a50d32c6f910d7ae13ae1d83a221ba55eb7962380572c9c354c8a3c5c52bf","urls":["bzz-raw://74b19a6c17ac7fab6edee53218a35154c5fe9ad3769ce8e22bac682dd32df0e8","dweb:/ipfs/QmYiG7i4tNfA4eTynoQVbNixvGepqoAedVz2isiMfxRF8D"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV1.sol":{"keccak256":"0x20aebc5f73ffd790da90b8e88d6412f9c3a11041239c669c03e188d0a6be1e3e","urls":["bzz-raw://24f85bcb1d9f52ae01f7127274100ef68640a823bf2b981f267faf71192d8235","dweb:/ipfs/QmPmz7q4rsy9vWXixdG9qBB8fLb1Wjj8LWyq6wyuFQR2HK"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterCallerV2.sol":{"keccak256":"0x8ae6f8b21d5fba09db20a979e797339d4cc385450d4da8cb4de2331db638caee","urls":["bzz-raw://162b488b86df5c57c8cecd6c02172122ab9d30d70dd135ea151db5d56bf06f62","dweb:/ipfs/Qmf9Kd89mH6PE5hoQ6ahV1Dsi28AFbakeUUw12W9Dp3sHW"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol":{"keccak256":"0xe03c065839e972fde62d73c45acf6fc2e88f42e3a07f4255ef5bfdcd30d3b1f1","urls":["bzz-raw://e766d9cfe9464f722e02320c3936fb0b98b9417663fefba6bac3dbb21007ce82","dweb:/ipfs/QmX88DnazhZw7B3Fxp1iDZXogi2k6dyMPvh2vXpXep11oQ"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol":{"keccak256":"0x8986cb9ba93034751b21245398bc1ef7a55fe10d34b5d4cc4207ee9d39a3e616","urls":["bzz-raw://dc7d8e706e96f0d0e53599582fadd591581484ac36921b0e4c6454c54b568c2b","dweb:/ipfs/QmNczMgGQKWJiDhXVbtXeBjUEtzFtr7k41uPjiU8P6BrHT"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV2.sol":{"keccak256":"0x0a9223e817a36a9717b91f977a9fce5e698afd393aa2405979baf53a12339805","urls":["bzz-raw://1537576666b7462485e898ddbd36848be401b3c1e3f8317eca4112d1b21d4e74","dweb:/ipfs/QmZYRLbnctnMKEZ4UYz9oZ9MFoqQy1hex29HrXPVBX5U1g"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/interface/deprecated/IParserV1.sol":{"keccak256":"0x19e1a217e8c67c671e319dd0e5608d7c496fbfc02363fbb2d08626715625dd55","urls":["bzz-raw://603b3234a5c084acb12d0b7e3909503869f9a6d860f91d86692e007f67aba25b","dweb:/ipfs/QmU7i9uyr9qWFzD2xjn1qjgiPjb8vUjuXA6dHEuGLVkmPj"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/bytecode/LibBytecode.sol":{"keccak256":"0xdebdca9d3d2a6c1be927f6fa1f28550cd7885aa52abd378ddb65e5f6495ef87c","urls":["bzz-raw://5ca7fe490fe2b1287c3c231ec34daa504b3b36fa6c3e69aacda9737db1e1b548","dweb:/ipfs/QmQozWFz6qFJDiRFS1YgPWCsRZgCCQ3yEzmwTVyiCs7SxY"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibContext.sol":{"keccak256":"0xd2cfeec3582d7b0b2a09573e258230ec4a6de169e60d9078f674a7a09d0c7b2d","urls":["bzz-raw://cf266d36372575856000331ebb8dca7d6025db6365d14f4c876ab55305090aba","dweb:/ipfs/QmYyoYFXryPM2SRMafgUgsBbAXPeCmzLFvzhHGR3i47zHy"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/caller/LibEvaluable.sol":{"keccak256":"0x922f6df3f98bc94869b9c244ae349e4ecfe0f250937414af7f3699e016b9f57e","urls":["bzz-raw://e4fd2f59466c83a6e5dfe843951880d3f1dbe98cf559746242d942ab20962166","dweb:/ipfs/QmTTD9vj8ph7ocmWFAjPb4D4UiwusCg7iZEPWoRfVtEEu1"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/deprecated/caller/LibEncodedDispatch.sol":{"keccak256":"0x0d9b888a01c5d508dd3cdfd53823ad56c6e16e06d18ca8b2ac68e82b102cc60a","urls":["bzz-raw://6f854a3243d04aa76169367843a97bec51574f01ddb1e31b271f8aa93e184dce","dweb:/ipfs/QmRc85MSQBbqvCvdcZBHvBrA8FFfVbxYWHbNV2vshmLF95"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/lib/rain.interpreter.interface/src/lib/ns/LibNamespace.sol":{"keccak256":"0x5e1f5a0e05fbadf8acfad550ed59d960dd05ebc1d74cfa676f22a26644cc0ee5","urls":["bzz-raw://ee31bfc695ae5dc841379c3164b345bb0951b8b10fd94f300d5bb2de51dd7a1e","dweb:/ipfs/QmT1CqR7Lpj2bEJADgEPgY9cmTqgKLEZm1QLbZxfHEd8PY"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/IOrderBookV4.sol":{"keccak256":"0x715c5211361bd469a9ec916710611536d087ae5630a3fc3f80e9802ec43c4596","urls":["bzz-raw://c61433f7de82ac5fbd752470aa1b9358dc70455ba85be87a9056509188f5db21","dweb:/ipfs/QmaGvPxe4xpqkVMdq9mo2moJyBHB9f8wTkcxZotk7tevVH"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/IOrderBookV4OrderTaker.sol":{"keccak256":"0x7d197bd91214d318ce6a9ee388228494606ba7bdae36bbc6ec6ed1681ff60bd8","urls":["bzz-raw://73caf415d34e06a83d104cbccf98ae76ccd522e5ae1fb32c2bb18af9bae7ccaa","dweb:/ipfs/QmYbiDgjfjpX6pvjawqhtQpiTkUuX24ncHodheJPtSg4d7"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v2/IOrderBookV2.sol":{"keccak256":"0x30c528f1772e9593b5329f1458cab4cce3510a2ccca01696b506af177fffd786","urls":["bzz-raw://9f53c14e5aaab2cd2fbf5b39d07c59acfdc09aff3476345816c2635de2cdd5d3","dweb:/ipfs/QmaomXfmDKdoeYwbMe9cy5anx4fDEMtP4W9Rre5s5DZVE6"],"license":"LicenseRef-DCL-1.0"},"lib/rain.orderbook.interface/src/interface/deprecated/v3/IOrderBookV3.sol":{"keccak256":"0xdca3fd0c6106ab98d08682e63e433b74250d1f01e646a5908c97183d9b25130b","urls":["bzz-raw://0f986a8388275a4144068981aa628e46bff221c2d27a3ad597a9c5fc2d4fcb09","dweb:/ipfs/QmR2pxkpY4ddhLb7jdoNAVSJwYHokyGpn5Tzg3Q7YnGYgW"],"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/IOrderBookV4ArbOrderTakerV2.sol":{"keccak256":"0x271d4a0fdeddc07a88b18fa52f39c840515e572d62a755f7710bbd1b20ebe389","urls":["bzz-raw://64000bb3455809c1eb2a8789023286ad9ccaa2cdfe014cff480e96bb1b7ad6a3","dweb:/ipfs/QmRDgNHR4mYjxvHJUNMaaDZdAnxZ7yDF9kCL3aaSYip6AH"],"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/OrderBookV4ArbCommon.sol":{"keccak256":"0xe24cce13b3e21ae36c0aae11380128c5f0ddf542a0298f1a1845a39845e10576","urls":["bzz-raw://5f5d04c151a7e9fe4a659cef55abc4a626bc2ba0e58edbd714dcbadb52f4b396","dweb:/ipfs/QmZHQiYBNdxMJWoMjHnsqoj2YszvFMWrGYqDcodKpwyv98"],"license":"LicenseRef-DCL-1.0"},"src/abstract/OrderBookV4ArbOrderTaker.sol":{"keccak256":"0xa419a3d91a8c362dad1bea2761e6e0218c96ff295064aad1f5548444977d7896","urls":["bzz-raw://0995be2430baeccbf24ead130e100f6d19a354b2703d65a3544a9bf516ff4c6c","dweb:/ipfs/QmVaKDPVFe8U4MxnR3vwr7yLPrxo6hzYEud4XZzkHShsMu"],"license":"LicenseRef-DCL-1.0"},"src/concrete/arb/BalancerRouterOrderBookV4ArbOrderTaker.sol":{"keccak256":"0x2591b8fcde79fa4a27854fbbb09822d1aa504df69561233223d992d473e06cf2","urls":["bzz-raw://4b2f128a405c55af13e0e5fa0e18db0a7aacc89a2439f3d73ed631eb16e9684b","dweb:/ipfs/QmeQSZhZy49SRHRbtQHWahDo4GsAbUU1pQDv8vskJpao4n"],"license":"LicenseRef-DCL-1.0"},"src/lib/LibOrderBook.sol":{"keccak256":"0xa33a7731cde01162cc5d5a1d28b96a17626a6919971620850f92cc32a20342cf","urls":["bzz-raw://9bcbc37dd34292bca2ebdc620b418fbfd8b65039a3d040512f9c8d091ed1f2bf","dweb:/ipfs/QmQEBw7n6QKuzF1BMtxyYcZTk8eK4Hed8QVEwuQtUUJ4AM"],"license":"LicenseRef-DCL-1.0"},"src/lib/LibOrderBookArb.sol":{"keccak256":"0xe6ba0ae436fbb48193585beaaac8fc9b367ec9f511281b55e6cbc354c7faae90","urls":["bzz-raw://2b69af34b0acdabe929170984243f7a04581df75010d790147b86f72bc6411c2","dweb:/ipfs/QmZAYyTLrfB5w3uintmQp1Au32YyVrknfqcd6hLLvf1RKk"],"license":"LicenseRef-DCL-1.0"}},"version":1},"id":53} \ No newline at end of file diff --git a/test/e2e/data.js b/test/e2e/data.js index 46f4f696..5710f58a 100644 --- a/test/e2e/data.js +++ b/test/e2e/data.js @@ -105,53 +105,52 @@ module.exports = [ // "0x96C3673Ee4B0d5303272193BaB0c565B7ce58D7A", // "0x22025257BeF969A81eDaC0b343ce82d777931327", ], - // [ - // ChainId.BASE, - // process?.env?.TEST_BASE_RPC, - // 16418720, - // [ - // WNATIVE[ChainId.BASE], - // new Token({ - // chainId: ChainId.BASE, - // address: "0x99b2B1A2aDB02B38222ADcD057783D7e5D1FCC7D", - // decimals: 18, - // symbol: "WLTH", - // }), - // new Token({ - // chainId: ChainId.BASE, - // address: "0x71DDE9436305D2085331AF4737ec6f1fe876Cf9f", - // decimals: 18, - // symbol: "PAID", - // }), - // new Token({ - // chainId: ChainId.BASE, - // address: "0x3982E57fF1b193Ca8eb03D16Db268Bd4B40818f8", - // decimals: 18, - // symbol: "BLOOD", - // }), - // ], - // [ - // "0x2B8804c2b652f05F7FDD8e0a02F01eE58F01667E", - // "0xD6216fC19DB775Df9774a6E33526131dA7D19a2c", - // "0x3ea31919Ef9b3e72Cc25657b604DB1ACDb1DdB4b", - // "0xf6D07A291443F31B129Ca7e2b46C6F882f0FAa5b", - // ], - // [LiquidityProviders.UniswapV3, LiquidityProviders.UniswapV2, LiquidityProviders.BaseSwap], - // ["1", "10000", "10000", "10000"], - // ], + [ + ChainId.BASE, + process?.env?.TEST_BASE_RPC, + 16418720, + [ + WNATIVE[ChainId.BASE], + new Token({ + chainId: ChainId.BASE, + address: "0x99b2B1A2aDB02B38222ADcD057783D7e5D1FCC7D", + decimals: 18, + symbol: "WLTH", + }), + new Token({ + chainId: ChainId.BASE, + address: "0x71DDE9436305D2085331AF4737ec6f1fe876Cf9f", + decimals: 18, + symbol: "PAID", + }), + new Token({ + chainId: ChainId.BASE, + address: "0x3982E57fF1b193Ca8eb03D16Db268Bd4B40818f8", + decimals: 18, + symbol: "BLOOD", + }), + ], + [ + "0x2B8804c2b652f05F7FDD8e0a02F01eE58F01667E", + "0xD6216fC19DB775Df9774a6E33526131dA7D19a2c", + "0x3ea31919Ef9b3e72Cc25657b604DB1ACDb1DdB4b", + "0xf6D07A291443F31B129Ca7e2b46C6F882f0FAa5b", + ], + [LiquidityProviders.UniswapV3, LiquidityProviders.UniswapV2, LiquidityProviders.BaseSwap], + ["1", "10000", "10000", "10000"], + ], [ // unique test for aerodrome slipstream ChainId.BASE, process?.env?.TEST_BASE_RPC, - // 16418720, 34181086, [WNATIVE[ChainId.BASE], USDC[ChainId.BASE]], [ - "0x2B8804c2b652f05F7FDD8e0a02F01eE58F01667E", + "0xd9eDC75a3a797Ec92Ca370F19051BAbebfb2edEe", "0x336307F2d8390035Ba926a61a86b45CA9dC91E57", ], [LiquidityProviders.AerodromeSlipstream], - ["1", "10000"], + ["1", "100"], ], [ ChainId.BSC, diff --git a/test/e2e/e2e.test.js b/test/e2e/e2e.test.js index c8ec62ae..170f71ea 100644 --- a/test/e2e/e2e.test.js +++ b/test/e2e/e2e.test.js @@ -81,6 +81,11 @@ for (let i = 0; i < testData.length; i++) { config.rpc = [rpc]; const rpcState = new RpcState(config.rpc.map((v) => ({ url: v }))); + const balancerRouter = (() => { + const balancerRouterInit = balancerHelpers.BalancerRouter.init(chainId); + if (balancerRouterInit.isOk()) return balancerRouterInit.value; + else return undefined; + })(); const state = new SharedState({ chainConfig: config, client: {}, @@ -93,6 +98,7 @@ for (let i = 0; i < testData.length; i++) { ownerLimits: {}, quoteGas: 1_000_000n, }, + balancerRouter, }); const client = createPublicClient({ chain: publicClientConfig[chainId].chain, @@ -107,34 +113,15 @@ for (let i = 0; i < testData.length; i++) { for (let j = 0; j < rpVersions.length; j++) { const rpVersion = rpVersions[j]; - it.only(`should clear orders successfully using route processor v${rpVersion}`, async function () { + it(`should clear orders successfully using route processor v${rpVersion}`, async function () { config.rpc = [rpc]; const viemClient = await viem.getPublicClient(); state.client = viemClient; - state.client.simulateContract = client.simulateContract; const dataFetcher = await dataFetcherPromise; state.dataFetcher = dataFetcher; dataFetcher.web3Client.transport.retryCount = 3; const testSpan = tracer.startSpan("test-clearing"); - // set as the route for POC - balancerHelpers.getBestBalancerRoute = async function (params) { - return Result.ok([ - { - steps: [ - { - pool: "0x88c044fb203b58b12252be7242926b1eeb113b4a", - tokenOut: "0x4200000000000000000000000000000000000006", - isBuffer: false, - }, - ], - tokenIn: params.tokenIn.address, - exactAmountIn: params.swapAmount, - minAmountOut: 0n, - }, - ]); - }; - // reset network before each test await helpers.reset(rpc, blockNumber); // get bot signer @@ -184,7 +171,7 @@ for (let i = 0; i < testData.length; i++) { : await ethers.getContractAt(orderbookAbi, orderbookAddress); const arb = !arbAddress - ? await balancerArbDeploy(orderbook.address, config.routeProcessors[rpVersion]) + ? await arbDeploy(orderbook.address, config.routeProcessors[rpVersion]) : await ethers.getContractAt(ABI.Orderbook.Primary.Arb, arbAddress); state.dispair = { @@ -377,7 +364,7 @@ for (let i = 0; i < testData.length; i++) { testSpan.end(); }); - it(`should clear orders successfully using route processor v${rpVersion}`, async function () { + it("should clear orders successfully using inter-orderbook", async function () { config.rpc = [rpc]; const viemClient = await viem.getPublicClient(); state.client = viemClient; @@ -388,6 +375,7 @@ for (let i = 0; i < testData.length; i++) { // reset network before each test await helpers.reset(rpc, blockNumber); + // get bot signer const bot = botAddress ? (await viem.getTestClient({ account: botAddress })) @@ -430,12 +418,13 @@ for (let i = 0; i < testData.length; i++) { store: store.address, parser: parser.address, }); - const orderbook = !orderbookAddress + const orderbook1 = !orderbookAddress ? await deployOrderBookNPE2() : await ethers.getContractAt(orderbookAbi, orderbookAddress); - + const orderbook2 = await deployOrderBookNPE2(); + const genericArb = await genericArbrbDeploy(orderbook2.address); const arb = !arbAddress - ? await arbDeploy(orderbook.address, config.routeProcessors[rpVersion]) + ? await arbDeploy(orderbook1.address, config.routeProcessors[rpVersion]) : await ethers.getContractAt(ABI.Orderbook.Primary.Arb, arbAddress); state.dispair = { @@ -451,15 +440,21 @@ for (let i = 0; i < testData.length; i++) { ERC20Artifact.abi, tokens[i].address, ); + if (i === 0) { + tokens[0].vaultIds = []; + for (let j = 0; j < tokens.length - 1; j++) { + tokens[0].vaultIds.push(ethers.BigNumber.from(randomUint256())); + } + } tokens[i].vaultId = ethers.BigNumber.from(randomUint256()); - tokens[i].depositAmount = ethers.utils.parseUnits( - deposits[i] ?? "100", - tokens[i].decimals, - ); - // owners.push( - // (await viem.getTestClient({account: addressesWithBalance[i]})).extend(publicActions).extend(walletActions) - // // await ethers.getImpersonatedSigner(addressesWithBalance[i]) - // ); + i > 0 + ? (tokens[i].depositAmount = ethers.utils.parseUnits( + deposits[i] ?? "100", + tokens[i].decimals, + )) + : (tokens[i].depositAmount = ethers.utils + .parseUnits(deposits[i] ?? "100", tokens[i].decimals) + .div(tokens.length - 1)); owners.push(await ethers.getImpersonatedSigner(addressesWithBalance[i])); await network.provider.send("hardhat_setBalance", [ addressesWithBalance[i], @@ -479,20 +474,20 @@ for (let i = 0; i < testData.length; i++) { // tokens as input let orders = []; for (let i = 1; i < tokens.length; i++) { - const depositConfigStruct = { + const depositConfigStruct1 = { token: tokens[i].address, vaultId: tokens[i].vaultId, amount: tokens[i].depositAmount.toString(), }; await tokens[i].contract .connect(owners[i]) - .approve(orderbook.address, depositConfigStruct.amount); - await orderbook + .approve(orderbook1.address, depositConfigStruct1.amount); + await orderbook1 .connect(owners[i]) .deposit2( - depositConfigStruct.token, - depositConfigStruct.vaultId, - depositConfigStruct.amount, + depositConfigStruct1.token, + depositConfigStruct1.vaultId, + depositConfigStruct1.amount, [], ); @@ -500,7 +495,7 @@ for (let i = 0; i < testData.length; i++) { const ratio = "0".repeat(64); // 0 const maxOutput = "f".repeat(64); // max const bytecode = `0x0000000000000000000000000000000000000000000000000000000000000002${maxOutput}${ratio}0000000000000000000000000000000000000000000000000000000000000015020000000c02020002011000000110000100000000`; - const addOrderConfig = { + const addOrderConfig1 = { evaluable: { interpreter: interpreter.address, store: store.address, @@ -524,11 +519,61 @@ for (let i = 0; i < testData.length; i++) { ], meta: encodeMeta("some_order"), }; - const tx = await orderbook.connect(owners[i]).addOrder2(addOrderConfig, []); + const tx1 = await orderbook1.connect(owners[i]).addOrder2(addOrderConfig1, []); orders.push( await mockSgFromEvent( - await getEventArgs(tx, "AddOrderV2", orderbook), - orderbook, + await getEventArgs(tx1, "AddOrderV2", orderbook1), + orderbook1, + tokens.map((v) => ({ ...v.contract, knownSymbol: v.symbol })), + ), + ); + + // opposing orders + const depositConfigStruct2 = { + token: tokens[0].address, + vaultId: tokens[0].vaultIds[i - 1], + amount: tokens[0].depositAmount.toString(), + }; + await tokens[0].contract + .connect(owners[0]) + .approve(orderbook2.address, depositConfigStruct2.amount); + await orderbook2 + .connect(owners[0]) + .deposit2( + depositConfigStruct2.token, + depositConfigStruct2.vaultId, + depositConfigStruct2.amount, + [], + ); + const addOrderConfig2 = { + evaluable: { + interpreter: interpreter.address, + store: store.address, + bytecode, + }, + nonce: "0x" + "0".repeat(63) + "1", + secret: "0x" + "0".repeat(63) + "1", + validInputs: [ + { + token: tokens[i].address, + decimals: tokens[i].decimals, + vaultId: tokens[i].vaultId, + }, + ], + validOutputs: [ + { + token: tokens[0].address, + decimals: tokens[0].decimals, + vaultId: tokens[0].vaultIds[i - 1], + }, + ], + meta: encodeMeta("some_order"), + }; + const tx2 = await orderbook2.connect(owners[0]).addOrder2(addOrderConfig2, []); + orders.push( + await mockSgFromEvent( + await getEventArgs(tx2, "AddOrderV2", orderbook2), + orderbook2, tokens.map((v) => ({ ...v.contract, knownSymbol: v.symbol })), ), ); @@ -543,9 +588,9 @@ for (let i = 0; i < testData.length; i++) { config.lps = liquidityProviders; config.rpVersion = rpVersion; config.arbAddress = arb.address; - config.orderbookAddress = orderbook.address; + config.genericArbAddress = genericArb.address; + config.orderbookAddress = orderbook1.address; config.testBlockNumber = BigInt(blockNumber); - config.testBlockNumberInc = BigInt(blockNumber); // increments during test updating to new block height config.gasCoveragePercentage = "1"; config.viemClient = viemClient; config.dataFetcher = dataFetcher; @@ -563,6 +608,20 @@ for (let i = 0; i < testData.length; i++) { await orderManager.addOrders(orders); orders = orderManager.getNextRoundOrders(false); + // mock init quotes + orders.forEach((pair) => { + pair.takeOrder.quote = { + ratio: ethers.constants.Zero.toBigInt(), + maxOutput: tokens + .find( + (t) => + t.contract.address.toLowerCase() === + pair.sellToken.toLowerCase(), + ) + ?.depositAmount.mul("1" + "0".repeat(18 - pair.sellTokenDecimals)) + .toBigInt(), + }; + }); state.gasPrice = await bot.getGasPrice(); orderManager.getNextRoundOrders = () => orders; const rainSolver = new RainSolver( @@ -578,23 +637,26 @@ for (let i = 0; i < testData.length; i++) { const { results: reports } = await rainSolver.processNextRound(undefined, false); // should have cleared correct number of orders - assert.ok(reports.length == tokens.length - 1, "Failed to clear all given orders"); + assert.ok( + reports.length == (tokens.length - 1) * 2, + "Failed to clear all given orders", + ); // validate each cleared order - let inputProfit = ethers.constants.Zero; let gasSpent = ethers.constants.Zero; - for (let i = 0; i < reports.length; i++) { + let inputProfit = ethers.constants.Zero; + for (let i = 0; i < reports.length / 2; i++) { const report = reports[i].value; assert.equal(report.status, ProcessOrderStatus.FoundOpportunity); const pair = `${tokens[0].symbol}/${tokens[i + 1].symbol}`; const clearedAmount = ethers.BigNumber.from(report.clearedAmount); - const outputVault = await orderbook.vaultBalance( + const outputVault = await orderbook1.vaultBalance( owners[i + 1].address, tokens[i + 1].address, tokens[i + 1].vaultId, ); - const inputVault = await orderbook.vaultBalance( + const inputVault = await orderbook1.vaultBalance( owners[0].address, tokens[0].address, tokens[0].vaultId, @@ -615,8 +677,17 @@ for (let i = 0; i < testData.length; i++) { `Unexpected current output vault balance: ${pair}`, ); assert.ok(inputVault.eq(0), `Unexpected current input vault balance: ${pair}`); + + // output bounties should equal to current bot's token balance assert.ok( - originalBotTokenBalances[i + 1].eq(botTokenBalance), + originalBotTokenBalances[i + 1] + .add( + ethers.utils.parseUnits( + report.outputTokenIncome, + tokens[i + 1].decimals, + ), + ) + .eq(botTokenBalance), `Unexpected current bot ${tokens[i + 1].symbol} balance`, ); @@ -625,14 +696,22 @@ for (let i = 0; i < testData.length; i++) { gasSpent = gasSpent.add(ethers.utils.parseUnits(report.gasCost.toString())); } + // all input bounties (+ old balance) should be equal to current bot's balance + assert.ok( + originalBotTokenBalances[0] + .add(inputProfit) + .eq(await tokens[0].contract.balanceOf(bot.account.address)), + "Unexpected bot bounty", + ); + testSpan.end(); }); - it("should clear orders successfully using inter-orderbook", async function () { + it("should clear orders successfully using intra-orderbook", async function () { config.rpc = [rpc]; const viemClient = await viem.getPublicClient(); - state.client = viemClient; const dataFetcher = await dataFetcherPromise; + state.client = viemClient; state.dataFetcher = dataFetcher; dataFetcher.web3Client.transport.retryCount = 3; const testSpan = tracer.startSpan("test-clearing"); @@ -682,13 +761,11 @@ for (let i = 0; i < testData.length; i++) { store: store.address, parser: parser.address, }); - const orderbook1 = !orderbookAddress + const orderbook = !orderbookAddress ? await deployOrderBookNPE2() : await ethers.getContractAt(orderbookAbi, orderbookAddress); - const orderbook2 = await deployOrderBookNPE2(); - const genericArb = await genericArbrbDeploy(orderbook2.address); const arb = !arbAddress - ? await arbDeploy(orderbook1.address, config.routeProcessors[rpVersion]) + ? await arbDeploy(orderbook.address, config.routeProcessors[rpVersion]) : await ethers.getContractAt(ABI.Orderbook.Primary.Arb, arbAddress); state.dispair = { @@ -718,7 +795,7 @@ for (let i = 0; i < testData.length; i++) { )) : (tokens[i].depositAmount = ethers.utils .parseUnits(deposits[i] ?? "100", tokens[i].decimals) - .div(tokens.length - 1)); + .div(4)); owners.push(await ethers.getImpersonatedSigner(addressesWithBalance[i])); await network.provider.send("hardhat_setBalance", [ addressesWithBalance[i], @@ -737,6 +814,7 @@ for (let i = 0; i < testData.length; i++) { // all orders have WETH as output and other specified // tokens as input let orders = []; + const opposingOrders = []; for (let i = 1; i < tokens.length; i++) { const depositConfigStruct1 = { token: tokens[i].address, @@ -745,8 +823,8 @@ for (let i = 0; i < testData.length; i++) { }; await tokens[i].contract .connect(owners[i]) - .approve(orderbook1.address, depositConfigStruct1.amount); - await orderbook1 + .approve(orderbook.address, depositConfigStruct1.amount); + await orderbook .connect(owners[i]) .deposit2( depositConfigStruct1.token, @@ -755,15 +833,18 @@ for (let i = 0; i < testData.length; i++) { [], ); - // prebuild bytecode: "_ _: 0 max; :;" - const ratio = "0".repeat(64); // 0 - const maxOutput = "f".repeat(64); // max - const bytecode = `0x0000000000000000000000000000000000000000000000000000000000000002${maxOutput}${ratio}0000000000000000000000000000000000000000000000000000000000000015020000000c02020002011000000110000100000000`; + // prebuild bytecode: "_ _: 0.5 max; :;" + const ratio1 = ethers.BigNumber.from("500000000000000000") + .toHexString() + .substring(2) + .padStart(64, "0"); // 0.5 + const maxOutput1 = "f".repeat(64); // max + const bytecode1 = `0x0000000000000000000000000000000000000000000000000000000000000002${maxOutput1}${ratio1}0000000000000000000000000000000000000000000000000000000000000015020000000c02020002011000000110000100000000`; const addOrderConfig1 = { evaluable: { interpreter: interpreter.address, store: store.address, - bytecode, + bytecode: bytecode1, }, nonce: "0x" + "0".repeat(63) + "1", secret: "0x" + "0".repeat(63) + "1", @@ -783,11 +864,11 @@ for (let i = 0; i < testData.length; i++) { ], meta: encodeMeta("some_order"), }; - const tx1 = await orderbook1.connect(owners[i]).addOrder2(addOrderConfig1, []); + const tx1 = await orderbook.connect(owners[i]).addOrder2(addOrderConfig1, []); orders.push( await mockSgFromEvent( - await getEventArgs(tx1, "AddOrderV2", orderbook1), - orderbook1, + await getEventArgs(tx1, "AddOrderV2", orderbook), + orderbook, tokens.map((v) => ({ ...v.contract, knownSymbol: v.symbol })), ), ); @@ -800,8 +881,8 @@ for (let i = 0; i < testData.length; i++) { }; await tokens[0].contract .connect(owners[0]) - .approve(orderbook2.address, depositConfigStruct2.amount); - await orderbook2 + .approve(orderbook.address, depositConfigStruct2.amount); + await orderbook .connect(owners[0]) .deposit2( depositConfigStruct2.token, @@ -809,11 +890,19 @@ for (let i = 0; i < testData.length; i++) { depositConfigStruct2.amount, [], ); + + // prebuild bytecode: "_ _: 1 max; :;" + const ratio2 = ethers.BigNumber.from("1000000000000000000") + .toHexString() + .substring(2) + .padStart(64, "0"); // 1 + const maxOutput2 = "f".repeat(64); // max + const bytecode2 = `0x0000000000000000000000000000000000000000000000000000000000000002${maxOutput2}${ratio2}0000000000000000000000000000000000000000000000000000000000000015020000000c02020002011000000110000100000000`; const addOrderConfig2 = { evaluable: { interpreter: interpreter.address, store: store.address, - bytecode, + bytecode: bytecode2, }, nonce: "0x" + "0".repeat(63) + "1", secret: "0x" + "0".repeat(63) + "1", @@ -833,15 +922,16 @@ for (let i = 0; i < testData.length; i++) { ], meta: encodeMeta("some_order"), }; - const tx2 = await orderbook2.connect(owners[0]).addOrder2(addOrderConfig2, []); - orders.push( + const tx2 = await orderbook.connect(owners[0]).addOrder2(addOrderConfig2, []); + opposingOrders.push( await mockSgFromEvent( - await getEventArgs(tx2, "AddOrderV2", orderbook2), - orderbook2, + await getEventArgs(tx2, "AddOrderV2", orderbook), + orderbook, tokens.map((v) => ({ ...v.contract, knownSymbol: v.symbol })), ), ); } + orders.push(...opposingOrders); // run the clearing process config.isTest = true; @@ -852,8 +942,7 @@ for (let i = 0; i < testData.length; i++) { config.lps = liquidityProviders; config.rpVersion = rpVersion; config.arbAddress = arb.address; - config.genericArbAddress = genericArb.address; - config.orderbookAddress = orderbook1.address; + config.orderbookAddress = orderbook.address; config.testBlockNumber = BigInt(blockNumber); config.gasCoveragePercentage = "1"; config.viemClient = viemClient; @@ -907,59 +996,50 @@ for (let i = 0; i < testData.length; i++) { ); // validate each cleared order + let c = 1; let gasSpent = ethers.constants.Zero; let inputProfit = ethers.constants.Zero; - for (let i = 0; i < reports.length / 2; i++) { + for (let i = 0; i < reports.length; i++) { const report = reports[i].value; + if (report.status !== ProcessOrderStatus.FoundOpportunity) continue; assert.equal(report.status, ProcessOrderStatus.FoundOpportunity); - const pair = `${tokens[0].symbol}/${tokens[i + 1].symbol}`; + const pair = `${tokens[0].symbol}/${tokens[c].symbol}`; const clearedAmount = ethers.BigNumber.from(report.clearedAmount); - const outputVault = await orderbook1.vaultBalance( - owners[i + 1].address, - tokens[i + 1].address, - tokens[i + 1].vaultId, + const outputVault = await orderbook.vaultBalance( + owners[c].address, + tokens[c].address, + tokens[c].vaultId, ); - const inputVault = await orderbook1.vaultBalance( + const inputVault = await orderbook.vaultBalance( owners[0].address, tokens[0].address, tokens[0].vaultId, ); - const botTokenBalance = await tokens[i + 1].contract.balanceOf( - bot.account.address, - ); + const botTokenBalance = await tokens[c].contract.balanceOf(bot.account.address); assert.equal(report.tokenPair, pair); // should have cleared equal to vault balance or lower assert.ok( - tokens[i + 1].depositAmount.gte(clearedAmount), + tokens[c].depositAmount.gte(clearedAmount), `Did not clear expected amount for: ${pair}`, ); assert.ok( - outputVault.eq(tokens[i + 1].depositAmount.sub(clearedAmount)), + outputVault.eq(tokens[c].depositAmount.sub(clearedAmount)), `Unexpected current output vault balance: ${pair}`, ); assert.ok(inputVault.eq(0), `Unexpected current input vault balance: ${pair}`); - - // output bounties should equal to current bot's token balance assert.ok( - originalBotTokenBalances[i + 1] - .add( - ethers.utils.parseUnits( - report.outputTokenIncome, - tokens[i + 1].decimals, - ), - ) - .eq(botTokenBalance), - `Unexpected current bot ${tokens[i + 1].symbol} balance`, + originalBotTokenBalances[c].eq(botTokenBalance), + `Unexpected current bot ${tokens[c].symbol} balance`, ); // collect all bot's input income (bounty) and gas cost inputProfit = inputProfit.add(ethers.utils.parseUnits(report.inputTokenIncome)); gasSpent = gasSpent.add(ethers.utils.parseUnits(report.gasCost.toString())); + c++; } - // all input bounties (+ old balance) should be equal to current bot's balance assert.ok( originalBotTokenBalances[0] @@ -971,18 +1051,40 @@ for (let i = 0; i < testData.length; i++) { testSpan.end(); }); - it("should clear orders successfully using intra-orderbook", async function () { + it(`should clear orders successfully using balancer router v${rpVersion}`, async function () { config.rpc = [rpc]; const viemClient = await viem.getPublicClient(); - const dataFetcher = await dataFetcherPromise; state.client = viemClient; + state.client.simulateContract = client.simulateContract; + const dataFetcher = await dataFetcherPromise; state.dataFetcher = dataFetcher; dataFetcher.web3Client.transport.retryCount = 3; const testSpan = tracer.startSpan("test-clearing"); + // set as the route for POC + balancerHelpers.BalancerRouter.prototype.getMarketPrice = async function (params) { + return Result.ok({ + route: [ + { + steps: [ + { + pool: "0x88c044fb203b58b12252be7242926b1eeb113b4a", + tokenOut: "0x4200000000000000000000000000000000000006", + isBuffer: false, + }, + ], + tokenIn: params.tokenIn.address, + exactAmountIn: params.swapAmount, + minAmountOut: 0n, + }, + ], + price: 100000000000000000000000n, + amountOut: 100000000000000000000000n, + }); + }; + // reset network before each test await helpers.reset(rpc, blockNumber); - // get bot signer const bot = botAddress ? (await viem.getTestClient({ account: botAddress })) @@ -1028,10 +1130,16 @@ for (let i = 0; i < testData.length; i++) { const orderbook = !orderbookAddress ? await deployOrderBookNPE2() : await ethers.getContractAt(orderbookAbi, orderbookAddress); + const arb = !arbAddress ? await arbDeploy(orderbook.address, config.routeProcessors[rpVersion]) : await ethers.getContractAt(ABI.Orderbook.Primary.Arb, arbAddress); + const balancerArb = await balancerArbDeploy( + orderbook.address, + config.routeProcessors[rpVersion], + ); + state.dispair = { interpreter: interpreter.address, store: store.address, @@ -1045,21 +1153,15 @@ for (let i = 0; i < testData.length; i++) { ERC20Artifact.abi, tokens[i].address, ); - if (i === 0) { - tokens[0].vaultIds = []; - for (let j = 0; j < tokens.length - 1; j++) { - tokens[0].vaultIds.push(ethers.BigNumber.from(randomUint256())); - } - } tokens[i].vaultId = ethers.BigNumber.from(randomUint256()); - i > 0 - ? (tokens[i].depositAmount = ethers.utils.parseUnits( - deposits[i] ?? "100", - tokens[i].decimals, - )) - : (tokens[i].depositAmount = ethers.utils - .parseUnits(deposits[i] ?? "100", tokens[i].decimals) - .div(4)); + tokens[i].depositAmount = ethers.utils.parseUnits( + deposits[i] ?? "100", + tokens[i].decimals, + ); + // owners.push( + // (await viem.getTestClient({account: addressesWithBalance[i]})).extend(publicActions).extend(walletActions) + // // await ethers.getImpersonatedSigner(addressesWithBalance[i]) + // ); owners.push(await ethers.getImpersonatedSigner(addressesWithBalance[i])); await network.provider.send("hardhat_setBalance", [ addressesWithBalance[i], @@ -1078,37 +1180,33 @@ for (let i = 0; i < testData.length; i++) { // all orders have WETH as output and other specified // tokens as input let orders = []; - const opposingOrders = []; for (let i = 1; i < tokens.length; i++) { - const depositConfigStruct1 = { + const depositConfigStruct = { token: tokens[i].address, vaultId: tokens[i].vaultId, amount: tokens[i].depositAmount.toString(), }; await tokens[i].contract .connect(owners[i]) - .approve(orderbook.address, depositConfigStruct1.amount); + .approve(orderbook.address, depositConfigStruct.amount); await orderbook .connect(owners[i]) .deposit2( - depositConfigStruct1.token, - depositConfigStruct1.vaultId, - depositConfigStruct1.amount, + depositConfigStruct.token, + depositConfigStruct.vaultId, + depositConfigStruct.amount, [], ); - // prebuild bytecode: "_ _: 0.5 max; :;" - const ratio1 = ethers.BigNumber.from("500000000000000000") - .toHexString() - .substring(2) - .padStart(64, "0"); // 0.5 - const maxOutput1 = "f".repeat(64); // max - const bytecode1 = `0x0000000000000000000000000000000000000000000000000000000000000002${maxOutput1}${ratio1}0000000000000000000000000000000000000000000000000000000000000015020000000c02020002011000000110000100000000`; - const addOrderConfig1 = { + // prebuild bytecode: "_ _: 0 max; :;" + const ratio = "0".repeat(64); // 0 + const maxOutput = "f".repeat(64); // max + const bytecode = `0x0000000000000000000000000000000000000000000000000000000000000002${maxOutput}${ratio}0000000000000000000000000000000000000000000000000000000000000015020000000c02020002011000000110000100000000`; + const addOrderConfig = { evaluable: { interpreter: interpreter.address, store: store.address, - bytecode: bytecode1, + bytecode, }, nonce: "0x" + "0".repeat(63) + "1", secret: "0x" + "0".repeat(63) + "1", @@ -1128,74 +1226,15 @@ for (let i = 0; i < testData.length; i++) { ], meta: encodeMeta("some_order"), }; - const tx1 = await orderbook.connect(owners[i]).addOrder2(addOrderConfig1, []); + const tx = await orderbook.connect(owners[i]).addOrder2(addOrderConfig, []); orders.push( await mockSgFromEvent( - await getEventArgs(tx1, "AddOrderV2", orderbook), - orderbook, - tokens.map((v) => ({ ...v.contract, knownSymbol: v.symbol })), - ), - ); - - // opposing orders - const depositConfigStruct2 = { - token: tokens[0].address, - vaultId: tokens[0].vaultIds[i - 1], - amount: tokens[0].depositAmount.toString(), - }; - await tokens[0].contract - .connect(owners[0]) - .approve(orderbook.address, depositConfigStruct2.amount); - await orderbook - .connect(owners[0]) - .deposit2( - depositConfigStruct2.token, - depositConfigStruct2.vaultId, - depositConfigStruct2.amount, - [], - ); - - // prebuild bytecode: "_ _: 1 max; :;" - const ratio2 = ethers.BigNumber.from("1000000000000000000") - .toHexString() - .substring(2) - .padStart(64, "0"); // 1 - const maxOutput2 = "f".repeat(64); // max - const bytecode2 = `0x0000000000000000000000000000000000000000000000000000000000000002${maxOutput2}${ratio2}0000000000000000000000000000000000000000000000000000000000000015020000000c02020002011000000110000100000000`; - const addOrderConfig2 = { - evaluable: { - interpreter: interpreter.address, - store: store.address, - bytecode: bytecode2, - }, - nonce: "0x" + "0".repeat(63) + "1", - secret: "0x" + "0".repeat(63) + "1", - validInputs: [ - { - token: tokens[i].address, - decimals: tokens[i].decimals, - vaultId: tokens[i].vaultId, - }, - ], - validOutputs: [ - { - token: tokens[0].address, - decimals: tokens[0].decimals, - vaultId: tokens[0].vaultIds[i - 1], - }, - ], - meta: encodeMeta("some_order"), - }; - const tx2 = await orderbook.connect(owners[0]).addOrder2(addOrderConfig2, []); - opposingOrders.push( - await mockSgFromEvent( - await getEventArgs(tx2, "AddOrderV2", orderbook), + await getEventArgs(tx, "AddOrderV2", orderbook), orderbook, tokens.map((v) => ({ ...v.contract, knownSymbol: v.symbol })), ), ); } - orders.push(...opposingOrders); // run the clearing process config.isTest = true; @@ -1206,8 +1245,10 @@ for (let i = 0; i < testData.length; i++) { config.lps = liquidityProviders; config.rpVersion = rpVersion; config.arbAddress = arb.address; + config.balancerArbAddress = balancerArb.address; config.orderbookAddress = orderbook.address; config.testBlockNumber = BigInt(blockNumber); + config.testBlockNumberInc = BigInt(blockNumber); // increments during test updating to new block height config.gasCoveragePercentage = "1"; config.viemClient = viemClient; config.dataFetcher = dataFetcher; @@ -1225,20 +1266,6 @@ for (let i = 0; i < testData.length; i++) { await orderManager.addOrders(orders); orders = orderManager.getNextRoundOrders(false); - // mock init quotes - orders.forEach((pair) => { - pair.takeOrder.quote = { - ratio: ethers.constants.Zero.toBigInt(), - maxOutput: tokens - .find( - (t) => - t.contract.address.toLowerCase() === - pair.sellToken.toLowerCase(), - ) - ?.depositAmount.mul("1" + "0".repeat(18 - pair.sellTokenDecimals)) - .toBigInt(), - }; - }); state.gasPrice = await bot.getGasPrice(); orderManager.getNextRoundOrders = () => orders; const rainSolver = new RainSolver( @@ -1254,63 +1281,52 @@ for (let i = 0; i < testData.length; i++) { const { results: reports } = await rainSolver.processNextRound(undefined, false); // should have cleared correct number of orders - assert.ok( - reports.length == (tokens.length - 1) * 2, - "Failed to clear all given orders", - ); + assert.ok(reports.length == tokens.length - 1, "Failed to clear all given orders"); // validate each cleared order - let c = 1; - let gasSpent = ethers.constants.Zero; let inputProfit = ethers.constants.Zero; + let gasSpent = ethers.constants.Zero; for (let i = 0; i < reports.length; i++) { const report = reports[i].value; - if (report.status !== ProcessOrderStatus.FoundOpportunity) continue; assert.equal(report.status, ProcessOrderStatus.FoundOpportunity); - const pair = `${tokens[0].symbol}/${tokens[c].symbol}`; + const pair = `${tokens[0].symbol}/${tokens[i + 1].symbol}`; const clearedAmount = ethers.BigNumber.from(report.clearedAmount); const outputVault = await orderbook.vaultBalance( - owners[c].address, - tokens[c].address, - tokens[c].vaultId, + owners[i + 1].address, + tokens[i + 1].address, + tokens[i + 1].vaultId, ); const inputVault = await orderbook.vaultBalance( owners[0].address, tokens[0].address, tokens[0].vaultId, ); - const botTokenBalance = await tokens[c].contract.balanceOf(bot.account.address); + const botTokenBalance = await tokens[i + 1].contract.balanceOf( + bot.account.address, + ); assert.equal(report.tokenPair, pair); // should have cleared equal to vault balance or lower assert.ok( - tokens[c].depositAmount.gte(clearedAmount), + tokens[i + 1].depositAmount.gte(clearedAmount), `Did not clear expected amount for: ${pair}`, ); assert.ok( - outputVault.eq(tokens[c].depositAmount.sub(clearedAmount)), + outputVault.eq(tokens[i + 1].depositAmount.sub(clearedAmount)), `Unexpected current output vault balance: ${pair}`, ); assert.ok(inputVault.eq(0), `Unexpected current input vault balance: ${pair}`); assert.ok( - originalBotTokenBalances[c].eq(botTokenBalance), - `Unexpected current bot ${tokens[c].symbol} balance`, + originalBotTokenBalances[i + 1].eq(botTokenBalance), + `Unexpected current bot ${tokens[i + 1].symbol} balance`, ); // collect all bot's input income (bounty) and gas cost inputProfit = inputProfit.add(ethers.utils.parseUnits(report.inputTokenIncome)); gasSpent = gasSpent.add(ethers.utils.parseUnits(report.gasCost.toString())); - c++; } - // all input bounties (+ old balance) should be equal to current bot's balance - assert.ok( - originalBotTokenBalances[0] - .add(inputProfit) - .eq(await tokens[0].contract.balanceOf(bot.account.address)), - "Unexpected bot bounty", - ); testSpan.end(); }); From 2fbd28dd1043a317fde4f97d35083487f5a7f3a2 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Wed, 20 Aug 2025 18:10:03 +0000 Subject: [PATCH 4/6] update --- src/core/modes/index.test.ts | 1 + src/core/modes/index.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/modes/index.test.ts b/src/core/modes/index.test.ts index 54fa3342..c1f9d244 100644 --- a/src/core/modes/index.test.ts +++ b/src/core/modes/index.test.ts @@ -33,6 +33,7 @@ describe("Test findBestTrade", () => { mockRainSolver = { appOptions: { rpOnly: false, + balancerArbAddress: "0xBalancerArb", }, state: {}, } as any; diff --git a/src/core/modes/index.ts b/src/core/modes/index.ts index 12a234a4..1e51aaf4 100644 --- a/src/core/modes/index.ts +++ b/src/core/modes/index.ts @@ -54,7 +54,7 @@ export async function findBestTrade( fromToken, ), // include balancer trade only if balancer router is available for the operating chain - ...(this.state.balancerRouter + ...(this.state.balancerRouter && this.appOptions.balancerArbAddress ? [ findBestBalancerTrade.call( this, From 8ec3e6450be46732e61095c4488a49facbc16cfc Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Sat, 23 Aug 2025 01:52:19 +0000 Subject: [PATCH 5/6] update --- scripts/downtime.ts | 2 +- src/core/modes/balancer/simulate.test.ts | 14 ++--- src/core/modes/balancer/simulate.ts | 22 ++++---- src/router/balancer.test.ts | 20 +++---- src/router/balancer.ts | 67 ++++++++++++++++++------ src/router/marketPrice.test.ts | 8 +-- src/router/marketPrice.ts | 41 +++++---------- test/e2e/e2e.test.js | 2 +- 8 files changed, 95 insertions(+), 81 deletions(-) diff --git a/scripts/downtime.ts b/scripts/downtime.ts index cfabbf5f..dac25097 100644 --- a/scripts/downtime.ts +++ b/scripts/downtime.ts @@ -8,7 +8,7 @@ import { DEFAULT_PAGE_SIZE, getTxsQuery } from "../src/subgraph/query"; config(); -const DURATION = process.env.DURATION ? parseInt(process.env.DURATION) : 30; // 7 days default +const DURATION = process.env.DURATION ? parseInt(process.env.DURATION) : 7; // 7 days default const THRESHOLD = (process.env.THRESHOLD ? parseInt(process.env.THRESHOLD) : 60) * 60 * 1000; // 60 minutes default const subgraphs = JSON.parse(process.env.SUBGRAPHS ?? "{}") as Record; diff --git a/src/core/modes/balancer/simulate.test.ts b/src/core/modes/balancer/simulate.test.ts index c1cbb7b6..2a04818d 100644 --- a/src/core/modes/balancer/simulate.test.ts +++ b/src/core/modes/balancer/simulate.test.ts @@ -65,7 +65,7 @@ describe("Test trySimulateTrade", () => { client: {}, balancerRouter: { routerAddress: "0xbalancerRouter", - getMarketPrice: vi.fn(), + tryQuote: vi.fn(), visualizeRoute: vi.fn().mockReturnValue(["visualRoute"]), }, }, @@ -91,7 +91,7 @@ describe("Test trySimulateTrade", () => { }); it("should return NoRoute if Router.findBestRoute returns NoWay", async () => { - (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + (solver.state.balancerRouter?.tryQuote as Mock).mockReturnValueOnce( Result.err( new BalancerRouterError( "Failed to fetch balancer routes", @@ -111,7 +111,7 @@ describe("Test trySimulateTrade", () => { }); it("should return OrderRatioGreaterThanMarketPrice if price < order ratio", async () => { - (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + (solver.state.balancerRouter?.tryQuote as Mock).mockReturnValueOnce( Result.ok({ route: [], amountOut: 1n * ONE18, @@ -135,7 +135,7 @@ describe("Test trySimulateTrade", () => { }); it("should return NoOpportunity if initial dryrun fails", async () => { - (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + (solver.state.balancerRouter?.tryQuote as Mock).mockReturnValueOnce( Result.ok({ route: [], amountOut: 20n * ONE18, @@ -162,7 +162,7 @@ describe("Test trySimulateTrade", () => { }); it("should return ok result if all steps succeed with gasCoveragePercentage 0", async () => { - (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + (solver.state.balancerRouter?.tryQuote as Mock).mockReturnValueOnce( Result.ok({ route: ["route"], amountOut: 20n * ONE18, @@ -228,7 +228,7 @@ describe("Test trySimulateTrade", () => { }); it("should return ok result if all steps succeed with gasCoveragePercentage not 0", async () => { - (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + (solver.state.balancerRouter?.tryQuote as Mock).mockReturnValueOnce( Result.ok({ route: [], amountOut: 20n * ONE18, @@ -278,7 +278,7 @@ describe("Test trySimulateTrade", () => { }); it("should return NoOpportunity if final dryrun fails when gasCoveragePercentage is not 0", async () => { - (solver.state.balancerRouter?.getMarketPrice as Mock).mockReturnValueOnce( + (solver.state.balancerRouter?.tryQuote as Mock).mockReturnValueOnce( Result.ok({ route: [], amountOut: 20n * ONE18, diff --git a/src/core/modes/balancer/simulate.ts b/src/core/modes/balancer/simulate.ts index db74f2f5..76011442 100644 --- a/src/core/modes/balancer/simulate.ts +++ b/src/core/modes/balancer/simulate.ts @@ -57,7 +57,7 @@ export async function trySimulateTrade( const maximumInput = scaleFrom18(maximumInputFixed, orderDetails.sellTokenDecimals); spanAttributes["amountIn"] = formatUnits(maximumInputFixed, 18); - const routeResult = await this.state.balancerRouter!.getMarketPrice( + const quoteResult = await this.state.balancerRouter!.tryQuote( { tokenIn: fromToken, tokenOut: toToken, @@ -65,16 +65,16 @@ export async function trySimulateTrade( }, signer, ); - if (routeResult.isErr()) { - spanAttributes["error"] = routeResult.error.message; + if (quoteResult.isErr()) { + spanAttributes["error"] = quoteResult.error.message; let reason = BalancerRouterSimulationHaltReason.NoOpportunity; - if (routeResult.error.type === BalancerRouterErrorType.NoRouteFound) { + if (quoteResult.error.type === BalancerRouterErrorType.NoRouteFound) { spanAttributes["route"] = "no-way"; reason = BalancerRouterSimulationHaltReason.NoRoute; - } else if (routeResult.error.type === BalancerRouterErrorType.FetchFailed) { + } else if (quoteResult.error.type === BalancerRouterErrorType.FetchFailed) { reason = BalancerRouterSimulationHaltReason.FetchFailed; - } else if (routeResult.error.type === BalancerRouterErrorType.SwapQueryFailed) { + } else if (quoteResult.error.type === BalancerRouterErrorType.SwapQueryFailed) { reason = BalancerRouterSimulationHaltReason.SwapQueryFailed; } else { reason = BalancerRouterSimulationHaltReason.NoOpportunity; @@ -87,16 +87,16 @@ export async function trySimulateTrade( }); } - const route = routeResult.value; - const amountOut = route.amountOut; - const price = route.price; + const quote = quoteResult.value; + const amountOut = quote.amountOut; + const price = quote.price; spanAttributes["amountOut"] = formatUnits(amountOut, toToken.decimals); spanAttributes["marketPrice"] = formatUnits(price, 18); const routeVisual: string[] = []; try { - BalancerRouter.visualizeRoute(route.route, this.state.watchedTokens).forEach((v) => { + BalancerRouter.visualizeRoute(quote.route, this.state.watchedTokens).forEach((v) => { routeVisual.push(v); }); } catch { @@ -126,7 +126,7 @@ export async function trySimulateTrade( orders, data: encodeAbiParameters( [{ type: "address" }, ABI.BalancerBatchRouter.Structs.SwapPathExactAmountIn], - [balancerRouter, route.route[0]], + [balancerRouter, quote.route[0]], ), }; diff --git a/src/router/balancer.test.ts b/src/router/balancer.test.ts index 21c3846c..761b5f7f 100644 --- a/src/router/balancer.test.ts +++ b/src/router/balancer.test.ts @@ -32,7 +32,7 @@ describe("test BalancerRouter", () => { expect(router).toBeInstanceOf(BalancerRouter); expect(router.chainId).toBe(chainId); expect(router.protocolVersion).toBe(3); - expect(router.routeTime).toBe(60_000); + expect(router.routeTime).toBe(300_000); expect(router.routerAddress).toBeDefined(); expect(router.balancerApi).toBeDefined(); expect(router.cache).toBeInstanceOf(Map); @@ -427,6 +427,7 @@ describe("test BalancerRouter", () => { ], }, ], + altRoutes: [], validUntil: Date.now() - 1000, // Expired 1 second ago price: 2000000000000000000000n, }; @@ -525,7 +526,7 @@ describe("test BalancerRouter", () => { }); }); - describe("test getMarketPrice method", () => { + describe("test tryQuote method", () => { let router: BalancerRouter; let mockBalancerApi: { sorSwapPaths: { fetchSorSwapPaths: Mock } }; let mockSigner: any; @@ -582,7 +583,7 @@ describe("test BalancerRouter", () => { mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); mockSigner.simulateContract.mockResolvedValue(mockSimulationResult); - const result = await router.getMarketPrice( + const result = await router.tryQuote( { tokenIn: mockTokenIn, tokenOut: mockTokenOut, @@ -625,6 +626,7 @@ describe("test BalancerRouter", () => { ], }, ], + altRoutes: [], validUntil: Date.now() + 60000, price: 3000000000000000000000n, onchainPrice, @@ -634,7 +636,7 @@ describe("test BalancerRouter", () => { const cacheKey = `${mockTokenIn.address.toLowerCase()}/${mockTokenOut.address.toLowerCase()}`; router.cache.set(cacheKey, cachedRoute); - const result = await router.getMarketPrice( + const result = await router.tryQuote( { tokenIn: mockTokenIn, tokenOut: mockTokenOut, @@ -677,7 +679,7 @@ describe("test BalancerRouter", () => { const customAddress = "0x9999999999999999999999999999999999999999" as `0x${string}`; - const result = await router.getMarketPrice( + const result = await router.tryQuote( { tokenIn: mockTokenIn, tokenOut: mockTokenOut, @@ -715,7 +717,7 @@ describe("test BalancerRouter", () => { result: [null, null, []], // Invalid simulation result }); - const result = await router.getMarketPrice( + const result = await router.tryQuote( { tokenIn: mockTokenIn, tokenOut: mockTokenOut, @@ -736,7 +738,7 @@ describe("test BalancerRouter", () => { const mockError = new Error("Network error"); mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockRejectedValue(mockError); - const result = await router.getMarketPrice( + const result = await router.tryQuote( { tokenIn: mockTokenIn, tokenOut: mockTokenOut, @@ -770,7 +772,7 @@ describe("test BalancerRouter", () => { mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); mockSigner.simulateContract.mockRejectedValue(simulationError); - const result = await router.getMarketPrice( + const result = await router.tryQuote( { tokenIn: mockTokenIn, tokenOut: mockTokenOut, @@ -810,7 +812,7 @@ describe("test BalancerRouter", () => { mockBalancerApi.sorSwapPaths.fetchSorSwapPaths.mockResolvedValue(mockSorPaths); mockSigner.simulateContract.mockResolvedValue(mockSimulationResult); - const result = await router.getMarketPrice( + const result = await router.tryQuote( { tokenIn: mockTokenIn, tokenOut: mockTokenOut, diff --git a/src/router/balancer.ts b/src/router/balancer.ts index 937a6e93..775ed028 100644 --- a/src/router/balancer.ts +++ b/src/router/balancer.ts @@ -42,8 +42,8 @@ export type FetchBalancerRoutesParams = { swapAmount: bigint; }; -/** Represents the parameters for getting the best Balancer route */ -export type GetBestBalancerRouteParams = { +/** Represents the parameters for quoting Balancer */ +export type BalancerQuoteParams = { tokenIn: TokenDetails | SushiToken; tokenOut: TokenDetails | SushiToken; swapAmount: bigint; @@ -54,6 +54,8 @@ export type GetBestBalancerRouteParams = { export type BalancerCachedRoute = { /** The route paths details used for getting calldata */ route: BalancerRouterPath[]; + /** The alternative route paths details */ + altRoutes: BalancerRouterPath[]; /** The timestamp until which the route is valid */ validUntil: number; /** The price of the route from balancer API */ @@ -83,10 +85,10 @@ export enum BalancerRouterErrorType { * * @example * ```typescript - * // with cause + * // without cause * throw new BalancerRouterError("msg", BalancerRouterErrorType); * - * // without cause + * // with cause * throw new BalancerRouterError("msg", BalancerRouterErrorType, originalError); * ``` */ @@ -112,7 +114,7 @@ export class BalancerRouter { /** The protocol version of the balancer */ readonly protocolVersion = 3 as const; /** The duration for which a route is considered valid in cache */ - readonly routeTime = 60_000 as const; // 1 minute in milliseconds + readonly routeTime = 300_000 as const; // 5 minutes in milliseconds /** The Balancer API instance */ readonly balancerApi: BalancerApi; /** The cache for storing previously fetched routes that are valid until specified timestamp */ @@ -146,12 +148,12 @@ export class BalancerRouter { } /** - * Gets the balancer market price for a token pair by simulating balancer swap query - * @param params The parameters for getting the best Balancer route and market price + * Gets the balancer market quote for a token pair by simulating balancer swap query + * @param params The parameters for getting the best Balancer market quote * @param signer The signer instance */ - async getMarketPrice( - params: GetBestBalancerRouteParams, + async tryQuote( + params: BalancerQuoteParams, signer: PublicClient | RainSolverSigner, address: `0x${string}` = `0x${"1".repeat(40)}`, ): Promise< @@ -172,12 +174,38 @@ export class BalancerRouter { amountOut: route.value.route[0].minAmountOut, }); } - const result = await signer.simulateContract({ - address: this.routerAddress, - abi: ABI.BalancerBatchRouter.Primary.BatchRouterV3, - functionName: "querySwapExactIn", - args: [route.value.route, signer.account?.address ?? address, "0x"], - }); + + // fallback to alt routes if the best one fails + const { result, pickedRoute } = await (async () => { + let err: any = undefined; + const allRoutes = [...route.value.route, ...route.value.altRoutes]; + for (let i = 0; i < allRoutes.length + 1; i++) { + try { + const result = await signer.simulateContract({ + address: this.routerAddress, + abi: ABI.BalancerBatchRouter.Primary.BatchRouterV3, + functionName: "querySwapExactIn", + args: [[allRoutes[i]], signer.account?.address ?? address, "0x"], + }); + if (i > 0) { + // swap the routes so that next time the working one is tried first + [route.value.route, route.value.altRoutes[i - 1]] = [ + [allRoutes[i]], + route.value.route[0], + ]; + // move the failed alt route to the end of alt routes + route.value.altRoutes.push(...route.value.altRoutes.splice(i - 1, 1)); + } + return { + result, + pickedRoute: allRoutes[i], + }; + } catch (error) { + if (!err) err = error; + } + } + throw err; + })(); const [price, amountOut] = (() => { try { @@ -192,7 +220,7 @@ export class BalancerRouter { } })(); - return Result.ok({ price, route: route.value.route, amountOut }); + return Result.ok({ price, route: [pickedRoute], amountOut }); } catch (error: any) { return Result.err( new BalancerRouterError( @@ -209,7 +237,7 @@ export class BalancerRouter { * @param params The parameters for getting the best Balancer route */ async getBestRoute( - params: GetBestBalancerRouteParams, + params: BalancerQuoteParams, ): Promise> { const key = `${params.tokenIn.address.toLowerCase()}/${params.tokenOut.address.toLowerCase()}`; @@ -241,6 +269,11 @@ export class BalancerRouter { minAmountOut, }, ], + altRoutes: balancerSortedRoutes.value.slice(1).map((r) => ({ + ...r, + exactAmountIn: params.swapAmount, + minAmountOut, + })), validUntil: Date.now() + this.routeTime, price, }; diff --git a/src/router/marketPrice.test.ts b/src/router/marketPrice.test.ts index 65db234f..8ad45860 100644 --- a/src/router/marketPrice.test.ts +++ b/src/router/marketPrice.test.ts @@ -60,10 +60,7 @@ describe("Test getMarketPrice", () => { describe("happy", () => { it("should return 1 if from/to tokens are the same", async () => { const result = await getMarketPrice.call(mockSharedState, mockFromToken, mockFromToken); - expect(result).toEqual({ - price: "1", - amountOut: "1", - }); + expect(result).toEqual({ price: "1" }); }); it("should call dataFetcher methods with correct parameters", async () => { @@ -115,10 +112,7 @@ describe("Test getMarketPrice", () => { const result = await getMarketPrice.call(mockSharedState, mockFromToken, mockToToken); expect(result).toHaveProperty("price"); - expect(result).toHaveProperty("amountOut"); expect(typeof result?.price).toBe("string"); - expect(typeof result?.amountOut).toBe("string"); - expect(result?.amountOut).toBe("2000"); expect(result?.price).toBe("2000"); }); diff --git a/src/router/marketPrice.ts b/src/router/marketPrice.ts index 3c12e4f3..364c4a56 100644 --- a/src/router/marketPrice.ts +++ b/src/router/marketPrice.ts @@ -1,7 +1,7 @@ +import { ONE18 } from "../math"; import { SharedState } from "../state"; import { Token } from "sushi/currency"; import { ChainId, Router } from "sushi"; -import { scaleTo18, ONE18 } from "../math"; import { PoolBlackList, RPoolFilter } from "."; import { formatUnits, parseUnits, maxUint256 } from "viem"; @@ -16,13 +16,10 @@ export async function getMarketPrice( fromToken: Token, toToken: Token, blockNumber?: bigint, -): Promise<{ price: string; amountOut: string } | undefined> { +): Promise<{ price: string } | undefined> { // return early if from and to tokens are the same if (fromToken.address.toLowerCase() === toToken.address.toLowerCase()) { - return { - price: "1", - amountOut: "1", - }; + return { price: "1" }; } const amountIn = parseUnits("1", fromToken.decimals); @@ -44,32 +41,20 @@ export async function getMarketPrice( if (route.status == "NoWay") { // try balancer if (this.balancerRouter) { - const balancerPriceResult = await this.balancerRouter.getMarketPrice( - { - tokenIn: fromToken, - tokenOut: toToken, - swapAmount: amountIn, - }, - this.client, - ); - if (balancerPriceResult.isOk()) { - const price = scaleTo18(balancerPriceResult.value.amountOut, toToken.decimals); - return { - price: formatUnits(price, 18), - amountOut: formatUnits( - balancerPriceResult.value.amountOut, - toToken.decimals, - ), - }; + const balancerRouteResult = await this.balancerRouter.getBestRoute({ + tokenIn: fromToken, + tokenOut: toToken, + swapAmount: amountIn, + }); + if (balancerRouteResult.isOk()) { + const price = + balancerRouteResult.value.onchainPrice ?? balancerRouteResult.value.price; + return { price: formatUnits(price, 18) }; } } return; } else { - const price = scaleTo18(route.amountOutBI, toToken.decimals); - return { - price: formatUnits(price, 18), - amountOut: formatUnits(route.amountOutBI, toToken.decimals), - }; + return { price: formatUnits(route.amountOutBI, toToken.decimals) }; } } catch (error) { return; diff --git a/test/e2e/e2e.test.js b/test/e2e/e2e.test.js index 170f71ea..97eee18f 100644 --- a/test/e2e/e2e.test.js +++ b/test/e2e/e2e.test.js @@ -1062,7 +1062,7 @@ for (let i = 0; i < testData.length; i++) { const testSpan = tracer.startSpan("test-clearing"); // set as the route for POC - balancerHelpers.BalancerRouter.prototype.getMarketPrice = async function (params) { + balancerHelpers.BalancerRouter.prototype.tryQuote = async function (params) { return Result.ok({ route: [ { From 78df4f588f6df49833e55432d228049692e1f951 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Tue, 26 Aug 2025 18:24:22 +0000 Subject: [PATCH 6/6] Update .env.config.yaml --- .env.config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.config.yaml b/.env.config.yaml index f501a315..b2954ffd 100644 --- a/.env.config.yaml +++ b/.env.config.yaml @@ -25,7 +25,7 @@ retries: $RETRIES maxRatio: $MAX_RATIO rpOnly: $RP_ONLY ownerProfile: $OWNER_PROFILE -selfFundOrders: $SELF_FUND_ORDERS +selfFundVaults: $SELF_FUND_ORDERS sgFilter: includeOrders: $INCLUDE_ORDERS excludeOrders: $EXCLUDE_ORDERS