Skip to content

Commit

Permalink
PR fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
0xripleys committed Jan 13, 2025
1 parent f3e3914 commit baac690
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 72 deletions.
109 changes: 54 additions & 55 deletions contracts/oracles/sources/oracles.move
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ module oracles::oracles {

/* Errors */
const EInvalidAdminCap: u64 = 0;
const EWrongCoinType: u64 = 1;
const EInvalidOracleType: u64 = 2;
const EInvalidOracleType: u64 = 1;

public struct OracleRegistry has key, store {
id: UID,
Expand Down Expand Up @@ -60,18 +59,18 @@ module oracles::oracles {
}

// hot potato ensures that price is fresh
public struct OraclePriceUpdate<phantom CoinType> has drop {
public struct OraclePriceUpdate has drop {
oracle_registry_id: ID,
price: OracleDecimal,
ema_price: Option<OracleDecimal>,
}

// == Public Getters ==
public fun price<CoinType>(price_update: &OraclePriceUpdate<CoinType>): OracleDecimal {
public fun price(price_update: &OraclePriceUpdate): OracleDecimal {
price_update.price
}

public fun ema_price<CoinType>(price_update: &OraclePriceUpdate<CoinType>): Option<OracleDecimal> {
public fun ema_price(price_update: &OraclePriceUpdate): Option<OracleDecimal> {
price_update.ema_price
}

Expand Down Expand Up @@ -110,49 +109,75 @@ module oracles::oracles {
}
}

/// Set a pyth oracle for CoinType
public fun set_pyth_oracle<CoinType>(
public fun add_pyth_oracle(
registry: &mut OracleRegistry,
admin_cap: &AdminCap,
price_info_obj: &PriceInfoObject,
ctx: &mut TxContext
) {
registry.version.assert_version_and_upgrade(CURRENT_VERSION);
assert!(admin_cap.oracle_registry_id == object::id(registry));

set_oracle<CoinType>(
registry,
admin_cap,
OracleType::Pyth {
price_identifier: price_info_obj.get_price_info_from_price_info_object().get_price_identifier()
},
ctx
);
registry.oracles.push_back(Oracle {
id: object::new(ctx),
oracle_type: OracleType::Pyth {
price_identifier: price_info_obj.get_price_info_from_price_info_object().get_price_identifier()
},
extra_fields: bag::new(ctx)
});
}

public fun set_pyth_oracle(
registry: &mut OracleRegistry,
admin_cap: &AdminCap,
price_info_obj: &PriceInfoObject,
oracle_index: u64
) {
registry.version.assert_version_and_upgrade(CURRENT_VERSION);
assert!(admin_cap.oracle_registry_id == object::id(registry));

registry.oracles[oracle_index].oracle_type = OracleType::Pyth {
price_identifier: price_info_obj.get_price_info_from_price_info_object().get_price_identifier()
};
}

public fun set_switchboard_oracle<CoinType>(
public fun add_switchboard_oracle(
registry: &mut OracleRegistry,
admin_cap: &AdminCap,
aggregator: &Aggregator,
ctx: &mut TxContext
) {
set_oracle<CoinType>(
registry,
admin_cap,
OracleType::Switchboard { feed_id: aggregator.id() },
ctx
);
registry.version.assert_version_and_upgrade(CURRENT_VERSION);
assert!(admin_cap.oracle_registry_id == object::id(registry));

registry.oracles.push_back(Oracle {
id: object::new(ctx),
oracle_type: OracleType::Switchboard { feed_id: aggregator.id() },
extra_fields: bag::new(ctx)
});
}

public fun set_switchboard_oracle(
registry: &mut OracleRegistry,
admin_cap: &AdminCap,
aggregator: &Aggregator,
oracle_index: u64
) {
registry.version.assert_version_and_upgrade(CURRENT_VERSION);
assert!(admin_cap.oracle_registry_id == object::id(registry));

registry.oracles[oracle_index].oracle_type = OracleType::Switchboard { feed_id: aggregator.id() };
}

public fun get_pyth_price<CoinType>(
public fun get_pyth_price(
registry: &OracleRegistry,
price_info_obj: &PriceInfoObject,
oracle_index: u64,
clock: &Clock,
): OraclePriceUpdate<CoinType> {
): OraclePriceUpdate {
registry.version.assert_version(CURRENT_VERSION);

let oracle = &registry.oracles[oracle_index];
assert!(oracle.type_name == type_name::get<CoinType>(), EWrongCoinType);

match (oracle.oracle_type) {
OracleType::Pyth { price_identifier } => {
Expand All @@ -164,7 +189,7 @@ module oracles::oracles {
price_identifier
);

OraclePriceUpdate<CoinType> {
OraclePriceUpdate {
oracle_registry_id: object::id(registry),
price,
ema_price: option::some(ema_price)
Expand All @@ -175,16 +200,15 @@ module oracles::oracles {

}

public fun get_switchboard_price<CoinType>(
public fun get_switchboard_price(
registry: &OracleRegistry,
aggregator: &Aggregator,
oracle_index: u64,
clock: &Clock,
): OraclePriceUpdate<CoinType> {
): OraclePriceUpdate {
registry.version.assert_version(CURRENT_VERSION);

let oracle = &registry.oracles[oracle_index];
assert!(oracle.type_name == type_name::get<CoinType>(), EWrongCoinType);

match (oracle.oracle_type) {
OracleType::Switchboard { feed_id } => {
Expand All @@ -196,7 +220,7 @@ module oracles::oracles {
feed_id
);

OraclePriceUpdate<CoinType> {
OraclePriceUpdate {
oracle_registry_id: object::id(registry),
price,
ema_price: option::none()
Expand All @@ -206,31 +230,6 @@ module oracles::oracles {
}
}

/* Private Functions */
fun set_oracle<CoinType>(
registry: &mut OracleRegistry,
admin_cap: &AdminCap,
oracle_type: OracleType,
ctx: &mut TxContext
) {
registry.version.assert_version_and_upgrade(CURRENT_VERSION);

assert!(admin_cap.oracle_registry_id == object::id(registry), EInvalidAdminCap);

let mut index = registry.oracles.find_index!(|oracle| oracle.type_name == type_name::get<CoinType>());
if (index.is_some()) {
registry.oracles[index.extract()].oracle_type = oracle_type;
} else {
let oracle = Oracle {
type_name: type_name::get<CoinType>(),
oracle_type,
extra_fields: bag::new(ctx)
};

registry.oracles.push_back(oracle);
};
}

#[test_only]
public fun new_oracle_registry_for_testing(config: OracleRegistryConfig, ctx: &mut TxContext): (OracleRegistry, AdminCap) {
let registry = OracleRegistry {
Expand Down
5 changes: 4 additions & 1 deletion contracts/oracles/sources/pyth.move
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ module oracles::pyth {
// confidence interval check
// we want to make sure conf / price <= x%
// -> conf * (100 / x )<= price
assert!(conf * (100 / max_confidence_interval_pct) <= price_mag, EConfidenceIntervalExceeded);
assert!(
(conf as u128) * 100u128 <= (price_mag as u128) * (max_confidence_interval_pct as u128),
EConfidenceIntervalExceeded
);

// check current sui time against pythnet publish time. there can be some issues that arise because the
// timestamps are from different sources and may get out of sync, but that's why we have a fallback oracle
Expand Down
2 changes: 1 addition & 1 deletion contracts/oracles/sources/switchboard.move
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ module oracles::switchboard {
// stddev / result <= x/100
// stddev * 100 <= result * x
assert!(
stdev.value() * 100u128 <= result.value() * (max_confidence_interval_pct as u128),
(stdev.value() as u256) * 100u256 <= (result.value() as u256) * (max_confidence_interval_pct as u256),
EPriceRangeIsTooLarge
);

Expand Down
Loading

0 comments on commit baac690

Please sign in to comment.