Pricing Fresh Token Launches in USD Before DexScreener Indexes Them
9 min read read
// server/lib/v4-price.js
export async function resolveV4Price(tokenAddress, opts = {}) {
const { ethPriceUsd = 0, allowSim = false } = opts;
const lower = (tokenAddress || '').toLowerCase();
const isNewThryx = (opts.isNewThryx ?? (lower === NEW_THRYX.toLowerCase()));
// Tier 1: on-chain slot0 (NEW THRYX only)
if (isNewThryx) {
const onChain = await resolveNewThryxOnChain(ethPriceUsd);
if (onChain != null) {
cacheSet(_lastGood, lower, { priceUsd: onChain, source: 'onchain' });
return { priceUsd: onChain, source: 'onchain', priceUnknown: false };
}
}
// Tier 2: DexScreener (quote-token whitelisted)
const ds = await resolveDexScreener(tokenAddress);
if (ds != null) return { priceUsd: ds, source: 'dexscreener', priceUnknown: false };
// Tier 3: state-override sell-simulation
if (ethPriceUsd > 0) {
const sim = await resolveSellSimStateOverride(tokenAddress, ethPriceUsd);
if (sim != null) return { priceUsd: sim, source: 'sim-override', priceUnknown: false };
}
// Tier 4: last-known-good
const lg = cacheGet(_lastGood, lower, TTL_LAST_GOOD_MS);
if (lg && lg.priceUsd != null) {
return { priceUsd: lg.priceUsd, source: `cached:${lg.source}`, priceUnknown: false };
}
return { priceUsd: null, source: 'unresolved', priceUnknown: true };
}
const slot = keccak256(abi.encode(NEW_POOL_ID, 6));
const slot0Raw = await poolMgr.extsload(slot);
const sqrtPriceX96 = BigInt(slot0Raw) & ((1n << 160n) - 1n);
// token0=WETH < token1=NEW lexicographically.
// (sqrtPriceX96 / 2^96)^2 = NEW per WETH.
// Scale by 1e18 BEFORE divide to preserve precision for tiny prices.
const num = sqrtPriceX96 * sqrtPriceX96;
const newPerWethScaled = (num * 10n**18n) / (1n << 192n);
const newPerWeth = Number(newPerWethScaled) / 1e18;
const usdPerNew = (1 / newPerWeth) * ethPriceUsd;
const SAFE_QUOTES = new Set([
'0x4200000000000000000000000000000000000006', // WETH
'0x49e4cf7097c497008800edc80dc76906edd189dd', // NEW THRYX
'0xc07e889e1816de2708bf718683e52150c20f3ba3', // OLD THRYX
'0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', // USDC (native Base)
]);
const safe = allPairs.filter(p =>
p?.chainId === 'base' &&
SAFE_QUOTES.has(p?.quoteToken?.address?.toLowerCase()) &&
parseFloat(p.priceUsd) > 0 &&
(p?.liquidity?.usd ?? 0) >= 5
);
safe.sort((a, b) => (b.liquidity?.usd || 0) - (a.liquidity?.usd || 0));
// Standard ERC20 storage layout: _balances at slot 0, _allowances at slot 1.
const PROBE = '0x0000000000000000000000000000000000001337';
const balanceSlot = keccak256(abi.encode(['address','uint256'], [PROBE, 0]));
const allowanceInner = keccak256(abi.encode(['address','uint256'], [PROBE, 1]));
const allowanceFinal = keccak256(abi.encode(['address','bytes32'], [DIAMOND, allowanceInner]));
const MAX = '0x' + (2n**255n).toString(16).padStart(64, '0');
const stateOverride = {
[tokenAddress]: {
stateDiff: {
[balanceSlot]: MAX, // probe has 2^255 tokens
[allowanceFinal]: MAX, // probe has approved Diamond for 2^255
},
},
};
const calldata = iface.encodeFunctionData('swap', [
tokenAddress, ZERO_ADDRESS, parseUnits('10000', 18), 1n,
]);
const result = await provider.send('eth_call', [
{ from: PROBE, to: DIAMOND, data: calldata, gas: '0x1e8480' },
'latest',
stateOverride,
]);
const [wethOut] = abi.decode(['uint256'], result);
const ethPerToken = Number((wethOut * 10n**18n) / parseUnits('10000', 18)) / 1e18;
const priceUsd = ethPerToken * ethPriceUsd;