Cross-check an oracle before capital moves

Compare oracle returns with pool-implied state and policy thresholds before routing, lending, liquidating, or rebalancing.

Goal

Return a PASS or REJECT row for a price-dependent action by checking two things first: whether the oracle round is fresh, and whether a pool-implied price is within the allowed deviation.

When to use this

Use this before route approval, lending actions, liquidation checks, vault rebalances, or agent-proposed trades when the action depends on a live price.

Inputs to change

  • $transport selects the RPC endpoint.
  • The Chainlink feed is the ETH/USD proxy address.
  • The pool is the Uniswap v3 USDC/WETH 0.30% pool.
  • $max_age_seconds is the maximum accepted age of the Chainlink update.
  • $max_deviation_pct is the maximum accepted absolute pool-vs-oracle difference.

What the query does

read latestRoundData -> compute Chainlink age -> read pool slot0 -> compute pool price -> compare thresholds

Query

1
WITH chainlink_round AS (
2
SELECT read_contract(
3
$transport,
4
'0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419'::ADDRESS,
5
'[{
6
"type": "function",
7
"name": "latestRoundData",
8
"stateMutability": "view",
9
"inputs": [],
10
"outputs": [
11
{"name":"roundId","type":"uint80"},
12
{"name":"answer","type":"int256"},
13
{"name":"startedAt","type":"uint256"},
14
{"name":"updatedAt","type":"uint256"},
15
{"name":"answeredInRound","type":"uint80"}
16
]
17
}]'::JSON,
18
'latestRoundData'
19
) AS round_data
20
),
21
 
22
chainlink AS (
23
SELECT
24
(round_data).answer AS answer_raw,
25
CASE
26
WHEN (round_data).answer > 0::INT256 THEN ((round_data).answer)::UINT256
27
ELSE NULL::UINT256
28
END AS answer_uint,
29
to_timestamp((round_data).updatedAt) AS updated_at
30
FROM chainlink_round
31
),
32
 
33
chainlink_freshness AS (
34
SELECT
35
answer_raw,
36
answer_uint,
37
normalized.updated_at,
38
date_diff('second', normalized.updated_at, NOW() AT TIME ZONE 'UTC')::BIGINT AS age_seconds
39
FROM (
40
SELECT
41
answer_raw,
42
answer_uint,
43
updated_at
44
FROM chainlink
45
) AS normalized
46
),
47
 
48
uniswap_slot0 AS (
49
SELECT read_contract(
50
$transport,
51
-- 95 more lines load when JavaScript runs
Notebook ready in readonly mode.

Read the output

The output is intentionally a decision row, not just a price cell. reason tells the caller which threshold failed.

decision | reason           | chainlink_eth_usd | chainlink_updated_at | chainlink_age_seconds | pool_eth_usd | pct_diff
---------|------------------|-------------------|----------------------|-----------------------|--------------|---------
PASS     | within_threshold | ...               | ...                  | ...                   | ...          | ...

Inspect chainlink_updated_at, chainlink_age_seconds, pool_eth_usd, and pct_diff before relying on the decision. pct_diff is positive when the pool-implied price is above the Chainlink value and negative when it is below.

Next step

Once the price input passes, continue by executing the candidate with evm_execute_candidate, applying durable policy through evm_create_policy_spec and evm_evaluate_policy, and promoting the selected branch with evm_promote_candidate_evidence.