From e1a2bcffb64b7beb90bf6e36722b581331f3300f Mon Sep 17 00:00:00 2001 From: Lezek123 Date: Thu, 7 Nov 2024 12:17:03 +0100 Subject: [PATCH] Marketplace tokens: configurable minimum volume threshold --- .env | 1 + CHANGELOG.md | 9 ++++++++- ...1730895049782-Views.js => 1730976542053-Views.js} | 4 ++-- db/viewDefinitions.js | 11 +++++++++-- schema/auth.graphql | 1 + .../resolvers/AdminResolver/index.ts | 12 +++++++++++- .../resolvers/AdminResolver/types.ts | 12 ++++++++++++ src/utils/config.ts | 2 ++ 8 files changed, 46 insertions(+), 6 deletions(-) rename db/migrations/{1730895049782-Views.js => 1730976542053-Views.js} (94%) diff --git a/.env b/.env index c916afc28..4cfeaa3d2 100644 --- a/.env +++ b/.env @@ -27,6 +27,7 @@ ARCHIVE_GATEWAY_URL=${CUSTOM_ARCHIVE_GATEWAY_URL:-http://localhost:8888/graphql} APP_NAME=Gleev SUPPORT_NO_CATEGORY_VIDEOS=true SUPPORT_NEW_CATEGORIES=true +CRT_MARKET_CAP_MIN_VOLUME_JOY=100 KILL_SWITCH_ON=false # 10 seconds VIDEO_VIEW_PER_USER_TIME_LIMIT=10 diff --git a/CHANGELOG.md b/CHANGELOG.md index 766756393..f22ae2db5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,14 @@ # 4.1.0 -## Misc +## Affected components: +- Migrations (`marketplace_tokens` view) +- GraphQL server (`tokensWithPriceChange` and `topSellingToken` queries, `setCrtMarketCapMinVolume` mutation) +- Config: `CRT_MARKET_CAP_MIN_VOLUME_JOY` +- Docker compose + +## Changes - `tokensWithPriceChange`, `marketplaceTokens` and `topSellingToken` queries now only take the currently active AMM sale into account when calculating values such as volume / liquidity / price change. +- `marketplaceTokens` query now takes into account a configurable `CRT_MARKET_CAP_MIN_VOLUME_JOY` value which allows specifying a volume threshold below which tokens are considered to have no market cap. - added `minVolume` argument to `tokensWithPriceChange` query to allow filtering out tokens w/ negligible volume - updated docker setup to support the latest docker version diff --git a/db/migrations/1730895049782-Views.js b/db/migrations/1730976542053-Views.js similarity index 94% rename from db/migrations/1730895049782-Views.js rename to db/migrations/1730976542053-Views.js index 11251134d..3f10deac2 100644 --- a/db/migrations/1730895049782-Views.js +++ b/db/migrations/1730976542053-Views.js @@ -1,8 +1,8 @@ const { getViewDefinitions } = require('../viewDefinitions') -module.exports = class Views1730895049782 { - name = 'Views1730895049782' +module.exports = class Views1730976542053 { + name = 'Views1730976542053' async up(db) { // these two queries will be invoked and the cleaned up by the squid itself diff --git a/db/viewDefinitions.js b/db/viewDefinitions.js index 8dfd4e7aa..af05d5f12 100644 --- a/db/viewDefinitions.js +++ b/db/viewDefinitions.js @@ -124,7 +124,13 @@ function getViewDefinitions(db) { ${withPriceChange({ periodDays: 30, currentBlock: 'last_block' })} SELECT COALESCE(tws.total_liquidity, 0) as liquidity, - (ct.last_price * ct.total_supply) as market_cap, + CASE + WHEN tws.amm_volume >= COALESCE( + market_cap_min_volume_cfg.value::int8, + ${parseInt(process.env.CRT_MARKET_CAP_MIN_VOLUME_JOY)} + ) THEN (ct.last_price * ct.total_supply) + ELSE 0 + END as market_cap, c.cumulative_revenue, c.id as channel_id, COALESCE(tws.amm_volume, 0) as amm_volume, @@ -142,7 +148,8 @@ function getViewDefinitions(db) { LEFT JOIN token_channel tc ON tc.token_id = ct.id LEFT JOIN channel c ON c.id = tc.channel_id LEFT JOIN tokens_with_price_change twpc ON twpc.token_id = ct.id - LEFT JOIN tokens_with_stats tws ON tws.token_id = ct.id`, + LEFT JOIN tokens_with_stats tws ON tws.token_id = ct.id + LEFT JOIN "admin"."gateway_config" market_cap_min_volume_cfg ON market_cap_min_volume_cfg.id = 'CRT_MARKET_CAP_MIN_VOLUME_JOY'`, } } diff --git a/schema/auth.graphql b/schema/auth.graphql index b87d6c99a..4c61c3750 100644 --- a/schema/auth.graphql +++ b/schema/auth.graphql @@ -13,6 +13,7 @@ enum OperatorPermission { RESTORE_CONTENT SET_PUBLIC_FEED_VIDEOS SET_FEATURED_CRTS + SET_CRT_MARKETCAP_MIN_VOLUME } type User @entity @schema(name: "admin") { diff --git a/src/server-extension/resolvers/AdminResolver/index.ts b/src/server-extension/resolvers/AdminResolver/index.ts index 6dfcea50f..d4966fe28 100644 --- a/src/server-extension/resolvers/AdminResolver/index.ts +++ b/src/server-extension/resolvers/AdminResolver/index.ts @@ -37,6 +37,7 @@ import { AppActionSignatureInput, AppRootDomain, ChannelWeight, + CrtMarketCapMinVolume, ExcludableContentType, ExcludeContentArgs, ExcludeContentResult, @@ -51,6 +52,7 @@ import { SetCategoryFeaturedVideosArgs, SetCategoryFeaturedVideosResult, SetChannelsWeightsArgs, + SetCrtMarketCapMinVolume, SetFeaturedCrtsInput, SetFeaturedCrtsResult, SetFeaturedNftsInput, @@ -232,6 +234,14 @@ export class AdminResolver { return results } + @UseMiddleware(OperatorOnly(OperatorPermission.SET_CRT_MARKETCAP_MIN_VOLUME)) + @Mutation(() => CrtMarketCapMinVolume) + async setCrtMarketCapMinVolume(@Args() args: SetCrtMarketCapMinVolume) { + const em = await this.em() + await config.set(ConfigVariable.CrtMarketCapMinVolumeJoy, args.minVolumeJoy, em) + return { minVolumeJoy: await config.get(ConfigVariable.CrtMarketCapMinVolumeJoy, em) } + } + @UseMiddleware(OperatorOnly(OperatorPermission.SET_KILL_SWITCH)) @Mutation(() => KillSwitch) async setKillSwitch(@Args() args: SetKillSwitchInput): Promise { @@ -353,7 +363,7 @@ export class AdminResolver { } } - @UseMiddleware(OperatorOnly(OperatorPermission.SET_SUPPORTED_CATEGORIES)) + @UseMiddleware(OperatorOnly(OperatorPermission.SET_CRT_MARKETCAP_MIN_VOLUME)) @Mutation(() => SetSupportedCategoriesResult) async setSupportedCategories( @Args() diff --git a/src/server-extension/resolvers/AdminResolver/types.ts b/src/server-extension/resolvers/AdminResolver/types.ts index 8a9099f8b..532601698 100644 --- a/src/server-extension/resolvers/AdminResolver/types.ts +++ b/src/server-extension/resolvers/AdminResolver/types.ts @@ -80,6 +80,18 @@ export class ChannelWeight { isApplied!: boolean } +@ArgsType() +export class SetCrtMarketCapMinVolume { + @Field(() => Int, { nullable: false }) + minVolumeJoy!: number +} + +@ObjectType() +export class CrtMarketCapMinVolume { + @Field(() => Int, { nullable: false }) + minVolumeJoy!: number +} + @ArgsType() export class SetKillSwitchInput { @Field(() => Boolean, { nullable: false }) diff --git a/src/utils/config.ts b/src/utils/config.ts index e91ea67b7..4f53a9f08 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -5,6 +5,7 @@ import { withHiddenEntities } from './sql' export enum ConfigVariable { SupportNoCategoryVideo = 'SUPPORT_NO_CATEGORY_VIDEOS', SupportNewCategories = 'SUPPORT_NEW_CATEGORIES', + CrtMarketCapMinVolumeJoy = 'CRT_MARKET_CAP_MIN_VOLUME_JOY', KillSwitch = 'KILL_SWITCH_ON', VideoViewPerUserTimeLimit = 'VIDEO_VIEW_PER_USER_TIME_LIMIT', VideoRelevanceViewsTick = 'VIDEO_RELEVANCE_VIEWS_TICK', @@ -49,6 +50,7 @@ const jsonType = () => ({ export const configVariables = { [ConfigVariable.SupportNoCategoryVideo]: boolType, [ConfigVariable.SupportNewCategories]: boolType, + [ConfigVariable.CrtMarketCapMinVolumeJoy]: intType, [ConfigVariable.KillSwitch]: boolType, [ConfigVariable.VideoViewPerUserTimeLimit]: intType, [ConfigVariable.VideoRelevanceViewsTick]: intType,