Documentation

Security

Security considerations for deploying and operating EnergyAS in production.

Key Management

  • Use a multisig (Gnosis Safe) as the contract owner — not an EOA
  • Use a multisig as the watcher owner for production watchers
  • Rotate watcher ownership via transferWatcherOwnership if keys are compromised
  • The Energy Type Admin is a separate role — delegate it to reduce owner key exposure

Attester Isolation

Per-project attester whitelisting ensures that a compromised IoT device can only affect a single project. This is the recommended pattern for device-level access:

PatternScopeRisk if Compromised
Per-project attesterOne project onlyAttacker can only submit false readings for that project
Watcher-wide attesterAll projects under watcherAttacker can submit false readings for any project
Note

Warning: Use watcher-wide attesters sparingly. Reserve them for trusted manual operators, not IoT devices.

Data Integrity

  • Duplicate period detection prevents double-counting — the same time window cannot be attested twice
  • Strict start-time uniqueness prevents overlapping periods starting at the same timestamp
  • Energy accumulators are updated atomically with each attestation and revocation
  • Revocations decrement accumulators correctly, preventing inflated totals
  • The registry is permanent — historical data cannot be altered or deleted

Contract Safety

  • Both contracts disable renounceOwnership() to prevent accidental lockout
  • Ownership transfer uses OpenZeppelin Ownable2Step (requires the new owner to accept)
  • The resolver is pausable for emergency stops — revocations still work when paused
  • The contract holds no ETH or tokens — attack surface is limited to data integrity
  • 152 tests cover the full protocol including edge cases and boundary values

Upgrade Safety

The two-contract design ensures upgrades are safe:

  • The registry is never replaced — all state is preserved across resolver upgrades
  • Multiple resolvers can be authorized simultaneously for zero-downtime migration
  • The old resolver can be paused and deauthorized after migration
  • No proxy pattern is used — the registry is a plain contract, not upgradeable