Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgradeability for accounts #33

Merged
merged 3 commits into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions src/accounts/base.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ pub mod RosettaAccount {
use core::num::traits::Zero;
use core::panic_with_felt252;
use starknet::{
ContractAddress, EthAddress, get_contract_address, get_caller_address, get_tx_info
ContractAddress, EthAddress, ClassHash, get_contract_address, get_caller_address, get_tx_info
};
use starknet::syscalls::{call_contract_syscall};
use starknet::syscalls::{call_contract_syscall, replace_class_syscall};
use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};
use rosettacontracts::accounts::utils::{is_valid_eth_signature, RosettanetSignature, RosettanetCall, RosettanetMulticall, prepare_multicall_context, validate_target_function, generate_tx_hash};
use crate::rosettanet::{IRosettanetDispatcher, IRosettanetDispatcherTrait};
Expand All @@ -45,6 +45,7 @@ pub mod RosettaAccount {

pub const TRANSFER_ENTRYPOINT: felt252 = 0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e;
pub const MULTICALL_SELECTOR: felt252 = 0xFFFFFFFF; // multicall eth selector
pub const UPGRADE_SELECTOR: felt252 = 0xFFFFFFFE; // upgrades contract

#[storage]
struct Storage {
Expand All @@ -71,14 +72,22 @@ pub mod RosettaAccount {
let sn_target: ContractAddress = IRosettanetDispatcher { contract_address: self.registry.read() }.get_starknet_address(eth_target);
assert(sn_target != starknet::contract_address_const::<0>(), 'target not registered');

// executes multicall
// Multicall or upgrade call
if(call.to == self.ethereum_address.read()) {
// This is multicall
assert(*call.calldata.at(0) == MULTICALL_SELECTOR, 'wrong multicall selector');
assert(call.value == 0, 'multicall value not zero');
panic_with_felt252(Errors::UNIMPLEMENTED_FEATURE);
let context = prepare_multicall_context(call.calldata); // First calldata element removed inside this function
return self.execute_multicall(context);
let selector = *call.calldata.at(0);
if(selector == MULTICALL_SELECTOR) {
assert(call.value == 0, 'multicall value not zero');
panic_with_felt252(Errors::UNIMPLEMENTED_FEATURE);
let context = prepare_multicall_context(call.calldata); // First calldata element removed inside this function
return self.execute_multicall(context);
} else if(selector == UPGRADE_SELECTOR) {
let latest_hash: ClassHash = IRosettanetDispatcher { contract_address: self.registry.read() }.latest_class();
replace_class_syscall(latest_hash).unwrap();
return array![array![latest_hash.into()].span()];
} else {
panic_with_felt252(Errors::UNIMPLEMENTED_FEATURE);
}
}

// If value transfer, send STRK before calling contract
Expand Down
23 changes: 14 additions & 9 deletions src/rosettanet.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub trait IRosettanet<TState> {
fn get_starknet_address(self: @TState, eth_address: EthAddress) -> ContractAddress;
fn get_ethereum_address(self: @TState, sn_address: ContractAddress) -> EthAddress;
fn precalculate_starknet_account(self: @TState, eth_address: EthAddress) -> ContractAddress;
fn account_class(self: @TState) -> ClassHash;
fn latest_class(self: @TState) -> ClassHash;
fn native_currency(self: @TState) -> ContractAddress;
fn developer(self: @TState) -> ContractAddress;
}
Expand Down Expand Up @@ -73,13 +73,18 @@ pub mod Rosettanet {
struct Storage {
sn_to_eth: Map<ContractAddress, EthAddress>,
eth_to_sn: Map<EthAddress, ContractAddress>,
account_class: ClassHash,
latest_class: ClassHash,
// Accounts will always deployed with initial class, so we can always precalculate the addresses.
// They may need to upgrade to the latest hash after deployment.
initial_class: ClassHash,
dev: ContractAddress,
strk: ContractAddress
}

#[constructor]
fn constructor(ref self: ContractState, developer: ContractAddress, strk: ContractAddress) {
fn constructor(ref self: ContractState, account_class: ClassHash, developer: ContractAddress, strk: ContractAddress) {
self.initial_class.write(account_class);
self.latest_class.write(account_class);
self.dev.write(developer);
self.strk.write(strk);

Expand All @@ -106,7 +111,7 @@ pub mod Rosettanet {
let eth_address_felt: felt252 = eth_address.into();

let (account, _) = deploy_syscall(
self.account_class.read(), eth_address_felt, array![eth_address_felt, get_contract_address().into()].span(), true
self.initial_class.read(), eth_address_felt, array![eth_address_felt, get_contract_address().into()].span(), true
)
.unwrap();

Expand Down Expand Up @@ -135,7 +140,7 @@ pub mod Rosettanet {
fn set_account_class(ref self: ContractState, class: ClassHash) {
assert(get_caller_address() == self.dev.read(), 'only dev');

self.account_class.write(class);
self.latest_class.write(class);

self.emit(AccountClassChanged {changer: get_caller_address(), new_class: class});
}
Expand Down Expand Up @@ -186,15 +191,15 @@ pub mod Rosettanet {
let eth_address_felt: felt252 = eth_address.into();
calculate_contract_address_from_deploy_syscall(
eth_address_felt,
self.account_class.read(),
self.initial_class.read(),
array![eth_address_felt, get_contract_address().into()].span(),
0.try_into().unwrap()
)
}

/// Returns current account class hash
fn account_class(self: @ContractState) -> ClassHash {
self.account_class.read()
/// Returns latest account class hash
fn latest_class(self: @ContractState) -> ClassHash {
self.latest_class.read()
}

/// Returns native currency address on current network
Expand Down
Loading