Skip to content

Commit

Permalink
feat: execute_call (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
obatirou committed Oct 28, 2024
1 parent d6563ae commit b71dd04
Show file tree
Hide file tree
Showing 4 changed files with 294 additions and 33 deletions.
26 changes: 1 addition & 25 deletions cairo/protocol_handler/src/kakarot_interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,9 @@ use starknet::{ContractAddress, ClassHash};

#[starknet::interface]
pub trait IKakarot<TContractState> {
//* ------------------------------------------------------------------------ *//
//* ADMIN FUNCTIONS *//
//* ------------------------------------------------------------------------ *//
fn upgrade(ref self: TContractState, new_class_hash: ClassHash);
fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress);
fn pause(ref self: TContractState);
fn unpause(ref self: TContractState);

//* ------------------------------------------------------------------------ *//
//* STORAGE SETTING FUNCTIONS *//
//* ------------------------------------------------------------------------ *//
fn set_native_token(ref self: TContractState, native_token: ContractAddress);
fn set_base_fee(ref self: TContractState, base_fee: u64);
fn set_coinbase(ref self: TContractState, new_coinbase: ContractAddress);
fn set_prev_randao(ref self: TContractState, pre_randao: felt252);
fn set_block_gas_limit(ref self: TContractState, new_block_gas_limit: felt252);
fn set_account_contract_class_hash(ref self: TContractState, new_class_hash: felt252);
fn set_uninitialized_account_class_hash(ref self: TContractState, new_class_hash: felt252);
fn set_authorized_cairo_precompile_caller(
ref self: TContractState, evm_address: ContractAddress, authorized: bool
);
fn set_cairo1_helpers_class_hash(ref self: TContractState, new_class_hash: felt252);
fn upgrade_account(ref self: TContractState, evm_address: ContractAddress, new_class: felt252);
fn set_authorized_pre_eip155_tx(
ref self: TContractState, sender_address: ContractAddress, msg_hash: felt252
);
fn set_l1_messaging_contract_address(
ref self: TContractState, l1_messaging_contract_address: ContractAddress
);
fn set_base_fee(ref self: TContractState, new_base_fee: felt252);
}
3 changes: 2 additions & 1 deletion cairo/protocol_handler/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod protocol_handler;
pub use protocol_handler::{
ProtocolHandler, IProtocolHandler, IProtocolHandlerDispatcher, IProtocolHandlerDispatcherTrait
ProtocolHandler, IProtocolHandlerDispatcher, IProtocolHandlerDispatcherTrait,
IProtocolHandlerSafeDispatcher, IProtocolHandlerSafeDispatcherTrait
};
mod kakarot_interface;
103 changes: 99 additions & 4 deletions cairo/protocol_handler/src/protocol_handler.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,41 @@ pub trait IProtocolHandler<TContractState> {
/// # Panics
/// * `Caller is missing role` in case the caller is not the security council
fn unpause(ref self: TContractState);

/// Set the base fee of the Kakarot contract.
/// Only the gas price admin can call this function.
/// # Arguments
/// * `base_fee` - The new base fee
///
/// # Panics
/// * `Caller is missing role` in case the caller is not the gas price admin
fn set_base_fee(ref self: TContractState, new_base_fee: felt252);

/// Execute a call to the Kakarot contract
/// Only the operator can call this function.
/// # Arguments
/// * `call` - The call to be executed
///
/// # Panics
/// * `Caller is missing role` in case the caller is not the operator
/// * `UNAUTHORIZED_SELECTOR` in case the selector is not authorized
/// * `ONLY_KAKAROT_CAN_BE_CALLED` in case the call is not to the Kakarot contract
fn execute_call(ref self: TContractState, call: Call);
}

