Skip to content

[Security] Implement Systematic Address Validation, Blacklisting, Freeze, and Recovery Mechanisms #26

Description

@KarenZita01

Description

The contract manages various address types (admin, users, meters, oracles, vaults, grid administrators, enterprise operators, multi-sig signers) but has no systematic address validation, no dead address detection, no contract vs. user address discrimination, and no address blacklisting. Invalid or uninitialized addresses can be stored in contract state, leading to failed operations or locked funds.

Address management gaps:

  • No is_contract(address) check before setting contract-specific roles (oracle, vault)
  • No address != Address::zero() validation in role assignments
  • No address blacklist for sanctioned or malicious addresses
  • No address freeze capability for security incidents
  • No address format validation (Ed25519 vs. Contract vs. Account)
  • Address::require_auth() panics for contract addresses that don't support it
  • No migration path if user loses access to their signing key (account recovery)

Technical Context & Impact

  • Affected Components/Files: contracts/utility_contracts/src/lib.rs, contracts/utility_contracts/src/asset.rs, contracts/utility_contracts/src/enterprise.rs, contracts/utility_contracts/src/Multi_Sig.rs
  • Impact: Security, User Experience, Regulatory Compliance

Step-by-Step Implementation Guide

  1. Create address validation module: src/address_utils.rs with:
    • require_valid_address(env, addr) - checks addr is not zero and is valid format
    • is_contract_address(env, addr) -> bool - checks if address is a contract
    • classify_address(env, addr) -> AddressType { Ed25519, Account, Contract }
  2. Add address blacklist: DataKey::BlacklistedAddresses as Vec<Address>; require_not_blacklisted(env, addr) in all user-facing functions
  3. Add address freeze: freeze_address(address, reason, duration) - prevents all operations from this address
  4. Implement account recovery: add_recovery_key(address, recovery_key, delay_ledgers) - after delay, recovery key can transfer ownership to new address
  5. Validate all address inputs: Add guards in register_meter, set_admin, set_fee_vault, set_oracle, set_grid_administrator, add_multi_sig_signer
  6. Add address migration: migrate_account(old_address, new_address, proof) with old address signing to authorize migration
  7. Test all address edge cases: Zero address, self-destructed contract address, invalid Ed25519 key, blacklisted address

Verification & Testing Steps

  1. Test address validation: attempt to set zero address as admin (should reject)
  2. Test blacklist: blacklist address -> that address tries to call any function (should revert)
  3. Test freeze: freeze address -> verify all operations blocked -> unfreeze -> operations resume
  4. Test account recovery: user loses key -> recovery key waits for delay -> transfers ownership
  5. Test account migration: old address signs -> new address confirmed -> state migrated to new address
  6. Run full test suite: cargo test --package utility_contracts

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions