Skip to content

Treasury set_fee_bps reads old fee from persistent() storage but initialize writes to instance() storage #350

Description

@Mac-5

Description

In contracts/treasury/src/lib.rs, there is a storage-tier mismatch between where fee_bps is written and where set_fee_bps reads the old value:

initialize writes to instance storage:

env.storage().instance().set(&DataKey::FeeBps, &fee_bps);

set_fee_bps reads old value from persistent storage:

let old_bps: u32 = env
    .storage()
    .persistent()   // ← wrong tier
    .get(&DataKey::FeeBps)
    .unwrap_or(50); // ← will always be 50 (default) on first update

Because the tiers are separate namespaces in Soroban, the old_bps read will always miss the value written by initialize and fall back to 50. The fee_rate_updated event will then always report the incorrect old fee, breaking any off-chain monitoring or audit tools that rely on the event log to reconstruct fee history.

Additionally, set_fee_bps writes the updated value back to persistent() while get_fee_bps (if it follows the same pattern as other getters) reads from instance(), causing further divergence.

Fix

Standardize to one storage tier throughout. The simplest fix is to use instance() everywhere for FeeBps (consistent with initialize), or document a deliberate migration to persistent().

Acceptance Criteria

  • initialize, set_fee_bps, and any fee getter all use the same storage tier for FeeBps.
  • The fee_rate_updated event correctly reports the old fee value.
  • A test verifies the event payload after initialization + one fee update.

Complexity: Low (75 points)

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