Skip to content

generate: bridge address case-sensitivity drops canonical tag + version field hardcoded #52

Description

@Nexory

Filing as Issue per CONTRIBUTING/policy (validate workflow blocks external PRs that touch src/). Happy to coordinate if a maintainer wants to take the diff. Two separable bugs in src/generate.ts:

Bug 1: CANONICAL_BRIDGES lookup is case-sensitive against lowercase data.json values

File: src/generate.ts (the CANONICAL_BRIDGES Set + the lookup at the chainToken loop)

The Set is constructed with checksum-cased addresses:

const CANONICAL_BRIDGES = new Set([
  '0x7f82f57F0Dd546519324392e408b01fcC7D709e8', // checksum
  '0x4200000000000000000000000000000000000010',
])

But data/ETH/data.json stores the Ethereum-side bridge address in all-lowercase:

"bridge": "0x7f82f57f0dd546519324392e408b01fcc7d709e8"

Set.has() is strict-equality string compare. The check CANONICAL_BRIDGES.has(chainToken.bridge) returns false for the lowercase value, so the published megaeth.tokenlist.json tags every ETH (chainId=1) token with extensions.bridgeType = 'others' instead of 'canonical'.

MegaETH-side (chainId=4326, address 0x4200...0010) is unaffected because that address is all-lowercase in both the Set and data.json.

Suggested fix: normalize both sides before the Set.has check.

// Build the Set as lowercase once
const CANONICAL_BRIDGES = new Set([
  '0x7f82f57f0dd546519324392e408b01fcc7d709e8',
  '0x4200000000000000000000000000000000000010',
])
// Or normalize the lookup:
extensions.bridgeType = CANONICAL_BRIDGES.has(chainToken.bridge.toLowerCase())
  ? 'canonical'
  : 'others'

The lowercase-everywhere convention matches what viem/ethers produce by default and what your data.json already stores.

Bug 2: Version object hardcoded {1,0,0} — never increments

File: src/generate.ts (the output object construction)

version: {
  major: 1,
  minor: 0,
  patch: 0,
},

This violates the Uniswap Token List schema monotonic-version invariant: every regeneration must bump at least the patch. Consumers caching the list by version-string see no change across regenerations even when tokens are added/removed.

Suggested fix: derive the version from git history (commit count on main since last tag, or just the commit count since repo creation). Minimal patch:

import { execSync } from 'node:child_process'
const commitCount = parseInt(
  execSync('git rev-list --count HEAD').toString().trim(),
  10,
)
// ...
version: {
  major: 1,
  minor: 0,
  patch: commitCount,
},

Or read it from package.json and bump via npm version patch in CI.

Reproduction

git clone https://github.com/megaeth-labs/mega-tokenlist
cd mega-tokenlist
npm install && npm run generate
jq '.tokens[] | select(.chainId == 1 and .extensions.bridgeType == "others")' megaeth.tokenlist.json
# returns every ETH-side token despite their bridges being the canonical OptimismPortal address

Context

PR #51 attempted to fix both directly but was blocked by the external-contributor validate check (only data/ is allowed). Closing that PR and re-filing as this Issue per the contribution policy.

Reporter: Nexory

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions