Overview & Background
Fixed-rate or strictly time-dependent streams cannot adapt to dynamic real-world conditions. Grants, bounty programs, and venture vesting often require condition-gated releases—such as unlocking a tranche only when a token reaches a specific price ceiling, or when a trusted third-party oracle attests that a development milestone, GitHub release, or KPI metric has been achieved. Integrating Soroban oracle interfaces (such as SEP-0040 or Reflector Oracle) allows FlowFi to pioneer dynamic condition-driven streaming.
Detailed Problem Statement
- Inability to Peg Streams to Real-World Value:
- In volatile cryptocurrency markets, paying contractors in native tokens (e.g. XLM) at a fixed token-per-second rate results in unfair wage inflation or deflation as price fluctuates against USD.
- Manual Milestone Approvals:
- Grant committees must manually execute contract cancellations or deployments when grantees meet or fail milestones, introducing latency and administrative overhead.
- No Standardized Soroban Oracle Hook:
- FlowFi's contract has no extensible callback or read interface to query on-chain price feeds or verifiable attestations.
Technical Specification & Architecture
1. Oracle Interface Integration (SEP-0040 / Reflector Interface)
#[contractclient(name = "OracleClient")]
pub trait PriceOracle {
fn lastprice(env: Env, asset: Asset) -> Option<PriceData>;
}
#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PriceData {
pub price: i128,
pub timestamp: u64,
}
2. Condition-Gated Vesting Model (types.rs)
#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum UnlockCondition {
TimeOnly { unlock_time: u64 },
PriceTarget { oracle_address: Address, target_price: i128, is_above: bool },
OracleAttestation { oracle_signer: Address, attestation_id: BytesN<32> },
}
#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ConditionalMilestone {
pub milestone_id: u32,
pub amount: i128,
pub condition: UnlockCondition,
pub is_unlocked: bool,
}
3. Verification & Trigger Entrypoint
pub fn verify_and_unlock_milestone(
env: Env,
caller: Address,
stream_id: u64,
milestone_id: u32,
) -> Result<i128, StreamError>
- Query oracle contract via cross-contract call.
- Verify price timestamp freshness (revert if stale > 3600 seconds).
- If condition evaluated to true:
- Mark
milestone.is_unlocked = true.
- Add
milestone.amount to claimable balance.
- Emit
MilestoneConditionUnlocked event.
Target Files
contracts/stream_contract/src/types.rs
contracts/stream_contract/src/lib.rs
contracts/stream_contract/src/oracle.rs
contracts/stream_contract/src/events.rs
contracts/stream_contract/src/test.rs
Acceptance Criteria
Overview & Background
Fixed-rate or strictly time-dependent streams cannot adapt to dynamic real-world conditions. Grants, bounty programs, and venture vesting often require condition-gated releases—such as unlocking a tranche only when a token reaches a specific price ceiling, or when a trusted third-party oracle attests that a development milestone, GitHub release, or KPI metric has been achieved. Integrating Soroban oracle interfaces (such as SEP-0040 or Reflector Oracle) allows FlowFi to pioneer dynamic condition-driven streaming.
Detailed Problem Statement
Technical Specification & Architecture
1. Oracle Interface Integration (SEP-0040 / Reflector Interface)
2. Condition-Gated Vesting Model (
types.rs)3. Verification & Trigger Entrypoint
milestone.is_unlocked = true.milestone.amountto claimable balance.MilestoneConditionUnlockedevent.Target Files
contracts/stream_contract/src/types.rscontracts/stream_contract/src/lib.rscontracts/stream_contract/src/oracle.rscontracts/stream_contract/src/events.rscontracts/stream_contract/src/test.rsAcceptance Criteria
StreamError::OracleDataStale.