Problem
At commit 6e764023ee6515fe70573e123ed2db912a7207b4, buildGenesis() checks duplicate accounts with account in allocs, using case-sensitive JavaScript object keys. Both lowercase and checksummed addresses pass the address schema.
As a result, a prefund list containing the same address in two casings is accepted and both balances contribute to the NativeCoinAuthority total-supply slot. Two allocations of 10 units for the same address produce a supply calculation of 20 units, even though there is only one EVM account identity.
The same gap accepts a prefund alias of a contract implementation or a reserved precompile. The output contains both the code-bearing allocation and a second, code-less allocation for the same address.
Relevant baseline code:
Arc imports Alloy's Genesis type, whose allocation map is keyed by binary addresses, so these string aliases cannot represent separate accounts. This is a genesis-generation correctness issue; the regression tests do not claim an exploit against an already running network. Alloy v2.0.4 Genesis source.
Reproduction
Add the regression test to the baseline checkout and run:
npm ci --ignore-scripts --no-audit --no-fund
node node_modules/mocha/bin/mocha.js --require ts-node/register tests/unit/genesis-account-collisions.test.ts
The test supplies this prefund pair to the real buildGenesis() pipeline:
[
{ address: '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd', balance: 10n },
{ address: '0xABcdEFABcdEFabcdEfAbCdefabcdeFABcDEFabCD', balance: 10n },
]
Before the fix: 2 passing, 4 failing (Missing expected rejection).
After the fix: all 6 passing.
Additional cases cover reversed ordering, identical spellings, prefund/implementation collisions, prefund/precompile collisions, and preservation of distinct accounts, original key casing, contract code/nonce, and total supply.
Only artifact loading is stubbed with a real ContractLoader populated with inert bytecode. Schema validation, all enabled allocation builders, duplicate detection, and supply storage generation execute normally.
Patch and verification
The focused fix and tests are available at Yudis-bit:fix/genesis-account-collisions, commit 5b38392. Production change: four added lines and one removed line in the account insertion helper.
- Regression suite: 2 passing / 4 failing before; 6 passing after.
- All unit files plus matcher tests: 43 passing using Mocha + ts-node with type checking and
TS_NODE_FILES=true.
- ESLint, Prettier, and
git diff --check passed.
- The Hardhat wrapper was attempted but requires the unavailable Forge binary in this environment. Its unit and matcher files were run directly instead.
Related #411 concerns operator/proxy-admin comparisons and role uniqueness. This report is specifically about duplicate keys in the top-level genesis allocation map; the patch does not modify those role schemas.
Expected Behavior
Reject a second allocation for the same 20-byte account, regardless of hexadecimal casing, before returning genesis data. Preserve the existing Duplicate account: <address> error and the serialization of valid inputs.
Proposed Fix
Track lowercase account identities in a Set inside the existing insertion helper while retaining original keys in the output. The production patch adds four lines and removes one.
I have the fix and regression test suite ready locally. Could a maintainer please assign this issue to me so I can submit a PR? Thanks!
Problem
At commit
6e764023ee6515fe70573e123ed2db912a7207b4,buildGenesis()checks duplicate accounts withaccount in allocs, using case-sensitive JavaScript object keys. Both lowercase and checksummed addresses pass the address schema.As a result, a prefund list containing the same address in two casings is accepted and both balances contribute to the NativeCoinAuthority total-supply slot. Two allocations of 10 units for the same address produce a supply calculation of 20 units, even though there is only one EVM account identity.
The same gap accepts a prefund alias of a contract implementation or a reserved precompile. The output contains both the code-bearing allocation and a second, code-less allocation for the same address.
Relevant baseline code:
Arc imports Alloy's Genesis type, whose allocation map is keyed by binary addresses, so these string aliases cannot represent separate accounts. This is a genesis-generation correctness issue; the regression tests do not claim an exploit against an already running network. Alloy v2.0.4 Genesis source.
Reproduction
Add the regression test to the baseline checkout and run:
The test supplies this prefund pair to the real
buildGenesis()pipeline:Before the fix: 2 passing, 4 failing (
Missing expected rejection).After the fix: all 6 passing.
Additional cases cover reversed ordering, identical spellings, prefund/implementation collisions, prefund/precompile collisions, and preservation of distinct accounts, original key casing, contract code/nonce, and total supply.
Only artifact loading is stubbed with a real
ContractLoaderpopulated with inert bytecode. Schema validation, all enabled allocation builders, duplicate detection, and supply storage generation execute normally.Patch and verification
The focused fix and tests are available at Yudis-bit:fix/genesis-account-collisions, commit 5b38392. Production change: four added lines and one removed line in the account insertion helper.
TS_NODE_FILES=true.git diff --checkpassed.Related #411 concerns operator/proxy-admin comparisons and role uniqueness. This report is specifically about duplicate keys in the top-level genesis allocation map; the patch does not modify those role schemas.
Expected Behavior
Reject a second allocation for the same 20-byte account, regardless of hexadecimal casing, before returning genesis data. Preserve the existing
Duplicate account: <address>error and the serialization of valid inputs.Proposed Fix
Track lowercase account identities in a Set inside the existing insertion helper while retaining original keys in the output. The production patch adds four lines and removes one.
I have the fix and regression test suite ready locally. Could a maintainer please assign this issue to me so I can submit a PR? Thanks!