# RedStone Oracle Divergence \[Use RedStone data in Newton policies to stop vault actions when price feeds are stale, divergent, or persistently outside thresholds.]

The RedStone policy compares a RedStone price feed against an onchain oracle and checks whether the divergence is acceptable. It is useful when vault operations depend on fresh and reliable market data.

## Deployment

| Field | Value |
| --- | --- |
| Pack id | `redstone` |
| Policy address | `newton-cli --chain-id <chain-id> policy packs show --pack redstone` ([details](/developers/vaults/policy-packs#pack-policy-addresses)) |
| Canonical deployments | [`deployments.json`](https://github.com/newt-foundation/newton-policy-packs/blob/main/deployments.json) |

### Secret

| Secret | Required? | Where to get it |
| --- | --- | --- |
| None | Keyless | [redstone.finance](https://redstone.finance) |

## Data Inputs

The RedStone data oracle returns values such as:

* `redstone_feed_age_seconds`
* `divergence_bp`
* `prev_snapshot_present`
* `prev_divergence_bp`
* `sustained_seconds`

## Rego Checks

Use these exact Rego checks to enforce each guardrail.

### Stale Feed

```rego
deny contains "redstone_feed_stale" if v.redstone_feed_age_seconds > t.max_feed_age_seconds
```

### Hard Divergence Cap

```rego
deny contains "divergence_above_hard_cap" if v.divergence_bp >= t.deny_bp
```

### Sustained Divergence

```rego
deny contains "divergence_sustained" if {
    t.enable_sustained_check
    v.prev_snapshot_present
    v.divergence_bp >= t.warn_bp
    v.prev_divergence_bp >= t.warn_bp
    v.sustained_seconds >= t.deny_sustained_seconds
}
```

### Final Allow Rule

`allow` is written as positive conditions rather than `count(deny) == 0`, so a missing oracle field, or one that is not a number, leaves it undefined and the policy fails closed even when no deny rule fires.

```rego
allow if {
    is_number(v.redstone_feed_age_seconds)
    is_number(v.divergence_bp)
    is_number(v.sustained_seconds)
    v.redstone_feed_age_seconds <= t.max_feed_age_seconds
    v.divergence_bp < t.deny_bp
    not divergence_sustained_blocks
}
```

## Complete Policy

```rego
package redstone_oracle_divergence

import future.keywords

default allow := false

t := data.params

v := data.wasm.redstone

deny contains "redstone_feed_stale" if v.redstone_feed_age_seconds > t.max_feed_age_seconds

deny contains "divergence_above_hard_cap" if v.divergence_bp >= t.deny_bp

deny contains "divergence_sustained" if {
    t.enable_sustained_check
    v.prev_snapshot_present
    v.divergence_bp >= t.warn_bp
    v.prev_divergence_bp >= t.warn_bp
    v.sustained_seconds >= t.deny_sustained_seconds
}

allow if {
    is_number(v.redstone_feed_age_seconds)
    is_number(v.divergence_bp)
    is_number(v.sustained_seconds)
    v.redstone_feed_age_seconds <= t.max_feed_age_seconds
    v.divergence_bp < t.deny_bp
    not divergence_sustained_blocks
}

divergence_sustained_blocks if {
    t.enable_sustained_check
    v.prev_snapshot_present
    not is_number(v.prev_divergence_bp)
}

divergence_sustained_blocks if {
    t.enable_sustained_check
    v.prev_snapshot_present
    v.divergence_bp >= t.warn_bp
    v.prev_divergence_bp >= t.warn_bp
    v.sustained_seconds >= t.deny_sustained_seconds
}
```
