Skip to content

Commit

Permalink
feat: implement oracle_utils
Browse files Browse the repository at this point in the history
  • Loading branch information
zarboq committed Oct 27, 2023
1 parent dd0ca39 commit 2dd8243
Show file tree
Hide file tree
Showing 8 changed files with 398 additions and 51 deletions.
3 changes: 3 additions & 0 deletions src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ mod oracle {
mod oracle_utils;
mod oracle;
mod price_feed;
mod interfaces {
mod account;
}
}

// `order` contains order management functions.
Expand Down
57 changes: 50 additions & 7 deletions src/oracle/error.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,10 @@ mod OracleError {
panic(array!['block number not sorted', data_1.into(), data_2.into()])
}

fn ARRAY_OUT_OF_BOUNDS_FELT252(mut data_1: Span<felt252>, data_2: u128, msg: felt252) {
fn ARRAY_OUT_OF_BOUNDS_FELT252(mut data_1: Span<Span<felt252>>, data_2: usize, msg: felt252) {
let mut data: Array<felt252> = array!['array out of bounds felt252'];
let mut length = data_1.len();
loop {
if length == 0 {
break;
}
data.append(*data_1.pop_front().expect('array pop_front failed'));
};
// TODO add data_1 data to error
data.append(data_2.into());
data.append(msg);
panic(data)
Expand Down Expand Up @@ -150,4 +145,52 @@ mod OracleError {
data.append(block_number.into());
panic(data)
}

fn BLOCK_NUMBER_NOT_WITHIN_RANGE(mut data_1: Span<u64>, mut data_2: Span<u64>, data_3: u64) {
let mut data: Array<felt252> = array!['block number not within range'];
let mut length = data_1.len();
loop {
if length == 0 {
break;
}
let el = *data_1.pop_front().unwrap();
data.append(el.into());
};
let mut length_2 = data_2.len();
loop {
if length_2 == 0 {
break;
}
let el = *data_2.pop_front().unwrap();
data.append(el.into());
};
data.append(data_3.into());
panic(data)
}

fn EMPTY_COMPACTED_PRICE(data_1: usize) {
panic(array!['empty compacted price', data_1.into()])
}

fn EMPTY_COMPACTED_TIMESTAMP(data_1: usize) {
panic(array!['empty compacted timestamp', data_1.into()])
}

fn INVALID_SIGNATURE(data_1: felt252, data_2: felt252) {
panic(array!['invalid signature', data_1.into(), data_2.into()])
}

fn BLOCK_NUMBERS_ARE_SMALLER_THAN_REQUIRED(mut data_1: Span<u64>, data_2: u64) {
let mut data: Array<felt252> = array!['block numbers too small'];
let mut length = data_1.len();
loop {
if length == 0 {
break;
}
let el = *data_1.pop_front().unwrap();
data.append(el.into());
};
data.append(data_2.into());
panic(data)
}
}
77 changes: 77 additions & 0 deletions src/oracle/interfaces/account.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#[starknet::interface]
trait IAccount<TContractState> {
fn __validate_declare__(self: @TContractState, class_hash: felt252) -> felt252;
fn __validate_deploy__(
self: @TContractState,
class_hash: felt252,
contract_address_salt: felt252,
owner: felt252,
guardian: felt252
) -> felt252;
// External

/// @notice Changes the owner
/// Must be called by the account and authorised by the owner and a guardian (if guardian is set).
/// @param new_owner New owner address
/// @param signature_r Signature R from the new owner
/// @param signature_S Signature S from the new owner
/// Signature is required to prevent changing to an address which is not in control of the user
/// Signature is the Signed Message of this hash:
/// hash = pedersen(0, (change_owner selector, chainid, contract address, old_owner))
fn change_owner(
ref self: TContractState, new_owner: felt252, signature_r: felt252, signature_s: felt252
);

/// @notice Changes the guardian
/// Must be called by the account and authorised by the owner and a guardian (if guardian is set).
/// @param new_guardian The address of the new guardian, or 0 to disable the guardian
/// @dev can only be set to 0 if there is no guardian backup set
fn change_guardian(ref self: TContractState, new_guardian: felt252);

/// @notice Changes the backup guardian
/// Must be called by the account and authorised by the owner and a guardian (if guardian is set).
/// @param new_guardian_backup The address of the new backup guardian, or 0 to disable the backup guardian
fn change_guardian_backup(ref self: TContractState, new_guardian_backup: felt252);

/// @notice Triggers the escape of the owner when it is lost or compromised.
/// Must be called by the account and authorised by just a guardian.
/// Cannot override an ongoing escape of the guardian.
/// @param new_owner The new account owner if the escape completes
/// @dev This method assumes that there is a guardian, and that `_newOwner` is not 0.
/// This must be guaranteed before calling this method, usually when validating the transaction.
fn trigger_escape_owner(ref self: TContractState, new_owner: felt252);

/// @notice Triggers the escape of the guardian when it is lost or compromised.
/// Must be called by the account and authorised by the owner alone.
/// Can override an ongoing escape of the owner.
/// @param new_guardian The new account guardian if the escape completes
/// @dev This method assumes that there is a guardian, and that `new_guardian` can only be 0
/// if there is no guardian backup.
/// This must be guaranteed before calling this method, usually when validating the transaction
fn trigger_escape_guardian(ref self: TContractState, new_guardian: felt252);

/// @notice Completes the escape and changes the owner after the security period
/// Must be called by the account and authorised by just a guardian
/// @dev This method assumes that there is a guardian, and that the there is an escape for the owner.
/// This must be guaranteed before calling this method, usually when validating the transaction.
fn escape_owner(ref self: TContractState);

/// @notice Completes the escape and changes the guardian after the security period
/// Must be called by the account and authorised by just the owner
/// @dev This method assumes that there is a guardian, and that the there is an escape for the guardian.
/// This must be guaranteed before calling this method. Usually when validating the transaction.
fn escape_guardian(ref self: TContractState);

/// @notice Cancels an ongoing escape if any.
/// Must be called by the account and authorised by the owner and a guardian (if guardian is set).
fn cancel_escape(ref self: TContractState);

// Views
fn get_owner(self: @TContractState) -> felt252;
fn get_guardian(self: @TContractState) -> felt252;
fn get_guardian_backup(self: @TContractState) -> felt252;
fn get_name(self: @TContractState) -> felt252;
fn get_guardian_escape_attempts(self: @TContractState) -> u32;
fn get_owner_escape_attempts(self: @TContractState) -> u32;

}
17 changes: 7 additions & 10 deletions src/oracle/oracle.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ struct SetPricesCache {
/// Struct used in validate_prices as an inner cache.
#[derive(Default, Drop)]
struct SetPricesInnerCache {
/// The current price index to retrieve from compactedMinPrices and compactedMaxPrices
/// to construct the minPrices and maxPrices array.
price_index: u128,
/// The current price index to retrieve from compacted_min_prices and compacted_max_prices
/// to construct the min_prices and max_prices array.
price_index: usize,
/// The current signature index to retrieve from the signatures array.
signature_index: u128,
signature_index: usize,
/// The index of the min price in min_prices for the current signer.
min_price_index: u128,
/// The index of the max price in max_prices for the current signer.
Expand Down Expand Up @@ -472,8 +472,8 @@ mod Oracle {
validated_price.token,
Price { min: validated_price.min, max: validated_price.max }
);
len += 1;
};
len += 1;
}

/// Validate prices in params.
Expand Down Expand Up @@ -637,7 +637,7 @@ mod Oracle {
compacted_max_span, inner_cache.signature_index
);

if inner_cache.signature_index >= signatures_span.len().into() {
if inner_cache.signature_index >= signatures_span.len() {
OracleError::ARRAY_OUT_OF_BOUNDS_FELT252(
signatures_span, inner_cache.signature_index, 'signatures'
);
Expand Down Expand Up @@ -686,10 +686,7 @@ mod Oracle {
oracle_utils::validate_signer(
self.get_salt(),
report_info,
arrays::get_felt252(
signatures_span,
inner_cache.signature_index.try_into().expect('u128 into u32 failed')
),
*signatures_span.at(inner_cache.signature_index),
signers_span.at(j)
);

Expand Down
Loading

0 comments on commit 2dd8243

Please sign in to comment.