D-070: AereGovernanceStaked retras in carte, cu dovada din bytecode ca nu poate detine nimic

Cheia era AereGovernanceStaked cu eticheta [@status CANONICAL] si o nota de patru
randuri deasupra. Nota spunea adevarul, dar eticheta citibila de masina spunea
contrariul, si numele nu oprea pe nimeni.

Masurat 2026-08-02 la blocul 11.967.896, cu eth_getProof, nu cu nonce-ul:
balance 0x0, codeHash 0x421a87e3...84e6, storageHash 0x269fcdee...8f496,
6.687 octeti, keccak(cod) == codeHash. owner() == Fundatia 0x0243A4...f3C3,
proposalCount() == 0.

Dovada POZITIVA din bytecode-ul desfasurat, nu dedusa dintr-o revenire goala:
mergand pe cei 6.687 de octeti ca instructiuni exista exact UN CALL, la pc 4507,
si exact UN opcode ADDRESS, la pc 4505, chiar in slotul de destinatie al acelui
CALL, cu GAS la pc 4506. In rest cinci STATICCALL si ZERO DELEGATECALL, CALLCODE,
CREATE, CREATE2, SELFDESTRUCT. Deci singurul apel care schimba stare pe care il
poate emite e address(this).call(...) catre el insusi, si nu poate exercita
niciodata onlyOwner pe ceva ce ar ajunge sa detina.

Gasit pe drum si scris in nota: staking() == 0xAbDb01d9...0DEc, adica
AereStaking_v1_DEPRECATED, nu AereStakingV2 0x1D95eF6D...55FC, si campul e
immutable, deci sursa puterii de vot nu se mai poate muta niciodata.

Retragerea e purtata in NUMELE cheii, nu doar intr-un @deprecated: TypeScript nu
face din @deprecated o eroare de tip, e doar un diagnostic de sugestie, deci o
constructie in CI ar fi ramas verde. Redenumirea e partea impusa de compilator.
Verificat: tsc --noEmit iese 0 si --listFiles arata ca addresses.ts chiar e
type-checked.
This commit is contained in:
Liviu 2026-08-02 22:23:49 +03:00
parent 319c3f5339
commit 0740f2af2e

View File

@ -227,11 +227,40 @@ export const AERE_MAINNET = {
AereNFTMarketplace: '0x852e07F2619F7F4aD10d9f2aC681310301d99528', // on-chain marketplace, 2.5% fee. [@status CANONICAL]
// ── Governance + locked staking ───────────────────────────
// SUPERSEDED_STILL_PRIVILEGED / LEGACY_NON_EXECUTING (audit C11, 2026-08-01). NEVER an ownership destination:
// its only execution path is a self-call address(this).call(...), so it can never emit a call to an outside
// address and can never act as the owner of anything. Ownership sent here is unrecoverable under one-step Ownable.
// Enforced by contracts/scripts/ownership/ownership-allowlist.js.
AereGovernanceStaked: '0x8D77C888e439C4fADb2e23F1567a0A1965F80bCb', // stake-weighted (reads AereStaking). [@status CANONICAL]
// The retraction below is carried in the KEY NAME on purpose. A JSDoc @deprecated tag is only a
// suggestion diagnostic: TypeScript never turns it into a type error, so an editor shows a
// strikethrough and a CI build stays green (typescript-eslint ships a whole `no-deprecated` rule
// precisely because of that gap). Renaming the key is the part the compiler actually enforces:
// any consumer that still reads the old name now FAILS TO COMPILE instead of quietly handing this
// address to a transferOwnership call. Same reasoning as AerePasskeyAccountFactoryV2 below.
/**
* @deprecated RETIRED 2026-08-02 (registry finding #70). LEGACY_NON_EXECUTING and
* SUPERSEDED_STILL_PRIVILEGED (audit C11, 2026-08-01). Superseded by the AereGovernorV2
* stack: AereGovernorV2 0x03251BD93047 with AereGovernorV2Timelock 0x9d618c5A5f85.
* The contract stays LIVE and callable on chain 2800; this retraction is a documentation
* gate, nothing more. Do not read it as "dead".
*
* NEVER AN OWNERSHIP DESTINATION, and that is proven POSITIVELY from the DEPLOYED bytecode,
* not inferred from a revert. Measured 2026-08-02 at block 11,967,896 with eth_getProof and
* never with the nonce: balance 0x0, codeHash 0x421a87e384e6, storageHash 0x269fcdee8f496,
* 6,687 runtime bytes, keccak(code) == codeHash. Walking those 6,687 bytes as instructions:
* exactly ONE CALL, at pc 4507, and exactly ONE ADDRESS opcode, at pc 4505, sitting directly
* in that CALL's target slot with GAS at pc 4506. Also five STATICCALLs and ZERO
* DELEGATECALL / CALLCODE / CREATE / CREATE2 / SELFDESTRUCT. So the only state-changing call
* this contract can ever emit is address(this).call(...) to ITSELF; it can never call an
* outside contract, therefore it can never exercise onlyOwner on anything it is made to own.
* Under one-step Ownable that transfer is IRREVERSIBLE and bricks the transferred contract.
* OpenZeppelin added Ownable2Step for exactly this mistake ("transfers of ownership to
* incorrect accounts, or to contracts that are unable to interact with the permission
* system"), but this deployment is immutable and cannot be retrofitted, so the address book
* plus contracts/scripts/ownership/ownership-allowlist.js are the only guards available.
*
* Its vote-weight source is IMMUTABLE and points at the DEPRECATED staking contract:
* staking() == 0xAbDb01d90DEc == AereStaking_v1_DEPRECATED above, NOT AereStakingV2
* 0x1D95eF6D55FC. It can never be repointed. owner() == Foundation 0x0243A4f3C3 (a
* single-key EOA, not a multisig); proposalCount() == 0, so it has never been used.
*/
AereGovernanceStaked_DEPRECATED_LEGACY_NON_EXECUTING: '0x8D77C888e439C4fADb2e23F1567a0A1965F80bCb', // RETIRED 2026-08-02. NEVER an ownership destination: measured on the deployed bytecode, its only state-changing call is a self-call address(this).call(...), so it can never act as the owner of anything, and one-step Ownable makes such a transfer irreversible. Vote weight comes immutably from AereStaking_v1_DEPRECATED 0xAbDb01d9, not AereStakingV2. [@status DEPRECATED @reason legacy-non-executing-self-call-only-never-an-ownership-destination @replacement AereGovernorV2]
AereLockedStaking: '0x21108c28A849b05aE6b7a3a5bc435C9Bc897E7Ad', // fixed-term locks: 30d/10%, 90d/15%, 180d/22%, 365d/30% APY. UNFUNDED: rewardReserve() == 0, so no yield is payable today and withdraw() at maturity reverts; earlyExit() still returns principal. [@status CANONICAL]
// ── Tier-1 DeFi (deployed 2026-05-31) ─────────────────────