fix(launchpad): dpnm-v2 registration + treeRoot + encodedParams double-selector#164
Open
lnlockly wants to merge 5 commits into
Open
fix(launchpad): dpnm-v2 registration + treeRoot + encodedParams double-selector#164lnlockly wants to merge 5 commits into
lnlockly wants to merge 5 commits into
Conversation
Add prep documentation for external audit (Code4rena/Sherlock/Spearbit): - THREAT_MODEL.md (STRIDE coverage, 23 threats with impact/likelihood) - INVARIANTS.md (24 invariants across accounting, curve, tree, migration, access) - ATTACK_SCENARIOS.md (13 step-by-step attacks with mitigations + test refs) - SCOPE.md (in/out of scope, ~3.7k SLOC, deployment plan, bounty scale) - REPRODUCE.md (auditor reproduction guide: clone -> test -> deploy testnet) - CHECKLIST.md (per-contract compliance: ReferralRegistry, Payouts, Bonding, Migrator) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…le closed system) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
$FLOW — closed-system MLM token modeled after dPNM, exclusive to AgentFlow
platform. 100% USDT-backed, no DEX graduation, supply expands on buy and
contracts on sell. Includes:
- contracts/flow/FlowToken.sol — ERC20Permit, MINTER_ROLE-gated mint/burn
- contracts/flow/FlowGrowToken.sol — GWT compensation token (1:1 vs USDT fees)
- contracts/flow/PhenomenalTree.sol — 3-branch x 10-level placement tree
with spillover and 10-level reward walk
- contracts/flow/FlowProtocol.sol — orchestrator: activate, buy, sell,
extendTree, buyIncomeLimitWithGWT, claimGWT
- contracts/flow/interfaces/* — interface declarations
- script/deploy-flow-bsc-testnet.ts — BSC testnet deploy script
- test/flow/flow.js — 24-test suite (activation, buy/sell, daily
limit, income limit math, 10-level
marketing payout, spillover, GWT, pause)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Clonable pattern)
Phase 1 launchpad refactor. Introduces a single LaunchpadFactory that
clones registered templates via EIP-1167 minimal proxies. Both the
existing virtuals-style bonding-curve stack and the new dPNM-style
closed-system stack now deploy through the same entry point.
Architecture:
- LaunchpadFactory (UUPS, AccessControl) — one registry of templates
keyed by bytes32 id. `launch(id, encodedParams, salt)` clones the
registered implementation, low-level-calls its initSelector with the
caller-supplied params, and emits Launched(id, instance, deployer).
- DpnmTemplate — orchestrator. On initialize, clones Flow + GWT + Tree
+ FlowProtocol implementations, wires inter-contract roles, hands
DEFAULT_ADMIN to the supplied admin and renounces itself.
- VirtualsTemplate — orchestrator. On initialize, clones the
FFactory + FRouter + Bonding trio, wires CREATOR / EXECUTOR / router
roles, transfers Bonding ownership to admin.
Sub-contracts converted to Initializable (clonable) with
_disableInitializers in the constructor:
- contracts/flow/FlowToken.sol
- contracts/flow/FlowGrowToken.sol
- contracts/flow/PhenomenalTree.sol
- contracts/flow/FlowProtocol.sol
(Bonding/FFactory/FRouter were already Initializable upstream.)
Deploy script (script/deploy-bsc-testnet.ts) now stands up the factory,
registers both templates, then launches \$FLOW exclusively through
factory.launch("dpnm", ...). Future tokens (agentic memecoins,
AI-generated contracts) just register a new template — no factory or
script changes required.
Tests:
- test/factory/factory.test.js — 11 cases (registration, paused,
unknown id, dpnm launch + activate/buy/sell, virtuals launch with
wired roles, predictAddress, salt uniqueness, fee collection +
underpayment revert).
- test/flow/flow.js — updated to use new Cloner helper for proxy
deployment; all 24 cases still passing.
Helper:
- contracts/dev/Cloner.sol — exposes Clones.clone for tests / scripts
that need to bypass the factory pipeline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e-selector
Bug 1: register keccak256("dpnm-v2") template on factory (BSC testnet).
Added DpnmV2Template + 6 sub-impls + deploy-dpnm-v2-template.ts script.
Artifact: deployment-dpnm-v2-template-bsc-testnet.json (tx 0x8644…569b).
Bug 2: default treeRoot was deployer.address — DPNMTree marks it placed in
initialize(), so deployer's activate() call hit AlreadyPlaced. Changed both
deploy-bsc-testnet.ts and deploy-dpnm-bsc-testnet.ts to default to
0x000000000000000000000000000000000000dEaD. Override via FLOW_TREE_ROOT /
DPNM_TREE_ROOT env vars.
Bug 3 (encoder guard): encodeInitializeParams already uses encodeAbiParameters
(no selector) which is correct — LaunchpadFactory prepends initSelector via
bytes.concat. Added explicit warning comment to prevent future regression.
Co-Authored-By: Claude Opus 4.7 (1M context) <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.
Summary
DpnmV2Template+ 6 sub-impl contracts, thedeploy-dpnm-v2-template.tsregistration script, and ran it on BSC testnet. The templatekeccak256("dpnm-v2")is now registered on factory0x713d03A5…with initSelector0x3ba009a3(tx0x86443124f8d95c65b45d6e1c4cfaa43fccd3b071d35370bbf04aaf2d1ff2569b). Deployment artifact:deployment-dpnm-v2-template-bsc-testnet.json.DPNMTree.initializemarkstreeRootas placed. WhentreeRoot == deployer, the deployer'sactivate()call hitsAlreadyPlaced. Fixed bothdeploy-bsc-testnet.tsanddeploy-dpnm-bsc-testnet.tsto default to0x000000000000000000000000000000000000dEaDinstead ofdeployer.address. Overridable viaFLOW_TREE_ROOT/DPNM_TREE_ROOTenv vars.encodeInitializeParamsalready correctly usesencodeAbiParameters(raw args, no selector).LaunchpadFactory.launchprependsinitSelectorviabytes.concat. Added explicit warning comment in the encoder to prevent future regression from switching toencodeFunctionData.Test plan
npx hardhat test test/factory/factory.test.js— factory integration still passesnpx hardhat test test/dpnm/template-v2.test.js— DpnmV2Template coverage passesfactory.templates(keccak256("dpnm-v2"))→registered: trueon BSC testnetTemplateMissingrevertactivate()— noAlreadyPlacedrevert (treeRoot is dead address)Docs: see agentflow-code-docs/subsystems/dpnm-v2-template.mdx (companion PR pending)
🤖 Generated with Claude Code