Skip to content

[Smart Contracts] Add Contract Upgradeability & Migration Harness via Soroban WASM Hash Update #1439

Description

@blurbeast

Overview & Background

Soroban smart contracts support in-place contract code upgrades via the native system call:

env.deployer().update_current_contract_wasm(new_wasm_hash)

Currently, FlowFi's stream_contract contains no upgrade entrypoint or storage migration mechanism. If a critical protocol vulnerability, security patch, or state schema update is needed, the current contract cannot be upgraded in place. Without an upgrade path, migrating active streams would require manual contract deprecation, fund extraction, and redeployment—disrupting ongoing vesting schedules.


Detailed Problem Statement

  1. Inability to Patch Bugs:
    • Discovered edge cases, arithmetic quirks, or Soroban SDK protocol bumps cannot be applied to the existing contract address.
  2. Permanent Address Invariance:
    • Deploying a new contract changes the contract address, breaking all existing integrations, indexers, frontends, and external smart contract integrations.
  3. Lack of Migration Framework:
    • No standardized schema versioning exists in instance storage to handle data schema changes between contract revisions.

Technical Specification & Architecture

1. Upgrade Entrypoint & Access Control

Implement in contracts/stream_contract/src/lib.rs:

pub fn upgrade(env: Env, new_wasm_hash: BytesN<32>) -> Result<(), StreamError> {
    let config = storage::load_config(&env).ok_or(StreamError::NotInitialized)?;
    config.admin.require_auth();
    env.deployer().update_current_contract_wasm(new_wasm_hash.clone());
    events::emit_contract_upgraded(&env, &new_wasm_hash);
    Ok(())
}

2. State Schema Versioning

Add contract version tracking to instance storage:

#[contracttype]
pub enum DataKey {
    // ...
    ContractVersion,
}

pub fn get_contract_version(env: Env) -> u32;
pub fn migrate(env: Env, target_version: u32) -> Result<(), StreamError>;

3. Events

Emit ContractUpgraded event containing old_wasm_hash, new_wasm_hash, and ledger timestamp.


Target Files

  • contracts/stream_contract/src/lib.rs
  • contracts/stream_contract/src/storage.rs
  • contracts/stream_contract/src/events.rs
  • contracts/stream_contract/src/test.rs

Acceptance Criteria

  • upgrade entrypoint updates the contract WASM hash on the ledger.
  • Non-admin callers attempting to invoke upgrade or migrate strictly fail with authorization errors.
  • Contract state (active streams, balances, protocol config) remains fully intact and functional post-upgrade.
  • Unit tests verify upgrading to a mock WASM binary with backward-compatible state reads.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions