feat: add support for AMM v1_1

This commit is contained in:
Kyle Fang
2023-05-07 14:10:08 +08:00
parent a452e8d214
commit 9a3f67be98
12 changed files with 2217 additions and 1164 deletions

View File

@@ -56,6 +56,7 @@
"@stacks/network": "^6.3.0",
"@stacks/stacks-blockchain-api-types": "^7.1.7",
"@stacks/transactions": "^6.2.0",
"@types/node": "^20.1.0",
"esm": "^3.2.25",
"husky": "^8.0.3",
"prettier": "^2.8.4",

2317
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@ const contracts = [
"swap-helper-v1-02",
"swap-helper-v1-03",
"amm-swap-pool",
"amm-swap-pool-v1-1",
"token-amm-swap-pool",
"swap-helper-bridged",

View File

@@ -21,11 +21,16 @@ export class AlexSDK {
}
getFeeRate(from: Currency, to: Currency): Promise<bigint> {
return getLiquidityProviderFee(from, to, AMMSwapPool.ammTokens);
return getLiquidityProviderFee(
from,
to,
AMMSwapPool.ammTokens,
AMMSwapPool.ammV1_1Tokens
);
}
getRouter(from: Currency, to: Currency): Promise<Currency[]> {
return getRoute(from, to, AMMSwapPool.ammTokens);
return getRoute(from, to, AMMSwapPool.ammTokens, AMMSwapPool.ammV1_1Tokens);
}
getAmountTo(
@@ -33,7 +38,7 @@ export class AlexSDK {
fromAmount: bigint,
to: Currency
): Promise<bigint> {
return getYAmountFromXAmount(from, to, fromAmount, AMMSwapPool.ammTokens);
return getYAmountFromXAmount(from, to, fromAmount, AMMSwapPool.ammTokens, AMMSwapPool.ammV1_1Tokens);
}
runSwap(
@@ -51,7 +56,8 @@ export class AlexSDK {
fromAmount,
minDy,
router,
AMMSwapPool.ammTokens
AMMSwapPool.ammTokens,
AMMSwapPool.ammV1_1Tokens
);
}

View File

@@ -10,4 +10,6 @@ export enum Currency {
MIA = 'token-wmia',
NYCC = 'token-wnycc',
CORGI = 'token-wcorgi',
ATALEXV2 = "auto-alex-v2",
sUSDT = "token-susdt",
}

View File

@@ -0,0 +1,715 @@
import {
defineContract,
principalT,
numberT,
optionalT,
responseSimpleT,
tupleT,
booleanT,
noneT
} from "../smartContractHelpers/codegenImport"
export const ammSwapPoolV11 = defineContract({
"amm-swap-pool-v1-1": {
'add-to-position': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'dx', type: numberT },
{ name: 'max-dy', type: optionalT(numberT, ) }
],
output: responseSimpleT(tupleT({ dx: numberT, dy: numberT, supply: numberT }, ), ),
mode: 'public'
},
'create-pool': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'pool-owner', type: principalT },
{ name: 'dx', type: numberT },
{ name: 'dy', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
pause: {
input: [ { name: 'new-paused', type: booleanT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'reduce-position': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'percent', type: numberT }
],
output: responseSimpleT(tupleT({ dx: numberT, dy: numberT }, ), ),
mode: 'public'
},
'set-contract-owner': {
input: [ { name: 'owner', type: principalT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-end-block': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'new-end-block', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-fee-rate-x': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'fee-rate-x', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-fee-rate-y': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'fee-rate-y', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-fee-rebate': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'fee-rebate', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-max-in-ratio': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'new-max-in-ratio', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-max-out-ratio': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'new-max-out-ratio', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-oracle-average': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'new-oracle-average', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-oracle-enabled': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'enabled', type: booleanT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-pool-owner': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'pool-owner', type: principalT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-start-block': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'new-start-block', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-switch-threshold': {
input: [ { name: 'new-threshold', type: numberT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-threshold-x': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'new-threshold', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-threshold-y': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'new-threshold', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'swap-helper': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'dx', type: numberT },
{ name: 'min-dy', type: optionalT(numberT, ) }
],
output: responseSimpleT(numberT, ),
mode: 'public'
},
'swap-helper-a': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'token-z-trait', type: principalT },
{ name: 'factor-x', type: numberT },
{ name: 'factor-y', type: numberT },
{ name: 'dx', type: numberT },
{ name: 'min-dz', type: optionalT(numberT, ) }
],
output: responseSimpleT(numberT, ),
mode: 'public'
},
'swap-helper-b': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'token-z-trait', type: principalT },
{ name: 'token-w-trait', type: principalT },
{ name: 'factor-x', type: numberT },
{ name: 'factor-y', type: numberT },
{ name: 'factor-z', type: numberT },
{ name: 'dx', type: numberT },
{ name: 'min-dw', type: optionalT(numberT, ) }
],
output: responseSimpleT(numberT, ),
mode: 'public'
},
'swap-helper-c': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'token-z-trait', type: principalT },
{ name: 'token-w-trait', type: principalT },
{ name: 'token-v-trait', type: principalT },
{ name: 'factor-x', type: numberT },
{ name: 'factor-y', type: numberT },
{ name: 'factor-z', type: numberT },
{ name: 'factor-w', type: numberT },
{ name: 'dx', type: numberT },
{ name: 'min-dv', type: optionalT(numberT, ) }
],
output: responseSimpleT(numberT, ),
mode: 'public'
},
'swap-x-for-y': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'dx', type: numberT },
{ name: 'min-dy', type: optionalT(numberT, ) }
],
output: responseSimpleT(tupleT({ dx: numberT, dy: numberT }, ), ),
mode: 'public'
},
'swap-y-for-x': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'dy', type: numberT },
{ name: 'min-dx', type: optionalT(numberT, ) }
],
output: responseSimpleT(tupleT({ dx: numberT, dy: numberT }, ), ),
mode: 'public'
},
'check-pool-status': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'readonly'
},
'fee-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'fee-helper-a': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: numberT },
{ name: 'factor-y', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'fee-helper-b': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'token-w', type: principalT },
{ name: 'factor-x', type: numberT },
{ name: 'factor-y', type: numberT },
{ name: 'factor-z', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'fee-helper-c': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'token-w', type: principalT },
{ name: 'token-v', type: principalT },
{ name: 'factor-x', type: numberT },
{ name: 'factor-y', type: numberT },
{ name: 'factor-z', type: numberT },
{ name: 'factor-w', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-balances': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(tupleT({ 'balance-x': numberT, 'balance-y': numberT }, ), ),
mode: 'readonly'
},
'get-contract-owner': {
input: [],
output: responseSimpleT(principalT, ),
mode: 'readonly'
},
'get-end-block': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-fee-rate-x': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-fee-rate-y': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-fee-rebate': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'dx', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-helper-a': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: numberT },
{ name: 'factor-y', type: numberT },
{ name: 'dx', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-helper-b': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'token-w', type: principalT },
{ name: 'factor-x', type: numberT },
{ name: 'factor-y', type: numberT },
{ name: 'factor-z', type: numberT },
{ name: 'dx', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-helper-c': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'token-w', type: principalT },
{ name: 'token-v', type: principalT },
{ name: 'factor-x', type: numberT },
{ name: 'factor-y', type: numberT },
{ name: 'factor-z', type: numberT },
{ name: 'factor-w', type: numberT },
{ name: 'dx', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-invariant': {
input: [
{ name: 'balance-x', type: numberT },
{ name: 'balance-y', type: numberT },
{ name: 't', type: numberT }
],
output: numberT,
mode: 'readonly'
},
'get-max-in-ratio': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-max-out-ratio': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-oracle-average': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-oracle-enabled': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(booleanT, ),
mode: 'readonly'
},
'get-oracle-instant': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-oracle-resilient': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-pool-details': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(tupleT({
'balance-x': numberT,
'balance-y': numberT,
'end-block': numberT,
'fee-rate-x': numberT,
'fee-rate-y': numberT,
'fee-rebate': numberT,
'max-in-ratio': numberT,
'max-out-ratio': numberT,
'oracle-average': numberT,
'oracle-enabled': booleanT,
'oracle-resilient': numberT,
'pool-id': numberT,
'pool-owner': principalT,
'start-block': numberT,
'threshold-x': numberT,
'threshold-y': numberT,
'total-supply': numberT
}, ), ),
mode: 'readonly'
},
'get-pool-details-by-id': {
input: [ { name: 'pool-id', type: numberT } ],
output: responseSimpleT(tupleT({ factor: numberT, 'token-x': principalT, 'token-y': principalT }, ), ),
mode: 'readonly'
},
'get-pool-exists': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: optionalT(tupleT({
'balance-x': numberT,
'balance-y': numberT,
'end-block': numberT,
'fee-rate-x': numberT,
'fee-rate-y': numberT,
'fee-rebate': numberT,
'max-in-ratio': numberT,
'max-out-ratio': numberT,
'oracle-average': numberT,
'oracle-enabled': booleanT,
'oracle-resilient': numberT,
'pool-id': numberT,
'pool-owner': principalT,
'start-block': numberT,
'threshold-x': numberT,
'threshold-y': numberT,
'total-supply': numberT
}, ), ),
mode: 'readonly'
},
'get-pool-owner': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(principalT, ),
mode: 'readonly'
},
'get-position-given-burn': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'token-amount', type: numberT }
],
output: responseSimpleT(tupleT({ dx: numberT, dy: numberT }, ), ),
mode: 'readonly'
},
'get-position-given-mint': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'token-amount', type: numberT }
],
output: responseSimpleT(tupleT({ dx: numberT, dy: numberT }, ), ),
mode: 'readonly'
},
'get-price': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-start-block': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-switch-threshold': { input: [], output: numberT, mode: 'readonly' },
'get-threshold-x': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-threshold-y': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-token-given-position': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'dx', type: numberT },
{ name: 'max-dy', type: optionalT(numberT, ) }
],
output: responseSimpleT(tupleT({ dy: numberT, token: numberT }, ), ),
mode: 'readonly'
},
'get-x-given-price': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'price', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-x-given-y': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'dy', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-x-in-given-y-out': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'dy', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-y-given-price': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'price', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-y-given-x': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'dx', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'get-y-in-given-x-out': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: numberT },
{ name: 'dx', type: numberT }
],
output: responseSimpleT(numberT, ),
mode: 'readonly'
},
'is-paused': { input: [], output: booleanT, mode: 'readonly' },
'pools-data-map': {
input: tupleT({ factor: numberT, 'token-x': principalT, 'token-y': principalT }, ),
output: optionalT(tupleT({
'balance-x': numberT,
'balance-y': numberT,
'end-block': numberT,
'fee-rate-x': numberT,
'fee-rate-y': numberT,
'fee-rebate': numberT,
'max-in-ratio': numberT,
'max-out-ratio': numberT,
'oracle-average': numberT,
'oracle-enabled': booleanT,
'oracle-resilient': numberT,
'pool-id': numberT,
'pool-owner': principalT,
'start-block': numberT,
'threshold-x': numberT,
'threshold-y': numberT,
'total-supply': numberT
}, ), ),
mode: 'mapEntry'
},
'pools-id-map': {
input: numberT,
output: optionalT(tupleT({ factor: numberT, 'token-x': principalT, 'token-y': principalT }, ), ),
mode: 'mapEntry'
},
'contract-owner': { input: noneT, output: principalT, mode: 'variable' },
paused: { input: noneT, output: booleanT, mode: 'variable' },
'pool-nonce': { input: noneT, output: numberT, mode: 'variable' },
'switch-threshold': { input: noneT, output: numberT, mode: 'variable' }
}
} as const)

View File

@@ -2,6 +2,7 @@ import { defineContract } from "../smartContractHelpers/codegenImport";
import { swapHelperV102 } from "./contract_swap-helper-v1-02"
import { swapHelperV103 } from "./contract_swap-helper-v1-03"
import { ammSwapPool } from "./contract_amm-swap-pool"
import { ammSwapPoolV11 } from "./contract_amm-swap-pool-v1-1"
import { tokenAmmSwapPool } from "./contract_token-amm-swap-pool"
import { swapHelperBridged } from "./contract_swap-helper-bridged"
@@ -9,6 +10,7 @@ export const AlexContracts = defineContract({
...swapHelperV102,
...swapHelperV103,
...ammSwapPool,
...ammSwapPoolV11,
...tokenAmmSwapPool,
...swapHelperBridged
});

View File

@@ -7,8 +7,51 @@ import { AlexSDK } from '../alexSDK';
export async function getLiquidityProviderFee(
tokenX: Currency,
tokenY: Currency,
ammPools: AMMSwapPool.PoolTokens[]
ammPools: AMMSwapPool.PoolTokens[],
ammV1_1Pools: AMMSwapPool.PoolTokens[]
): Promise<bigint> {
const ammV1_1Route = AMMSwapPool.getRoute(tokenX, tokenY, ammV1_1Pools);
if (ammV1_1Route.length === 1) {
return await readonlyCall('amm-swap-pool-v1-1', 'fee-helper', {
'token-x': tokenX,
'token-y': tokenY,
factor: AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
}).then(unwrapResponse);
}
if (ammV1_1Route.length === 2) {
return await readonlyCall('amm-swap-pool-v1-1', 'fee-helper-a', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
}).then(unwrapResponse);
}
if (ammV1_1Route.length === 3) {
return await readonlyCall('amm-swap-pool-v1-1', 'fee-helper-b', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'token-w': ammV1_1Route[2]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
}).then(unwrapResponse);
}
if (ammV1_1Route.length === 4) {
return await readonlyCall('amm-swap-pool-v1-1', 'fee-helper-c', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'token-w': ammV1_1Route[2]!.neighbour,
'token-v': ammV1_1Route[3]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
'factor-w': AMMSwapPool.getFactor(ammV1_1Route[3]!.pool),
}).then(unwrapResponse);
}
const ammRoute = AMMSwapPool.getRoute(tokenX, tokenY, ammPools);
if (ammRoute.length === 0) {
const reachableInAmm = AMMSwapPool.reachableInAMM(tokenX, tokenY, ammPools);

View File

@@ -8,8 +8,54 @@ export const getYAmountFromXAmount = async (
tokenX: Currency,
tokenY: Currency,
fromAmount: bigint,
ammPools: AMMSwapPool.PoolTokens[]
ammPools: AMMSwapPool.PoolTokens[],
ammV1_1Tokens: AMMSwapPool.Pool[]
): Promise<bigint> => {
const ammV1_1Route = AMMSwapPool.getRoute(tokenX, tokenY, ammV1_1Tokens);
if (ammV1_1Route.length === 1) {
return await readonlyCall('amm-swap-pool-v1-1', 'get-helper', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
dx: fromAmount,
factor: AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
}).then(unwrapResponse);
}
if (ammV1_1Route.length === 2) {
return await readonlyCall('amm-swap-pool-v1-1', 'get-helper-a', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
dx: fromAmount,
}).then(unwrapResponse);
}
if (ammV1_1Route.length === 3) {
return await readonlyCall('amm-swap-pool-v1-1', 'get-helper-b', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'token-w': ammV1_1Route[2]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
dx: fromAmount,
}).then(unwrapResponse);
}
if (ammV1_1Route.length === 4) {
return await readonlyCall('amm-swap-pool-v1-1', 'get-helper-c', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'token-w': ammV1_1Route[2]!.neighbour,
'token-v': ammV1_1Route[3]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
'factor-w': AMMSwapPool.getFactor(ammV1_1Route[3]!.pool),
dx: fromAmount,
}).then(unwrapResponse);
}
const ammRoute = AMMSwapPool.getRoute(tokenX, tokenY, ammPools);
if (ammRoute.length === 0) {
const reachableInAMM = AMMSwapPool.reachableInAMM(tokenX, tokenY, ammPools);

View File

@@ -7,13 +7,18 @@ import { AlexSDK } from '../alexSDK';
export async function getRoute(
from: Currency,
to: Currency,
pools: AMMSwapPool.PoolTokens[]
ammPools: AMMSwapPool.PoolTokens[],
ammV1_1Tokens: AMMSwapPool.Pool[]
): Promise<Currency[]> {
const ammRoute = AMMSwapPool.getRoute(from, to, pools);
const ammV1_1Route = AMMSwapPool.getRoute(from, to, ammV1_1Tokens);
if (ammV1_1Route.length > 0) {
return [from, ...ammV1_1Route.map((a) => a.neighbour)];
}
const ammRoute = AMMSwapPool.getRoute(from, to, ammPools);
if (ammRoute.length > 0) {
return [from, ...ammRoute.map((a) => a.neighbour)];
}
const reachableInAmm = AMMSwapPool.reachableInAMM(from, to, pools);
const reachableInAmm = AMMSwapPool.reachableInAMM(from, to, ammPools);
if (reachableInAmm.type === 'fromAmm') {
const result = await readonlyCall(
'swap-helper-bridged',

View File

@@ -58,11 +58,188 @@ export function runSpot(
fromAmount: bigint,
minDy: bigint,
router: Currency[],
ammPools: AMMSwapPool.PoolTokens[]
ammPools: AMMSwapPool.PoolTokens[],
ammV1_1Pools: AMMSwapPool.PoolTokens[]
): TxToBroadCast {
const middleSteps = router.slice(1, -1);
const AlexVaultV1_1 = `${configs.CONTRACT_DEPLOYER}.alex-vault-v1-1`;
const ammV1_1Route = AMMSwapPool.getRoute(currencyX, currencyY, ammV1_1Pools);
if (ammV1_1Route.length === 1) {
return composeTx(
'amm-swap-pool-v1-1',
'swap-helper',
{
'token-x-trait': currencyX,
'token-y-trait': ammV1_1Route[0]!.neighbour,
factor: AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
dx: fromAmount,
'min-dy': minDy,
},
[
transfer(stxAddress, currencyX, fromAmount),
transfer(
AlexVaultV1_1,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
if (ammV1_1Route.length === 2) {
return composeTx(
'amm-swap-pool-v1-1',
'swap-helper-a',
{
'token-x-trait': currencyX,
'token-y-trait': ammV1_1Route[0]!.neighbour,
'token-z-trait': ammV1_1Route[1]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
dx: fromAmount,
'min-dz': minDy,
},
[
transfer(stxAddress, currencyX, fromAmount),
transfer(
AlexVaultV1_1,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
if (ammV1_1Route.length === 3) {
return composeTx(
'amm-swap-pool-v1-1',
'swap-helper-b',
{
'token-x-trait': currencyX,
'token-y-trait': ammV1_1Route[0]!.neighbour,
'token-z-trait': ammV1_1Route[1]!.neighbour,
'token-w-trait': ammV1_1Route[2]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
dx: fromAmount,
'min-dw': minDy,
},
[
transfer(stxAddress, currencyX, fromAmount),
transfer(
AlexVaultV1_1,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
ammV1_1Route[1]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[1]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
if (ammV1_1Route.length === 4) {
return composeTx(
'amm-swap-pool-v1-1',
'swap-helper-c',
{
'token-x-trait': currencyX,
'token-y-trait': ammV1_1Route[0]!.neighbour,
'token-z-trait': ammV1_1Route[1]!.neighbour,
'token-w-trait': ammV1_1Route[2]!.neighbour,
'token-v-trait': ammV1_1Route[3]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
'factor-w': AMMSwapPool.getFactor(ammV1_1Route[3]!.pool),
dx: fromAmount,
'min-dv': minDy,
},
[
transfer(stxAddress, currencyX, fromAmount),
transfer(
AlexVaultV1_1,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
ammV1_1Route[1]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[1]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
ammV1_1Route[2]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[2]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
const AlexVault = `${configs.CONTRACT_DEPLOYER}.alex-vault`;
const ammRoute = AMMSwapPool.getRoute(currencyX, currencyY, ammPools);
const middleSteps = router.slice(1, -1);
if (ammRoute.length === 0) {
const reachableInAMM = AMMSwapPool.reachableInAMM(
currencyX,

View File

@@ -15,6 +15,13 @@ export namespace AMMSwapPool {
// AMM_SWAP_POOL_ALEX_WUSDA = 'token-amm-swap-pool:age000-governance-token,token-wusda,1e8',
AMM_SWAP_POOL_ALEX_WDIKO = 'token-amm-swap-pool:age000-governance-token,token-wdiko,1e8',
AMM_SWAP_POOL_WSTX_WCORGI = 'token-amm-swap-pool:token-wstx,token-wcorgi,1e8',
AMM_SWAP_POOL_WSTX_SUSDT = 'token-amm-swap-pool:token-wstx,token-susdt,1e8',
AMM_SWAP_POOL_V1_1_WSTX_XBTC = 'token-amm-swap-pool-v1-1:token-wstx,token-wbtc,1e8',
AMM_SWAP_POOL_V1_1_WSTX_SUSDT = 'token-amm-swap-pool-v1-1:token-wstx,token-susdt,1e8',
AMM_SWAP_POOL_V1_1_WSTX_ALEX = 'token-amm-swap-pool-v1-1:token-wstx,age000-governance-token,1e8',
AMM_SWAP_POOL_V1_1_ALEX_DIKO = 'token-amm-swap-pool-v1-1:age000-governance-token,token-wdiko,1e8',
AMM_SWAP_POOL_V1_1_ALEX_ATALEXV2 = 'token-amm-swap-pool-v1-1:age000-governance-token,auto-alex-v2,1e8',
}
export type SwapTokens = Currency;
@@ -42,11 +49,24 @@ export namespace AMMSwapPool {
Pool.AMM_SWAP_POOL_WXUSD_WUSDA_2,
Pool.AMM_SWAP_POOL_ALEX_WDIKO,
Pool.AMM_SWAP_POOL_WSTX_WCORGI,
Pool.AMM_SWAP_POOL_WSTX_SUSDT,
];
export type PoolTokens = (typeof ammTokens)[number];
export const isPoolToken = (token: string): token is PoolTokens =>
ammTokens.includes(token as PoolTokens);
export const ammV1_1Tokens = [
Pool.AMM_SWAP_POOL_V1_1_WSTX_SUSDT,
Pool.AMM_SWAP_POOL_V1_1_WSTX_XBTC,
Pool.AMM_SWAP_POOL_V1_1_WSTX_ALEX,
Pool.AMM_SWAP_POOL_V1_1_ALEX_DIKO,
Pool.AMM_SWAP_POOL_V1_1_ALEX_ATALEXV2,
];
export type PoolTokens = Pool;
export const isPoolV1Token = (token: string): token is PoolTokens =>
ammTokens.includes(token as any);
export const isPoolV1_1Token = (token: string): token is PoolTokens =>
ammV1_1Tokens.includes(token as any);
export const fromXY = (
x: Currency,
@@ -78,6 +98,18 @@ export namespace AMMSwapPool {
return [Currency.ALEX, Currency.DIKO];
case Pool.AMM_SWAP_POOL_WSTX_WCORGI:
return [Currency.STX, Currency.CORGI];
case Pool.AMM_SWAP_POOL_WSTX_SUSDT:
return [Currency.STX, Currency.sUSDT];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_XBTC:
return [Currency.STX, Currency.XBTC];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_ALEX:
return [Currency.STX, Currency.ALEX];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_SUSDT:
return [Currency.STX, Currency.sUSDT];
case Pool.AMM_SWAP_POOL_V1_1_ALEX_DIKO:
return [Currency.ALEX, Currency.DIKO];
case Pool.AMM_SWAP_POOL_V1_1_ALEX_ATALEXV2:
return [Currency.ALEX, Currency.ATALEXV2];
default:
assertNever(poolToken);
}
@@ -95,6 +127,12 @@ export namespace AMMSwapPool {
// case Pool.AMM_SWAP_POOL_ALEX_WUSDA:
case Pool.AMM_SWAP_POOL_ALEX_WDIKO:
case Pool.AMM_SWAP_POOL_WSTX_WCORGI:
case Pool.AMM_SWAP_POOL_WSTX_SUSDT:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_XBTC:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_ALEX:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_SUSDT:
case Pool.AMM_SWAP_POOL_V1_1_ALEX_DIKO:
case Pool.AMM_SWAP_POOL_V1_1_ALEX_ATALEXV2:
return BigInt(1e8);
default:
assertNever(poolToken);