Mobile (390x844): Canonical fee sinks panel truncates addresses with no scroll, copy, or expand affordance #93

Closed
opened 2026-04-30 03:15:15 +00:00 by Brouie · 10 comments
Brouie commented 2026-04-30 03:15:15 +00:00 (Migrated from gitlab.com)

Summary

At mobile viewport (390x844, iPhone 12 Pro preset via DevTools), the Canonical fee sinks (read-only) panel that appears on every page truncates each sink address mid-string with no scroll affordance, no tap-to-expand, no copy-to-clipboard button, and no text-overflow: ellipsis indicator that more content exists. Users on real phones cannot read or verify the sink addresses.

Repro

  1. Bring up SKIP+KUMBAYA+NO_COOLDOWN stack on 282eb62
  2. Open localhost:5173/ (or any route — panel is global)
  3. Chrome DevTools → device toolbar → iPhone 12 Pro (390x844)
  4. Scroll to the "Canonical fee sinks (read-only)" panel at the bottom

Observed

Each of the 5 sink rows clips the hex address at the panel's right edge:

  • DOUB/CL8Y LP (locked): 30.00% → 0x5FC8d32690cc91D4c39d9d3abcBD16989F8... [clipped]
  • CL8Y burned (sale proceeds): 40.00% → 0x000000000000000000000000000000000000... [clipped]
  • Podium pool: 20.00% → 0xCf7Ed3AccA5a467e9e704C703E8D87F6341... [clipped]
  • Team / reserved (0% default): 0.00% → 0xa513E6E4b8f2a923D98304ec87F64353C4D... [clipped]
  • Rabbit Treasury: 10.00% → 0x8A791620dd6260079BF849Dc5567aDC3F2F... [clipped]

Full addresses cannot be visually verified, copied, or parsed. No interaction surfaces the truncated portion.

Why it matters

The canonical fee sinks panel is the trust surface for "where does my CL8Y go" — users want to verify sink addresses match the spec / docs / their own audit notes. On mobile (where most retail will land post-TGE), this critical transparency surface is functionally broken because the addresses are unreadable.

