Skip to content

[pallet-revive] Terminating a contract at a pre-funded address inflates active issuance #12641

Description

@Nathy-bajo

Since init_contract mints the ED and calls deactivate(ed) only when !account_exists (exec.rs) while destroy_contract unconditionally calls burn_from(ed) plus reactivate(ed) on termination (exec.rs, bodies at deposit_payment.rs), and the deactivate/reactivate pair only balances when both halves run, an attacker can transfer ED to a future CREATE2 address X (leaving AccountInfoOf[X] unset so instantiation is not blocked), deploy at X so that account_exists(X) is already true and init_contract's deactivate is skipped, then terminate so the unconditional reactivate(ed) fires with no matching deactivate, moving ED from the inactive pool into active issuance on every repeat and drifting active_issuance (which feeds inflation, staking rewards, and OpenGov conviction) upward, permissionlessly and repeatably.

Fix: gate the destroy side reactivate/burn on whether the pallet actually minted the ED for this account, so the two sides stay symmetric.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions