fix(token): check global symbol uniqueness in finishCreate to prevent duplicate mint - #1312
Open
33cn wants to merge 2 commits into
Open
fix(token): check global symbol uniqueness in finishCreate to prevent duplicate mint#131233cn wants to merge 2 commits into
33cn wants to merge 2 commits into
Conversation
… duplicate mint finishCreate only looked up the per-owner (symbol, owner) record, so the same symbol precreated by N different owners could be finished N times and each finish triggered GenesisInit, over-issuing N*Total of the same token. Add a global symbol uniqueness check in finishCreate (the mavl-token-<symbol> record already written by the first finish), gated by the new dapp fork ForkTokenFinishCheck (registered at height 0). Pre-fork behavior is unchanged. preCreate is intentionally left per-owner: the global key only exists after a finish (already guarded by checkTokenExist in preCreate), and multiple owners precreating the same symbol before any finish remains a valid first-finisher- wins flow.
…ss check finishCreate 的全局 symbol 唯一性修复需要经过真实链路径验证,因为直接调用 exec.Exec 与 testnode 的 mempool -> 共识 -> executor 完整链路行为不同。 新增 testnode 端到端用例: - fork 生效后,同一 symbol 第二次 finishCreate 被拒绝,仅第一个 owner 持有 Total; - fork 高度之前,旧行为保留(重复 finish 成功,实际发行 2*Total,超发对照)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Vulnerability
Duplicate
finishCreateof the same token symbol causes over-issuance (N x Total minted).plugin/dapp/token/executor/tokendb.gofinishCreate(~line 242)Root cause
finishCreateonly looked up the per-owner record keyed by(symbol, owner)and checked its status. UnlikepreCreate, which rejects a symbol whose global recordmavl-token-<symbol>already exists (checkTokenExist, tokendb.go:182),finishCreatehad no global symbol uniqueness check.As a result, the same symbol could be precreated by N different owners (per-owner records, first-finisher-wins flow), and every owner could then be finished: each
finishCreateranGenesisInit(owner, Total), so a token declaringTotalsupply was actually issued N x Total.Fix
In
finishCreate, after the per-owner precreated-status check, add a global uniqueness check: if the global recordmavl-token-<symbol>already exists (written by the first successful finish), reject withErrTokenExist.preCreateis intentionally left per-owner:checkTokenExist(tokendb.go:182).Fork gating
The behavior change is gated by a new dapp fork
ForkTokenFinishCheck(token/types, registered at height 0, following theForkEVMFixOverflowpattern). Before the fork height the old behavior is preserved to avoid breaking consensus of running chains. Config lines are added under[fork.sub.token]inchain33.fork.toml,chain33.para.toml,plugin/dapp/evm/cmd/ci2/chain33.proxyminer.tomlandplugin/dapp/ticket/executor/testdata/chain33.cfg.toml.Tests
New file
plugin/dapp/token/executor/token_finishcheck_test.go(helpers uniquely prefixed withdupFinishto avoid redefinition when merging with other PRs):TestTokenDupFinishCreateRejected: with the fork active, two owners precreate the same symbol; the first finish succeeds; the duplicate finish is rejected withErrTokenExist; repeated same-owner finish still fails withErrTokenNotPrecreated; only the first owner holdsTotal, no over-issuance.TestTokenDupFinishCreatePreFork: below the fork height the old behavior is unchanged (duplicate finish succeeds).TestToken/TestFinish).go test -ldflags=-checklinkname=0 -count=1 ./plugin/dapp/token/...all pass;./plugin/dapp/ticket/...(testdata toml touched) all pass.