Suggested resolution options

  1. Truncate with ellipsis in the middle (e.g., 0x5FC8...5707) and provide tap-to-expand or tap-to-copy. Standard wallet UX pattern.
  2. Word-break / break-all on hex so the address wraps to the next line. Less elegant but no interaction needed.
  3. Add a copy-to-clipboard button next to each address, with toast confirmation (matches the pattern used on the referrals share-link rows per #86).
  4. Horizontal scroll on the address line only — preserves single-line display and lets the user pan to see the full address. Acceptable but less discoverable.

Option 1 plus option 3 (middle ellipsis + copy button) is the strongest combo — matches what every wallet / explorer does for hex addresses on mobile.

Scope

This is a mobile-only display issue. Desktop renders the full address line correctly. Same panel, same component (looks like a shared footer surface across all routes), so a single-component fix lands everywhere.

Severity

P2-medium. Not a launch-blocker (data is technically correct, not user-tampering surface), but is a real polish gap on the most-trust-sensitive panel for mobile users.

Reference screenshot

Captured during F-13 mobile walkthrough as part of #38 deferred items.

cc @PlasticDigits

## Summary At mobile viewport (390x844, iPhone 12 Pro preset via DevTools), the **Canonical fee sinks (read-only)** panel that appears on every page truncates each sink address mid-string with no scroll affordance, no tap-to-expand, no copy-to-clipboard button, and no `text-overflow: ellipsis` indicator that more content exists. Users on real phones cannot read or verify the sink addresses. ## Repro 1. Bring up SKIP+KUMBAYA+NO_COOLDOWN stack on `282eb62` 2. Open `localhost:5173/` (or any route — panel is global) 3. Chrome DevTools → device toolbar → iPhone 12 Pro (390x844) 4. Scroll to the "Canonical fee sinks (read-only)" panel at the bottom ## Observed Each of the 5 sink rows clips the hex address at the panel's right edge: - DOUB/CL8Y LP (locked): 30.00% → `0x5FC8d32690cc91D4c39d9d3abcBD16989F8...` [clipped] - CL8Y burned (sale proceeds): 40.00% → `0x000000000000000000000000000000000000...` [clipped] - Podium pool: 20.00% → `0xCf7Ed3AccA5a467e9e704C703E8D87F6341...` [clipped] - Team / reserved (0% default): 0.00% → `0xa513E6E4b8f2a923D98304ec87F64353C4D...` [clipped] - Rabbit Treasury: 10.00% → `0x8A791620dd6260079BF849Dc5567aDC3F2F...` [clipped] Full addresses cannot be visually verified, copied, or parsed. No interaction surfaces the truncated portion. ## Why it matters The canonical fee sinks panel is the trust surface for "where does my CL8Y go" — users want to verify sink addresses match the spec / docs / their own audit notes. On mobile (where most retail will land post-TGE), this critical transparency surface is functionally broken because the addresses are unreadable. ## Suggested resolution options 1. **Truncate with ellipsis in the middle** (e.g., `0x5FC8...5707`) and provide tap-to-expand or tap-to-copy. Standard wallet UX pattern. 2. **Word-break / break-all on hex** so the address wraps to the next line. Less elegant but no interaction needed. 3. **Add a copy-to-clipboard button** next to each address, with toast confirmation (matches the pattern used on the referrals share-link rows per #86). 4. **Horizontal scroll on the address line only** — preserves single-line display and lets the user pan to see the full address. Acceptable but less discoverable. Option 1 plus option 3 (middle ellipsis + copy button) is the strongest combo — matches what every wallet / explorer does for hex addresses on mobile. ## Scope This is a **mobile-only display** issue. Desktop renders the full address line correctly. Same panel, same component (looks like a shared footer surface across all routes), so a single-component fix lands everywhere. ## Severity P2-medium. Not a launch-blocker (data is technically correct, not user-tampering surface), but is a real polish gap on the most-trust-sensitive panel for mobile users. ## Reference screenshot Captured during F-13 mobile walkthrough as part of #38 deferred items. cc @PlasticDigits
Brouie commented 2026-04-30 03:19:34 +00:00 (Migrated from gitlab.com)

image.png{width=259 height=308}

image.png{width=308 height=447}

image.png{width=335 height=281}

image.png{width=328 height=314}

![image.png](/uploads/073bb3298c59350c0ee59450830fe895/image.png){width=259 height=308} ![image.png](/uploads/4bf329b56b8d367a1acf321975316bbc/image.png){width=308 height=447} ![image.png](/uploads/b84a6636eef97fd8118804cdc0a3bf84/image.png){width=335 height=281} ![image.png](/uploads/fb3fb6ef99bc3b7b8a578eca4a54dcfa/image.png){width=328 height=314}
Brouie commented 2026-04-30 03:31:15 +00:00 (Migrated from gitlab.com)

mentioned in issue #95

mentioned in issue #95
Brouie commented 2026-04-30 04:21:08 +00:00 (Migrated from gitlab.com)

mentioned in issue #38

mentioned in issue #38
PlasticDigits commented 2026-04-30 04:52:34 +00:00 (Migrated from gitlab.com)

mentioned in commit 787e586718

mentioned in commit 787e58671816675a20df35673ef9bb63e3423209
PlasticDigits commented 2026-04-30 04:53:00 +00:00 (Migrated from gitlab.com)

Implemented #93 on `main` (commit 3480d53).

What changed

  • Snake_case view names (e.g. `WARBOW_FLAG_SILENCE_SEC`) render as spaced title case via `humanizeKvLabel` on `/timecurve/protocol` and the Arena Raw contract accordion (`TimeCurveSections.tsx`).
  • camelCase getters (e.g. `warbowPendingFlagOwner`) get the same treatment; multi-word prose like seconds remaining is left as-is.
  • Canonical fee sinks (`FeeTransparency`) and protocol sink / wired-address rows use `MegaScannerAddressLink`: at ≤479px width, full `0x`+40-hex addresses display as first 4 + … + last 4 characters; link target is always `https://mega.etherscan.io/address/{addr}` (lowercased path), including Anvil.
  • Kept upstream `ConversionArrow` between bps and address in the sink list.
  • Docs: `docs/frontend/timecurve-views.md` (anchor `#global-footer-fee-sinks-mobile-issue-93`), `docs/testing/invariants-and-business-logic.md` § canonical-fee-sinks-mobile-gitlab-93; play checklist `skills/verify-yo-fee-sinks-mobile/SKILL.md`; guardrails item #32.

Verify (for @brouie)

  • 390×844 (or any ≤479px): footer sinks show abbreviated hex + tap opens mega.etherscan.
  • ≥480px: footer + protocol show full address in the same link.
  • `/timecurve/protocol`: WarBow / pending-flag labels read as words; addresses still match `cast call`.
  • Arena → Raw contract accordion: KV labels humanized; prose rows unchanged.
  • Vitest green: `humanizeIdentifier.test.ts`, `megaEtherscan.test.ts`, `addressFormat.test.ts`.

Leaving issue open per request.

Implemented **#93** on \`main\` (commit **3480d53**). ### What changed - **Snake_case** view names (e.g. \`WARBOW_FLAG_SILENCE_SEC\`) render as spaced title case via \`humanizeKvLabel\` on **\`/timecurve/protocol\`** and the Arena **Raw contract** accordion (\`TimeCurveSections.tsx\`). - **camelCase** getters (e.g. \`warbowPendingFlagOwner\`) get the same treatment; multi-word prose like *seconds remaining* is left as-is. - **Canonical fee sinks** (\`FeeTransparency\`) and protocol sink / wired-address rows use **\`MegaScannerAddressLink\`**: at **≤479px** width, full \`0x\`+40-hex addresses display as **first 4 + … + last 4** characters; link target is always **\`https://mega.etherscan.io/address/\{addr\}\`** (lowercased path), including **Anvil**. - Kept upstream **\`ConversionArrow\`** between bps and address in the sink list. - Docs: \`docs/frontend/timecurve-views.md\` (anchor \`#global-footer-fee-sinks-mobile-issue-93\`), \`docs/testing/invariants-and-business-logic.md\` § **canonical-fee-sinks-mobile-gitlab-93**; play checklist \`skills/verify-yo-fee-sinks-mobile/SKILL.md\`; guardrails item **#32**. ### Verify (for @brouie) - [ ] **390×844** (or any **≤479px**): footer sinks show **abbreviated** hex + tap opens **mega.etherscan**. - [ ] **≥480px**: footer + protocol show **full** address in the same link. - [ ] **\`/timecurve/protocol\`**: WarBow / pending-flag labels read as words; addresses still match \`cast call\`. - [ ] **Arena → Raw contract accordion**: KV labels humanized; prose rows unchanged. - [ ] **Vitest** green: \`humanizeIdentifier.test.ts\`, \`megaEtherscan.test.ts\`, \`addressFormat.test.ts\`. Leaving issue **open** per request.
PlasticDigits commented 2026-04-30 05:25:10 +00:00 (Migrated from gitlab.com)

mentioned in issue #100

mentioned in issue #100
PlasticDigits commented 2026-04-30 06:06:56 +00:00 (Migrated from gitlab.com)

mentioned in commit ca2aaffdd6

mentioned in commit ca2aaffdd6e6c953d8d1e03569db684505e0f65e
Brouie commented 2026-05-01 15:09:38 +00:00 (Migrated from gitlab.com)

Partial verification on 3480d53 (carried into 243e2a0).

Item 5: Vitest guards green

$ npx vitest run humanizeIdentifier megaEtherscan addressFormat
 ✓ src/lib/addressFormat.test.ts (4 tests) 5ms
 ✓ src/lib/humanizeIdentifier.test.ts (5 tests) 3ms
 ✓ src/lib/megaEtherscan.test.ts (3 tests) 4ms
 Test Files  3 passed (3)
      Tests  12 passed (12)

Item 3 partial: addresses match cast call

Verified feeRouter.sinks(0..4) against the live deployment at 0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0:

i Address bps Sink
0 0x5FC8d32690cc91D4c39d9d3abcBD16989F875707 3000 (30.00%) DOUB/CL8Y LP locked
1 0x000000000000000000000000000000000000dEaD 4000 (40.00%) CL8Y burned
2 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 2000 (20.00%) Podium pool
3 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853 0 (0.00%) Team / reserved
4 0x8A791620dd6260079BF849Dc5567aDC3F2FdC318 1000 (10.00%) Rabbit Treasury
  • All 5 match the original repro's observed prefixes exactly.
  • Sink #2 (0xCf7Ed3Ac...0Fc9) matches PodiumPool in contracts/deployments/local-anvil-registry.json.
  • Sink #4 (0x8A791620...DC318) matches RabbitTreasury in registry + VITE_RABBIT_TREASURY_ADDRESS in frontend/.env.local.
  • bps sum: 3000 + 4000 + 2000 + 0 + 1000 = 10000 (100%) — protocol invariant holds.

cc @PlasticDigits

Partial verification on `3480d53` (carried into `243e2a0`). ### Item 5: Vitest guards green ``` $ npx vitest run humanizeIdentifier megaEtherscan addressFormat ✓ src/lib/addressFormat.test.ts (4 tests) 5ms ✓ src/lib/humanizeIdentifier.test.ts (5 tests) 3ms ✓ src/lib/megaEtherscan.test.ts (3 tests) 4ms Test Files 3 passed (3) Tests 12 passed (12) ``` ### Item 3 partial: addresses match `cast call` Verified `feeRouter.sinks(0..4)` against the live deployment at `0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0`: | i | Address | bps | Sink | |---|---|---|---| | 0 | `0x5FC8d32690cc91D4c39d9d3abcBD16989F875707` | 3000 (30.00%) | DOUB/CL8Y LP locked | | 1 | `0x000000000000000000000000000000000000dEaD` | 4000 (40.00%) | CL8Y burned | | 2 | `0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9` | 2000 (20.00%) | Podium pool | | 3 | `0xa513E6E4b8f2a923D98304ec87F64353C4D5C853` | 0 (0.00%) | Team / reserved | | 4 | `0x8A791620dd6260079BF849Dc5567aDC3F2FdC318` | 1000 (10.00%) | Rabbit Treasury | - All 5 match the original repro's observed prefixes exactly. - Sink #2 (`0xCf7Ed3Ac...0Fc9`) matches `PodiumPool` in `contracts/deployments/local-anvil-registry.json`. - Sink #4 (`0x8A791620...DC318`) matches `RabbitTreasury` in registry + `VITE_RABBIT_TREASURY_ADDRESS` in `frontend/.env.local`. - bps sum: 3000 + 4000 + 2000 + 0 + 1000 = **10000 (100%)** — protocol invariant holds. cc @PlasticDigits
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-05-02 04:36:16 +00:00
PlasticDigits commented 2026-05-19 07:53:22 +00:00 (Migrated from gitlab.com)

mentioned in issue #217

mentioned in issue #217
PlasticDigits commented 2026-05-21 09:32:21 +00:00 (Migrated from gitlab.com)

mentioned in issue #232

mentioned in issue #232
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega#93
No description provided.