White-label brands deploying a DAO on Lux infrastructure consume the
audited contracts from @luxfi/standard via Foundry remappings. They
do not fork the DAO + Safe + Quasar-signer source tree. This LP
documents the canonical wrapper pattern, exemplified by @zooai/safe
+ @zooai/vote.
luxfi/standard is the only authoritative tree for:
contracts/safe/)contracts/dao/)contracts/governance/Governor.sol)Brands MUST NOT copy these files. The previous duplication between
luxfi/standard and luxfi/dao was the bug this LP closes.
A brand wrapper (zooai/safe, hanzoai/safe, parsdao/safe, …) is a
*pure-config + remappings* package:
<brand>/safe/
├── package.json # declares @luxfi/standard as peer-dependency
├── foundry.toml # remappings only — no src
├── remappings.txt # same remappings outside [profile]
├── contracts/<Brand>Safe.sol # re-export barrel; no logic
├── config/<brand>.json # brand colors, RPCs, addresses
└── test/ # tests via the re-export barrel
The <Brand>Safe.sol barrel exists so downstream apps depend on the
brand wrapper rather than reaching into @luxfi/standard directly.
Reads are decoupled from writes: contract source is one address (in the
luxfi org); brand identity is another (in the brand org).
A brand frontend wrapper (zooai/vote, hanzoai/vote, …) consumes the
brand's contract wrapper:
<brand>/vote/
├── package.json # depends on @<brand>/safe
├── config/<brand>.json # network → deployed addresses
├── config/index.ts # resolveAddresses({ chainId })
├── src/ # branded UI
└── functions/ # Cloudflare Pages functions
Brand deploys reuse luxfi/standard/script/DeployLuxDAO.s.sol directly
or wrap it minimally. There is no DeployZooDAO.s.sol that copies the
logic — the same Foundry script targets a different RPC / chain ID.
'*.sol' | xargs grep -L "// SPDX" | head` returns empty after
excluding the single re-export barrel.
@luxfi/standard via remappings, not viacopy-paste of the files.
Corona, Magnetar) — no "Corona" anywhere.
every brand. The current eight-signer set lives in one tree.
~/work/hanzo/CLAUDE.md) keeps brand identity at the edge: the
frontend looks at window.location.hostname and resolves the brand
config; the contracts have no opinion.
This LP defines the gate that prevents that drift.
lux.vote → contracts at C-Chain mainnet (96369), testnet(96368), devnet (96370).
vote.zoo.network → contracts at Zoo L2 (200200 mainnet,200201 testnet).
pattern.
re-exports the LP-039 set. Adding a new primitive requires a new LP
+ new audit on luxfi/standard.
config/<brand>.json is plain JSON — not a contract — sobumping it can't change consensus rules. Addresses recorded there are
output, not input, of the canonical Foundry deploy script.