From 64876c7ddc33159034f4ced968eb26bead681e60 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 24 Nov 2024 20:11:38 -0500 Subject: [PATCH] WingRiders V2 --- README.md | 1 + src/constants.ts | 9 + src/dex/definitions/wingriders-v2/order.ts | 110 ++++++++ src/dex/definitions/wingriders-v2/pool.ts | 71 +++++ src/dex/logo/wingridersv2.png | Bin 0 -> 27931 bytes src/dex/wingriders-v2.ts | 300 +++++++++++++++++++++ src/dex/wingriders.ts | 7 +- src/dexter.ts | 2 + src/index.ts | 1 + 9 files changed, 495 insertions(+), 6 deletions(-) create mode 100644 src/dex/definitions/wingriders-v2/order.ts create mode 100644 src/dex/definitions/wingriders-v2/pool.ts create mode 100644 src/dex/logo/wingridersv2.png create mode 100644 src/dex/wingriders-v2.ts diff --git a/README.md b/README.md index 586af9d..8f787b2 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ + diff --git a/src/constants.ts b/src/constants.ts index 6ae00df..e3722dd 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -12,6 +12,8 @@ export enum DatumParameterKey { ReserveA = 'ReserveA', ReserveB = 'ReserveB', CancelDatum = 'CancelDatum', + AScale = 'AScale', + BScale = 'BScale', /** * Swap/wallet info. @@ -45,6 +47,11 @@ export enum DatumParameterKey { FeesFinalized = 'FeesFinalized', MarketOpen = 'MarketOpen', ProtocolFee = 'ProtocolFee', + SwapFee = 'SwapFee', + ProjectFeeInBasis = 'ProjectFeeInBasis', + ReserveFeeInBasis = 'ReserveFeeInBasis', + FeeBasis = 'FeeBasis', + AgentFee = 'AgentFee', /** * LP info. @@ -69,6 +76,8 @@ export enum DatumParameterKey { RequestScriptHash = 'RequestScriptHash', StakeAdminPolicy = 'StakeAdminPolicy', LqBound = 'LqBound', + + Unknown = 'Unknown', } export enum TransactionStatus { diff --git a/src/dex/definitions/wingriders-v2/order.ts b/src/dex/definitions/wingriders-v2/order.ts new file mode 100644 index 0000000..0a6902d --- /dev/null +++ b/src/dex/definitions/wingriders-v2/order.ts @@ -0,0 +1,110 @@ +import { DatumParameterKey } from '@app/constants'; + +export default { + constructor: 0, + fields: [ + { + int: DatumParameterKey.DepositFee + }, + { + constructor: 0, + fields: [ + { + constructor: 0, + fields: [ + { + bytes: DatumParameterKey.ReceiverPubKeyHash + } + ] + }, + { + constructor: 0, + fields: [ + { + constructor: 0, + fields: [ + { + constructor: 0, + fields: [ + { + bytes: DatumParameterKey.ReceiverStakingKeyHash + } + ] + } + ] + } + ] + } + ] + }, + { + constructor: 0, + fields: [ + { + constructor: 0, + fields: [ + { + bytes: DatumParameterKey.ReceiverPubKeyHash + } + ] + }, + { + constructor: 0, + fields: [ + { + constructor: 0, + fields: [ + { + constructor: 0, + fields: [ + { + bytes: DatumParameterKey.ReceiverStakingKeyHash + } + ] + } + ] + } + ] + } + ] + }, + [], + { + constructor: 0, + fields: [] + }, + { + int: DatumParameterKey.Expiration + }, + { + bytes: DatumParameterKey.PoolAssetAPolicyId + }, + { + bytes: DatumParameterKey.PoolAssetAAssetName + }, + { + bytes: DatumParameterKey.PoolAssetBPolicyId + }, + { + bytes: DatumParameterKey.PoolAssetBAssetName + }, + { + constructor: 0, + fields: [ + { + constructor: DatumParameterKey.Action, + fields: [] + }, + { + int: DatumParameterKey.MinReceive + } + ] + }, + { + int: DatumParameterKey.AScale + }, + { + int: DatumParameterKey.BScale + } + ] +}; \ No newline at end of file diff --git a/src/dex/definitions/wingriders-v2/pool.ts b/src/dex/definitions/wingriders-v2/pool.ts new file mode 100644 index 0000000..c49c1e3 --- /dev/null +++ b/src/dex/definitions/wingriders-v2/pool.ts @@ -0,0 +1,71 @@ +import { DatumParameterKey } from '@app/constants'; +import { DatumParameters, DefinitionField } from '@app/types'; + +export default { + constructor: 0, + fields: [ + { + bytes: DatumParameterKey.RequestScriptHash + }, + { + bytes: DatumParameterKey.PoolAssetAPolicyId, + }, + { + bytes: DatumParameterKey.PoolAssetAAssetName, + }, + { + bytes: DatumParameterKey.PoolAssetBPolicyId, + }, + { + bytes: DatumParameterKey.PoolAssetBAssetName, + }, + { + int: DatumParameterKey.SwapFee + }, + { + int: DatumParameterKey.ProtocolFee + }, + { + int: DatumParameterKey.ProjectFeeInBasis + }, + { + int: DatumParameterKey.ReserveFeeInBasis + }, + { + int: DatumParameterKey.FeeBasis + }, + { + int: DatumParameterKey.AgentFee + }, + { + int: DatumParameterKey.LastInteraction + }, + { + int: DatumParameterKey.PoolAssetATreasury + }, + { + int: DatumParameterKey.PoolAssetBTreasury + }, + { + int: DatumParameterKey.Unknown + }, + { + int: DatumParameterKey.Unknown + }, + { + int: DatumParameterKey.Unknown + }, + { + int: DatumParameterKey.Unknown + }, + (field: DefinitionField, parameters: DatumParameters, shouldExtract: boolean = true) => { + return parameters; + }, + (field: DefinitionField, parameters: DatumParameters, shouldExtract: boolean = true) => { + return parameters; + }, + (field: DefinitionField, parameters: DatumParameters, shouldExtract: boolean = true) => { + return parameters; + }, + ] +}; \ No newline at end of file diff --git a/src/dex/logo/wingridersv2.png b/src/dex/logo/wingridersv2.png new file mode 100644 index 0000000000000000000000000000000000000000..439f7136475c04a9a6b805ed6faae9f0665c7cda GIT binary patch literal 27931 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 literal 0 HcmV?d00001 diff --git a/src/dex/wingriders-v2.ts b/src/dex/wingriders-v2.ts new file mode 100644 index 0000000..26905a5 --- /dev/null +++ b/src/dex/wingriders-v2.ts @@ -0,0 +1,300 @@ +import { BaseDex } from './base-dex'; +import { + AssetAddress, + AssetBalance, + DatumParameters, + DefinitionConstr, + DefinitionField, + PayToAddress, + RequestConfig, SpendUTxO, + SwapFee, + UTxO +} from '@app/types'; +import { Asset, Token } from './models/asset'; +import { LiquidityPool } from './models/liquidity-pool'; +import { BaseDataProvider } from '@providers/data/base-data-provider'; +import { correspondingReserves, tokensMatch } from '@app/utils'; +import { AddressType, DatumParameterKey } from '@app/constants'; +import { DefinitionBuilder } from '@app/definition-builder'; +import order from '@dex/definitions/wingriders-v2/order'; +import { BaseApi } from '@dex/api/base-api'; +import pool from "@dex/definitions/wingriders-v2/pool"; +import { Script } from 'lucid-cardano'; + +/** + * WingRiders constants. + */ +const MIN_POOL_ADA: bigint = 3_000_000n; +const MAX_INT: bigint = 9_223_372_036_854_775_807n; + +export class WingRidersV2 extends BaseDex { + + public static readonly identifier: string = 'WingRidersV2'; + public readonly api: BaseApi; + + /** + * On-Chain constants. + */ + public readonly orderAddress: string = 'addr1w8qnfkpe5e99m7umz4vxnmelxs5qw5dxytmfjk964rla98q605wte'; + public readonly poolValidityAsset: string = '6fdc63a1d71dc2c65502b79baae7fb543185702b12c3c5fb639ed7374c'; + public readonly cancelDatum: string = 'd87a80'; + public readonly orderScript: Script = { + type: 'PlutusV2', + script: '59019e010000323232323232323232222325333008001149858c8c8c94ccc028cdc3a40040042664601444a666aae7c0045280a99980699baf301000100314a226004601c00264646464a66601c66e1d20000021301100116301100230110013754601c601a002601a6010601800c646eb0c038c8c034c034c034c034c034c034c028004c034004c034c0300104ccc888cdc79919191bae301300132323253330123370e90000010b0800980a801180a8009baa3012301100132301230110013011300f301000133300c222533301033712900500109980199b8100248028c044c044c044c044c04400454ccc040cdc3801240002602600226644a66602466e20009200016133301122253330153370e00490000980c00089980199b8100248008c058004008004cdc0801240046022002004646eb0c044c040004c040c03c00400cdd70039bad300d001004300d002300d00137540046ea52211caf97793b8702f381976cec83e303e9ce17781458c73c4bb16fe02b83002300430040012323002233002002001230022330020020015734ae888c00cdd5000aba15573caae741', + }; + + private _assetAddresses: AssetAddress[] = []; + + constructor(requestConfig: RequestConfig = {}) { + super(); + } + + public async liquidityPoolAddresses(provider: BaseDataProvider): Promise { + const validityAsset: Asset = Asset.fromIdentifier(this.poolValidityAsset); + const assetAddresses: AssetAddress[] = this._assetAddresses.length > 0 + ? this._assetAddresses + : await provider.assetAddresses(validityAsset); + + return Promise.resolve([...new Set(assetAddresses.map((assetAddress: AssetAddress) => assetAddress.address))]); + } + + async liquidityPools(provider: BaseDataProvider): Promise { + const validityAsset: Asset = Asset.fromIdentifier(this.poolValidityAsset); + const poolAddresses: string[] = await this.liquidityPoolAddresses(provider); + + const addressPromises: Promise[] = poolAddresses.map(async (address: string) => { + const utxos: UTxO[] = await provider.utxos(address, validityAsset); + + return await Promise.all( + utxos.map(async (utxo: UTxO) => { + return await this.liquidityPoolFromUtxo(provider, utxo); + }) + ) + .then((liquidityPools: (LiquidityPool | undefined)[]) => { + return liquidityPools.filter((liquidityPool?: LiquidityPool) => { + return liquidityPool !== undefined; + }) as LiquidityPool[] + }); + }); + + return Promise.all(addressPromises) + .then((liquidityPools: (Awaited)[]) => liquidityPools.flat()); + } + + public async liquidityPoolFromUtxo(provider: BaseDataProvider, utxo: UTxO): Promise { + if (! utxo.datumHash) { + return Promise.resolve(undefined); + } + + const validityAsset: Asset = Asset.fromIdentifier(this.poolValidityAsset); + + const relevantAssets: AssetBalance[] = utxo.assetBalances.filter((assetBalance: AssetBalance) => { + const assetBalanceId: string = assetBalance.asset === 'lovelace' ? 'lovelace' : assetBalance.asset.identifier(); + + return ! assetBalanceId.startsWith(validityAsset.policyId); + }); + + // Irrelevant UTxO + if (relevantAssets.length < 2) { + return Promise.resolve(undefined); + } + + // Could be ADA/X or X/X pool + const assetAIndex: number = relevantAssets.length === 2 ? 0 : 1; + const assetBIndex: number = relevantAssets.length === 2 ? 1 : 2; + + const assetAQuantity: bigint = relevantAssets[assetAIndex].quantity; + const assetBQuantity: bigint = relevantAssets[assetBIndex].quantity; + const liquidityPool: LiquidityPool = new LiquidityPool( + WingRidersV2.identifier, + relevantAssets[assetAIndex].asset, + relevantAssets[assetBIndex].asset, + relevantAssets[assetAIndex].asset === 'lovelace' + ? (assetAQuantity - MIN_POOL_ADA < 1_000_000n) + ? assetAQuantity - MIN_POOL_ADA + : assetAQuantity + : assetAQuantity, + relevantAssets[assetBIndex].asset === 'lovelace' + ? (assetBQuantity - MIN_POOL_ADA < 1_000_000n) + ? assetBQuantity - MIN_POOL_ADA + : assetBQuantity + : assetBQuantity, + utxo.address, + this.orderAddress, + this.orderAddress, + ); + + const lpTokenBalance: AssetBalance | undefined = utxo.assetBalances.find((assetBalance) => { + return assetBalance.asset !== 'lovelace' + && assetBalance.asset.policyId === validityAsset.policyId + && assetBalance.asset.nameHex !== validityAsset.nameHex; + }); + + if (lpTokenBalance) { + liquidityPool.lpToken = lpTokenBalance.asset as Asset; + liquidityPool.identifier = liquidityPool.lpToken.identifier(); + liquidityPool.totalLpTokens = MAX_INT - lpTokenBalance.quantity; + } + liquidityPool.poolFeePercent = 0.35; + + 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); + + liquidityPool.reserveA = typeof parameters.PoolAssetATreasury === 'number' + ? (liquidityPool.reserveA - BigInt(parameters.PoolAssetATreasury)) + : liquidityPool.reserveA; + liquidityPool.reserveB = typeof parameters.PoolAssetBTreasury === 'number' + ? (liquidityPool.reserveB - BigInt(parameters.PoolAssetBTreasury)) + : liquidityPool.reserveB; + } catch (e) { + return liquidityPool; + } + + return liquidityPool; + } + + estimatedGive(liquidityPool: LiquidityPool, swapOutToken: Token, swapOutAmount: bigint): bigint { + const poolFeeMultiplier: bigint = 10000n; + const poolFeeModifier: bigint = poolFeeMultiplier - BigInt(Math.round((liquidityPool.poolFeePercent / 100) * Number(poolFeeMultiplier))); + + const [reserveOut, reserveIn]: bigint[] = correspondingReserves(liquidityPool, swapOutToken); + + const swapInNumerator: bigint = swapOutAmount * reserveIn * poolFeeMultiplier; + const swapInDenominator: bigint = (reserveOut - swapOutAmount) * poolFeeModifier; + + return swapInNumerator / swapInDenominator; + } + + estimatedReceive(liquidityPool: LiquidityPool, swapInToken: Token, swapInAmount: bigint): bigint { + const poolFeeMultiplier: bigint = 10000n; + const poolFeeModifier: bigint = poolFeeMultiplier - BigInt(Math.round((liquidityPool.poolFeePercent / 100) * Number(poolFeeMultiplier))); + + const [reserveIn, reserveOut]: bigint[] = correspondingReserves(liquidityPool, swapInToken); + + const swapOutNumerator: bigint = swapInAmount * reserveOut * poolFeeModifier; + const swapOutDenominator: bigint = swapInAmount * poolFeeModifier + reserveIn * poolFeeMultiplier; + + return swapOutNumerator / swapOutDenominator; + } + + priceImpactPercent(liquidityPool: LiquidityPool, swapInToken: Token, swapInAmount: bigint): number { + const estimatedReceive: bigint = this.estimatedReceive(liquidityPool, swapInToken, swapInAmount); + const swapPrice: number = Number(swapInAmount) / Number(estimatedReceive); + const poolPrice: number = tokensMatch(liquidityPool.assetA, swapInToken) + ? liquidityPool.price + : (1 / liquidityPool.price); + + return Math.abs(swapPrice - poolPrice) + / ((swapPrice + poolPrice) / 2) + * 100; + } + + public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: SpendUTxO[] = []): Promise { + const agentFee: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'agentFee'); + const oil: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'oil'); + + if (! agentFee || ! oil) { + return Promise.reject('Parameters for datum are not set.'); + } + + const swapInToken: string = (swapParameters.SwapInTokenPolicyId as string) + (swapParameters.SwapInTokenAssetName as string); + const swapOutToken: string = (swapParameters.SwapOutTokenPolicyId as string) + (swapParameters.SwapOutTokenAssetName as string); + const swapDirection: number = [swapInToken, swapOutToken].sort((a: string, b: string) => { + return a.localeCompare(b); + })[0] === swapInToken ? 0 : 1; + + swapParameters = { + ...swapParameters, + [DatumParameterKey.Action]: swapDirection, + [DatumParameterKey.DepositFee]: 2_000000n, + [DatumParameterKey.Expiration]: new Date().getTime() + (60 * 60 * 6 * 1000), + [DatumParameterKey.AScale]: 1, + [DatumParameterKey.BScale]: 1, + [DatumParameterKey.PoolAssetAPolicyId]: swapDirection === 0 + ? swapParameters.SwapInTokenPolicyId + : swapParameters.SwapOutTokenPolicyId, + [DatumParameterKey.PoolAssetAAssetName]: swapDirection === 0 + ? swapParameters.SwapInTokenAssetName + : swapParameters.SwapOutTokenAssetName, + [DatumParameterKey.PoolAssetBPolicyId]: swapDirection === 0 + ? swapParameters.SwapOutTokenPolicyId + : swapParameters.SwapInTokenPolicyId, + [DatumParameterKey.PoolAssetBAssetName]: swapDirection === 0 + ? swapParameters.SwapOutTokenAssetName + : swapParameters.SwapInTokenAssetName, + }; + + const datumBuilder: DefinitionBuilder = new DefinitionBuilder(); + await datumBuilder.loadDefinition(order) + .then((builder: DefinitionBuilder) => { + builder.pushParameters(swapParameters); + }); + + return [ + this.buildSwapOrderPayment( + swapParameters, + { + address: this.orderAddress, + addressType: AddressType.Contract, + assetBalances: [ + { + asset: 'lovelace', + quantity: agentFee.value + oil.value, + }, + ], + datum: datumBuilder.getCbor(), + isInlineDatum: true, + spendUtxos: spendUtxos, + } + ) + ]; + } + + public async buildCancelSwapOrder(txOutputs: UTxO[], returnAddress: string): Promise { + const relevantUtxo: UTxO | undefined = txOutputs.find((utxo: UTxO) => { + return utxo.address === this.orderAddress; + }); + + if (! relevantUtxo) { + return Promise.reject('Unable to find relevant UTxO for cancelling the swap order.'); + } + + return [ + { + address: returnAddress, + addressType: AddressType.Base, + assetBalances: relevantUtxo.assetBalances, + isInlineDatum: false, + spendUtxos: [{ + utxo: relevantUtxo, + redeemer: this.cancelDatum, + validator: this.orderScript, + signer: returnAddress, + }], + } + ]; + } + + public swapOrderFees(): SwapFee[] { + return [ + { + id: 'agentFee', + title: 'Agent Fee', + description: 'WingRiders DEX employs decentralized Agents to ensure equal access, strict fulfillment ordering and protection to every party involved in exchange for a small fee.', + value: 2_000000n, + isReturned: false, + }, + { + id: 'oil', + title: 'Oil', + description: 'A small amount of ADA has to be bundled with all token transfers on the Cardano Blockchain. We call this "Oil ADA" and it is always returned to the owner when the request gets fulfilled. If the request expires and the funds are reclaimed, the Oil ADA is returned as well.', + value: 2_000000n, + isReturned: true, + }, + ]; + } + +} diff --git a/src/dex/wingriders.ts b/src/dex/wingriders.ts index a7c6665..851e4cd 100644 --- a/src/dex/wingriders.ts +++ b/src/dex/wingriders.ts @@ -184,13 +184,8 @@ export class WingRiders extends BaseDex { } priceImpactPercent(liquidityPool: LiquidityPool, swapInToken: Token, swapInAmount: bigint): number { - const swapOutTokenDecimals: number = tokensMatch(liquidityPool.assetA, swapInToken) - ? (liquidityPool.assetB === 'lovelace' ? 6 : liquidityPool.assetB.decimals) - : (liquidityPool.assetA === 'lovelace' ? 6 : liquidityPool.assetA.decimals) - const estimatedReceive: bigint = this.estimatedReceive(liquidityPool, swapInToken, swapInAmount); - const swapPrice: number = (Number(swapInAmount) / 10**(swapInToken === 'lovelace' ? 6 : swapInToken.decimals)) - / (Number(estimatedReceive) / 10**swapOutTokenDecimals); + const swapPrice: number = Number(swapInAmount) / Number(estimatedReceive); const poolPrice: number = tokensMatch(liquidityPool.assetA, swapInToken) ? liquidityPool.price : (1 / liquidityPool.price); diff --git a/src/dexter.ts b/src/dexter.ts index aac5feb..69b6e6f 100644 --- a/src/dexter.ts +++ b/src/dexter.ts @@ -20,6 +20,7 @@ import { Spectrum } from '@dex/spectrum'; import { SplitCancelSwapRequest } from '@requests/split-cancel-swap-request'; import { SundaeSwapV3 } from '@dex/sundaeswap-v3'; import { MinswapV2 } from '@dex/minswap-v2'; +import { WingRidersV2 } from '@dex/wingriders-v2'; export class Dexter { @@ -65,6 +66,7 @@ export class Dexter { [MinswapV2.identifier]: new MinswapV2(this.requestConfig), [MuesliSwap.identifier]: new MuesliSwap(this.requestConfig), [WingRiders.identifier]: new WingRiders(this.requestConfig), + [WingRidersV2.identifier]: new WingRidersV2(this.requestConfig), [VyFinance.identifier]: new VyFinance(this.requestConfig), [TeddySwap.identifier]: new TeddySwap(this.requestConfig), [Spectrum.identifier]: new Spectrum(this.requestConfig), diff --git a/src/index.ts b/src/index.ts index e9b7b50..c3554fd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,6 +45,7 @@ export * from './dex/sundaeswap-v1'; export * from './dex/sundaeswap-v3'; export * from './dex/muesliswap'; export * from './dex/wingriders'; +export * from './dex/wingriders-v2'; export * from './dex/vyfinance'; export * from './dex/teddyswap'; export * from './dex/spectrum';