Como atualizar os contratos upgradeáveis com segurança. Os contratos usam proxies transparentes (OpenZeppelin) + storage namespaced ERC-7201, então upgrades preservam estado se o layout for compatível (apenas append de campos no fim de cada namespace).
| Contrato | Upgradeável? | Proxy |
|---|---|---|
BitChickenToken |
✅ | transparente |
BitChickenNFT |
✅ | transparente |
BitChickenStaking |
✅ | transparente |
BitChickenMarketplace |
✅ | transparente |
BitChickenForge |
❌ não-upgradeável (imutável por design — VRF) | — |
@custom:storage-location).selfdestruct, delegatecall, variável immutable/constructor
que escreve estado. Ver test/upgrade.test.ts (caso negativo).ReferralTreeManagement (reescrito) usa ERC-7201 sem __gap — o namespace isola o storage e novos
campos são appendados com segurança (ver armadilhas.md).npm run validate-upgrade # valida upgrade-safety dos 4 contratos (scripts/validate-upgrade.ts)
Roda no CI (job crypto em .github/workflows/ci.yml) e falha o build se algum contrato ficar
não-upgrade-safe.
npx hardhat test mocha test/upgrade.test.ts
Prova: estado preservado pós-upgradeProxy + nova função; implementação insegura é rejeitada.
npm run upgrade:localhost # ou upgrade:testnet / upgrade:mainnet
scripts/deployed-localhost.json (localnet) ou das envs
TOKEN_PROXY/NFT_PROXY/STAKING_PROXY/MARKETPLACE_PROXY (testnet/mainnet).UPGRADE_ONLY=token npm run upgrade:localhost atualiza só um proxy..openzeppelin/{bsc,bsc-testnet}.json (são a fonte de verdade do layout por rede).scripts/upgrade.ts — validateUpgrade + upgradeProxy para os 4 proxies.scripts/validate-upgrade.ts — validateImplementation (estático, para CI).test/upgrade.test.ts — E2E (estado preservado + rejeição de impl insegura).contracts/mocks/bitchicken-token-v2.sol / bitchicken-token-bad-v2.sol — fixtures do teste.Em mainnet, o owner dos proxies deve ser um Gnosis Safe (multisig) + TimelockController; o
upgradeProxy é proposto no Safe e executado após o delay do Timelock. (Fora do escopo da fase de dev.)