chore(config): switch DEMO/USDCx/PROMPT display addresses to synthetic placeholders#287
Merged
Merged
Conversation
…c placeholders
The api-server's token.supported_tokens map keys these tokens by their EVM
display address — the value MetaMask sees when rendering the user's Canton-side
balance. They are placeholders, not real on-chain contracts: PROMPT lives at
0x28d38d…1544 on Ethereum mainnet but that address is only load-bearing in the
relayer's ethereum.token_contract; USDCx and DEMO are Canton-native and have no
mainnet ERC-20 at all.
The previous USDCx placeholder reused real mainnet USDC's address
(0xA0b86991…eB48), which MetaMask flags as a phishing risk when users try to
import the token (its anti-phishing check compares addresses against the known-
mainnet-tokens registry, chain-agnostic, so the warning fires even on our
Canton-facade chainId). Use synthetic addresses instead:
PROMPT 0x9907000000000000000000000000000000000001 (was missing from mainnet template)
DEMO 0xDE30000000000000000000000000000000000001 (unchanged)
USDCx 0xC1A0000000000000000000000000000000000001 (was 0xA0b86991…eB48)
PROMPT is also given a synthetic placeholder defensively, in case it's ever
listed in MetaMask's high-profile registry. The relayer's ethereum.token_contract
keeps the real mainnet PROMPT address — that side is load-bearing.
The docker and local-devnet configs keep their existing PROMPT addresses
(0x5FbDB2…aa3 / 0x90cb4f9e…48e) because on those test chains PROMPT is the
actual deployed ERC-20 used by E2E bridge flows, not a display placeholder.
Updated:
- pkg/config/defaults/config.api-server.{mainnet,docker,local-devnet}.yaml
- config.e2e-local.yaml
- pkg/config/tests/*.api.yaml fixtures
- tests/e2e/devstack/stack/types.go (USDCxTokenVirtualAddr constant)
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #287 +/- ##
=======================================
Coverage ? 31.27%
=======================================
Files ? 131
Lines ? 10179
Branches ? 0
=======================================
Hits ? 3183
Misses ? 6725
Partials ? 271
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Contributor
There was a problem hiding this comment.
Code Review
This pull request replaces the real Ethereum mainnet address for USDC with a synthetic address (0xC1A0000000000000000000000000000000000001) for the USDCx token across multiple configuration and test files. This prevents MetaMask from flagging the imported token as a phishing attempt. Additionally, a new synthetic token 'PROMPT' has been added to the mainnet configuration. No review comments were provided, and the changes look correct.
dhyaniarun1993
approved these changes
May 28, 2026
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.
Summary
The api-server's
token.supported_tokensmap keys each Canton-supported token by an EVM display address — the value MetaMask sees when rendering the user's Canton-side balance. These are placeholders, not real on-chain contracts:0x28d38dF637dB75533bD3F71426F3410a82041544on Ethereum mainnet, but that address is only load-bearing inethereum.token_contractof the relayer config (used to watch mainnet for deposit events).The previous USDCx placeholder reused real mainnet USDC's address (
0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48). MetaMask flags that as a phishing risk on import because its anti-phishing check compares any imported token address against the known-mainnet-tokens registry — chain-agnostic, so the warning fires even on our Canton-facade chain. Arun hit this on prod1 yesterday:What changed
0x99070000000000000000000000000000000000010xDE300000000000000000000000000000000000010xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48(real mainnet USDC)0xC1A0000000000000000000000000000000000001The PROMPT placeholder is also switched defensively, in case PROMPT is ever listed in MM's high-profile registry. The relayer's
ethereum.token_contractkeeps the real mainnet PROMPT address — that side actually watches the on-chain contract for deposit events.What's intentionally unchanged
pkg/config/defaults/config.api-server.docker.yamlkeeps0x5FbDB2…aa3for PROMPT — that's the anvil-deterministic first-deploy address used by E2E tests, a real ERC-20 deployment.pkg/config/defaults/config.api-server.local-devnet.yamlkeeps0x90cb4f9e…48efor PROMPT — the deployed Sepolia bridge token used by Sepolia↔devnet flows, also a real ERC-20.ethereum.token_contract,ethereum.bridge_contract).scripts/setup/bootstrap-bridge.go,contracts/canton-erc20/daml/bridge-wayfinder/src/Wayfinder/Bridge.daml,docs/WAYFINDER_DEPLOYMENT_REQUIREMENTS.md, and thecontracts/*CHANGELOG/DEPLOYMENT docs all keep the real PROMPT mainnet address — those reference it as the real address it is.Files touched
pkg/config/defaults/config.api-server.mainnet.yaml— USDCx swap, added PROMPT row with synthetic placeholderpkg/config/defaults/config.api-server.docker.yaml— USDCx swappkg/config/defaults/config.api-server.local-devnet.yaml— USDCx swapconfig.e2e-local.yaml— USDCx swappkg/config/tests/{minimal,missing-env,invalid-database-url,env-substitution}.api.yaml— USDCx swap (test fixtures)tests/e2e/devstack/stack/types.go—USDCxTokenVirtualAddrconstant updated, doc comment expandedTest plan
go build ./...— cleango vet ./...— cleango test ./pkg/...— all green (config tests use the updated fixtures)go test -tags e2e -count=0 ./tests/e2e/tests/...— compiles cleanly (runtime fails only on the expected devstack-not-running discovery step)scripts/testing/that touched these addresses compileHeads-up for testers
Anyone with an existing MetaMask import of PROMPT or USDCx on the Canton-facade chain will see "0 balance" after this rolls out, because the api-server's
eth_call balanceOflookup keys on the new address. Remove the old token entry in MM and re-import using the new addresses above. Fresh accounts unaffected.PROMPT bridging on real Ethereum mainnet is unaffected — the relayer continues to use the real
0x28d38d…1544contract.