Skip to content

Commit 4faadb4

Browse files
committed
test(uniswap_v3): cover Ramses + Slipstream CL-style mint dispatch
uniswap_v3.ts branches went 47.36% → 75%. The Uniswap V3 standard mint path (11-field MintParams with uint24 fee) was already exercised; the two CL-fork branches were dead under coverage: - cl_style='ramses' → 11-field RamsesMintParams (int24 tickSpacing replaces uint24 fee, no sqrtPriceX96) - cl_style='slipstream' → 12-field SlipstreamMintParams (adds trailing uint160 sqrtPriceX96=0) Both branches now have a happy-path test that decodes the emitted calldata through the matching ABI and asserts amount{0,1}Min came from the default 50bps slippage applied to the sorted token pair. The Ramses test additionally asserts the slipstream ABI cannot decode the same payload (length mismatch), proving the 11-vs-12 field selector landed correctly. Tick range is passed explicitly so neither test hits the slot0() auto-range path (which requires an RPC mock).
1 parent 12e8f50 commit 4faadb4

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

ts/packages/defi-protocols/src/dex/uniswap_v3.test.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,83 @@ describe("UniswapV3Adapter slippage protection (SSOT 7.3)", () => {
231231
expect(params.amount1Min).toBe(11n);
232232
});
233233
});
234+
235+
// Ramses CL mint = 11-field, no sqrtPriceX96, third field is tickSpacing (int24).
236+
const ramsesMintAbi = parseAbi([
237+
"function mint((address token0, address token1, int24 tickSpacing, int24 tickLower, int24 tickUpper, uint256 amount0Desired, uint256 amount1Desired, uint256 amount0Min, uint256 amount1Min, address recipient, uint256 deadline) params) returns (uint256, uint128, uint256, uint256)",
238+
]);
239+
240+
// Slipstream mint = 12-field, includes trailing sqrtPriceX96 (uint160).
241+
const slipstreamMintAbi = parseAbi([
242+
"function mint((address token0, address token1, int24 tickSpacing, int24 tickLower, int24 tickUpper, uint256 amount0Desired, uint256 amount1Desired, uint256 amount0Min, uint256 amount1Min, address recipient, uint256 deadline, uint160 sqrtPriceX96) params) returns (uint256, uint128, uint256, uint256)",
243+
]);
244+
245+
interface CLMintTuple {
246+
token0: Address;
247+
token1: Address;
248+
tickSpacing: number;
249+
amount0Min: bigint;
250+
amount1Min: bigint;
251+
}
252+
253+
interface SlipstreamMintTuple extends CLMintTuple {
254+
sqrtPriceX96: bigint;
255+
}
256+
257+
describe("UniswapV3Adapter CL-style mint dispatch (ramses / slipstream)", () => {
258+
it("cl_style='ramses' emits the 11-field Ramses MintParams (no sqrtPriceX96)", async () => {
259+
const ramsesEntry: ProtocolEntry = {
260+
...ENTRY,
261+
cl_style: "ramses",
262+
};
263+
const adapter = new UniswapV3Adapter(ramsesEntry);
264+
const tx = await adapter.buildAddLiquidity({
265+
protocol: ramsesEntry.slug,
266+
token_a: LOW,
267+
token_b: HIGH,
268+
amount_a: 1_000_000n,
269+
amount_b: 2_000_000n,
270+
recipient: RECIPIENT,
271+
// tick_lower/upper must be explicit for ramses without slot0() RPC.
272+
tick_lower: -887_220,
273+
tick_upper: 887_220,
274+
});
275+
const decoded = decodeFunctionData({ abi: ramsesMintAbi, data: tx.data as Hex });
276+
const params = decoded.args[0] as CLMintTuple;
277+
expect(params.token0.toLowerCase()).toBe(LOW.toLowerCase());
278+
expect(params.token1.toLowerCase()).toBe(HIGH.toLowerCase());
279+
expect(params.amount0Min).toBe(995_000n);
280+
expect(params.amount1Min).toBe(1_990_000n);
281+
// Decoding through the slipstream ABI would also succeed but pick up an
282+
// extra trailing zero; the byte-length difference proves we hit the
283+
// 11-field encoder, not the 12-field one.
284+
expect(() =>
285+
decodeFunctionData({ abi: slipstreamMintAbi, data: tx.data as Hex }),
286+
).toThrow();
287+
});
288+
289+
it("cl_style='slipstream' emits the 12-field Slipstream MintParams (with sqrtPriceX96=0)", async () => {
290+
const slipstreamEntry: ProtocolEntry = {
291+
...ENTRY,
292+
cl_style: "slipstream",
293+
};
294+
const adapter = new UniswapV3Adapter(slipstreamEntry);
295+
const tx = await adapter.buildAddLiquidity({
296+
protocol: slipstreamEntry.slug,
297+
token_a: LOW,
298+
token_b: HIGH,
299+
amount_a: 1_000_000n,
300+
amount_b: 2_000_000n,
301+
recipient: RECIPIENT,
302+
tick_lower: -887_220,
303+
tick_upper: 887_220,
304+
});
305+
const decoded = decodeFunctionData({ abi: slipstreamMintAbi, data: tx.data as Hex });
306+
const params = decoded.args[0] as SlipstreamMintTuple;
307+
expect(params.token0.toLowerCase()).toBe(LOW.toLowerCase());
308+
expect(params.token1.toLowerCase()).toBe(HIGH.toLowerCase());
309+
expect(params.amount0Min).toBe(995_000n);
310+
expect(params.amount1Min).toBe(1_990_000n);
311+
expect(params.sqrtPriceX96).toBe(0n);
312+
});
313+
});

0 commit comments

Comments
 (0)