@paraswap/dex-lib 5.0.6-fallback-encoding.0 → 5.0.6-fallback-encoding.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/config.js +3 -2
- package/build/config.js.map +1 -1
- package/build/executor/Executor02BytecodeBuilder.d.ts +15 -0
- package/build/executor/Executor02BytecodeBuilder.js +117 -1
- package/build/executor/Executor02BytecodeBuilder.js.map +1 -1
- package/build/executor/ExecutorDetector.js +7 -6
- package/build/executor/ExecutorDetector.js.map +1 -1
- package/build/executor/fallback-routes/generate.d.ts +5 -0
- package/build/executor/fallback-routes/generate.js +294 -0
- package/build/executor/fallback-routes/generate.js.map +1 -0
- package/build/executor/fallback-routes/scenarios.d.ts +7 -0
- package/build/executor/fallback-routes/scenarios.js +209 -0
- package/build/executor/fallback-routes/scenarios.js.map +1 -0
- package/build/executor/fallback-routes/types.d.ts +45 -0
- package/build/executor/fallback-routes/types.js +3 -0
- package/build/executor/fallback-routes/types.js.map +1 -0
- package/build/generic-swap-transaction-builder.js +1 -2
- package/build/generic-swap-transaction-builder.js.map +1 -1
- package/build/implementations/local-paraswap-sdk.d.ts +1 -0
- package/build/implementations/local-paraswap-sdk.js +7 -1
- package/build/implementations/local-paraswap-sdk.js.map +1 -1
- package/build/types.d.ts +1 -4
- package/package.json +2 -2
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.generateAllRoutes = generateAllRoutes;
|
|
40
|
+
/* eslint-disable no-console */
|
|
41
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
42
|
+
dotenv_1.default.config();
|
|
43
|
+
/**
|
|
44
|
+
* Fallback test-route generator.
|
|
45
|
+
*
|
|
46
|
+
* For each scenario in ./scenarios.ts: price every hop (and split slice) live
|
|
47
|
+
* on Arbitrum via LocalParaswapSDK, assemble a multi-hop OptimalRate, and
|
|
48
|
+
* replace the marked member with a fabricated always-reverting `Native` quote
|
|
49
|
+
* whose revertable fallback is the real priced quote. Writes ./routes.json,
|
|
50
|
+
* consumed by src/executor/fallback-routes-live-e2e.test.ts.
|
|
51
|
+
*
|
|
52
|
+
* Run: GENERATE_FALLBACK_ROUTES=1 npx jest src/executor/fallback-routes/generate-routes.test.ts --forceExit
|
|
53
|
+
* Requires .env: HTTP_PROVIDER_42161.
|
|
54
|
+
*/
|
|
55
|
+
const fs = __importStar(require("fs"));
|
|
56
|
+
const path = __importStar(require("path"));
|
|
57
|
+
const abi_1 = require("@ethersproject/abi");
|
|
58
|
+
const core_1 = require("@paraswap/core");
|
|
59
|
+
const local_paraswap_sdk_1 = require("../../implementations/local-paraswap-sdk");
|
|
60
|
+
const constants_1 = require("../../constants");
|
|
61
|
+
const utils_1 = require("../../utils");
|
|
62
|
+
const scenarios_1 = require("./scenarios");
|
|
63
|
+
const NETWORK = constants_1.Network.ARBITRUM;
|
|
64
|
+
const PRICING_DEX = 'UniswapV3';
|
|
65
|
+
const AUGUSTUS_V6 = '0x6a000f20005980200259b80c5102003040001068';
|
|
66
|
+
const WETH_ARBITRUM = '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1';
|
|
67
|
+
// Local token map (generate.ts is compiled as source, so it cannot import
|
|
68
|
+
// tests/constants-e2e which lives outside the tsconfig rootDir).
|
|
69
|
+
const TOKENS = {
|
|
70
|
+
ETH: {
|
|
71
|
+
address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
|
|
72
|
+
decimals: 18,
|
|
73
|
+
},
|
|
74
|
+
WETH: { address: WETH_ARBITRUM, decimals: 18 },
|
|
75
|
+
USDC: {
|
|
76
|
+
address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
|
|
77
|
+
decimals: 6,
|
|
78
|
+
},
|
|
79
|
+
USDT: {
|
|
80
|
+
address: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
|
|
81
|
+
decimals: 6,
|
|
82
|
+
},
|
|
83
|
+
WBTC: {
|
|
84
|
+
address: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f',
|
|
85
|
+
decimals: 8,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
const erc20 = new abi_1.Interface(['function transferFrom(address,address,uint256)']);
|
|
89
|
+
// A quote whose calldata always reverts on-chain: transferFrom with no allowance.
|
|
90
|
+
function fabricatedRevertingQuote(hopSrcToken, amount) {
|
|
91
|
+
return {
|
|
92
|
+
quote: {
|
|
93
|
+
txRequest: {
|
|
94
|
+
// eee has no code — use WETH as the reverting ERC20 target for ETH hops
|
|
95
|
+
target: (0, utils_1.isETHAddress)(hopSrcToken) ? WETH_ARBITRUM : hopSrcToken,
|
|
96
|
+
calldata: erc20.encodeFunctionData('transferFrom', [
|
|
97
|
+
'0x000000000000000000000000000000000000dEaD',
|
|
98
|
+
'0x000000000000000000000000000000000000bEEF',
|
|
99
|
+
amount,
|
|
100
|
+
]),
|
|
101
|
+
value: '0',
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// One SDK (with initialized pricing) per venue, created lazily.
|
|
107
|
+
class SdkRegistry {
|
|
108
|
+
sdks = {};
|
|
109
|
+
async get(dexKey) {
|
|
110
|
+
if (!this.sdks[dexKey]) {
|
|
111
|
+
const sdk = new local_paraswap_sdk_1.LocalParaswapSDK(NETWORK, [dexKey], '');
|
|
112
|
+
await sdk.initializePricing?.();
|
|
113
|
+
this.sdks[dexKey] = sdk;
|
|
114
|
+
}
|
|
115
|
+
return this.sdks[dexKey];
|
|
116
|
+
}
|
|
117
|
+
async release() {
|
|
118
|
+
for (const sdk of Object.values(this.sdks)) {
|
|
119
|
+
await sdk.releaseResources?.();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Build the swaps (hops) of one route, pricing every slice live. Returns the
|
|
124
|
+
// route's swaps, its output amount and the latest pricing block.
|
|
125
|
+
async function buildRouteSwaps(sdks, scenarioName, path, hops, routeAmount) {
|
|
126
|
+
const tokens = TOKENS;
|
|
127
|
+
if (hops.length !== path.length - 1) {
|
|
128
|
+
throw new Error(`${scenarioName}: hops must match path segments`);
|
|
129
|
+
}
|
|
130
|
+
let runningAmount = routeAmount;
|
|
131
|
+
let blockNumber = 0;
|
|
132
|
+
const swaps = [];
|
|
133
|
+
for (let i = 0; i < hops.length; i++) {
|
|
134
|
+
const hop = hops[i];
|
|
135
|
+
const from = tokens[path[i]];
|
|
136
|
+
const to = tokens[path[i + 1]];
|
|
137
|
+
const split = hop.split ?? [100];
|
|
138
|
+
if (split.reduce((a, b) => a + b, 0) !== 100) {
|
|
139
|
+
throw new Error(`${scenarioName}: hop ${i} split must sum to 100`);
|
|
140
|
+
}
|
|
141
|
+
// Slice amounts; last slice takes the remainder to preserve the total.
|
|
142
|
+
const slices = split.map(p => (runningAmount * BigInt(p)) / 100n);
|
|
143
|
+
slices[slices.length - 1] =
|
|
144
|
+
runningAmount - slices.slice(0, -1).reduce((a, b) => a + b, 0n);
|
|
145
|
+
const members = [];
|
|
146
|
+
let hopDestTotal = 0n;
|
|
147
|
+
const priceSlice = async (dexKey, amount) => {
|
|
148
|
+
const sdk = await sdks.get(dexKey);
|
|
149
|
+
const priced = await sdk.getPrices(from, to, amount, constants_1.SwapSide.SELL, constants_1.ContractMethod.swapExactAmountIn);
|
|
150
|
+
blockNumber = priced.blockNumber;
|
|
151
|
+
return priced.bestRoute[0].swaps[0].swapExchanges[0];
|
|
152
|
+
};
|
|
153
|
+
for (let j = 0; j < slices.length; j++) {
|
|
154
|
+
const memberDex = hop.pricingDexes?.[j] ?? PRICING_DEX;
|
|
155
|
+
const realSe = await priceSlice(memberDex, slices[j]);
|
|
156
|
+
const member = {
|
|
157
|
+
...realSe,
|
|
158
|
+
srcAmount: slices[j].toString(),
|
|
159
|
+
percent: split[j],
|
|
160
|
+
};
|
|
161
|
+
if (hop.fabricatedMemberIndex === j) {
|
|
162
|
+
// The fallback may be priced on a different venue (e.g. a raw-ETH one).
|
|
163
|
+
const fallbackSe = hop.fallbackPricingDex
|
|
164
|
+
? {
|
|
165
|
+
...(await priceSlice(hop.fallbackPricingDex, slices[j])),
|
|
166
|
+
srcAmount: slices[j].toString(),
|
|
167
|
+
percent: split[j],
|
|
168
|
+
}
|
|
169
|
+
: member;
|
|
170
|
+
hopDestTotal += BigInt(fallbackSe.destAmount);
|
|
171
|
+
members.push({
|
|
172
|
+
exchange: 'Native',
|
|
173
|
+
srcAmount: member.srcAmount,
|
|
174
|
+
destAmount: fallbackSe.destAmount,
|
|
175
|
+
percent: split[j],
|
|
176
|
+
data: fabricatedRevertingQuote(from.address, slices[j]),
|
|
177
|
+
fallback: fallbackSe, // the real quote is the revertable fallback
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
hopDestTotal += BigInt(realSe.destAmount);
|
|
182
|
+
members.push(member);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
swaps.push({
|
|
186
|
+
srcToken: from.address,
|
|
187
|
+
srcDecimals: from.decimals,
|
|
188
|
+
destToken: to.address,
|
|
189
|
+
destDecimals: to.decimals,
|
|
190
|
+
swapExchanges: members,
|
|
191
|
+
});
|
|
192
|
+
runningAmount = hopDestTotal;
|
|
193
|
+
}
|
|
194
|
+
return { swaps, out: runningAmount, blockNumber };
|
|
195
|
+
}
|
|
196
|
+
async function generateScenario(sdks, spec) {
|
|
197
|
+
const tokens = TOKENS;
|
|
198
|
+
const routeSpecs = spec.routes ?? [
|
|
199
|
+
{ percent: 100, path: spec.path, hops: spec.hops },
|
|
200
|
+
];
|
|
201
|
+
if (routeSpecs.reduce((a, r) => a + r.percent, 0) !== 100) {
|
|
202
|
+
throw new Error(`${spec.name}: route percents must sum to 100`);
|
|
203
|
+
}
|
|
204
|
+
const srcSym = routeSpecs[0].path[0];
|
|
205
|
+
const destSym = routeSpecs[0].path[routeSpecs[0].path.length - 1];
|
|
206
|
+
if (!routeSpecs.every(r => r.path[0] === srcSym && r.path[r.path.length - 1] === destSym)) {
|
|
207
|
+
throw new Error(`${spec.name}: all routes must share src and dest tokens`);
|
|
208
|
+
}
|
|
209
|
+
// Split the src amount across routes; last route takes the remainder.
|
|
210
|
+
const total = BigInt(spec.amount);
|
|
211
|
+
const routeAmounts = routeSpecs.map(r => (total * BigInt(r.percent)) / 100n);
|
|
212
|
+
routeAmounts[routeAmounts.length - 1] =
|
|
213
|
+
total - routeAmounts.slice(0, -1).reduce((a, b) => a + b, 0n);
|
|
214
|
+
let blockNumber = 0;
|
|
215
|
+
let destAmount = 0n;
|
|
216
|
+
const bestRoute = [];
|
|
217
|
+
for (let i = 0; i < routeSpecs.length; i++) {
|
|
218
|
+
const r = routeSpecs[i];
|
|
219
|
+
const built = await buildRouteSwaps(sdks, spec.name, r.path, r.hops, routeAmounts[i]);
|
|
220
|
+
blockNumber = built.blockNumber;
|
|
221
|
+
destAmount += built.out;
|
|
222
|
+
bestRoute.push({ percent: r.percent, swaps: built.swaps });
|
|
223
|
+
}
|
|
224
|
+
const src = tokens[srcSym];
|
|
225
|
+
const dest = tokens[destSym];
|
|
226
|
+
const priceRoute = {
|
|
227
|
+
blockNumber,
|
|
228
|
+
network: NETWORK,
|
|
229
|
+
srcToken: src.address,
|
|
230
|
+
srcDecimals: src.decimals,
|
|
231
|
+
srcAmount: spec.amount,
|
|
232
|
+
destToken: dest.address,
|
|
233
|
+
destDecimals: dest.decimals,
|
|
234
|
+
destAmount: destAmount.toString(),
|
|
235
|
+
bestRoute,
|
|
236
|
+
gasCostUSD: '0',
|
|
237
|
+
gasCost: '0',
|
|
238
|
+
others: [],
|
|
239
|
+
side: constants_1.SwapSide.SELL,
|
|
240
|
+
contractAddress: AUGUSTUS_V6,
|
|
241
|
+
tokenTransferProxy: '',
|
|
242
|
+
version: core_1.ParaSwapVersion.V6,
|
|
243
|
+
contractMethod: constants_1.ContractMethod.swapExactAmountIn,
|
|
244
|
+
partner: 'test',
|
|
245
|
+
maxImpactReached: false,
|
|
246
|
+
hmac: '0',
|
|
247
|
+
srcUSD: '0',
|
|
248
|
+
destUSD: '0',
|
|
249
|
+
};
|
|
250
|
+
return {
|
|
251
|
+
name: spec.name,
|
|
252
|
+
description: spec.description,
|
|
253
|
+
network: NETWORK,
|
|
254
|
+
generatedAt: new Date().toISOString(),
|
|
255
|
+
slippageBps: spec.slippageBps ?? 300,
|
|
256
|
+
expectGroup: spec.expectGroup ?? true,
|
|
257
|
+
expectSuccess: spec.expectSuccess ?? true,
|
|
258
|
+
priceRoute,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
async function generateAllRoutes() {
|
|
262
|
+
const sdks = new SdkRegistry();
|
|
263
|
+
const routes = [];
|
|
264
|
+
const failures = [];
|
|
265
|
+
try {
|
|
266
|
+
for (const spec of scenarios_1.SCENARIOS) {
|
|
267
|
+
try {
|
|
268
|
+
console.log(`generating: ${spec.name} ...`);
|
|
269
|
+
routes.push(await generateScenario(sdks, spec));
|
|
270
|
+
}
|
|
271
|
+
catch (e) {
|
|
272
|
+
console.error(`FAILED: ${spec.name}:`, e);
|
|
273
|
+
failures.push(spec.name);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
await sdks.release();
|
|
279
|
+
}
|
|
280
|
+
const out = {
|
|
281
|
+
_readme: 'GENERATED by src/executor/fallback-routes/generate.ts — do not edit by hand. ' +
|
|
282
|
+
'Manufactured fallback test routes: each marked member is a Native swapExchange ' +
|
|
283
|
+
'with an always-reverting quote whose `fallback` is a real quote priced at the ' +
|
|
284
|
+
'pinned blockNumber. Regenerate when routes go stale: ' +
|
|
285
|
+
'GENERATE_FALLBACK_ROUTES=1 npx jest src/executor/fallback-routes/generate-routes.test.ts --forceExit',
|
|
286
|
+
routes,
|
|
287
|
+
};
|
|
288
|
+
const outPath = path.join(__dirname, 'routes.json');
|
|
289
|
+
fs.writeFileSync(outPath, JSON.stringify(out, null, 2));
|
|
290
|
+
console.log(`\nwrote ${routes.length}/${scenarios_1.SCENARIOS.length} routes to ${outPath}` +
|
|
291
|
+
(failures.length ? `\nfailed: ${failures.join(', ')}` : ''));
|
|
292
|
+
return { routes, failures };
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/executor/fallback-routes/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SCENARIOS = void 0;
|
|
4
|
+
const USDC_10 = (10n * 10n ** 6n).toString();
|
|
5
|
+
const USDT_10 = (10n * 10n ** 6n).toString();
|
|
6
|
+
const ETH_0_01 = (10n ** 16n).toString();
|
|
7
|
+
/**
|
|
8
|
+
* The fallback test matrix. All SELL, Arbitrum, priced on UniswapV3.
|
|
9
|
+
*
|
|
10
|
+
* Executor mapping: 100%-per-hop routes -> Executor01; any split -> Executor02.
|
|
11
|
+
*/
|
|
12
|
+
exports.SCENARIOS = [
|
|
13
|
+
{
|
|
14
|
+
name: 'single-hop-fallback',
|
|
15
|
+
description: 'E01 whole-hop group: single USDC->WETH hop, primary reverts, fallback fills',
|
|
16
|
+
path: ['USDC', 'WETH'],
|
|
17
|
+
amount: USDC_10,
|
|
18
|
+
hops: [{ fabricatedMemberIndex: 0 }],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'multihop-fallback-first-hop',
|
|
22
|
+
description: 'E01 group at sequence START: USDC->WETH->WBTC, hop0 falls back, its output threads to hop1',
|
|
23
|
+
path: ['USDC', 'WETH', 'WBTC'],
|
|
24
|
+
amount: USDC_10,
|
|
25
|
+
hops: [{ fabricatedMemberIndex: 0 }, {}],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'multihop-fallback-last-hop',
|
|
29
|
+
description: 'E01 group at sequence END: USDC->WETH->WBTC, hop1 falls back after a real hop0',
|
|
30
|
+
path: ['USDC', 'WETH', 'WBTC'],
|
|
31
|
+
amount: USDC_10,
|
|
32
|
+
hops: [{}, { fabricatedMemberIndex: 0 }],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'multihop-fallback-middle-hop',
|
|
36
|
+
description: 'E01 group in sequence MIDDLE: USDT->USDC->WETH->WBTC, hop1 falls back between real hops',
|
|
37
|
+
path: ['USDT', 'USDC', 'WETH', 'WBTC'],
|
|
38
|
+
amount: USDT_10,
|
|
39
|
+
hops: [{}, { fabricatedMemberIndex: 0 }, {}],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'eth-src-wrap-in-try',
|
|
43
|
+
description: 'E01 wrap rollback: ETH->USDC, primary (needs WETH) wraps inside the try; on revert the wrap rolls back and the fallback re-wraps',
|
|
44
|
+
path: ['ETH', 'USDC'],
|
|
45
|
+
amount: ETH_0_01,
|
|
46
|
+
hops: [{ fabricatedMemberIndex: 0 }],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'eth-dest-unwrap',
|
|
50
|
+
description: 'E01 unwrap side: USDC->ETH, primary and fallback both WETH-based (same wrap-ness), unwrap-after machinery',
|
|
51
|
+
path: ['USDC', 'ETH'],
|
|
52
|
+
amount: USDC_10,
|
|
53
|
+
hops: [{ fabricatedMemberIndex: 0 }],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'split-member-fallback',
|
|
57
|
+
description: 'E02 group nested in a path: USDC->WETH split 50/50, member 0 falls back, sibling unaffected',
|
|
58
|
+
path: ['USDC', 'WETH'],
|
|
59
|
+
amount: USDC_10,
|
|
60
|
+
hops: [{ split: [50, 50], fabricatedMemberIndex: 0 }],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'multihop-split-then-fallback-hop',
|
|
64
|
+
description: 'E02 WHOLE-HOP group with threading flag: USDC->WETH->WBTC, hop0 split 50/50 (all real), hop1 single fabricated',
|
|
65
|
+
path: ['USDC', 'WETH', 'WBTC'],
|
|
66
|
+
amount: USDC_10,
|
|
67
|
+
hops: [{ split: [50, 50] }, { fabricatedMemberIndex: 0 }],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'eth-src-split-member-fallback',
|
|
71
|
+
description: 'E02 input normalization: ETH->USDC split 50/50, member 0 falls back; external wrap persists, fallback gets its approve prepended',
|
|
72
|
+
path: ['ETH', 'USDC'],
|
|
73
|
+
amount: ETH_0_01,
|
|
74
|
+
hops: [{ split: [50, 50], fabricatedMemberIndex: 0 }],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'multihop-fallback-hop-then-split',
|
|
78
|
+
description: 'E02 MID-ROUTE whole-hop group threading (flag 11): USDC->WETH->WBTC, hop0 single fabricated (its output must thread on), hop1 split 50/50 all real',
|
|
79
|
+
path: ['USDC', 'WETH', 'WBTC'],
|
|
80
|
+
amount: USDC_10,
|
|
81
|
+
hops: [{ fabricatedMemberIndex: 0 }, { split: [50, 50] }],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'split-last-member-fallback',
|
|
85
|
+
description: 'E02 group as the LAST split member (remainder-path semantics): USDC->WETH split 50/50, member 1 falls back',
|
|
86
|
+
path: ['USDC', 'WETH'],
|
|
87
|
+
amount: USDC_10,
|
|
88
|
+
hops: [{ split: [50, 50], fabricatedMemberIndex: 1 }],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'eth-dest-split-member-fallback',
|
|
92
|
+
description: 'E02 ETH-dest split: USDC->ETH split 50/50, member 0 falls back; unwrap-after machinery composes with the group (same wrap-ness)',
|
|
93
|
+
path: ['USDC', 'ETH'],
|
|
94
|
+
amount: USDC_10,
|
|
95
|
+
hops: [{ split: [50, 50], fabricatedMemberIndex: 0 }],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'multihop-double-fallback',
|
|
99
|
+
description: 'E01 TWO groups in one route: USDC->WETH->WBTC, both hops fall back sequentially',
|
|
100
|
+
path: ['USDC', 'WETH', 'WBTC'],
|
|
101
|
+
amount: USDC_10,
|
|
102
|
+
hops: [{ fabricatedMemberIndex: 0 }, { fabricatedMemberIndex: 0 }],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'split-member-and-hop-double-fallback',
|
|
106
|
+
description: 'E02 TWO groups in one route: hop0 split 50/50 with member 0 falling back (group in path), hop1 single fabricated (whole-hop group)',
|
|
107
|
+
path: ['USDC', 'WETH', 'WBTC'],
|
|
108
|
+
amount: USDC_10,
|
|
109
|
+
hops: [
|
|
110
|
+
{ split: [50, 50], fabricatedMemberIndex: 0 },
|
|
111
|
+
{ fabricatedMemberIndex: 0 },
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'eth-src-raw-eth-fallback',
|
|
116
|
+
description: 'E01 raw-ETH fallback: ETH->USDC, primary (needs WETH) wraps inside the try; on revert the wrap rolls back and the UniswapV4 fallback spends raw ETH directly',
|
|
117
|
+
path: ['ETH', 'USDC'],
|
|
118
|
+
amount: ETH_0_01,
|
|
119
|
+
hops: [{ fabricatedMemberIndex: 0, fallbackPricingDex: 'UniswapV4' }],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'eth-src-split-fallback-unwrap-normalization',
|
|
123
|
+
description: 'E02 input normalization WITHDRAW branch: ETH->USDC split 50/50 (all members need WETH -> root wrap, external), member 0 falls back to raw-ETH UniswapV4 -> WETH.withdraw(slice) prepended to the fallback block',
|
|
124
|
+
path: ['ETH', 'USDC'],
|
|
125
|
+
amount: ETH_0_01,
|
|
126
|
+
hops: [
|
|
127
|
+
{
|
|
128
|
+
split: [50, 50],
|
|
129
|
+
fabricatedMemberIndex: 0,
|
|
130
|
+
fallbackPricingDex: 'UniswapV4',
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'eth-src-mixed-siblings-wrap-in-try',
|
|
136
|
+
description: 'E02 branch-local wrap: ETH->USDC split 50/50 with a raw-ETH sibling (UniswapV4) -> no root wrap -> member 0 wraps INSIDE its try; on revert the wrap rolls back and the WETH-based fallback re-wraps',
|
|
137
|
+
path: ['ETH', 'USDC'],
|
|
138
|
+
amount: ETH_0_01,
|
|
139
|
+
hops: [
|
|
140
|
+
{
|
|
141
|
+
split: [50, 50],
|
|
142
|
+
fabricatedMemberIndex: 0,
|
|
143
|
+
pricingDexes: [undefined, 'UniswapV4'],
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'eth-dest-mixed-wrapness-e01',
|
|
149
|
+
description: 'E01 mixed wrap-ness on ETH dest (no guard needed: E01 threads per-branch via raw return): USDC->ETH, primary WETH-based, fallback raw-ETH UniswapV4',
|
|
150
|
+
path: ['USDC', 'ETH'],
|
|
151
|
+
amount: USDC_10,
|
|
152
|
+
hops: [{ fabricatedMemberIndex: 0, fallbackPricingDex: 'UniswapV4' }],
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: 'megaswap-fallback-in-route',
|
|
156
|
+
description: 'MEGASWAP (bestRoute.length=2, 50/50): routeA = USDC->WETH->WBTC with hop0 falling back mid-route, routeB = same path all real',
|
|
157
|
+
amount: USDC_10,
|
|
158
|
+
routes: [
|
|
159
|
+
{
|
|
160
|
+
percent: 50,
|
|
161
|
+
path: ['USDC', 'WETH', 'WBTC'],
|
|
162
|
+
hops: [{ fabricatedMemberIndex: 0 }, {}],
|
|
163
|
+
},
|
|
164
|
+
{ percent: 50, path: ['USDC', 'WETH', 'WBTC'], hops: [{}, {}] },
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: 'megaswap-split-member-fallback',
|
|
169
|
+
description: 'MEGASWAP deepest nesting: routeA hop0 is a 50/50 split whose member 0 falls back (group in path, inside a nested vertical branch), routeB simple real',
|
|
170
|
+
amount: USDC_10,
|
|
171
|
+
routes: [
|
|
172
|
+
{
|
|
173
|
+
percent: 50,
|
|
174
|
+
path: ['USDC', 'WETH', 'WBTC'],
|
|
175
|
+
hops: [{ split: [50, 50], fabricatedMemberIndex: 0 }, {}],
|
|
176
|
+
},
|
|
177
|
+
{ percent: 50, path: ['USDC', 'WETH', 'WBTC'], hops: [{}, {}] },
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: 'megaswap-whole-route-fallback',
|
|
182
|
+
description: 'MEGASWAP: routeA is a single fabricated hop (the group IS the whole route content), routeB real multi-hop',
|
|
183
|
+
amount: USDC_10,
|
|
184
|
+
routes: [
|
|
185
|
+
{
|
|
186
|
+
percent: 50,
|
|
187
|
+
path: ['USDC', 'WBTC'],
|
|
188
|
+
hops: [{ fabricatedMemberIndex: 0 }],
|
|
189
|
+
},
|
|
190
|
+
{ percent: 50, path: ['USDC', 'WETH', 'WBTC'], hops: [{}, {}] },
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: 'eth-dest-split-mixed-wrapness-runs-plain',
|
|
195
|
+
description: 'NEGATIVE, E02 guard: USDC->ETH split 50/50, member 0 primary WETH-based with raw-ETH UniswapV4 fallback -> mixed wrap-ness on ETH dest is guarded, no group is encoded, the reverting primary runs plain and the tx fails',
|
|
196
|
+
path: ['USDC', 'ETH'],
|
|
197
|
+
amount: USDC_10,
|
|
198
|
+
hops: [
|
|
199
|
+
{
|
|
200
|
+
split: [50, 50],
|
|
201
|
+
fabricatedMemberIndex: 0,
|
|
202
|
+
fallbackPricingDex: 'UniswapV4',
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
expectGroup: false,
|
|
206
|
+
expectSuccess: false,
|
|
207
|
+
},
|
|
208
|
+
];
|
|
209
|
+
//# sourceMappingURL=scenarios.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenarios.js","sourceRoot":"","sources":["../../../src/executor/fallback-routes/scenarios.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { OptimalRate } from '@paraswap/core';
|
|
2
|
+
/**
|
|
3
|
+
* Declarative spec for a manufactured fallback test route.
|
|
4
|
+
*
|
|
5
|
+
* Every scenario is a SELL route along `path`. Each hop is priced live (per
|
|
6
|
+
* split slice) with a real AMM; the hop/member marked `fabricated` becomes a
|
|
7
|
+
* `Native` swapExchange with an always-reverting quote carrying the real
|
|
8
|
+
* priced quote as its revertable fallback.
|
|
9
|
+
*/
|
|
10
|
+
export type HopSpec = {
|
|
11
|
+
split?: number[];
|
|
12
|
+
fabricatedMemberIndex?: number;
|
|
13
|
+
pricingDexes?: (string | undefined)[];
|
|
14
|
+
fallbackPricingDex?: string;
|
|
15
|
+
};
|
|
16
|
+
export type RouteSpec = {
|
|
17
|
+
percent: number;
|
|
18
|
+
path: string[];
|
|
19
|
+
hops: HopSpec[];
|
|
20
|
+
};
|
|
21
|
+
export type ScenarioSpec = {
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
amount: string;
|
|
25
|
+
path?: string[];
|
|
26
|
+
hops?: HopSpec[];
|
|
27
|
+
routes?: RouteSpec[];
|
|
28
|
+
slippageBps?: number;
|
|
29
|
+
expectGroup?: boolean;
|
|
30
|
+
expectSuccess?: boolean;
|
|
31
|
+
};
|
|
32
|
+
export type GeneratedRoute = {
|
|
33
|
+
name: string;
|
|
34
|
+
description: string;
|
|
35
|
+
network: number;
|
|
36
|
+
generatedAt: string;
|
|
37
|
+
slippageBps: number;
|
|
38
|
+
expectGroup: boolean;
|
|
39
|
+
expectSuccess: boolean;
|
|
40
|
+
priceRoute: OptimalRate;
|
|
41
|
+
};
|
|
42
|
+
export type GeneratedRoutesFile = {
|
|
43
|
+
_readme: string;
|
|
44
|
+
routes: GeneratedRoute[];
|
|
45
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/executor/fallback-routes/types.ts"],"names":[],"mappings":""}
|
|
@@ -102,8 +102,7 @@ class GenericSwapTransactionBuilder {
|
|
|
102
102
|
// Revertable fallback alternative attached during pricing (api).
|
|
103
103
|
// Build it the same way as the primary so its setup (approve/wrap)
|
|
104
104
|
// is encoded inside the group's fallback branch.
|
|
105
|
-
const seFallback = se
|
|
106
|
-
.fallback;
|
|
105
|
+
const seFallback = se.fallback;
|
|
107
106
|
const fallback = seFallback
|
|
108
107
|
? await this.buildSingleExchangeParam(priceRoute, routeIndex, swap, swapIndex, seFallback, minMaxAmount, bytecodeBuilder, getDexParamOptions)
|
|
109
108
|
: undefined;
|