Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MEX-663] Fix tokens liquidity #1549

Merged
merged 8 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@
"VOLUME_WEIGHT": 0.25,
"TRADES_COUNT_WEIGHT": 0.25
},
"AWS_QUERY_CACHE_WARMER_DELAY": 100
"AWS_QUERY_CACHE_WARMER_DELAY": 50
},
"dataApi": {
"tableName": "XEXCHANGE_ANALYTICS"
Expand Down
16 changes: 2 additions & 14 deletions src/modules/pair/services/pair.compute.loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,8 @@ export class PairComputeLoader {
string
>(
async (addresses: string[]) => {
return await getAllKeys(
this.cacheService,
return await this.pairCompute.getAllFirstTokensLockedValueUSD(
addresses,
'pair.firstTokenLockedValueUSD',
this.pairCompute.firstTokenLockedValueUSD.bind(
this.pairCompute,
),
CacheTtlInfo.ContractInfo,
);
},
{
Expand All @@ -106,14 +100,8 @@ export class PairComputeLoader {
string
>(
async (addresses: string[]) => {
return await getAllKeys(
this.cacheService,
return await this.pairCompute.getAllSecondTokensLockedValueUSD(
addresses,
'pair.secondTokenLockedValueUSD',
this.pairCompute.secondTokenLockedValueUSD.bind(
this.pairCompute,
),
CacheTtlInfo.ContractInfo,
);
},
{
Expand Down
72 changes: 64 additions & 8 deletions src/modules/pair/services/pair.compute.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { CacheService } from '@multiversx/sdk-nestjs-cache';
import { getAllKeys } from 'src/utils/get.many.utils';
import moment from 'moment';
import { ElasticSearchEventsService } from 'src/services/elastic-search/services/es.events.service';
import { RouterAbiService } from 'src/modules/router/services/router.abi.service';

@Injectable()
export class PairComputeService implements IPairComputeService {
Expand All @@ -49,6 +50,7 @@ export class PairComputeService implements IPairComputeService {
private readonly apiService: MXApiService,
private readonly farmCompute: FarmComputeServiceV2,
private readonly stakingCompute: StakingComputeService,
private readonly routerAbi: RouterAbiService,
private readonly cachingService: CacheService,
private readonly elasticEventsService: ElasticSearchEventsService,
) {}
Expand Down Expand Up @@ -313,6 +315,18 @@ export class PairComputeService implements IPairComputeService {
.multipliedBy(firstTokenPriceUSD);
}

async getAllFirstTokensLockedValueUSD(
pairAddresses: string[],
): Promise<string[]> {
return await getAllKeys(
this.cachingService,
pairAddresses,
'pair.firstTokenLockedValueUSD',
this.firstTokenLockedValueUSD.bind(this),
CacheTtlInfo.ContractInfo,
);
}

@ErrorLoggerAsync({
logArgs: true,
})
Expand Down Expand Up @@ -343,6 +357,18 @@ export class PairComputeService implements IPairComputeService {
.multipliedBy(secondTokenPriceUSD);
}

async getAllSecondTokensLockedValueUSD(
pairAddresses: string[],
): Promise<string[]> {
return await getAllKeys(
this.cachingService,
pairAddresses,
'pair.secondTokenLockedValueUSD',
this.secondTokenLockedValueUSD.bind(this),
CacheTtlInfo.ContractInfo,
);
}

@ErrorLoggerAsync({
logArgs: true,
})
Expand All @@ -357,15 +383,45 @@ export class PairComputeService implements IPairComputeService {
}

async computeLockedValueUSD(pairAddress: string): Promise<BigNumber> {
const [firstTokenLockedValueUSD, secondTokenLockedValueUSD] =
await Promise.all([
this.computeFirstTokenLockedValueUSD(pairAddress),
this.computeSecondTokenLockedValueUSD(pairAddress),
]);

return new BigNumber(firstTokenLockedValueUSD).plus(
const [
firstTokenLockedValueUSD,
secondTokenLockedValueUSD,
);
firstTokenID,
secondTokenID,
commonTokenIDs,
] = await Promise.all([
this.computeFirstTokenLockedValueUSD(pairAddress),
this.computeSecondTokenLockedValueUSD(pairAddress),
this.pairAbi.firstTokenID(pairAddress),
this.pairAbi.secondTokenID(pairAddress),
this.routerAbi.commonTokensForUserPairs(),
]);

if (
commonTokenIDs.includes(firstTokenID) &&
commonTokenIDs.includes(secondTokenID)
) {
return new BigNumber(firstTokenLockedValueUSD).plus(
secondTokenLockedValueUSD,
);
}

const state = await this.pairAbi.state(pairAddress);
if (state === 'Active') {
return new BigNumber(firstTokenLockedValueUSD).plus(
secondTokenLockedValueUSD,
);
}

if (commonTokenIDs.includesNone([firstTokenID, secondTokenID])) {
return new BigNumber(0);
}

const commonTokenLockedValueUSD = commonTokenIDs.includes(firstTokenID)
? new BigNumber(firstTokenLockedValueUSD)
: new BigNumber(secondTokenLockedValueUSD);

return commonTokenLockedValueUSD.multipliedBy(2);
}

@ErrorLoggerAsync({
Expand Down
86 changes: 61 additions & 25 deletions src/modules/tokens/services/token.compute.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import moment from 'moment';
import { PendingExecutor } from 'src/utils/pending.executor';
import { CacheService } from '@multiversx/sdk-nestjs-cache';
import { TokenService } from './token.service';
import { computeValueUSD } from 'src/utils/token.converters';
import { getAllKeys } from 'src/utils/get.many.utils';
import { ElasticSearchEventsService } from 'src/services/elastic-search/services/es.events.service';

Expand Down Expand Up @@ -550,33 +549,70 @@ export class TokenComputeService implements ITokenComputeService {
}

async computeTokenLiquidityUSD(tokenID: string): Promise<string> {
const pairs = await this.routerAbi.pairsMetadata();
const priceUSD = await this.tokenPriceDerivedUSD(tokenID);
const tokenMetadata = await this.tokenService.tokenMetadata(tokenID);
const promises = [];
for (const pair of pairs) {
switch (tokenID) {
case pair.firstTokenID:
promises.push(this.pairAbi.firstTokenReserve(pair.address));
break;
case pair.secondTokenID:
promises.push(
this.pairAbi.secondTokenReserve(pair.address),
);
break;
const [pairs, commonTokenIDs] = await Promise.all([
this.routerAbi.pairsMetadata(),
this.routerAbi.commonTokensForUserPairs(),
]);

const relevantPairs = pairs.filter(
(pair) =>
tokenID === pair.firstTokenID || pair.secondTokenID === tokenID,
);

const [
allFirstTokensLockedValueUSD,
allSecondTokensLockedValueUSD,
allPairsState,
] = await Promise.all([
this.pairCompute.getAllFirstTokensLockedValueUSD(
relevantPairs.map((pair) => pair.address),
),
this.pairCompute.getAllSecondTokensLockedValueUSD(
relevantPairs.map((pair) => pair.address),
),
this.pairService.getAllStates(
relevantPairs.map((pair) => pair.address),
),
]);

let newLockedValue = new BigNumber(0);
for (const [index, pair] of relevantPairs.entries()) {
const firstTokenLockedValueUSD =
allFirstTokensLockedValueUSD[index];
const secondTokenLockedValueUSD =
allSecondTokensLockedValueUSD[index];
const state = allPairsState[index];

if (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should reconsider this check as it isn't accurate.

state === 'Active' ||
(commonTokenIDs.includes(pair.firstTokenID) &&
commonTokenIDs.includes(pair.secondTokenID))
) {
const tokenLockedValueUSD =
tokenID === pair.firstTokenID
? firstTokenLockedValueUSD
: secondTokenLockedValueUSD;
newLockedValue = newLockedValue.plus(tokenLockedValueUSD);
continue;
}

if (
!commonTokenIDs.includes(pair.firstTokenID) &&
!commonTokenIDs.includes(pair.secondTokenID)
) {
continue;
}

const commonTokenLockedValueUSD = commonTokenIDs.includes(
pair.firstTokenID,
)
? new BigNumber(firstTokenLockedValueUSD)
: new BigNumber(secondTokenLockedValueUSD);

newLockedValue = newLockedValue.plus(commonTokenLockedValueUSD);
}
const allLockedValues = await Promise.all(promises);
let newLockedValue = new BigNumber(0);
allLockedValues.forEach((value) => {
newLockedValue = newLockedValue.plus(value);
});

return computeValueUSD(
newLockedValue.toFixed(),
tokenMetadata.decimals,
priceUSD,
).toFixed();
return newLockedValue.toFixed();
}

async getAllTokensLiquidityUSD(tokenIDs: string[]): Promise<string[]> {
Expand Down
2 changes: 1 addition & 1 deletion src/services/crons/aws.query.cache.warmer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export class AWSQueryCacheWarmerService {
);
}

@Cron(CronExpression.EVERY_5_MINUTES)
@Cron(CronExpression.EVERY_10_MINUTES)
@Lock({ name: 'updateHistoricPairsData', verbose: true })
async updateHistoricPairsData(): Promise<void> {
if (!this.apiConfig.isAWSTimestreamRead()) {
Expand Down
Loading