From c43be9506def2fb74f7e03abd39c0ccc74a486fb Mon Sep 17 00:00:00 2001 From: Kyle Fang Date: Fri, 19 Jan 2024 00:17:35 +0800 Subject: [PATCH] fix: swap-helper-bridged --- src/helpers/FeeHelper.ts | 71 +++++++---- src/helpers/RateHelper.ts | 73 +++++++---- src/helpers/RouteHelper.ts | 36 +++++- src/helpers/SwapHelper.ts | 252 ++++++++++++++++++++++++------------- 4 files changed, 292 insertions(+), 140 deletions(-) diff --git a/src/helpers/FeeHelper.ts b/src/helpers/FeeHelper.ts index ed1cff7..85861a8 100644 --- a/src/helpers/FeeHelper.ts +++ b/src/helpers/FeeHelper.ts @@ -52,30 +52,33 @@ export async function getLiquidityProviderFee( }).then(unwrapResponse); } - const ammRoute = AMMSwapPool.getRoute(tokenX, tokenY, ammPools); - if (ammRoute.length === 0) { - const reachableInAmm = AMMSwapPool.reachableInAMM(tokenX, tokenY, ammPools); - if (reachableInAmm.type === 'fromAmm') { - return await readonlyCall('swap-helper-bridged-v1-1', 'fee-helper-from-amm', { - 'token-x': reachableInAmm.tokenX, - 'token-y': reachableInAmm.tokenY, - 'token-z': reachableInAmm.tokenZ, - 'factor-x': reachableInAmm.factorX, - }).then(unwrapResponse); - } - if (reachableInAmm.type === 'toAmm') { - return await readonlyCall('swap-helper-bridged-v1-1', 'fee-helper-to-amm', { - 'token-x': reachableInAmm.tokenX, - 'token-y': reachableInAmm.tokenY, - 'token-z': reachableInAmm.tokenZ, - 'factor-y': reachableInAmm.factorY, - }).then(unwrapResponse); - } - return await readonlyCall('swap-helper-v1-03', 'fee-helper', { - 'token-x': tokenX, - 'token-y': tokenY, + const reachableInAmm1_1 = AMMSwapPool.reachableInAMM( + tokenX, + tokenY, + ammV1_1Pools + ); + if (reachableInAmm1_1.type === 'fromAmm') { + return await readonlyCall( + 'swap-helper-bridged-v1-1', + 'fee-helper-from-amm', + { + 'token-x': reachableInAmm1_1.tokenX, + 'token-y': reachableInAmm1_1.tokenY, + 'token-z': reachableInAmm1_1.tokenZ, + 'factor-x': reachableInAmm1_1.factorX, + } + ).then(unwrapResponse); + } + if (reachableInAmm1_1.type === 'toAmm') { + return await readonlyCall('swap-helper-bridged-v1-1', 'fee-helper-to-amm', { + 'token-x': reachableInAmm1_1.tokenX, + 'token-y': reachableInAmm1_1.tokenY, + 'token-z': reachableInAmm1_1.tokenZ, + 'factor-y': reachableInAmm1_1.factorY, }).then(unwrapResponse); } + + const ammRoute = AMMSwapPool.getRoute(tokenX, tokenY, ammPools); if (ammRoute.length === 1) { return await readonlyCall('amm-swap-pool', 'fee-helper', { 'token-x': tokenX, @@ -116,5 +119,27 @@ export async function getLiquidityProviderFee( 'factor-w': AMMSwapPool.getFactor(ammRoute[3]!.pool), }).then(unwrapResponse); } - throw new Error('Too many AMM pools in route'); + + const reachableInAmm = AMMSwapPool.reachableInAMM(tokenX, tokenY, ammPools); + if (reachableInAmm.type === 'fromAmm') { + return await readonlyCall('swap-helper-bridged', 'fee-helper-from-amm', { + 'token-x': reachableInAmm.tokenX, + 'token-y': reachableInAmm.tokenY, + 'token-z': reachableInAmm.tokenZ, + 'factor-x': reachableInAmm.factorX, + }).then(unwrapResponse); + } + if (reachableInAmm.type === 'toAmm') { + return await readonlyCall('swap-helper-bridged', 'fee-helper-to-amm', { + 'token-x': reachableInAmm.tokenX, + 'token-y': reachableInAmm.tokenY, + 'token-z': reachableInAmm.tokenZ, + 'factor-y': reachableInAmm.factorY, + }).then(unwrapResponse); + } + + return await readonlyCall('swap-helper-v1-03', 'fee-helper', { + 'token-x': tokenX, + 'token-y': tokenY, + }).then(unwrapResponse); } diff --git a/src/helpers/RateHelper.ts b/src/helpers/RateHelper.ts index a489a16..ddc80be 100644 --- a/src/helpers/RateHelper.ts +++ b/src/helpers/RateHelper.ts @@ -56,33 +56,35 @@ export const getYAmountFromXAmount = async ( dx: fromAmount, }).then(unwrapResponse); } - const ammRoute = AMMSwapPool.getRoute(tokenX, tokenY, ammPools); - if (ammRoute.length === 0) { - const reachableInAMM = AMMSwapPool.reachableInAMM(tokenX, tokenY, ammPools); - if (reachableInAMM.type === 'fromAmm') { - return await readonlyCall('swap-helper-bridged-v1-1', 'get-helper-from-amm', { + const reachableInAMMV1_1 = AMMSwapPool.reachableInAMM( + tokenX, + tokenY, + ammV1_1Tokens + ); + if (reachableInAMMV1_1.type === 'fromAmm') { + return await readonlyCall( + 'swap-helper-bridged-v1-1', + 'get-helper-from-amm', + { dx: fromAmount, - 'token-x': reachableInAMM.tokenX, - 'token-y': reachableInAMM.tokenY, - 'token-z': reachableInAMM.tokenZ, - 'factor-x': reachableInAMM.factorX, - }).then(unwrapResponse); - } - if (reachableInAMM.type === 'toAmm') { - return await readonlyCall('swap-helper-bridged-v1-1', 'get-helper-to-amm', { - dx: fromAmount, - 'token-x': reachableInAMM.tokenX, - 'token-y': reachableInAMM.tokenY, - 'token-z': reachableInAMM.tokenZ, - 'factor-y': reachableInAMM.factorY, - }).then(unwrapResponse); - } - return await readonlyCall('swap-helper-v1-03', 'get-helper', { - 'token-x': tokenX, - 'token-y': tokenY, + 'token-x': reachableInAMMV1_1.tokenX, + 'token-y': reachableInAMMV1_1.tokenY, + 'token-z': reachableInAMMV1_1.tokenZ, + 'factor-x': reachableInAMMV1_1.factorX, + } + ).then(unwrapResponse); + } + if (reachableInAMMV1_1.type === 'toAmm') { + return await readonlyCall('swap-helper-bridged-v1-1', 'get-helper-to-amm', { dx: fromAmount, + 'token-x': reachableInAMMV1_1.tokenX, + 'token-y': reachableInAMMV1_1.tokenY, + 'token-z': reachableInAMMV1_1.tokenZ, + 'factor-y': reachableInAMMV1_1.factorY, }).then(unwrapResponse); } + + const ammRoute = AMMSwapPool.getRoute(tokenX, tokenY, ammPools); if (ammRoute.length === 1) { return await readonlyCall('amm-swap-pool', 'get-helper', { 'token-x': tokenX, @@ -127,5 +129,28 @@ export const getYAmountFromXAmount = async ( dx: fromAmount, }).then(unwrapResponse); } - throw new Error('Too many AMM pools in route'); + const reachableInAMM = AMMSwapPool.reachableInAMM(tokenX, tokenY, ammPools); + if (reachableInAMM.type === 'fromAmm') { + return await readonlyCall('swap-helper-bridged', 'get-helper-from-amm', { + dx: fromAmount, + 'token-x': reachableInAMM.tokenX, + 'token-y': reachableInAMM.tokenY, + 'token-z': reachableInAMM.tokenZ, + 'factor-x': reachableInAMM.factorX, + }).then(unwrapResponse); + } + if (reachableInAMM.type === 'toAmm') { + return await readonlyCall('swap-helper-bridged', 'get-helper-to-amm', { + dx: fromAmount, + 'token-x': reachableInAMM.tokenX, + 'token-y': reachableInAMM.tokenY, + 'token-z': reachableInAMM.tokenZ, + 'factor-y': reachableInAMM.factorY, + }).then(unwrapResponse); + } + return await readonlyCall('swap-helper-v1-03', 'get-helper', { + 'token-x': tokenX, + 'token-y': tokenY, + dx: fromAmount, + }).then(unwrapResponse); }; diff --git a/src/helpers/RouteHelper.ts b/src/helpers/RouteHelper.ts index 5cfd1af..caff0de 100644 --- a/src/helpers/RouteHelper.ts +++ b/src/helpers/RouteHelper.ts @@ -2,7 +2,6 @@ import { AMMSwapPool } from '../utils/ammPool'; import { unwrapResponse } from 'clarity-codegen'; import { readonlyCall } from '../utils/readonlyCallExecutor'; import { Currency } from '../currency'; -import { AlexSDK } from '../alexSDK'; export async function getRoute( from: Currency, @@ -18,10 +17,41 @@ export async function getRoute( if (ammRoute.length > 0) { return [from, ...ammRoute.map((a) => a.neighbour)]; } + const reachableInAmmV1_1 = AMMSwapPool.reachableInAMM( + from, + to, + ammV1_1Tokens + ); + if (reachableInAmmV1_1.type === 'fromAmm') { + const result = await readonlyCall( + 'swap-helper-bridged-v1-1', + 'route-helper-from-amm', + { + 'token-x': reachableInAmmV1_1.tokenX, + 'token-y': reachableInAmmV1_1.tokenY, + 'token-z': reachableInAmmV1_1.tokenZ, + 'factor-x': reachableInAmmV1_1.factorX, + } + ).then(unwrapResponse); + return result.map((x) => x as Currency); + } + if (reachableInAmmV1_1.type === 'toAmm') { + const result = await readonlyCall( + 'swap-helper-bridged-v1-1', + 'route-helper-to-amm', + { + 'token-x': reachableInAmmV1_1.tokenX, + 'token-y': reachableInAmmV1_1.tokenY, + 'token-z': reachableInAmmV1_1.tokenZ, + 'factor-y': reachableInAmmV1_1.factorY, + } + ).then(unwrapResponse); + return result.map((x) => x as Currency); + } const reachableInAmm = AMMSwapPool.reachableInAMM(from, to, ammPools); if (reachableInAmm.type === 'fromAmm') { const result = await readonlyCall( - 'swap-helper-bridged-v1-1', + 'swap-helper-bridged', 'route-helper-from-amm', { 'token-x': reachableInAmm.tokenX, @@ -34,7 +64,7 @@ export async function getRoute( } if (reachableInAmm.type === 'toAmm') { const result = await readonlyCall( - 'swap-helper-bridged-v1-1', + 'swap-helper-bridged', 'route-helper-to-amm', { 'token-x': reachableInAmm.tokenX, diff --git a/src/helpers/SwapHelper.ts b/src/helpers/SwapHelper.ts index fc88398..cb9baf9 100644 --- a/src/helpers/SwapHelper.ts +++ b/src/helpers/SwapHelper.ts @@ -62,6 +62,7 @@ export function runSpot( ammV1_1Pools: AMMSwapPool.PoolTokens[] ): TxToBroadCast { const middleSteps = router.slice(1, -1); + const AlexVault = `${configs.CONTRACT_DEPLOYER}.alex-vault`; const AlexVaultV1_1 = `${configs.CONTRACT_DEPLOYER}.alex-vault-v1-1`; const ammV1_1Route = AMMSwapPool.getRoute(currencyX, currencyY, ammV1_1Pools); @@ -238,102 +239,28 @@ export function runSpot( ); } - const AlexVault = `${configs.CONTRACT_DEPLOYER}.alex-vault`; - const ammRoute = AMMSwapPool.getRoute(currencyX, currencyY, ammPools); - if (ammRoute.length === 0) { - const reachableInAMM = AMMSwapPool.reachableInAMM( - currencyX, - currencyY, - ammPools - ); - if (reachableInAMM.type === 'fromAmm') { - return composeTx( - 'swap-helper-bridged-v1-1', - 'swap-helper-from-amm', - { - 'token-x-trait': reachableInAMM.tokenX, - 'token-y-trait': reachableInAMM.tokenY, - 'token-z-trait': reachableInAMM.tokenZ, - dx: fromAmount, - 'min-dz': minDy, - 'factor-x': reachableInAMM.factorX, - }, - [ - transfer(stxAddress, currencyX, fromAmount), - ...middleSteps.flatMap((middle) => [ - transfer( - AlexVault, - middle, - BigInt(0), - FungibleConditionCode.GreaterEqual - ), - transfer( - stxAddress, - middle, - BigInt(0), - FungibleConditionCode.GreaterEqual - ), - ]), - transfer( - AlexVault, - currencyY, - minDy, - FungibleConditionCode.GreaterEqual - ), - ] - ); - } - if (reachableInAMM.type === 'toAmm') { - return composeTx( - 'swap-helper-bridged-v1-1', - 'swap-helper-to-amm', - { - 'token-x-trait': reachableInAMM.tokenX, - 'token-y-trait': reachableInAMM.tokenY, - 'token-z-trait': reachableInAMM.tokenZ, - dx: fromAmount, - 'min-dz': minDy, - 'factor-y': reachableInAMM.factorY, - }, - [ - transfer(stxAddress, currencyX, fromAmount), - ...middleSteps.flatMap((middle) => [ - transfer( - AlexVault, - middle, - BigInt(0), - FungibleConditionCode.GreaterEqual - ), - transfer( - stxAddress, - middle, - BigInt(0), - FungibleConditionCode.GreaterEqual - ), - ]), - transfer( - AlexVault, - currencyY, - minDy, - FungibleConditionCode.GreaterEqual - ), - ] - ); - } + const reachableInAMMV1_1 = AMMSwapPool.reachableInAMM( + currencyX, + currencyY, + ammPools + ); + if (reachableInAMMV1_1.type === 'fromAmm') { return composeTx( - 'swap-helper-v1-03', - 'swap-helper', + 'swap-helper-bridged-v1-1', + 'swap-helper-from-amm', { - 'token-x-trait': currencyX, - 'token-y-trait': currencyY, + 'token-x-trait': reachableInAMMV1_1.tokenX, + 'token-y-trait': reachableInAMMV1_1.tokenY, + 'token-z-trait': reachableInAMMV1_1.tokenZ, dx: fromAmount, - 'min-dy': minDy, + 'min-dz': minDy, + 'factor-x': reachableInAMMV1_1.factorX, }, [ transfer(stxAddress, currencyX, fromAmount), - ...middleSteps.flatMap((middle) => [ + ...middleSteps.flatMap((middle, index) => [ transfer( - AlexVault, + index === 0 ? AlexVaultV1_1 : AlexVault, middle, BigInt(0), FungibleConditionCode.GreaterEqual @@ -354,6 +281,45 @@ export function runSpot( ] ); } + if (reachableInAMMV1_1.type === 'toAmm') { + return composeTx( + 'swap-helper-bridged-v1-1', + 'swap-helper-to-amm', + { + 'token-x-trait': reachableInAMMV1_1.tokenX, + 'token-y-trait': reachableInAMMV1_1.tokenY, + 'token-z-trait': reachableInAMMV1_1.tokenZ, + dx: fromAmount, + 'min-dz': minDy, + 'factor-y': reachableInAMMV1_1.factorY, + }, + [ + transfer(stxAddress, currencyX, fromAmount), + ...middleSteps.flatMap((middle) => [ + transfer( + AlexVault, + middle, + BigInt(0), + FungibleConditionCode.GreaterEqual + ), + transfer( + stxAddress, + middle, + BigInt(0), + FungibleConditionCode.GreaterEqual + ), + ]), + transfer( + AlexVaultV1_1, + currencyY, + minDy, + FungibleConditionCode.GreaterEqual + ), + ] + ); + } + + const ammRoute = AMMSwapPool.getRoute(currencyX, currencyY, ammPools); if (ammRoute.length === 1) { return composeTx( 'amm-swap-pool', @@ -527,5 +493,111 @@ export function runSpot( ); } - throw new Error('Too many AMM pools in route'); + const reachableInAMM = AMMSwapPool.reachableInAMM( + currencyX, + currencyY, + ammPools + ); + if (reachableInAMM.type === 'fromAmm') { + return composeTx( + 'swap-helper-bridged', + 'swap-helper-from-amm', + { + 'token-x-trait': reachableInAMM.tokenX, + 'token-y-trait': reachableInAMM.tokenY, + 'token-z-trait': reachableInAMM.tokenZ, + dx: fromAmount, + 'min-dz': minDy, + 'factor-x': reachableInAMM.factorX, + }, + [ + transfer(stxAddress, currencyX, fromAmount), + ...middleSteps.flatMap((middle, index) => [ + transfer( + index === 0 ? AlexVaultV1_1 : AlexVault, + middle, + BigInt(0), + FungibleConditionCode.GreaterEqual + ), + transfer( + stxAddress, + middle, + BigInt(0), + FungibleConditionCode.GreaterEqual + ), + ]), + transfer( + AlexVault, + currencyY, + minDy, + FungibleConditionCode.GreaterEqual + ), + ] + ); + } + if (reachableInAMM.type === 'toAmm') { + return composeTx( + 'swap-helper-bridged', + 'swap-helper-to-amm', + { + 'token-x-trait': reachableInAMM.tokenX, + 'token-y-trait': reachableInAMM.tokenY, + 'token-z-trait': reachableInAMM.tokenZ, + dx: fromAmount, + 'min-dz': minDy, + 'factor-y': reachableInAMM.factorY, + }, + [ + transfer(stxAddress, currencyX, fromAmount), + ...middleSteps.flatMap((middle) => [ + transfer( + AlexVault, + middle, + BigInt(0), + FungibleConditionCode.GreaterEqual + ), + transfer( + stxAddress, + middle, + BigInt(0), + FungibleConditionCode.GreaterEqual + ), + ]), + transfer( + AlexVaultV1_1, + currencyY, + minDy, + FungibleConditionCode.GreaterEqual + ), + ] + ); + } + return composeTx( + 'swap-helper-v1-03', + 'swap-helper', + { + 'token-x-trait': currencyX, + 'token-y-trait': currencyY, + dx: fromAmount, + 'min-dy': minDy, + }, + [ + transfer(stxAddress, currencyX, fromAmount), + ...middleSteps.flatMap((middle) => [ + transfer( + AlexVault, + middle, + BigInt(0), + FungibleConditionCode.GreaterEqual + ), + transfer( + stxAddress, + middle, + BigInt(0), + FungibleConditionCode.GreaterEqual + ), + ]), + transfer(AlexVault, currencyY, minDy, FungibleConditionCode.GreaterEqual), + ] + ); }