Skip to content

Commit 32c9d73

Browse files
ci(release): publish latest release
1 parent cb2349c commit 32c9d73

5 files changed

Lines changed: 47 additions & 58 deletions

File tree

RELEASE

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
IPFS hash of the deployment:
2-
- CIDv0: `QmcMz6DNz5J4zKEpacghK2qti4cNNCMTM52L6W29sD7nrv`
3-
- CIDv1: `bafybeigqlmoljlfj2t7hzn2pscueekclcktd7oefssqshoika5nlxv65cm`
2+
- CIDv0: `QmSCo841x3an3oGaeRkGYR4s15pMdv32W7nhomMUYR6bBp`
3+
- CIDv1: `bafybeibznoorvrw5anzk7vpb6qxpl5nnxp5xpwolnw5dgr6xswk6fivwum`
44

55
The latest release is always mirrored at [app.uniswap.org](https://app.uniswap.org).
66

@@ -10,5 +10,5 @@ You can also access the Uniswap Interface from an IPFS gateway.
1010
Your Uniswap settings are never remembered across different URLs.
1111

1212
IPFS gateways:
13-
- https://bafybeigqlmoljlfj2t7hzn2pscueekclcktd7oefssqshoika5nlxv65cm.ipfs.dweb.link/
14-
- [ipfs://QmcMz6DNz5J4zKEpacghK2qti4cNNCMTM52L6W29sD7nrv/](ipfs://QmcMz6DNz5J4zKEpacghK2qti4cNNCMTM52L6W29sD7nrv/)
13+
- https://bafybeibznoorvrw5anzk7vpb6qxpl5nnxp5xpwolnw5dgr6xswk6fivwum.ipfs.dweb.link/
14+
- [ipfs://QmSCo841x3an3oGaeRkGYR4s15pMdv32W7nhomMUYR6bBp/](ipfs://QmSCo841x3an3oGaeRkGYR4s15pMdv32W7nhomMUYR6bBp/)

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
web/5.141.7
1+
web/5.141.8

apps/web/src/components/Toucan/Auction/BidDistributionChart/utils/combinedChartPanZoom.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { groupTickBars } from '~/components/Charts/ToucanChart/bidDistribution/utils/tickGrouping'
22
import type { ChartBarData, ProcessedChartData } from '~/components/Toucan/Auction/BidDistributionChart/utils/utils'
33

4-
const TARGET_GROUPED_BARS = 33
4+
const TARGET_GROUPED_BARS = 80
55

66
interface NormalizedDataSlice {
77
yMin: number

apps/web/src/components/Toucan/Auction/BidDistributionChart/utils/utils.ts

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -582,12 +582,13 @@ export function generateChartData({
582582
const entries = Array.from(bidData.entries())
583583
.map(([tickQ96, amount]) => {
584584
const amountInBidToken = toDecimal(amount, bidTokenInfo.decimals)
585+
const tick = fromQ96ToDecimalWithTokenDecimals({
586+
q96Value: tickQ96,
587+
bidTokenDecimals: bidTokenInfo.decimals,
588+
auctionTokenDecimals,
589+
})
585590
return {
586-
tick: fromQ96ToDecimalWithTokenDecimals({
587-
q96Value: tickQ96,
588-
bidTokenDecimals: bidTokenInfo.decimals,
589-
auctionTokenDecimals,
590-
}),
591+
tick,
591592
tickQ96, // Preserve original Q96 string for precision
592593
amount: bidTokenInfo.priceFiat > 0 ? amountInBidToken * bidTokenInfo.priceFiat : amountInBidToken,
593594
}
@@ -766,29 +767,38 @@ export function generateChartData({
766767

767768
// Build bars array - one bar per tick_size step
768769
const bars: ChartBarData[] = []
769-
// Store both amount and Q96 string for precise matching
770-
const bidLookup = new Map(effectiveEntries.map((e) => [e.tick, { amount: e.amount, tickQ96: e.tickQ96 }]))
771770

772771
// Calculate base tick offset: how many ticks from floorPrice to minTick
773772
// This is needed to correctly calculate Q96 for ticks that don't have bid data
774773
const floorToMinOffset = Math.round((minTick - floorPriceDecimal) / tickSizeDecimal)
775774
const rawTicksPerBar = Math.max(1, Math.round(barStep / tickSizeDecimal))
776775

777-
for (let i = 0; i < totalBars; i++) {
778-
const currentTick = minTick + i * barStep
776+
// When barStep > tickSize, multiple bids can fall within a single bar's range.
777+
// Pre-aggregate bid volumes into bar buckets so no volume is silently dropped.
778+
const barAggregates = new Map<number, { amount: number; tickQ96: string | null }>()
779+
780+
for (const entry of effectiveEntries) {
781+
// Find the nearest bar index for this entry
782+
const barIndex = Math.floor((entry.tick - minTick) / barStep)
783+
if (barIndex < 0 || barIndex >= totalBars) {
784+
continue
785+
}
779786

780-
// Find exact match or very close match (within small tolerance for floating point)
781-
const tolerance = barStep * TOLERANCE.TICK_COMPARISON
782-
let matchedEntry = bidLookup.get(currentTick)
783-
if (!matchedEntry) {
784-
// Check for near matches
785-
for (const [tick, data] of bidLookup.entries()) {
786-
if (Math.abs(tick - currentTick) < tolerance) {
787-
matchedEntry = data
788-
break
789-
}
787+
const existing = barAggregates.get(barIndex)
788+
if (existing) {
789+
existing.amount += entry.amount
790+
// Keep the Q96 of the first bid in this bucket (entries are sorted ascending)
791+
if (!existing.tickQ96) {
792+
existing.tickQ96 = entry.tickQ96
790793
}
794+
} else {
795+
barAggregates.set(barIndex, { amount: entry.amount, tickQ96: entry.tickQ96 })
791796
}
797+
}
798+
799+
for (let i = 0; i < totalBars; i++) {
800+
const currentTick = minTick + i * barStep
801+
const aggregate = barAggregates.get(i)
792802

793803
const displayValue = calculateTickDisplayValue({
794804
tickValue: currentTick,
@@ -799,7 +809,7 @@ export function generateChartData({
799809

800810
// Use matched Q96 if available, otherwise calculate from floor price
801811
const tickQ96 =
802-
matchedEntry?.tickQ96 ??
812+
aggregate?.tickQ96 ??
803813
calculateTickQ96({
804814
basePriceQ96: floorPrice,
805815
tickSizeQ96: tickSize,
@@ -810,7 +820,7 @@ export function generateChartData({
810820
tick: currentTick,
811821
tickQ96,
812822
tickDisplay: formatter(displayValue),
813-
amount: matchedEntry?.amount ?? 0,
823+
amount: aggregate?.amount ?? 0,
814824
index: i,
815825
})
816826
}

apps/web/src/components/Toucan/Auction/hooks/useLoadBidDistributionData.ts

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useEffect, useMemo, useRef } from 'react'
44
import { auctionQueries } from 'uniswap/src/data/rest/auctions/auctionQueries'
55
import { EVMUniverseChainId } from 'uniswap/src/features/chains/types'
66
import { logger } from 'utilities/src/logger/logger'
7-
import { CHART_CONSTRAINTS, MAX_RENDERABLE_BARS } from '~/components/Toucan/Auction/BidDistributionChart/constants'
7+
import { MAX_RENDERABLE_BARS } from '~/components/Toucan/Auction/BidDistributionChart/constants'
88
import { AuctionProgressState, BidDistributionData } from '~/components/Toucan/Auction/store/types'
99
import { useAuctionStore, useAuctionStoreActions } from '~/components/Toucan/Auction/store/useAuctionStore'
1010
import { getPollingIntervalMs } from '~/utils/averageBlockTimeMs'
@@ -32,22 +32,19 @@ function areBidMapsEqual(a: BidDistributionData | undefined, b: BidDistributionD
3232
}
3333

3434
/**
35-
* Caps concentration data to MAX_RENDERABLE_BARS ticks.
35+
* Caps concentration data to MAX_RENDERABLE_BARS ticks above floor price.
3636
*
37-
* The cap window is centered around the clearing price (with a few ticks below
38-
* and the rest above) so bids near the clearing price are always preserved.
39-
* Falls back to a floor-based window when clearing price is unavailable.
37+
* Includes all bids from floor price upward (so bids below clearing are preserved),
38+
* but caps the upper range to avoid extreme outlier bids blowing up the chart.
4039
*/
4140
function capConcentrationData({
4241
concentration,
4342
floorPriceQ96,
4443
tickSizeQ96,
45-
clearingPriceQ96,
4644
}: {
4745
concentration: Record<string, { volume: string }> | undefined
4846
floorPriceQ96: string | undefined
4947
tickSizeQ96: string | undefined
50-
clearingPriceQ96: string | undefined
5148
}): { cappedConcentration: Record<string, { volume: string }>; capped: boolean; excludedVolume: bigint } {
5249
if (!concentration || !floorPriceQ96 || !tickSizeQ96) {
5350
return { cappedConcentration: concentration ?? {}, capped: false, excludedVolume: 0n }
@@ -60,25 +57,9 @@ function capConcentrationData({
6057
return { cappedConcentration: concentration, capped: false, excludedVolume: 0n }
6158
}
6259

63-
let minPriceQ96: bigint
64-
let maxPriceQ96: bigint
65-
66-
if (clearingPriceQ96) {
67-
// Align with computeTickWindow's asymmetric logic: keep only a few ticks below
68-
// clearing price and fill the rest of the budget above. This avoids holding
69-
// thousands of below-clearing bids in memory that will never render.
70-
const belowTicks = BigInt(CHART_CONSTRAINTS.PREFERRED_TICKS_BELOW_CLEARING_PRICE)
71-
const clearing = BigInt(clearingPriceQ96)
72-
minPriceQ96 = clearing - belowTicks * tickSize
73-
if (minPriceQ96 < floor) {
74-
minPriceQ96 = floor
75-
}
76-
maxPriceQ96 = minPriceQ96 + tickSize * BigInt(MAX_RENDERABLE_BARS - 1)
77-
} else {
78-
// Fallback: cap from floor when clearing price is unknown
79-
minPriceQ96 = floor
80-
maxPriceQ96 = floor + tickSize * BigInt(MAX_RENDERABLE_BARS - 1)
81-
}
60+
// Include everything from floor up to MAX_RENDERABLE_BARS ticks above floor
61+
const minPriceQ96 = floor
62+
const maxPriceQ96 = floor + tickSize * BigInt(MAX_RENDERABLE_BARS - 1)
8263

8364
const filteredEntries: Array<[string, { volume: string }]> = []
8465
let excludedVolume = 0n
@@ -91,7 +72,7 @@ function capConcentrationData({
9172
excludedVolume += BigInt(value.volume)
9273
}
9374
} catch {
94-
// Ignore unparsable entries; they won't be rendered.
75+
// Ignore unparsable entries
9576
}
9677
}
9778

@@ -152,10 +133,9 @@ interface UseLoadBidDistributionDataParams {
152133
*/
153134
export function useLoadBidDistributionData({ chainId, auctionAddress }: UseLoadBidDistributionDataParams): void {
154135
const { setBidDistributionData } = useAuctionStoreActions()
155-
const { floorPrice, tickSize, clearingPrice, isAuctionActive } = useAuctionStore((state) => ({
136+
const { floorPrice, tickSize, isAuctionActive } = useAuctionStore((state) => ({
156137
floorPrice: state.auctionDetails?.floorPrice,
157138
tickSize: state.auctionDetails?.tickSize,
158-
clearingPrice: state.auctionDetails?.clearingPrice,
159139
isAuctionActive: state.progress.state === AuctionProgressState.IN_PROGRESS,
160140
}))
161141

@@ -208,7 +188,6 @@ export function useLoadBidDistributionData({ chainId, auctionAddress }: UseLoadB
208188
concentration,
209189
floorPriceQ96: floorPrice,
210190
tickSizeQ96: tickSize,
211-
clearingPriceQ96: clearingPrice,
212191
})
213192

214193
// Sort prices numerically (ascending) before creating the map
@@ -238,5 +217,5 @@ export function useLoadBidDistributionData({ chainId, auctionAddress }: UseLoadB
238217
prevBidMapRef.current = bidMap
239218
setBidDistributionData(bidMap, excludedVolume > 0n ? excludedVolume.toString() : null)
240219
}
241-
}, [data, setBidDistributionData, floorPrice, tickSize, clearingPrice])
220+
}, [data, setBidDistributionData, floorPrice, tickSize])
242221
}

0 commit comments

Comments
 (0)