Skip to content

forge-vesting compute_vested() uses paused_at as effective_now when paused — but paused_at is u64 defaulting to 0 if pause was never called #331

@Austinaminu2

Description

@Austinaminu2

Summary

compute_vested() uses paused_at as the freeze point when paused:

let effective_now = if config.paused { config.paused_at } else { now };

config.paused_at is a u64 initialized to 0 in initialize(). If somehow config.paused == true but config.paused_at == 0 (which should not happen via normal flow, but could if a storage migration or future code path sets paused = true without setting paused_at), effective_now would be 0, making elapsed = 0.saturating_sub(start_time) = 0, and returning 0 vested — freezing all tokens at zero permanently.

Unlike forge-stream which correctly uses Option<u64> for paused_at, forge-vesting uses a plain u64 with 0 as sentinel.

Tasks

  • Change paused_at: u64 to paused_at: Option<u64> in VestingConfig
  • Update pause() to set paused_at = Some(env.ledger().timestamp())
  • Update unpause() to read paused_at.unwrap_or(now) and reset to None
  • Update compute_vested() to use config.paused_at.unwrap_or(now) when paused
  • Verify all existing pause/unpause tests still pass

Labels: bug, forge-vesting

Metadata

Metadata

Assignees

No one assigned

    Labels

    Stellar WaveIssues in the Stellar wave program

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions