feat(tokens): cap the built-in token table at 500 entries — frees 23,104 B flash - #39
Merged
Merged
Conversation
…104 B flash
`tokens` is the single largest read-only symbol in the ARM image: 31,104 bytes
for 1,945 entries, bigger than MessagesMap (27,264) or the BIP-39 wordlist
(8,196). After this it is 8,000 bytes.
tokens 31,104 -> 8,000 B (500 entries x 16)
saved 23,104 B of flash
WHY A BUDGET RATHER THAN A BIGGER TABLE. The vetted source is a stale snapshot
and cannot be made current by shipping more of it. Measured against
ethereum-lists as pinned here:
- 1,924 of 1,945 entries are Ethereum mainnet. Optimism has 2, Polygon 3,
BSC 3. The "top EVM chains" are effectively absent, and Base and Arbitrum
have no directory at all.
- Absent entirely: UNI, AAVE, stETH, wstETH, rETH, cbETH, PEPE, and every
modern stablecoin -- FRAX, LUSD, PYUSD, crvUSD, USDe.
- `ARB` resolves to 0xafbec4d6..., a 2017 token named "ARBITRAGE". Arbitrum's
real ARB (0xB50721BC...) is not in the table.
So the long tail is not coverage, it is 2017-era ICO tokens occupying flash
while the assets users actually hold are missing. USDC, USDT, DAI, WETH, WBTC
and LINK are present and correct, and those are what the budget protects.
POLICY (keepkeylib/eth/token_policy.py, and it is the whole design):
1. Budget: 350 from ethereum-lists + 150 from the uniswap list.
2. Priority symbols first -- stablecoins, then majors.
3. A priority symbol is taken ONLY when the source gives it exactly one
address. Two entries sharing a symbol is how a scam token inherits a real
one's label, and the device would render the attacker's name. Ambiguous
symbols are dropped from the priority pass and reported at build time.
4. Remaining budget filled in the existing deterministic order (by address),
so output is reproducible and diffable.
NO ADDRESS IS WRITTEN IN THE POLICY. Symbols are matched against the vetted
source. A hand-typed address in a token table is a mislabelling defect waiting
to happen, and the file says so, so it does not become the place one appears.
TWO GROUPS PINNED FOR STRUCTURAL REASONS, both named rather than hidden:
- REQUIRED_BY_COINS (26): tickers coins[] declares with a contract address.
Coins.TableSanity asserts each resolves uniquely, and correctly FAILED when
the first cut dropped them -- the device would advertise a coin it cannot
name. They are 2017 tokens and are exactly what should go next, but the cut
has to happen in coins[] first, itself a 23,808-byte symbol.
- REQUIRED_BY_TESTS (1): ADT, which
test_ethereum_signtx_knownerc20_eip_1559 uses as its canonical "known
ERC-20" while asserting a hardcoded signature. A fixture should not get to
pin firmware flash; migrating that test to USDC retires the entry, and is
tracked as fixture debt rather than smuggled into this commit.
Verified: firmware-unit 439/439 (including Coins.TableSanity), full pyk suite
632 passed / 25 skipped / 0 failed, ARM SRAM reserve unchanged at 18,172 B.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
tokensis the single largest read-only symbol in the ARM image: 31,104 bytes for 1,945 entries — bigger thanMessagesMap(27,264) or the BIP-39 wordlist (8,196).Why a budget, not a bigger table
The vetted source is a stale snapshot and cannot be made current by shipping more of it. Measured against
ethereum-listsas pinned:ARBresolves to0xafbec4d6…, a 2017 token called "ARBITRAGE". Arbitrum's real ARB (0xB50721BC…) is not in the table.So the long tail is not coverage — it is 2017-era ICO tokens occupying flash while the assets users hold are missing. USDC, USDT, DAI, WETH, WBTC, LINK are present and correct, and those are what the budget protects.
Policy
No address is written in the policy — symbols are matched against the vetted source. A hand-typed address in a token table is a mislabelling defect waiting to happen.
Two groups pinned for structural reasons, both named
439/439 · full pyk 632 passed / 25 skipped / 0 failed · ARM SRAM unchanged at 18,172 B