Skip to content

Commit

Permalink
Pool definition
Browse files Browse the repository at this point in the history
  • Loading branch information
Sluder committed Mar 7, 2024
1 parent 71e5fc6 commit 48673d6
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 119 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

All notable changes to Dexter will be documented in this file.

## [UNRELEASED]
- SundaeSwap v3 implementation

## [v5.1.0]
- Fix cancelling orders for each DEX
- Add new split cancel order request
Expand Down
4 changes: 4 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export enum DatumParameterKey {
BatcherFee = 'BatcherFee',
DepositFee = 'DepositFee',
ScooperFee = 'ScooperFee',
OpeningFee = 'OpeningFee',
FinalFee = 'FinalFee',
FeesFinalized = 'FeesFinalized',
MarketOpen = 'MarketOpen',

/**
* LP info.
Expand Down
142 changes: 75 additions & 67 deletions src/dex/api/sundaeswap-v3-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { BaseApi } from './base-api';
import { Asset, Token } from '../models/asset';
import { LiquidityPool } from '../models/liquidity-pool';
import axios, { AxiosInstance } from 'axios';
import { SundaeSwapV1 } from '../sundaeswap-v1';
import { RequestConfig } from '@app/types';
import { appendSlash } from '@app/utils';
import { SundaeSwapV3 } from '@dex/sundaeswap-v3';
Expand All @@ -25,90 +24,99 @@ export class SundaeSwapV3Api extends BaseApi {
});
}

liquidityPools(assetA: Token, assetB?: Token): Promise<LiquidityPool[]> {
const maxPerPage: number = 100;

async liquidityPools(assetA: Token, assetB?: Token): Promise<LiquidityPool[]> {
const assetAId: string = (assetA === 'lovelace')
? ''
? 'ada.lovelace'
: assetA.identifier('.');
let assetBId: string = (assetB && assetB !== 'lovelace')
const assetBId: string = (assetB && assetB !== 'lovelace')
? assetB.identifier('.')
: '';
: 'ada.lovelace';
const assets: string[] = [assetAId, assetBId].sort();

const getPaginatedResponse = (page: number): Promise<LiquidityPool[]> => {
return this.api.post('', {
operationName: 'getPoolsByAssetIds',
query: `
query getPoolsByAssetIds($assetIds: [String!]!, $pageSize: Int, $page: Int) {
pools(assetIds: $assetIds, pageSize: $pageSize, page: $page) {
...PoolFragment
return await this.api.post('', {
operationName: 'fetchPoolsByPair',
query: `
query fetchPoolsByPair($assetA: ID!, $assetB: ID!) {
pools {
byPair(assetA: $assetA, assetB: $assetB) {
...PoolBrambleFragment
}
}
fragment PoolFragment on Pool {
assetA {
...AssetFragment
}
assetB {
...AssetFragment
}
assetLP {
...AssetFragment
}
name
fee
quantityA
quantityB
quantityLP
ident
assetID
}
fragment PoolBrambleFragment on Pool {
id
assetA {
...AssetBrambleFragment
}
assetB {
...AssetBrambleFragment
}
assetLP {
...AssetBrambleFragment
}
feesFinalized {
slot
}
marketOpen {
slot
}
openingFee
finalFee
current {
quantityA {
quantity
}
quantityB {
quantity
}
fragment AssetFragment on Asset {
assetId
decimals
quantityLP {
quantity
}
`,
variables: {
page: page,
pageSize: maxPerPage,
assetIds: [assetBId !== '' ? assetBId : assetAId],
},
}).then((response: any) => {
const pools = response.data.data.pools;
const liquidityPools = pools.map((pool: any) => {
tvl {
quantity
}
}
version
}
fragment AssetBrambleFragment on Asset {
id
decimals
}
`,
variables: {
assetA: assets[0],
assetB: assets[1],
},
}).then((response: any) => {
const pools = response.data.data.pools.byPair;

return pools
.filter((pool: any) => pool.version === 'V3')
.map((pool: any) => {
let liquidityPool: LiquidityPool = new LiquidityPool(
SundaeSwapV1.identifier,
pool.assetA.assetId
? Asset.fromIdentifier(pool.assetA.assetId, pool.assetA.decimals)
: 'lovelace',
pool.assetB.assetId
? Asset.fromIdentifier(pool.assetB.assetId, pool.assetB.decimals)
: 'lovelace',
BigInt(pool.quantityA),
BigInt(pool.quantityB),
SundaeSwapV3.identifier,
pool.assetA.id === 'ada.lovelace'
? 'lovelace'
: Asset.fromIdentifier(pool.assetA.id, pool.assetA.decimals),
pool.assetB.id === 'ada.lovelace'
? 'lovelace'
: Asset.fromIdentifier(pool.assetB.id, pool.assetB.decimals),
BigInt(pool.current.quantityA),
BigInt(pool.current.quantityB),
this.dex.poolAddress,
this.dex.orderAddress,
this.dex.orderAddress,
);

liquidityPool.identifier = pool.ident;
liquidityPool.lpToken = Asset.fromIdentifier(pool.assetLP.assetId);
liquidityPool.poolFeePercent = Number(pool.fee);
liquidityPool.totalLpTokens = BigInt(pool.quantityLP);
liquidityPool.identifier = pool.id;
liquidityPool.lpToken = Asset.fromIdentifier(pool.assetLP.id);
liquidityPool.poolFeePercent = Number((pool.openingFee[0] / pool.openingFee[1]) * 100);
liquidityPool.totalLpTokens = BigInt(pool.current.quantityLP.quantity);

return liquidityPool;
});
});

if (pools.length < maxPerPage) {
return liquidityPools;
}

return getPaginatedResponse(page + 1).then((nextPagePools: LiquidityPool[]) => {
return liquidityPools.concat(nextPagePools);
});
});
};

return getPaginatedResponse(0);
}

}
61 changes: 29 additions & 32 deletions src/dex/definitions/sundaeswap-v3/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,45 @@ export default {
constructor: 0,
fields: [
{
constructor: 0,
fields: [
bytes: DatumParameterKey.PoolIdentifier
},
[
[
{
bytes: DatumParameterKey.PoolAssetAPolicyId
},
{
constructor: 0,
fields: [
{
bytes: DatumParameterKey.PoolAssetAPolicyId
},
{
bytes: DatumParameterKey.PoolAssetAAssetName
}
]
bytes: DatumParameterKey.PoolAssetAAssetName
}
],
[
{
bytes: DatumParameterKey.PoolAssetBPolicyId
},
{
constructor: 0,
fields: [
{
bytes: DatumParameterKey.PoolAssetBPolicyId
},
{
bytes: DatumParameterKey.PoolAssetBAssetName
}
]
bytes: DatumParameterKey.PoolAssetBAssetName
}
]
],
{
int: DatumParameterKey.TotalLpTokens
},
[
{
int: DatumParameterKey.OpeningFee
},
{
int: DatumParameterKey.FinalFee
}
],
{
bytes: DatumParameterKey.PoolIdentifier
int: DatumParameterKey.FeesFinalized
},
{
int: DatumParameterKey.TotalLpTokens
int: DatumParameterKey.MarketOpen
},
{
constructor: 0,
fields: [
{
int: DatumParameterKey.LpFeeNumerator
},
{
int: DatumParameterKey.LpFeeDenominator
}
]
int: "36925460726"
}
]
}
}
33 changes: 13 additions & 20 deletions src/dex/sundaeswap-v3.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LiquidityPool } from './models/liquidity-pool';
import { BaseDataProvider } from '@providers/data/base-data-provider';
import { Asset, Token } from './models/asset';
import { Token } from './models/asset';
import { BaseDex } from './base-dex';
import {
AssetBalance,
Expand Down Expand Up @@ -29,13 +29,15 @@ export class SundaeSwapV3 extends BaseDex {
/**
* On-Chain constants.
*/
public readonly orderAddress: string = '';
public readonly poolAddress: string = '';
public readonly lpTokenPolicyId: string = '';
// TODO - update for mainnet
public readonly orderAddress: string = 'addr_test1zpyyj6wexm6gf3zlzs7ez8upvdh7jfgy3cs9qj8wrljp925y2usavetr7qg4zg6cc8kqup4veczmfykgquw2kmmuhs5qkzsen3';
public readonly poolAddress: string = 'addr_test1wzq5p39cjs50cfjwjzcscuw98fxrl8899dnkhuwek50tnjs09luug';
public readonly lpTokenPolicyId: string = '4086577ed57c514f8e29b78f42ef4f379363355a3b65b9a032ee30c9';
public readonly validityTokenPolicyId: string = '8140c4b89428fc264e90b10c71c53a4c3f9ce52b676bf1d9b51eb9ca';
public readonly cancelDatum: string = 'd87a80';
public readonly orderScript: Script = {
type: 'PlutusV1',
script: '',
script: '59081f010000332323232323232322322223253330093232533300b3370e90010010991919991119198008008021119299980999b87480000044c8c8cc00400401c894ccc06400452809919299980c19b8f00200514a226600800800260380046eb8c068004dd7180b98088010a99980999b87480080044c8c8c8cc004004008894ccc06800452889919299980c998048048010998020020008a50301d002301b0013758603000260220042a66602666e1d200400113232323300100100222533301a00114a026464a6660326601201200429444cc010010004c074008c06c004dd6180c00098088010a99980999b87480180044c8c8c8c8cdc48019919980080080124000444a66603a00420022666006006603e00464a66603666016016002266e0000920021002301e0023758603400260340046eb4c060004c04400854ccc04ccdc3a4010002264646464a66602e66e1d20020011323253330193370e9001180d1baa300d3017300d301700a13371200200a266e20004014dd6980e000980a8010a503015001300b301330093013006375a60300026022004264646464a66602e66e1d20020011323253330193370e9001180d1baa300d3017300f301700a13371200a002266e20014004dd6980e000980a8010a503015001300b3013300b3013006375a603000260220046022002600260160106eb0c044c048c048c048c048c048c048c048c048c02cc00cc02c018c044c048c048c048c048c048c048c048c02cc00cc02c0188c044c048004c8c8c8c8c94ccc040cdc3a40000022646464646464646464646464a66603e60420042646464649319299981019b87480000044c8c94ccc094c09c00852616375c604a002603c00e2a66604066e1d20020011323232325333027302900213232498c8c8c8c8c94ccc0b4c0bc00852616375a605a002605a0046eb8c0ac004c0ac00cdd718148011919191919299981618170010a4c2c6eb4c0b0004c0b0008dd7181500098150021bae3028003163758604e002604e0046eb0c094004c07801c54ccc080cdc3a400800226464a66604a604e004264931919191919191919299981698178010a4c2c6eb4c0b4004c0b4008dd7181580098158019bae30290023232323232533302c302e002149858dd6981600098160011bae302a001302a003375c60500046eb0c094008dd618118008b1919bb03026001302630270013758604a002603c00e2a66604066e1d20060011323253330253027002132498c8c8c8c8c94ccc0a8c0b000852616375a605400260540046eb8c0a0004c0a0008dd718130008b1bac3025001301e007153330203370e9004000899192999812981380109924c6464646464646464a66605a605e0042930b1bad302d001302d002375c605600260560066eb8c0a4008c8c8c8c8c94ccc0b0c0b800852616375a605800260580046eb8c0a8004c0a800cdd718140011bac3025002375860460022c6466ec0c098004c098c09c004dd61812800980f0038b180f00319299980f99b87480000044c8c8c8c94ccc098c0a00084c8c9263253330253370e90000008a99981418118018a4c2c2a66604a66e1d200200113232533302a302c002149858dd7181500098118018a99981299b87480100044c8c94ccc0a8c0b000852616302a00130230031630230023253330243370e9000000899191919299981598168010991924c64a66605466e1d200000113232533302f3031002132498c94ccc0b4cdc3a400000226464a66606460680042649318120008b181900098158010a99981699b87480080044c8c8c8c8c8c94ccc0d8c0e000852616375a606c002606c0046eb4c0d0004c0d0008dd6981900098158010b18158008b181780098140018a99981519b874800800454ccc0b4c0a000c52616163028002301d00316302b001302b0023029001302200416302200316302600130260023024001301d00816301d007300f00a32533301d3370e900000089919299981118120010a4c2c6eb8c088004c06c03054ccc074cdc3a40040022a66604060360182930b0b180d8058b180f800980f801180e800980e801180d800980d8011bad30190013019002301700130170023015001300e00b16300e00a3001001223253330103370e900000089919299980a980b8010a4c2c6eb8c054004c03800854ccc040cdc3a400400226464a66602a602e00426493198030009198030030008b1bac3015001300e002153330103370e900200089919299980a980b80109924c6600c00246600c00c0022c6eb0c054004c03800854ccc040cdc3a400c002264646464a66602e603200426493198040009198040040008b1bac30170013017002375a602a002601c0042a66602066e1d20080011323253330153017002149858dd6980a80098070010a99980819b87480280044c8c94ccc054c05c00852616375a602a002601c0042c601c00244646600200200644a66602600229309919801801980b0011801980a000919299980699b87480000044c8c94ccc048c05000852616375c602400260160042a66601a66e1d20020011323253330123014002149858dd7180900098058010b1805800899192999808180900109919299980799b8748000c0380084c8c94ccc044cdc3a40046020002266e3cdd7180a9807800806801980a00098068010008a50300e0011630100013756601e6020602060206020602060206012600260120084601e002601000629309b2b19299980499b874800000454ccc030c01c00c52616153330093370e90010008a99980618038018a4c2c2c600e0046eb80048c014dd5000918019baa0015734aae7555cf2ab9f5742ae893011e581c6ed8ba08a3a0ab1cdc63079fb057f84ff43f87dc4792f6f09b94e8030001',
};

constructor(requestConfig: RequestConfig = {}) {
Expand Down Expand Up @@ -71,11 +73,11 @@ export class SundaeSwapV3 extends BaseDex {
const relevantAssets: AssetBalance[] = utxo.assetBalances.filter((assetBalance: AssetBalance) => {
const assetBalanceId: string = assetBalance.asset === 'lovelace' ? 'lovelace' : assetBalance.asset.identifier();

return ! assetBalanceId.startsWith(this.lpTokenPolicyId);
return ! assetBalanceId.startsWith(this.validityTokenPolicyId);
});

// Irrelevant UTxO
if (! [2, 3].includes(relevantAssets.length)) {
if (relevantAssets.length !== 2) {
return Promise.resolve(undefined);
}

Expand All @@ -94,28 +96,18 @@ export class SundaeSwapV3 extends BaseDex {
this.orderAddress,
);

// Load additional pool information
const lpToken: Asset = utxo.assetBalances.find((assetBalance) => {
return assetBalance.asset !== 'lovelace' && assetBalance.asset.policyId === this.lpTokenPolicyId;
})?.asset as Asset;

if (lpToken) {
lpToken.nameHex = '6c' + lpToken.nameHex;
liquidityPool.lpToken = lpToken;
liquidityPool.identifier = lpToken.identifier();
}

try {
const builder: DefinitionBuilder = await (new DefinitionBuilder())
.loadDefinition(pool);
const datum: DefinitionField = await provider.datumValue(utxo.datumHash);
const parameters: DatumParameters = builder.pullParameters(datum as DefinitionConstr);

// TODO - can we grab the LP token?
liquidityPool.identifier = typeof parameters.PoolIdentifier === 'string'
? parameters.PoolIdentifier
: '';
liquidityPool.poolFeePercent = typeof parameters.LpFeeNumerator === 'number' && typeof parameters.LpFeeDenominator === 'number'
? (parameters.LpFeeNumerator / parameters.LpFeeDenominator) * 100
liquidityPool.poolFeePercent = typeof parameters.OpeningFee === 'number'
? (parameters.OpeningFee / 10_000) * 100
: 0;
liquidityPool.totalLpTokens = typeof parameters.TotalLpTokens === 'number'
? BigInt(parameters.TotalLpTokens)
Expand Down Expand Up @@ -153,6 +145,7 @@ export class SundaeSwapV3 extends BaseDex {
}

public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: SpendUTxO[] = []): Promise<PayToAddress[]> {
// TODO
const scooperFee: SwapFee | undefined = this.swapOrderFees(liquidityPool).find((fee: SwapFee) => fee.id === 'scooperFee');
const deposit: SwapFee | undefined = this.swapOrderFees(liquidityPool).find((fee: SwapFee) => fee.id === 'deposit');

Expand Down

0 comments on commit 48673d6

Please sign in to comment.