Unify wallet address validation and Ownable2Step for UUPS proxies #329
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#329
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent
GitLab #325 — Security review (findings F-09, partial F-01; approved recommendation #5).
Note: Full UUPS multisig + timelock (F-01 recommendation #1) was rejected on parent #325 until $100k monthly volume. This issue covers only the approved subset:
valid_0x_address20consistency andOwnable2StepUpgradeablefor future proxy versions.Current codebase
Indexer wallet path validation (F-09)
indexer/src/api.rs:valid_0x_address20requires0x+ 42 chars + 40 hex digits; used on referral query params.indexer/src/api_arena.rs:arena_wallet_statsand donor filter (L130–137) only checkstarts_with("0x")andlen() == 42— non-hex addresses return 200 with empty stats.Contracts ownership (F-01 partial)
contracts/src/arena/TimeArena.sol:OwnableUpgradeable+UUPSUpgradeable;_authorizeUpgrade→onlyOwner; single-step ownership transfer.contracts/src/ReferralRegistry.sol: same pattern.contracts/src/arena/TimeArenaBuyRouter.sol: non-upgradeable; already usesOwnable2Step— good reference.Why needed
400 invalid_addressuniformly.transferOwnershipon UUPS proxies risks mistyped or malicious immediate takeover;Ownable2StepUpgradeableadds accept step. Approved for future proxy implementation versions (requires UUPS upgrade deploy — not changing live mainnet in this issue alone).Constraints / guardrails
Ownable2StepUpgradeablechange must be upgrade-safe: storage layout compatible with OpenZeppelin upgrades; updateDeployProduction/DeployDevinitializers for new deployments; document upgrade path for existing proxies.valid_0x_address20fromapi.rsor smallapi_validate.rsmodule; avoid copy-paste.forge testand indexer tests after changes.Relevant files
indexer/src/api.rs,indexer/src/api_arena.rscontracts/src/arena/TimeArena.sol,contracts/src/ReferralRegistry.sol,contracts/test/TimeArena.t.sol,contracts/test/ReferralRegistry.t.solcontracts/script/DeployProduction.s.sol,contracts/script/DeployDev.s.soldocs/onchain/security-and-threat-model.mdRecommended direction
Indexer
valid_0x_address20to a shared module (e.g.api_validate.rs) used byapi.rsandapi_arena.rs.arena_wallet_stats, donor filter, player filters, any0x+42 handlers.api.rstests for rejection of0xZZZZ…addresses.Contracts
OwnableUpgradeablewithOwnable2StepUpgradeableonTimeArenaandReferralRegistry(import from@openzeppelin/contracts-upgradeable).initialize/__Ownable_init→__Ownable2Step_init(or equivalent OZ 5.x API).transferOwnership+acceptOwnershipflow; upgrade stillonlyOwner.Acceptance criteria
GET /v1/arena/wallet/0xGGGG…/stats(non-hex) returns 400invalid_address.TimeArenaandReferralRegistrycompile and pass tests withOwnable2StepUpgradeable.DeployDev) succeeds;DevStackIntegration.t.solpasses.Test plan
cd indexer && cargo clippy --all-targets -- -D warnings && cargo testcd indexer && cargo test --test integration_stage2bash scripts/verify-wallet-profile-anvil.shcd contracts && forge test(skip fork tests ifdoub.csvmissing)bash scripts/verify-evm-dev-wallet-seed-anvil.shAttack / abuse test plan
transferOwnership(attacker)withoutacceptOwnership— attacker must not gain owner role.upgradeTostill blocked for non-owner.Verification criteria
mentioned in issue #325
mentioned in commit
9c89ffcc6dmentioned in merge request !501
mentioned in commit
117d9aa327Verification complete — GitLab #329
Verified on
mainat117d9aa3(MR !501). No repo changes required.Acceptance criteria
GET /v1/arena/wallet/0xGGGG…/stats(non-hex) → 400invalid_addressintegration_stage2::arena_wallet_stats_two_epochs_and_bonus_fieldsasserts 400 +invalid_addressfor0xgggg…;api_validate.rsunit test rejects same patternbash scripts/verify-wallet-profile-anvil.sh— wallet statsbuy_count=1, buys parity fields OKTimeArena+ReferralRegistrywithOwnable2StepUpgradeableforge test --match-contract "TimeArena|ReferralRegistry|DevStackIntegration"— 152 passedDeployDev+DevStackIntegration.t.solbash scripts/verify-evm-dev-wallet-seed-anvil.sh— PASS; DevStackIntegration in contract suitedocs/onchain/security-and-threat-model.md§ UUPS ownership upgrades (#329); invariantsINV-CONTRACTS-329-OWNABLE2STEP,INV-INDEXER-329-ADDRESS-VALIDATETest plan
cd indexer && cargo clippy --all-targets -- -D warningscd indexer && cargo testcd indexer && cargo test --test integration_stage2bash scripts/verify-wallet-profile-anvil.shcd contracts && forge test --match-contract "TimeArena|ReferralRegistry|DevStackIntegration"cd contracts && forge testDoubAirdropMegaethForktests fail without gitignoredairdrop/doub.csv(expected); 209 other tests passbash scripts/verify-evm-dev-wallet-seed-anvil.shAttack / abuse checks
invalid_addresstransferOwnershipwithoutacceptOwnership— attacker not ownertest_ownable2step_transfer_requires_accept(TimeArena + ReferralRegistry)upgradeToblocked for non-ownertest_uups_upgrade_blocked_for_non_owner; pending owner cannot upgrade (test_ownable2step_pending_owner_cannot_upgrade)Verification criteria
Closing as verified.
mentioned in merge request !509
mentioned in issue #341