#[starknet::contract]
pub mod ProtocolHandler {
use starknet::event::EventEmitter;
use starknet::account::Call;
use starknet::{ContractAddress, ClassHash, get_block_timestamp, SyscallResultTrait};
use starknet::storage::{Map, StoragePointerReadAccess, StoragePointerWriteAccess};
use starknet::storage::{
Map, StoragePointerReadAccess, StoragePointerWriteAccess, StorageMapReadAccess,
StorageMapWriteAccess
};
use openzeppelin_access::accesscontrol::AccessControlComponent;
use openzeppelin_introspection::src5::SRC5Component;
use crate::kakarot_interface::{IKakarotDispatcher, IKakarotDispatcherTrait};


//* ------------------------------------------------------------------------ *//
//* COMPONENTS *//
//* ------------------------------------------------------------------------ *//
Expand All @@ -83,8 +105,9 @@ pub mod ProtocolHandler {

// Access controls roles
const SECURITY_COUNCIL_ROLE: felt252 = selector!("SECURITY_COUNCIL_ROLE");
const GUARDIAN_ROLE: felt252 = selector!("GUARDIAN_ROLE");
const OPERATOR_ROLE: felt252 = selector!("OPERATOR_ROLE");
const GUARDIAN_ROLE: felt252 = selector!("GUARDIAN_ROLE");
const GAS_PRICE_ADMIN_ROLE: felt252 = selector!("GAS_PRICE_ADMIN_ROLE");
// Pause delay
pub const SOFT_PAUSE_DELAY: u64 = 12 * 60 * 60; // 12 hours
pub const HARD_PAUSE_DELAY: u64 = 7 * 24 * 60 * 60; // 7 days
Expand All @@ -97,6 +120,7 @@ pub mod ProtocolHandler {
pub mod errors {
pub const ONLY_KAKAROT_CAN_BE_CALLED: felt252 = 'ONLY_KAKAROT_CAN_BE_CALLED';
pub const PROTOCOL_ALREADY_PAUSED: felt252 = 'PROTOCOL_ALREADY_PAUSED';
pub const UNAUTHORIZED_SELECTOR: felt252 = 'UNAUTHORIZED_SELECTOR';
}

//* ------------------------------------------------------------------------ *//
Expand All @@ -108,7 +132,9 @@ pub mod ProtocolHandler {
pub kakarot: IKakarotDispatcher,
pub operator: ContractAddress,
pub guardians: Map<ContractAddress, bool>,
pub gas_price_admin: ContractAddress,
pub protocol_frozen_until: u64,
pub authorized_operator_selector: Map<felt252, bool>,
#[substorage(v0)]
accesscontrol: AccessControlComponent::Storage,
#[substorage(v0)]
Expand All @@ -128,6 +154,8 @@ pub mod ProtocolHandler {
SoftPause: SoftPause,
HardPause: HardPause,
Unpause: Unpause,
BaseFeeChanged: BaseFeeChanged,
Execution: Execution,
#[flat]
AccessControlEvent: AccessControlComponent::Event,
#[flat]
Expand Down Expand Up @@ -162,6 +190,16 @@ pub mod ProtocolHandler {
#[derive(Drop, starknet::Event)]
pub struct Unpause {}

#[derive(Drop, starknet::Event)]
pub struct BaseFeeChanged {
pub new_base_fee: felt252
}

#[derive(Drop, starknet::Event)]
pub struct Execution {
pub call: Call
}

//* ------------------------------------------------------------------------ *//
//* CONSTRUCTOR *//
//* ------------------------------------------------------------------------ *//
Expand All @@ -172,7 +210,8 @@ pub mod ProtocolHandler {
kakarot: ContractAddress,
security_council: ContractAddress,
operator: ContractAddress,
mut guardians: Span<ContractAddress>,
gas_price_admin: ContractAddress,
mut guardians: Span<ContractAddress>
) {
// Store the Kakarot address
self.kakarot.write(IKakarotDispatcher { contract_address: kakarot });
Expand All @@ -186,6 +225,26 @@ pub mod ProtocolHandler {
for guardian in guardians {
self.accesscontrol._grant_role(GUARDIAN_ROLE, *guardian);
};
self.accesscontrol._grant_role(GAS_PRICE_ADMIN_ROLE, gas_price_admin);

// Store the authorized selectors for the operator
self.authorized_operator_selector.write(selector!("set_native_token"), true);
self.authorized_operator_selector.write(selector!("set_coinbase"), true);
self.authorized_operator_selector.write(selector!("set_prev_randao"), true);
self.authorized_operator_selector.write(selector!("set_block_gas_limit"), true);
self.authorized_operator_selector.write(selector!("set_account_contract_class_hash"), true);
self
.authorized_operator_selector
.write(selector!("set_uninitialized_account_class_hash"), true);
self
.authorized_operator_selector
.write(selector!("set_authorized_cairo_precompile_caller"), true);
self.authorized_operator_selector.write(selector!("set_cairo1_helpers_class_hash"), true);
self.authorized_operator_selector.write(selector!("upgrade_account"), true);
self.authorized_operator_selector.write(selector!("set_authorized_pre_eip155_tx"), true);
self
.authorized_operator_selector
.write(selector!("set_l1_messaging_contract_address"), true);
}

#[abi(embed_v0)]
Expand Down Expand Up @@ -291,5 +350,41 @@ pub mod ProtocolHandler {
// Emit Unpause event
self.emit(Unpause {});
}

fn set_base_fee(ref self: ContractState, new_base_fee: felt252) {
// Check only gas price admin can call
self.accesscontrol.assert_only_role(GAS_PRICE_ADMIN_ROLE);

// Call the Kakarot set_base_fee function
let kakarot = self.kakarot.read();
kakarot.set_base_fee(new_base_fee);

// Emit BaseFeeChanged
self.emit(BaseFeeChanged { new_base_fee });
}

//* ------------------------------------------------------------------------ *//
//* EXECUTE OPERATOR CALL *//
//* ------------------------------------------------------------------------ *//

fn execute_call(ref self: ContractState, call: Call) {
// Check only operator can call
self.accesscontrol.assert_only_role(OPERATOR_ROLE);

// Ensure the selector to call is part of the authorized selectors
let authorized = self.authorized_operator_selector.read(call.selector);
assert(authorized, errors::UNAUTHORIZED_SELECTOR);

// Ensure the call is to the Kakarot
let kakarot = self.kakarot.read();
assert(call.to == kakarot.contract_address, errors::ONLY_KAKAROT_CAN_BE_CALLED);

// Call Kakarot with syscall
starknet::syscalls::call_contract_syscall(call.to, call.selector, call.calldata)
.unwrap_syscall();

// Emit Event Execution event
self.emit(Execution { call });
}
}
}
Loading

0 comments on commit b71dd04

Please sign in to comment.