Skip to content

Commit

Permalink
add price_oracle_aggregator
Browse files Browse the repository at this point in the history
  • Loading branch information
ken-underscore committed Dec 31, 2024
1 parent 701f626 commit b494ebf
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 22 deletions.
2 changes: 1 addition & 1 deletion lib/datums.ak
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub type PoolDatum {
}

pub type HusdParamsDatum {
price_oracle_hash: ScriptHash,
price_oracle_aggregator_hash: ScriptHash,
min_reserve_ratio: Fraction,
pool_script: ScriptHash,
price_oracles: List<ScriptHash>,
Expand Down
8 changes: 8 additions & 0 deletions lib/utils.ak
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,11 @@ pub fn get_husd_params(
expect params: HusdParamsDatum = husd_datum
params
}

pub fn sum(xs: List<Int>) -> Int {
list.reduce(xs, 0, fn(total, x) { total + x })
}

pub fn average(xs: List<Int>) -> Int {
sum(xs) / list.length(xs)
}
18 changes: 12 additions & 6 deletions validators/pool.ak
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,17 @@ validator pool(husd_policy: ScriptHash) {
withdrawals,
)
//price oracle validator withdrawal present
let HusdParamsDatum { price_oracle_hash, min_reserve_ratio, .. } =
get_husd_params(reference_inputs, husd_policy)
let HusdParamsDatum {
price_oracle_aggregator_hash,
min_reserve_ratio,
..
} = get_husd_params(reference_inputs, husd_policy)
expect Some(Pair(price_oracle_cred, _)) =
list.find(
withdrawals,
fn(Pair(cred, _)) {
when cred is {
Script(hash) -> hash == price_oracle_hash
Script(hash) -> hash == price_oracle_aggregator_hash
_other -> False
}
},
Expand Down Expand Up @@ -175,14 +178,17 @@ validator pool(husd_policy: ScriptHash) {
expect own_dat == expected_dat
//price oracle validator withdrawal present
//price oracle validator withdrawal present
let HusdParamsDatum { price_oracle_hash, min_reserve_ratio, .. } =
get_husd_params(reference_inputs, husd_policy)
let HusdParamsDatum {
price_oracle_aggregator_hash,
min_reserve_ratio,
..
} = get_husd_params(reference_inputs, husd_policy)
expect Some(Pair(price_oracle_cred, _)) =
list.find(
withdrawals,
fn(Pair(cred, _)) {
when cred is {
Script(hash) -> hash == price_oracle_hash
Script(hash) -> hash == price_oracle_aggregator_hash
_other -> False
}
},
Expand Down
40 changes: 25 additions & 15 deletions validators/price_oracle.ak
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,38 @@ use cardano/transaction.{
}
use datums.{HusdParamsDatum, PoolDatum}
use redeemers.{PriceOracleRedeemer, ResolvedOraclePrice}
use utils.{get_husd_params, staking_cred_approves}
use utils.{average, get_husd_params}

validator price_oracle(husd_policy: ScriptHash) {
//all price oracles specified in husd_params must be present, aggregation of those prices must match ResolvedOraclePrice
validator price_oracle_aggregator(husd_policy: ScriptHash) {
withdraw(
redeemer: ResolvedOraclePrice,
credential: Credential,
_credential: Credential,
transaction: Transaction,
) {
let Transaction {
inputs,
reference_inputs,
outputs,
mint,
withdrawals,
extra_signatories,
redeemers,
id,
..
} = transaction
let Transaction { reference_inputs, redeemers, .. } = transaction
let HusdParamsDatum { price_oracles, .. } =
get_husd_params(reference_inputs, husd_policy)

let prices: List<Int> =
list.filter_map(
redeemers,
fn(Pair(purpose, rdmr)) {
when purpose is {
Withdraw(Script(hash)) ->
if list.has(price_oracles, hash) {
expect PriceOracleRedeemer { price } = rdmr
Some(price)
} else {
None
}
_other -> None
}
},
)
//all price oracles must be present in redeemers
expect list.length(price_oracles) == list.length(prices)
//aggregated price must match ResolvedOraclePrice, todo: more advanced handling than average
expect average(prices) == redeemer.price
True
}

Expand Down

0 comments on commit b494ebf

Please sign in to comment.