From 33ba4f2f2387b435c868626196fc9f988c43a9a1 Mon Sep 17 00:00:00 2001 From: katzman Date: Mon, 6 Oct 2025 12:37:39 -0700 Subject: [PATCH 1/6] Reuse launch auction logic to function for premium price auctions --- .../Basenames/PremiumExplainerModal/index.tsx | 16 +++++---- .../Basenames/RegistrationForm/index.tsx | 3 +- .../src/hooks/useActiveEthPremiumAmount.ts | 14 ++++---- apps/web/src/hooks/useActivePremiumAmount.ts | 25 -------------- apps/web/src/hooks/useBasenamesLaunchTime.ts | 34 +++++++++++++++++-- apps/web/src/utils/usernames.ts | 5 +-- 6 files changed, 52 insertions(+), 45 deletions(-) delete mode 100644 apps/web/src/hooks/useActivePremiumAmount.ts diff --git a/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx b/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx index 6ada5f9bbe5..c8c4da32055 100644 --- a/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx +++ b/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx @@ -1,13 +1,13 @@ import Modal from 'apps/web/src/components/Modal'; import data from 'apps/web/src/data/usernamePriceDecayTable.json'; -import { useBasenamesLaunchTime } from 'apps/web/src/hooks/useBasenamesLaunchTime'; +import { useBasenamesNameExpires } from 'apps/web/src/hooks/useBasenamesLaunchTime'; import { CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip } from 'recharts'; import { formatEther } from 'viem'; type CustomTooltipProps = { active?: boolean; baseSingleYearEthCost?: bigint; - launchTimeSeconds?: bigint; + auctionStartTimeSeconds?: bigint; payload: [ { dataKey: 'premium'; @@ -22,13 +22,13 @@ function CustomTooltip({ active, payload, baseSingleYearEthCost, - launchTimeSeconds, + auctionStartTimeSeconds, }: CustomTooltipProps) { - if (active && payload?.length && launchTimeSeconds && baseSingleYearEthCost) { + if (active && payload?.length && auctionStartTimeSeconds && baseSingleYearEthCost) { const premium = payload[0].value; const hours = payload[0].payload.hours; const seconds = hours * 60 * 60; - const tooltipSeconds = seconds + Number(launchTimeSeconds); + const tooltipSeconds = seconds + Number(auctionStartTimeSeconds); const timeOfPremium = new Date(tooltipSeconds * 1000).toLocaleString(undefined, { year: 'numeric', month: '2-digit', @@ -65,6 +65,7 @@ type PremiumExplainerModalProps = { toggleModal: () => void; premiumEthAmount: bigint | undefined; baseSingleYearEthCost: bigint; + name: string; }; const chartMarginValues = { top: 2, right: 2, left: 2, bottom: 2 }; export function PremiumExplainerModal({ @@ -72,8 +73,9 @@ export function PremiumExplainerModal({ toggleModal, premiumEthAmount, baseSingleYearEthCost, + name, }: PremiumExplainerModalProps) { - const { data: launchTimeSeconds } = useBasenamesLaunchTime(); + const { data: auctionStartTimeSeconds } = useBasenamesNameExpires(name); if (!premiumEthAmount || !baseSingleYearEthCost) return null; const formattedOneYearCost = Number(formatEther(baseSingleYearEthCost)).toLocaleString( @@ -147,7 +149,7 @@ export function PremiumExplainerModal({ // @ts-expect-error type wants an unnecessary prop } /> diff --git a/apps/web/src/components/Basenames/RegistrationForm/index.tsx b/apps/web/src/components/Basenames/RegistrationForm/index.tsx index cae6463d344..e98515ce293 100644 --- a/apps/web/src/components/Basenames/RegistrationForm/index.tsx +++ b/apps/web/src/components/Basenames/RegistrationForm/index.tsx @@ -138,7 +138,7 @@ export default function RegistrationForm() { const usdPrice = hasResolvedUSDPrice ? formatUsdPrice(price, ethUsdPrice) : '--.--'; const nameIsFree = !hasRegisteredWithDiscount && price === 0n; - const { seconds, timestamp: premiumEndTimestamp } = usePremiumEndDurationRemaining(); + const { seconds, timestamp: premiumEndTimestamp } = usePremiumEndDurationRemaining(selectedName); const isPremiumActive = Boolean(premiumPrice && premiumPrice !== 0n && seconds !== 0n); const mainRegistrationElementClasses = classNames( @@ -331,6 +331,7 @@ export default function RegistrationForm() { baseSingleYearEthCost={singleYearBasePrice} isOpen={premiumExplainerModalOpen} toggleModal={togglePremiumExplainerModal} + name={selectedName} /> )} diff --git a/apps/web/src/hooks/useActiveEthPremiumAmount.ts b/apps/web/src/hooks/useActiveEthPremiumAmount.ts index 8fb0c9726b9..3f5709909d0 100644 --- a/apps/web/src/hooks/useActiveEthPremiumAmount.ts +++ b/apps/web/src/hooks/useActiveEthPremiumAmount.ts @@ -1,11 +1,11 @@ -import { useBasenamesLaunchTime } from 'apps/web/src/hooks/useBasenamesLaunchTime'; +import { useBasenamesNameExpires } from 'apps/web/src/hooks/useBasenamesLaunchTime'; import { useState } from 'react'; import { useInterval } from 'usehooks-ts'; const SECONDS_IN_A_MINUTE = 60; const SECONDS_IN_AN_HOUR = 60 * SECONDS_IN_A_MINUTE; const SECONDS_IN_A_DAY = 24 * SECONDS_IN_AN_HOUR; -const THIRTY_SIX_HOURS_IN_SECONDS = 36 * SECONDS_IN_AN_HOUR; +const TWENTY_ONE_DAYS_IN_SECONDS = 21 * SECONDS_IN_A_DAY; function formatTimeUnit(unit: number): string { return unit.toString().padStart(2, '0'); @@ -22,15 +22,15 @@ function calculateTimeLeft(differenceInSeconds: number): string { )}:${formatTimeUnit(seconds)}`; } -export function usePremiumEndDurationRemaining() { +export function usePremiumEndDurationRemaining(name: string) { const [timeLeft, setTimeLeft] = useState(null); - const { data: launchTimeSeconds } = useBasenamesLaunchTime(); + const { data: auctionStartTimeSeconds } = useBasenamesNameExpires(name); useInterval(() => { - if (!launchTimeSeconds) return; + if (!auctionStartTimeSeconds) return; const currentTimeInSeconds = Math.floor(Date.now() / 1000); - const endTimeInSeconds = Number(launchTimeSeconds) + THIRTY_SIX_HOURS_IN_SECONDS; + const endTimeInSeconds = Number(auctionStartTimeSeconds) + TWENTY_ONE_DAYS_IN_SECONDS; const timeDifference = endTimeInSeconds - currentTimeInSeconds; if (timeDifference > 0) { @@ -40,5 +40,5 @@ export function usePremiumEndDurationRemaining() { } }, 1000); - return { seconds: launchTimeSeconds, timestamp: timeLeft }; + return { seconds: auctionStartTimeSeconds, timestamp: timeLeft }; } diff --git a/apps/web/src/hooks/useActivePremiumAmount.ts b/apps/web/src/hooks/useActivePremiumAmount.ts deleted file mode 100644 index 391ec9ba720..00000000000 --- a/apps/web/src/hooks/useActivePremiumAmount.ts +++ /dev/null @@ -1,25 +0,0 @@ -import ExponentialPremiumPriceOracleABI from 'apps/web/src/abis/ExponentialPremiumPriceOracleAbi'; -import { EXPONENTIAL_PREMIUM_PRICE_ORACLE } from 'apps/web/src/addresses/usernames'; -import { useBasenamesLaunchTime } from 'apps/web/src/hooks/useBasenamesLaunchTime'; -import { useMemo } from 'react'; -import { useReadContract } from 'wagmi'; -import { base } from 'viem/chains'; - -export function useActiveEthPremiumAmount() { - const { data: launchTimeSeconds } = useBasenamesLaunchTime(); - - const timeSinceLaunch = useMemo( - () => (launchTimeSeconds ? BigInt(Math.floor(Date.now() / 1000)) - launchTimeSeconds : null), - [launchTimeSeconds], - ); - - return useReadContract({ - abi: ExponentialPremiumPriceOracleABI, - address: EXPONENTIAL_PREMIUM_PRICE_ORACLE[base.id], - functionName: 'decayedPremium', - args: [timeSinceLaunch as bigint], - query: { - enabled: typeof timeSinceLaunch === 'bigint', - }, - }); -} diff --git a/apps/web/src/hooks/useBasenamesLaunchTime.ts b/apps/web/src/hooks/useBasenamesLaunchTime.ts index 93529a54d1a..24aa4b1234e 100644 --- a/apps/web/src/hooks/useBasenamesLaunchTime.ts +++ b/apps/web/src/hooks/useBasenamesLaunchTime.ts @@ -1,4 +1,32 @@ -export function useBasenamesLaunchTime() { - // Temporarily hardcoded from RegistrarController - return { data: 1724184000n }; +import { useReadContract } from 'wagmi'; +import BaseRegistrarAbi from 'apps/web/src/abis/BaseRegistrarAbi'; +import { USERNAME_BASE_REGISTRAR_ADDRESSES } from 'apps/web/src/addresses/usernames'; +import { + getTokenIdFromBasename, + formatBaseEthDomain, + getChainForBasename, + GRACE_PERIOD_DURATION_SECONDS, +} from 'apps/web/src/utils/usernames'; +import { Basename } from '@coinbase/onchainkit/identity'; + +export function useBasenamesNameExpires(name: string) { + // Convert name to full basename format + const fullBasename = name.includes('.') ? (name as Basename) : formatBaseEthDomain(name, 8453); // Base mainnet + const chain = getChainForBasename(fullBasename); + const tokenId = getTokenIdFromBasename(fullBasename); + + const { data: nameExpiresTimestamp } = useReadContract({ + abi: BaseRegistrarAbi, + address: USERNAME_BASE_REGISTRAR_ADDRESSES[chain.id], + functionName: 'nameExpires', + args: [tokenId], + chainId: chain.id, + }); + + // Add 90 days (grace period) to get the auction start time + const auctionStartTime = nameExpiresTimestamp + ? nameExpiresTimestamp + BigInt(GRACE_PERIOD_DURATION_SECONDS) + : undefined; + + return { data: auctionStartTime }; } diff --git a/apps/web/src/utils/usernames.ts b/apps/web/src/utils/usernames.ts index d410ce8eb3c..2af1a89cc87 100644 --- a/apps/web/src/utils/usernames.ts +++ b/apps/web/src/utils/usernames.ts @@ -831,8 +831,9 @@ export const REGISTER_CONTRACT_ADDRESSES = UPGRADEABLE_REGISTRAR_CONTROLLER_ADDR export const isBasenameRenewalsKilled = process.env.NEXT_PUBLIC_KILL_BASENAMES_RENEWALS === 'true'; -// Grace period duration in seconds (90 days) -export const GRACE_PERIOD_DURATION_MS = 90 * 24 * 60 * 60 * 1000; +// Grace period duration (90 days) +export const GRACE_PERIOD_DURATION_SECONDS = 90 * 24 * 60 * 60; +export const GRACE_PERIOD_DURATION_MS = GRACE_PERIOD_DURATION_SECONDS * 1000; /** * Check if a basename is in its grace period (expired but still renewable) From f4988643d8c4dc2c485cb74d60822d62b7d69689 Mon Sep 17 00:00:00 2001 From: katzman Date: Mon, 6 Oct 2025 13:47:46 -0700 Subject: [PATCH 2/6] Rename hook to match new method --- .../src/components/Basenames/PremiumExplainerModal/index.tsx | 2 +- apps/web/src/hooks/useActiveEthPremiumAmount.ts | 2 +- .../{useBasenamesLaunchTime.ts => useBasenamesNameExpires.ts} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename apps/web/src/hooks/{useBasenamesLaunchTime.ts => useBasenamesNameExpires.ts} (100%) diff --git a/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx b/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx index c8c4da32055..e6dc69f5a59 100644 --- a/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx +++ b/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx @@ -1,6 +1,6 @@ import Modal from 'apps/web/src/components/Modal'; import data from 'apps/web/src/data/usernamePriceDecayTable.json'; -import { useBasenamesNameExpires } from 'apps/web/src/hooks/useBasenamesLaunchTime'; +import { useBasenamesNameExpires } from 'apps/web/src/hooks/useBasenamesNameExpires'; import { CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip } from 'recharts'; import { formatEther } from 'viem'; diff --git a/apps/web/src/hooks/useActiveEthPremiumAmount.ts b/apps/web/src/hooks/useActiveEthPremiumAmount.ts index 3f5709909d0..f1456efc52a 100644 --- a/apps/web/src/hooks/useActiveEthPremiumAmount.ts +++ b/apps/web/src/hooks/useActiveEthPremiumAmount.ts @@ -1,4 +1,4 @@ -import { useBasenamesNameExpires } from 'apps/web/src/hooks/useBasenamesLaunchTime'; +import { useBasenamesNameExpires } from 'apps/web/src/hooks/useBasenamesNameExpires'; import { useState } from 'react'; import { useInterval } from 'usehooks-ts'; diff --git a/apps/web/src/hooks/useBasenamesLaunchTime.ts b/apps/web/src/hooks/useBasenamesNameExpires.ts similarity index 100% rename from apps/web/src/hooks/useBasenamesLaunchTime.ts rename to apps/web/src/hooks/useBasenamesNameExpires.ts From 41b0b2c820c1906e842ee69cea5c74cde298d751 Mon Sep 17 00:00:00 2001 From: katzman Date: Mon, 6 Oct 2025 14:26:46 -0700 Subject: [PATCH 3/6] Replace auction table with prod premium auction data --- .../Basenames/PremiumExplainerModal/index.tsx | 10 +- .../web/src/data/usernamePriceDecayTable.json | 1442 +---------------- 2 files changed, 90 insertions(+), 1362 deletions(-) diff --git a/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx b/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx index e6dc69f5a59..c08247c0e2b 100644 --- a/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx +++ b/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx @@ -12,7 +12,7 @@ type CustomTooltipProps = { { dataKey: 'premium'; name: 'premium'; - payload: { hours: number; premium: number }; + payload: { days: number; premium: number }; value: number; }, ]; @@ -26,8 +26,8 @@ function CustomTooltip({ }: CustomTooltipProps) { if (active && payload?.length && auctionStartTimeSeconds && baseSingleYearEthCost) { const premium = payload[0].value; - const hours = payload[0].payload.hours; - const seconds = hours * 60 * 60; + const days = payload[0].payload.days; + const seconds = days * 24 * 60 * 60; // Convert days to seconds const tooltipSeconds = seconds + Number(auctionStartTimeSeconds); const timeOfPremium = new Date(tooltipSeconds * 1000).toLocaleString(undefined, { year: 'numeric', @@ -96,8 +96,8 @@ export function PremiumExplainerModal({

This name has a temporary premium

- To ensure fair distribution of Basenames, all names have a temporary premium starting at - 100 ETH that then decays exponentially to 0 over 36 hours. + To ensure fair distribution of recently expired Basenames, all names have a price premium + which starts at 100 ETH that then decays exponentially to 0 over 21 days.

diff --git a/apps/web/src/data/usernamePriceDecayTable.json b/apps/web/src/data/usernamePriceDecayTable.json index 2c19c152a85..9ef40bd652a 100644 --- a/apps/web/src/data/usernamePriceDecayTable.json +++ b/apps/web/src/data/usernamePriceDecayTable.json @@ -1,1446 +1,174 @@ [ { - "hours": 0, - "premium": 99.99999404 + "days": 0, + "premium": 100 }, { - "hours": 0.1, - "premium": 95.48415443 + "days": 0.5, + "premium": 70.71067812 }, { - "hours": 0.2, - "premium": 91.1722429 + "days": 1, + "premium": 50 }, { - "hours": 0.3, - "premium": 87.05505037 + "days": 1.5, + "premium": 35.35533906 }, { - "hours": 0.4, - "premium": 83.12378365 + "days": 2, + "premium": 25 }, { - "hours": 0.5, - "premium": 79.37004664 + "days": 2.5, + "premium": 17.67766953 }, { - "hours": 0.6, - "premium": 75.78582237 + "days": 3, + "premium": 12.5 }, { - "hours": 0.7, - "premium": 72.36345591 + "days": 3.5, + "premium": 8.83883476 }, { - "hours": 0.8, - "premium": 69.09563804 + "days": 4, + "premium": 6.25 }, { - "hours": 0.9, - "premium": 65.97538958 + "days": 4.5, + "premium": 4.41941738 }, { - "hours": 1, - "premium": 62.99604653 + "days": 5, + "premium": 3.125 }, { - "hours": 1.1, - "premium": 60.15124584 + "days": 5.5, + "premium": 2.20970869 }, { - "hours": 1.2, - "premium": 57.43491179 + "days": 6, + "premium": 1.5625 }, { - "hours": 1.3, - "premium": 54.84124302 + "days": 6.5, + "premium": 1.10485435 }, { - "hours": 1.4, - "premium": 52.36470018 + "days": 7, + "premium": 0.78125 }, { - "hours": 1.5, - "premium": 49.99999404 + "days": 7.5, + "premium": 0.55242717 }, { - "hours": 1.6, - "premium": 47.74207424 + "days": 8, + "premium": 0.390625 }, { - "hours": 1.7, - "premium": 45.58611847 + "days": 8.5, + "premium": 0.27621359 }, { - "hours": 1.8, - "premium": 43.5275222 + "days": 9, + "premium": 0.1953125 }, { - "hours": 1.9, - "premium": 41.56188885 + "days": 9.5, + "premium": 0.13810679 }, { - "hours": 2, - "premium": 39.68502034 + "days": 10, + "premium": 0.09765625 }, { - "hours": 2.1, - "premium": 37.8929082 + "days": 10.5, + "premium": 0.0690534 }, { - "hours": 2.2, - "premium": 36.18172498 + "days": 11, + "premium": 0.04882812 }, { - "hours": 2.3, - "premium": 34.54781604 + "days": 11.5, + "premium": 0.0345267 }, { - "hours": 2.4, - "premium": 32.98769181 + "days": 12, + "premium": 0.02441406 }, { - "hours": 2.5, - "premium": 31.49802029 + "days": 12.5, + "premium": 0.01726335 }, { - "hours": 2.6, - "premium": 30.07561994 + "days": 13, + "premium": 0.01220703 }, { - "hours": 2.7, - "premium": 28.71745291 + "days": 13.5, + "premium": 0.00863167 }, { - "hours": 2.8, - "premium": 27.42061853 + "days": 14, + "premium": 0.00610352 }, { - "hours": 2.9, - "premium": 26.18234711 + "days": 14.5, + "premium": 0.00431584 }, { - "hours": 3, - "premium": 24.99999404 + "days": 15, + "premium": 0.00305176 }, { - "hours": 3.1, - "premium": 23.87103414 + "days": 15.5, + "premium": 0.00215792 }, { - "hours": 3.2, - "premium": 22.79305625 + "days": 16, + "premium": 0.00152588 }, { - "hours": 3.3, - "premium": 21.76375812 + "days": 16.5, + "premium": 0.00107896 }, { - "hours": 3.4, - "premium": 20.78094144 + "days": 17, + "premium": 0.00076294 }, { - "hours": 3.5, - "premium": 19.84250719 + "days": 17.5, + "premium": 0.00053948 }, { - "hours": 3.6, - "premium": 18.94645112 + "days": 18, + "premium": 0.00038147 }, { - "hours": 3.7, - "premium": 18.09085951 + "days": 18.5, + "premium": 0.00026974 }, { - "hours": 3.8, - "premium": 17.27390504 + "days": 19, + "premium": 0.00019073 }, { - "hours": 3.9, - "premium": 16.49384292 + "days": 19.5, + "premium": 0.00013487 }, { - "hours": 4, - "premium": 15.74900716 + "days": 20, + "premium": 0.00009537 }, { - "hours": 4.1, - "premium": 15.03780699 + "days": 20.5, + "premium": 0.00006743 }, { - "hours": 4.2, - "premium": 14.35872348 - }, - { - "hours": 4.3, - "premium": 13.71030629 - }, - { - "hours": 4.4, - "premium": 13.09117057 - }, - { - "hours": 4.5, - "premium": 12.49999404 - }, - { - "hours": 4.6, - "premium": 11.93551409 - }, - { - "hours": 4.7, - "premium": 11.39652515 - }, - { - "hours": 4.8, - "premium": 10.88187608 - }, - { - "hours": 4.9, - "premium": 10.39046774 - }, - { - "hours": 5, - "premium": 9.921250614 - }, - { - "hours": 5.1, - "premium": 9.47322258 - }, - { - "hours": 5.2, - "premium": 9.045426774 - }, - { - "hours": 5.3, - "premium": 8.636949539 - }, - { - "hours": 5.4, - "premium": 8.246918482 - }, - { - "hours": 5.5, - "premium": 7.874500601 - }, - { - "hours": 5.6, - "premium": 7.518900515 - }, - { - "hours": 5.7, - "premium": 7.179358758 - }, - { - "hours": 5.8, - "premium": 6.855150163 - }, - { - "hours": 5.9, - "premium": 6.545582307 - }, - { - "hours": 6, - "premium": 6.24999404 - }, - { - "hours": 6.1, - "premium": 5.967754064 - }, - { - "hours": 6.2, - "premium": 5.698259593 - }, - { - "hours": 6.3, - "premium": 5.44093506 - }, - { - "hours": 6.4, - "premium": 5.19523089 - }, - { - "hours": 6.5, - "premium": 4.960622327 - }, - { - "hours": 6.6, - "premium": 4.73660831 - }, - { - "hours": 6.7, - "premium": 4.522710407 - }, - { - "hours": 6.8, - "premium": 4.318471789 - }, - { - "hours": 6.9, - "premium": 4.123456261 - }, - { - "hours": 7, - "premium": 3.93724732 - }, - { - "hours": 7.1, - "premium": 3.759447277 - }, - { - "hours": 7.2, - "premium": 3.589676399 - }, - { - "hours": 7.3, - "premium": 3.427572101 - }, - { - "hours": 7.4, - "premium": 3.272788173 - }, - { - "hours": 7.5, - "premium": 3.12499404 - }, - { - "hours": 7.6, - "premium": 2.983874052 - }, - { - "hours": 7.7, - "premium": 2.849126816 - }, - { - "hours": 7.8, - "premium": 2.72046455 - }, - { - "hours": 7.9, - "premium": 2.597612465 - }, - { - "hours": 8, - "premium": 2.480308183 - }, - { - "hours": 8.1, - "premium": 2.368301175 - }, - { - "hours": 8.2, - "premium": 2.261352223 - }, - { - "hours": 8.3, - "premium": 2.159232914 - }, - { - "hours": 8.4, - "premium": 2.06172515 - }, - { - "hours": 8.5, - "premium": 1.96862068 - }, - { - "hours": 8.6, - "premium": 1.879720658 - }, - { - "hours": 8.7, - "premium": 1.794835219 - }, - { - "hours": 8.8, - "premium": 1.71378307 - }, - { - "hours": 8.9, - "premium": 1.636391106 - }, - { - "hours": 9, - "premium": 1.56249404 - }, - { - "hours": 9.1, - "premium": 1.491934046 - }, - { - "hours": 9.2, - "premium": 1.424560428 - }, - { - "hours": 9.3, - "premium": 1.360229295 - }, - { - "hours": 9.4, - "premium": 1.298803252 - }, - { - "hours": 9.5, - "premium": 1.240151111 - }, - { - "hours": 9.6, - "premium": 1.184147607 - }, - { - "hours": 9.7, - "premium": 1.130673131 - }, - { - "hours": 9.8, - "premium": 1.079613477 - }, - { - "hours": 9.9, - "premium": 1.030859595 - }, - { - "hours": 10, - "premium": 0.9843073598 - }, - { - "hours": 10.1, - "premium": 0.939857349 - }, - { - "hours": 10.2, - "premium": 0.8974146294 - }, - { - "hours": 10.3, - "premium": 0.8568885549 - }, - { - "hours": 10.4, - "premium": 0.818192573 - }, - { - "hours": 10.5, - "premium": 0.7812440395 - }, - { - "hours": 10.6, - "premium": 0.7459640426 - }, - { - "hours": 10.7, - "premium": 0.7122772337 - }, - { - "hours": 10.8, - "premium": 0.6801116671 - }, - { - "hours": 10.9, - "premium": 0.6493986459 - }, - { - "hours": 11, - "premium": 0.6200725755 - }, - { - "hours": 11.1, - "premium": 0.5920708233 - }, - { - "hours": 11.2, - "premium": 0.5653335854 - }, - { - "hours": 11.3, - "premium": 0.5398037583 - }, - { - "hours": 11.4, - "premium": 0.5154268172 - }, - { - "hours": 11.5, - "premium": 0.4921506997 - }, - { - "hours": 11.6, - "premium": 0.4699256943 - }, - { - "hours": 11.7, - "premium": 0.4487043345 - }, - { - "hours": 11.8, - "premium": 0.4284412972 - }, - { - "hours": 11.9, - "premium": 0.4090933063 - }, - { - "hours": 12, - "premium": 0.3906190395 - }, - { - "hours": 12.1, - "premium": 0.3729790411 - }, - { - "hours": 12.2, - "premium": 0.3561356366 - }, - { - "hours": 12.3, - "premium": 0.3400528533 - }, - { - "hours": 12.4, - "premium": 0.3246963427 - }, - { - "hours": 12.5, - "premium": 0.3100333075 - }, - { - "hours": 12.6, - "premium": 0.2960324314 - }, - { - "hours": 12.7, - "premium": 0.2826638125 - }, - { - "hours": 12.8, - "premium": 0.2698988989 - }, - { - "hours": 12.9, - "premium": 0.2577104284 - }, - { - "hours": 13, - "premium": 0.2460723696 - }, - { - "hours": 13.1, - "premium": 0.2349598669 - }, - { - "hours": 13.2, - "premium": 0.224349187 - }, - { - "hours": 13.3, - "premium": 0.2142176684 - }, - { - "hours": 13.4, - "premium": 0.2045436729 - }, - { - "hours": 13.5, - "premium": 0.1953065395 - }, - { - "hours": 13.6, - "premium": 0.1864865403 - }, - { - "hours": 13.7, - "premium": 0.1780648381 - }, - { - "hours": 13.8, - "premium": 0.1700234464 - }, - { - "hours": 13.9, - "premium": 0.1623451911 - }, - { - "hours": 14, - "premium": 0.1550136735 - }, - { - "hours": 14.1, - "premium": 0.1480132355 - }, - { - "hours": 14.2, - "premium": 0.141328926 - }, - { - "hours": 14.3, - "premium": 0.1349464692 - }, - { - "hours": 14.4, - "premium": 0.1288522339 - }, - { - "hours": 14.5, - "premium": 0.1230332046 - }, - { - "hours": 14.6, - "premium": 0.1174769532 - }, - { - "hours": 14.7, - "premium": 0.1121716133 - }, - { - "hours": 14.8, - "premium": 0.107105854 - }, - { - "hours": 14.9, - "premium": 0.1022688562 - }, - { - "hours": 15, - "premium": 0.09765028954 - }, - { - "hours": 15.1, - "premium": 0.09324028992 - }, - { - "hours": 15.2, - "premium": 0.08902943881 - }, - { - "hours": 15.3, - "premium": 0.08500874298 - }, - { - "hours": 15.4, - "premium": 0.08116961533 - }, - { - "hours": 15.5, - "premium": 0.07750385653 - }, - { - "hours": 15.6, - "premium": 0.07400363751 - }, - { - "hours": 15.7, - "premium": 0.07066148277 - }, - { - "hours": 15.8, - "premium": 0.06747025438 - }, - { - "hours": 15.9, - "premium": 0.06442313674 - }, - { - "hours": 16, - "premium": 0.06151362205 - }, - { - "hours": 16.1, - "premium": 0.05873549638 - }, - { - "hours": 16.2, - "premium": 0.0560828264 - }, - { - "hours": 16.3, - "premium": 0.05354994675 - }, - { - "hours": 16.4, - "premium": 0.05113144788 - }, - { - "hours": 16.5, - "premium": 0.04882216454 - }, - { - "hours": 16.6, - "premium": 0.04661716473 - }, - { - "hours": 16.7, - "premium": 0.04451173917 - }, - { - "hours": 16.8, - "premium": 0.04250139126 - }, - { - "hours": 16.9, - "premium": 0.04058182743 - }, - { - "hours": 17, - "premium": 0.03874894803 - }, - { - "hours": 17.1, - "premium": 0.03699883852 - }, - { - "hours": 17.2, - "premium": 0.03532776115 - }, - { - "hours": 17.3, - "premium": 0.03373214696 - }, - { - "hours": 17.4, - "premium": 0.03220858814 - }, - { - "hours": 17.5, - "premium": 0.03075383079 - }, - { - "hours": 17.6, - "premium": 0.02936476796 - }, - { - "hours": 17.7, - "premium": 0.02803843297 - }, - { - "hours": 17.8, - "premium": 0.02677199314 - }, - { - "hours": 17.9, - "premium": 0.02556274371 - }, - { - "hours": 18, - "premium": 0.02440810204 - }, - { - "hours": 18.1, - "premium": 0.02330560213 - }, - { - "hours": 18.2, - "premium": 0.02225288935 - }, - { - "hours": 18.3, - "premium": 0.0212477154 - }, - { - "hours": 18.4, - "premium": 0.02028793348 - }, - { - "hours": 18.5, - "premium": 0.01937149378 - }, - { - "hours": 18.6, - "premium": 0.01849643903 - }, - { - "hours": 18.7, - "premium": 0.01766090034 - }, - { - "hours": 18.8, - "premium": 0.01686309325 - }, - { - "hours": 18.9, - "premium": 0.01610131384 - }, - { - "hours": 19, - "premium": 0.01537393516 - }, - { - "hours": 19.1, - "premium": 0.01467940375 - }, - { - "hours": 19.2, - "premium": 0.01401623625 - }, - { - "hours": 19.3, - "premium": 0.01338301634 - }, - { - "hours": 19.4, - "premium": 0.01277839162 - }, - { - "hours": 19.5, - "premium": 0.01220107079 - }, - { - "hours": 19.6, - "premium": 0.01164982083 - }, - { - "hours": 19.7, - "premium": 0.01112346444 - }, - { - "hours": 19.8, - "premium": 0.01062087747 - }, - { - "hours": 19.9, - "premium": 0.01014098651 - }, - { - "hours": 20, - "premium": 0.009682766659 - }, - { - "hours": 20.1, - "premium": 0.009245239282 - }, - { - "hours": 20.2, - "premium": 0.00882746994 - }, - { - "hours": 20.3, - "premium": 0.008428566391 - }, - { - "hours": 20.4, - "premium": 0.008047676686 - }, - { - "hours": 20.5, - "premium": 0.00768398735 - }, - { - "hours": 20.6, - "premium": 0.007336721641 - }, - { - "hours": 20.7, - "premium": 0.007005137894 - }, - { - "hours": 20.8, - "premium": 0.006688527937 - }, - { - "hours": 20.9, - "premium": 0.006386215578 - }, - { - "hours": 21, - "premium": 0.006097555161 - }, - { - "hours": 21.1, - "premium": 0.005821930184 - }, - { - "hours": 21.2, - "premium": 0.00555875199 - }, - { - "hours": 21.3, - "premium": 0.005307458501 - }, - { - "hours": 21.4, - "premium": 0.005067513023 - }, - { - "hours": 21.5, - "premium": 0.004838403097 - }, - { - "hours": 21.6, - "premium": 0.004619639409 - }, - { - "hours": 21.7, - "premium": 0.004410754738 - }, - { - "hours": 21.8, - "premium": 0.004211302963 - }, - { - "hours": 21.9, - "premium": 0.004020858111 - }, - { - "hours": 22, - "premium": 0.003839013443 - }, - { - "hours": 22.1, - "premium": 0.003665380588 - }, - { - "hours": 22.2, - "premium": 0.003499588715 - }, - { - "hours": 22.3, - "premium": 0.003341283736 - }, - { - "hours": 22.4, - "premium": 0.003190127557 - }, - { - "hours": 22.5, - "premium": 0.003045797348 - }, - { - "hours": 22.6, - "premium": 0.00290798486 - }, - { - "hours": 22.7, - "premium": 0.002776395763 - }, - { - "hours": 22.8, - "premium": 0.002650749018 - }, - { - "hours": 22.9, - "premium": 0.002530776279 - }, - { - "hours": 23, - "premium": 0.002416221316 - }, - { - "hours": 23.1, - "premium": 0.002306839472 - }, - { - "hours": 23.2, - "premium": 0.002202397137 - }, - { - "hours": 23.3, - "premium": 0.002102671249 - }, - { - "hours": 23.4, - "premium": 0.002007448823 - }, - { - "hours": 23.5, - "premium": 0.001916526489 - }, - { - "hours": 23.6, - "premium": 0.001829710062 - }, - { - "hours": 23.7, - "premium": 0.001746814125 - }, - { - "hours": 23.8, - "premium": 0.001667661636 - }, - { - "hours": 23.9, - "premium": 0.001592083546 - }, - { - "hours": 24, - "premium": 0.001519918442 - }, - { - "hours": 24.1, - "premium": 0.001451012198 - }, - { - "hours": 24.2, - "premium": 0.001385217649 - }, - { - "hours": 24.3, - "premium": 0.001322394277 - }, - { - "hours": 24.4, - "premium": 0.001262407907 - }, - { - "hours": 24.5, - "premium": 0.001205130426 - }, - { - "hours": 24.6, - "premium": 0.001150439504 - }, - { - "hours": 24.7, - "premium": 0.001098218336 - }, - { - "hours": 24.8, - "premium": 0.001048355392 - }, - { - "hours": 24.9, - "premium": 0.001000744179 - }, - { - "hours": 25, - "premium": 0.0009552830123 - }, - { - "hours": 25.1, - "premium": 0.0009118747986 - }, - { - "hours": 25.2, - "premium": 0.0008704268303 - }, - { - "hours": 25.3, - "premium": 0.0008308505857 - }, - { - "hours": 25.4, - "premium": 0.0007930615408 - }, - { - "hours": 25.5, - "premium": 0.0007569789886 - }, - { - "hours": 25.6, - "premium": 0.0007225258666 - }, - { - "hours": 25.7, - "premium": 0.0006896285923 - }, - { - "hours": 25.8, - "premium": 0.0006582169062 - }, - { - "hours": 25.9, - "premium": 0.0006282237214 - }, - { - "hours": 26, - "premium": 0.0005995849808 - }, - { - "hours": 26.1, - "premium": 0.0005722395197 - }, - { - "hours": 26.2, - "premium": 0.0005461289358 - }, - { - "hours": 26.3, - "premium": 0.000521197464 - }, - { - "hours": 26.4, - "premium": 0.0004973918574 - }, - { - "hours": 26.5, - "premium": 0.0004746612739 - }, - { - "hours": 26.6, - "premium": 0.0004529571671 - }, - { - "hours": 26.7, - "premium": 0.0004322331829 - }, - { - "hours": 26.8, - "premium": 0.0004124450606 - }, - { - "hours": 26.9, - "premium": 0.0003935505382 - }, - { - "hours": 27, - "premium": 0.0003755092621 - }, - { - "hours": 27.1, - "premium": 0.0003582827011 - }, - { - "hours": 27.2, - "premium": 0.0003418340639 - }, - { - "hours": 27.3, - "premium": 0.0003261282209 - }, - { - "hours": 27.4, - "premium": 0.0003111316285 - }, - { - "hours": 27.5, - "premium": 0.0002968122581 - }, - { - "hours": 27.6, - "premium": 0.0002831395276 - }, - { - "hours": 27.7, - "premium": 0.0002700842357 - }, - { - "hours": 27.8, - "premium": 0.0002576184997 - }, - { - "hours": 27.9, - "premium": 0.0002457156965 - }, - { - "hours": 28, - "premium": 0.0002343504047 - }, - { - "hours": 28.1, - "premium": 0.0002234983513 - }, - { - "hours": 28.2, - "premium": 0.0002131363592 - }, - { - "hours": 28.3, - "premium": 0.0002032422981 - }, - { - "hours": 28.4, - "premium": 0.0001937950369 - }, - { - "hours": 28.5, - "premium": 0.0001847743988 - }, - { - "hours": 28.6, - "premium": 0.0001761611183 - }, - { - "hours": 28.7, - "premium": 0.0001679367997 - }, - { - "hours": 28.8, - "premium": 0.0001600838782 - }, - { - "hours": 28.9, - "premium": 0.000152585582 - }, - { - "hours": 29, - "premium": 0.0001454258968 - }, - { - "hours": 29.1, - "premium": 0.0001385895316 - }, - { - "hours": 29.2, - "premium": 0.0001320618856 - }, - { - "hours": 29.3, - "premium": 0.0001258290176 - }, - { - "hours": 29.4, - "premium": 0.000119877616 - }, - { - "hours": 29.5, - "premium": 0.0001141949701 - }, - { - "hours": 29.6, - "premium": 0.0001087689434 - }, - { - "hours": 29.7, - "premium": 0.0001035879474 - }, - { - "hours": 29.8, - "premium": 0.00009864091679 - }, - { - "hours": 29.9, - "premium": 0.00009391728619 - }, - { - "hours": 30, - "premium": 0.00008940696716 - }, - { - "hours": 30.1, - "premium": 0.00008510032691 - }, - { - "hours": 30.2, - "premium": 0.00008098816763 - }, - { - "hours": 30.3, - "premium": 0.00007706170686 - }, - { - "hours": 30.4, - "premium": 0.00007331255876 - }, - { - "hours": 30.5, - "premium": 0.00006973271618 - }, - { - "hours": 30.6, - "premium": 0.00006631453354 - }, - { - "hours": 30.7, - "premium": 0.00006305071056 - }, - { - "hours": 30.8, - "premium": 0.00005993427658 - }, - { - "hours": 30.9, - "premium": 0.00005695857576 - }, - { - "hours": 31, - "premium": 0.00005411725282 - }, - { - "hours": 31.1, - "premium": 0.00005140423947 - }, - { - "hours": 31.2, - "premium": 0.00004881374144 - }, - { - "hours": 31.3, - "premium": 0.00004634022616 - }, - { - "hours": 31.4, - "premium": 0.00004397841085 - }, - { - "hours": 31.5, - "premium": 0.00004172325134 - }, - { - "hours": 31.6, - "premium": 0.00003956993122 - }, - { - "hours": 31.7, - "premium": 0.00003751385157 - }, - { - "hours": 31.8, - "premium": 0.00003555062119 - }, - { - "hours": 31.9, - "premium": 0.00003367604714 - }, - { - "hours": 32, - "premium": 0.00003188612585 - }, - { - "hours": 32.1, - "premium": 0.00003017703453 - }, - { - "hours": 32.2, - "premium": 0.00002854512304 - }, - { - "hours": 32.3, - "premium": 0.00002698690605 - }, - { - "hours": 32.4, - "premium": 0.00002549905564 - }, - { - "hours": 32.5, - "premium": 0.00002407839417 - }, - { - "hours": 32.6, - "premium": 0.00002272188749 - }, - { - "hours": 32.7, - "premium": 0.00002142663848 - }, - { - "hours": 32.8, - "premium": 0.00002018988084 - }, - { - "hours": 32.9, - "premium": 0.00001900897319 - }, - { - "hours": 33, - "premium": 0.00001788139343 - }, - { - "hours": 33.1, - "premium": 0.00001680473337 - }, - { - "hours": 33.2, - "premium": 0.00001577669355 - }, - { - "hours": 33.3, - "premium": 0.00001479507836 - }, - { - "hours": 33.4, - "premium": 0.00001385779133 - }, - { - "hours": 33.5, - "premium": 0.00001296283069 - }, - { - "hours": 33.6, - "premium": 0.00001210828503 - }, - { - "hours": 33.7, - "premium": 0.00001129232928 - }, - { - "hours": 33.8, - "premium": 0.00001051322079 - }, - { - "hours": 33.9, - "premium": 0.000009769295582 - }, - { - "hours": 34, - "premium": 0.000009058964847 - }, - { - "hours": 34.1, - "premium": 0.000008380711508 - }, - { - "hours": 34.2, - "premium": 0.000007733087003 - }, - { - "hours": 34.3, - "premium": 0.000007114708181 - }, - { - "hours": 34.4, - "premium": 0.000006524254355 - }, - { - "hours": 34.5, - "premium": 0.000005960464477 - }, - { - "hours": 34.6, - "premium": 0.000005422134446 - }, - { - "hours": 34.7, - "premium": 0.000004908114535 - }, - { - "hours": 34.8, - "premium": 0.000004417306939 - }, - { - "hours": 34.9, - "premium": 0.000003948663427 - }, - { - "hours": 35, - "premium": 0.000003501183104 - }, - { - "hours": 35.1, - "premium": 0.000003073910275 - }, - { - "hours": 35.2, - "premium": 0.000002665932401 - }, - { - "hours": 35.3, - "premium": 0.000002276378154 - }, - { - "hours": 35.4, - "premium": 0.000001904415552 - }, - { - "hours": 35.5, - "premium": 0.000001549250184 - }, - { - "hours": 35.6, - "premium": 0.000001210123515 - }, - { - "hours": 35.7, - "premium": 8.86311262e-7 - }, - { - "hours": 35.8, - "premium": 5.77121852e-7 - }, - { - "hours": 35.9, - "premium": 2.81894939e-7 - }, - { - "hours": 36, + "days": 21, "premium": 0 } ] From 86a555eb2776964df9a6791ef364d560ddc03a69 Mon Sep 17 00:00:00 2001 From: katzman Date: Mon, 6 Oct 2025 15:43:45 -0700 Subject: [PATCH 4/6] increase granularity of ui plot --- .../web/src/data/usernamePriceDecayTable.json | 672 ++++++++++++++++++ 1 file changed, 672 insertions(+) diff --git a/apps/web/src/data/usernamePriceDecayTable.json b/apps/web/src/data/usernamePriceDecayTable.json index 9ef40bd652a..4edc14e425a 100644 --- a/apps/web/src/data/usernamePriceDecayTable.json +++ b/apps/web/src/data/usernamePriceDecayTable.json @@ -3,170 +3,842 @@ "days": 0, "premium": 100 }, + { + "days": 0.1, + "premium": 93.30329915 + }, + { + "days": 0.2, + "premium": 87.05505633 + }, + { + "days": 0.3, + "premium": 81.22523964 + }, + { + "days": 0.4, + "premium": 75.78582833 + }, { "days": 0.5, "premium": 70.71067812 }, + { + "days": 0.6, + "premium": 65.97539554 + }, + { + "days": 0.7, + "premium": 61.55722067 + }, + { + "days": 0.8, + "premium": 57.43491775 + }, + { + "days": 0.9, + "premium": 53.58867313 + }, { "days": 1, "premium": 50 }, + { + "days": 1.1, + "premium": 46.65164958 + }, + { + "days": 1.2, + "premium": 43.52752816 + }, + { + "days": 1.3, + "premium": 40.61261982 + }, + { + "days": 1.4, + "premium": 37.89291416 + }, { "days": 1.5, "premium": 35.35533906 }, + { + "days": 1.6, + "premium": 32.98769777 + }, + { + "days": 1.7, + "premium": 30.77861033 + }, + { + "days": 1.8, + "premium": 28.71745887 + }, + { + "days": 1.9, + "premium": 26.79433656 + }, { "days": 2, "premium": 25 }, + { + "days": 2.1, + "premium": 23.32582479 + }, + { + "days": 2.2, + "premium": 21.76376408 + }, + { + "days": 2.3, + "premium": 20.30630991 + }, + { + "days": 2.4, + "premium": 18.94645708 + }, { "days": 2.5, "premium": 17.67766953 }, + { + "days": 2.6, + "premium": 16.49384888 + }, + { + "days": 2.7, + "premium": 15.38930517 + }, + { + "days": 2.8, + "premium": 14.35872944 + }, + { + "days": 2.9, + "premium": 13.39716828 + }, { "days": 3, "premium": 12.5 }, + { + "days": 3.1, + "premium": 11.66291239 + }, + { + "days": 3.2, + "premium": 10.88188204 + }, + { + "days": 3.3, + "premium": 10.15315495 + }, + { + "days": 3.4, + "premium": 9.47322854 + }, { "days": 3.5, "premium": 8.83883476 }, + { + "days": 3.6, + "premium": 8.24692444 + }, + { + "days": 3.7, + "premium": 7.69465258 + }, + { + "days": 3.8, + "premium": 7.17936472 + }, + { + "days": 3.9, + "premium": 6.69858414 + }, { "days": 4, "premium": 6.25 }, + { + "days": 4.1, + "premium": 5.8314562 + }, + { + "days": 4.2, + "premium": 5.44094102 + }, + { + "days": 4.3, + "premium": 5.07657748 + }, + { + "days": 4.4, + "premium": 4.73661427 + }, { "days": 4.5, "premium": 4.41941738 }, + { + "days": 4.6, + "premium": 4.12346222 + }, + { + "days": 4.7, + "premium": 3.84732629 + }, + { + "days": 4.8, + "premium": 3.58968236 + }, + { + "days": 4.9, + "premium": 3.34929207 + }, { "days": 5, "premium": 3.125 }, + { + "days": 5.1, + "premium": 2.9157281 + }, + { + "days": 5.2, + "premium": 2.72047051 + }, + { + "days": 5.3, + "premium": 2.53828874 + }, + { + "days": 5.4, + "premium": 2.36830714 + }, { "days": 5.5, "premium": 2.20970869 }, + { + "days": 5.6, + "premium": 2.06173111 + }, + { + "days": 5.7, + "premium": 1.92366315 + }, + { + "days": 5.8, + "premium": 1.79484118 + }, + { + "days": 5.9, + "premium": 1.67464604 + }, { "days": 6, "premium": 1.5625 }, + { + "days": 6.1, + "premium": 1.45786405 + }, + { + "days": 6.2, + "premium": 1.36023526 + }, + { + "days": 6.3, + "premium": 1.26914437 + }, + { + "days": 6.4, + "premium": 1.18415357 + }, { "days": 6.5, "premium": 1.10485435 }, + { + "days": 6.6, + "premium": 1.03086556 + }, + { + "days": 6.7, + "premium": 0.96183157 + }, + { + "days": 6.8, + "premium": 0.89742059 + }, + { + "days": 6.9, + "premium": 0.83732302 + }, { "days": 7, "premium": 0.78125 }, + { + "days": 7.1, + "premium": 0.72893202 + }, + { + "days": 7.2, + "premium": 0.68011763 + }, + { + "days": 7.3, + "premium": 0.63457218 + }, + { + "days": 7.4, + "premium": 0.59207678 + }, { "days": 7.5, "premium": 0.55242717 }, + { + "days": 7.6, + "premium": 0.51543278 + }, + { + "days": 7.7, + "premium": 0.48091579 + }, + { + "days": 7.8, + "premium": 0.44871029 + }, + { + "days": 7.9, + "premium": 0.41866151 + }, { "days": 8, "premium": 0.390625 }, + { + "days": 8.1, + "premium": 0.36446601 + }, + { + "days": 8.2, + "premium": 0.34005881 + }, + { + "days": 8.3, + "premium": 0.31728609 + }, + { + "days": 8.4, + "premium": 0.29603839 + }, { "days": 8.5, "premium": 0.27621359 }, + { + "days": 8.6, + "premium": 0.25771639 + }, + { + "days": 8.7, + "premium": 0.24045789 + }, + { + "days": 8.8, + "premium": 0.22435515 + }, + { + "days": 8.9, + "premium": 0.20933075 + }, { "days": 9, "premium": 0.1953125 }, + { + "days": 9.1, + "premium": 0.18223301 + }, + { + "days": 9.2, + "premium": 0.17002941 + }, + { + "days": 9.3, + "premium": 0.15864305 + }, + { + "days": 9.4, + "premium": 0.1480192 + }, { "days": 9.5, "premium": 0.13810679 }, + { + "days": 9.6, + "premium": 0.12885819 + }, + { + "days": 9.7, + "premium": 0.12022895 + }, + { + "days": 9.8, + "premium": 0.11217757 + }, + { + "days": 9.9, + "premium": 0.10466538 + }, { "days": 10, "premium": 0.09765625 }, + { + "days": 10.1, + "premium": 0.0911165 + }, + { + "days": 10.2, + "premium": 0.0850147 + }, + { + "days": 10.3, + "premium": 0.07932152 + }, + { + "days": 10.4, + "premium": 0.0740096 + }, { "days": 10.5, "premium": 0.0690534 }, + { + "days": 10.6, + "premium": 0.0644291 + }, + { + "days": 10.7, + "premium": 0.06011447 + }, + { + "days": 10.8, + "premium": 0.05608879 + }, + { + "days": 10.9, + "premium": 0.05233269 + }, { "days": 11, "premium": 0.04882812 }, + { + "days": 11.1, + "premium": 0.04555825 + }, + { + "days": 11.2, + "premium": 0.04250735 + }, + { + "days": 11.3, + "premium": 0.03966076 + }, + { + "days": 11.4, + "premium": 0.0370048 + }, { "days": 11.5, "premium": 0.0345267 }, + { + "days": 11.6, + "premium": 0.03221455 + }, + { + "days": 11.7, + "premium": 0.03005724 + }, + { + "days": 11.8, + "premium": 0.02804439 + }, + { + "days": 11.9, + "premium": 0.02616634 + }, { "days": 12, "premium": 0.02441406 }, + { + "days": 12.1, + "premium": 0.02277913 + }, + { + "days": 12.2, + "premium": 0.02125368 + }, + { + "days": 12.3, + "premium": 0.01983038 + }, + { + "days": 12.4, + "premium": 0.0185024 + }, { "days": 12.5, "premium": 0.01726335 }, + { + "days": 12.6, + "premium": 0.01610727 + }, + { + "days": 12.7, + "premium": 0.01502862 + }, + { + "days": 12.8, + "premium": 0.0140222 + }, + { + "days": 12.9, + "premium": 0.01308317 + }, { "days": 13, "premium": 0.01220703 }, + { + "days": 13.1, + "premium": 0.01138956 + }, + { + "days": 13.2, + "premium": 0.01062684 + }, + { + "days": 13.3, + "premium": 0.00991519 + }, + { + "days": 13.4, + "premium": 0.0092512 + }, { "days": 13.5, "premium": 0.00863167 }, + { + "days": 13.6, + "premium": 0.00805364 + }, + { + "days": 13.7, + "premium": 0.00751431 + }, + { + "days": 13.8, + "premium": 0.0070111 + }, + { + "days": 13.9, + "premium": 0.00654159 + }, { "days": 14, "premium": 0.00610352 }, + { + "days": 14.1, + "premium": 0.00569478 + }, + { + "days": 14.2, + "premium": 0.00531342 + }, + { + "days": 14.3, + "premium": 0.0049576 + }, + { + "days": 14.4, + "premium": 0.0046256 + }, { "days": 14.5, "premium": 0.00431584 }, + { + "days": 14.6, + "premium": 0.00402682 + }, + { + "days": 14.7, + "premium": 0.00375715 + }, + { + "days": 14.8, + "premium": 0.00350555 + }, + { + "days": 14.9, + "premium": 0.00327079 + }, { "days": 15, "premium": 0.00305176 }, + { + "days": 15.1, + "premium": 0.00284739 + }, + { + "days": 15.2, + "premium": 0.00265671 + }, + { + "days": 15.3, + "premium": 0.0024788 + }, + { + "days": 15.4, + "premium": 0.0023128 + }, { "days": 15.5, "premium": 0.00215792 }, + { + "days": 15.6, + "premium": 0.00201341 + }, + { + "days": 15.7, + "premium": 0.00187858 + }, + { + "days": 15.8, + "premium": 0.00175277 + }, + { + "days": 15.9, + "premium": 0.0016354 + }, { "days": 16, "premium": 0.00152588 }, + { + "days": 16.1, + "premium": 0.0014237 + }, + { + "days": 16.2, + "premium": 0.00132835 + }, + { + "days": 16.3, + "premium": 0.0012394 + }, + { + "days": 16.4, + "premium": 0.0011564 + }, { "days": 16.5, "premium": 0.00107896 }, + { + "days": 16.6, + "premium": 0.0010067 + }, + { + "days": 16.7, + "premium": 0.00093929 + }, + { + "days": 16.8, + "premium": 0.00087639 + }, + { + "days": 16.9, + "premium": 0.0008177 + }, { "days": 17, "premium": 0.00076294 }, + { + "days": 17.1, + "premium": 0.00071185 + }, + { + "days": 17.2, + "premium": 0.00066418 + }, + { + "days": 17.3, + "premium": 0.0006197 + }, + { + "days": 17.4, + "premium": 0.0005782 + }, { "days": 17.5, "premium": 0.00053948 }, + { + "days": 17.6, + "premium": 0.00050335 + }, + { + "days": 17.7, + "premium": 0.00046964 + }, + { + "days": 17.8, + "premium": 0.00043819 + }, + { + "days": 17.9, + "premium": 0.00040885 + }, { "days": 18, "premium": 0.00038147 }, + { + "days": 18.1, + "premium": 0.00035592 + }, + { + "days": 18.2, + "premium": 0.00033209 + }, + { + "days": 18.3, + "premium": 0.00030985 + }, + { + "days": 18.4, + "premium": 0.0002891 + }, { "days": 18.5, "premium": 0.00026974 }, + { + "days": 18.6, + "premium": 0.00025168 + }, + { + "days": 18.7, + "premium": 0.00023482 + }, + { + "days": 18.8, + "premium": 0.0002191 + }, + { + "days": 18.9, + "premium": 0.00020442 + }, { "days": 19, "premium": 0.00019073 }, + { + "days": 19.1, + "premium": 0.00017796 + }, + { + "days": 19.2, + "premium": 0.00016604 + }, + { + "days": 19.3, + "premium": 0.00015492 + }, + { + "days": 19.4, + "premium": 0.00014455 + }, { "days": 19.5, "premium": 0.00013487 }, + { + "days": 19.6, + "premium": 0.00012584 + }, + { + "days": 19.7, + "premium": 0.00011741 + }, + { + "days": 19.8, + "premium": 0.00010955 + }, + { + "days": 19.9, + "premium": 0.00010221 + }, { "days": 20, "premium": 0.00009537 }, + { + "days": 20.1, + "premium": 0.00008898 + }, + { + "days": 20.2, + "premium": 0.00008302 + }, + { + "days": 20.3, + "premium": 0.00007746 + }, + { + "days": 20.4, + "premium": 0.00007227 + }, { "days": 20.5, "premium": 0.00006743 }, + { + "days": 20.6, + "premium": 0.00006292 + }, + { + "days": 20.7, + "premium": 0.00005871 + }, + { + "days": 20.8, + "premium": 0.00005477 + }, + { + "days": 20.9, + "premium": 0.00005111 + }, { "days": 21, "premium": 0 From 2d8bac7381dc00dd5c0ee9f190675e5e2d2ca44f Mon Sep 17 00:00:00 2001 From: katzman Date: Mon, 27 Oct 2025 09:28:45 -0700 Subject: [PATCH 5/6] Rename and refactor hook --- ...useBasenamesNameExpiresWithGracePeriod.ts} | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) rename apps/web/src/hooks/{useBasenamesNameExpires.ts => useBasenamesNameExpiresWithGracePeriod.ts} (50%) diff --git a/apps/web/src/hooks/useBasenamesNameExpires.ts b/apps/web/src/hooks/useBasenamesNameExpiresWithGracePeriod.ts similarity index 50% rename from apps/web/src/hooks/useBasenamesNameExpires.ts rename to apps/web/src/hooks/useBasenamesNameExpiresWithGracePeriod.ts index 24aa4b1234e..e028cfdecb5 100644 --- a/apps/web/src/hooks/useBasenamesNameExpires.ts +++ b/apps/web/src/hooks/useBasenamesNameExpiresWithGracePeriod.ts @@ -1,32 +1,41 @@ import { useReadContract } from 'wagmi'; +import useBasenameChain from 'apps/web/src/hooks/useBasenameChain'; import BaseRegistrarAbi from 'apps/web/src/abis/BaseRegistrarAbi'; import { USERNAME_BASE_REGISTRAR_ADDRESSES } from 'apps/web/src/addresses/usernames'; import { getTokenIdFromBasename, formatBaseEthDomain, - getChainForBasename, GRACE_PERIOD_DURATION_SECONDS, } from 'apps/web/src/utils/usernames'; import { Basename } from '@coinbase/onchainkit/identity'; +import { logger } from 'apps/web/src/utils/logger'; -export function useBasenamesNameExpires(name: string) { - // Convert name to full basename format - const fullBasename = name.includes('.') ? (name as Basename) : formatBaseEthDomain(name, 8453); // Base mainnet - const chain = getChainForBasename(fullBasename); +export function useBasenamesNameExpiresWithGracePeriod(name: string) { + const chain = useBasenameChain().basenameChain.id; + const fullBasename = name.includes('.') ? (name as Basename) : formatBaseEthDomain(name, chain); const tokenId = getTokenIdFromBasename(fullBasename); const { data: nameExpiresTimestamp } = useReadContract({ abi: BaseRegistrarAbi, - address: USERNAME_BASE_REGISTRAR_ADDRESSES[chain.id], + address: USERNAME_BASE_REGISTRAR_ADDRESSES[chain], functionName: 'nameExpires', args: [tokenId], - chainId: chain.id, + chainId: chain, }); + if (!nameExpiresTimestamp) { + const errorMessage = `Unable to retrieve expiration timestamp for name: ${name}`; + logger.error(errorMessage, { + name, + fullBasename, + chain, + context: 'useBasenamesNameExpiresWithGracePeriod', + }); + throw new Error(errorMessage); + } + // Add 90 days (grace period) to get the auction start time - const auctionStartTime = nameExpiresTimestamp - ? nameExpiresTimestamp + BigInt(GRACE_PERIOD_DURATION_SECONDS) - : undefined; + const auctionStartTime = nameExpiresTimestamp + BigInt(GRACE_PERIOD_DURATION_SECONDS); return { data: auctionStartTime }; } From 67aa5d1836072f3600695b677738a40b8a0d4493 Mon Sep 17 00:00:00 2001 From: katzman Date: Mon, 27 Oct 2025 09:28:52 -0700 Subject: [PATCH 6/6] Fix deps --- .../src/components/Basenames/PremiumExplainerModal/index.tsx | 4 ++-- apps/web/src/hooks/useActiveEthPremiumAmount.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx b/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx index c08247c0e2b..782b69b1ddd 100644 --- a/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx +++ b/apps/web/src/components/Basenames/PremiumExplainerModal/index.tsx @@ -1,6 +1,6 @@ import Modal from 'apps/web/src/components/Modal'; import data from 'apps/web/src/data/usernamePriceDecayTable.json'; -import { useBasenamesNameExpires } from 'apps/web/src/hooks/useBasenamesNameExpires'; +import { useBasenamesNameExpiresWithGracePeriod } from 'apps/web/src/hooks/useBasenamesNameExpiresWithGracePeriod'; import { CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip } from 'recharts'; import { formatEther } from 'viem'; @@ -75,7 +75,7 @@ export function PremiumExplainerModal({ baseSingleYearEthCost, name, }: PremiumExplainerModalProps) { - const { data: auctionStartTimeSeconds } = useBasenamesNameExpires(name); + const { data: auctionStartTimeSeconds } = useBasenamesNameExpiresWithGracePeriod(name); if (!premiumEthAmount || !baseSingleYearEthCost) return null; const formattedOneYearCost = Number(formatEther(baseSingleYearEthCost)).toLocaleString( diff --git a/apps/web/src/hooks/useActiveEthPremiumAmount.ts b/apps/web/src/hooks/useActiveEthPremiumAmount.ts index f1456efc52a..bcf6d5c8aeb 100644 --- a/apps/web/src/hooks/useActiveEthPremiumAmount.ts +++ b/apps/web/src/hooks/useActiveEthPremiumAmount.ts @@ -1,4 +1,4 @@ -import { useBasenamesNameExpires } from 'apps/web/src/hooks/useBasenamesNameExpires'; +import { useBasenamesNameExpiresWithGracePeriod } from 'apps/web/src/hooks/useBasenamesNameExpiresWithGracePeriod'; import { useState } from 'react'; import { useInterval } from 'usehooks-ts'; @@ -24,7 +24,7 @@ function calculateTimeLeft(differenceInSeconds: number): string { export function usePremiumEndDurationRemaining(name: string) { const [timeLeft, setTimeLeft] = useState(null); - const { data: auctionStartTimeSeconds } = useBasenamesNameExpires(name); + const { data: auctionStartTimeSeconds } = useBasenamesNameExpiresWithGracePeriod(name); useInterval(() => { if (!auctionStartTimeSeconds) return;