From 934096a19ac358cdbc2023d7b2e434386f01c817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Triay?= Date: Thu, 22 Feb 2024 02:32:34 +0000 Subject: [PATCH] first draft --- src/account/account.cairo | 11 +++++-- src/account/interface.cairo | 8 ++--- src/account/utils.cairo | 1 + src/account/utils/add_owner.cairo | 52 +++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 src/account/utils/add_owner.cairo diff --git a/src/account/account.cairo b/src/account/account.cairo index 2f720b8a4..ce8334afa 100644 --- a/src/account/account.cairo +++ b/src/account/account.cairo @@ -7,6 +7,7 @@ #[starknet::component] mod AccountComponent { use openzeppelin::account::interface; + use openzeppelin::account::utils::add_owner::AddOwner; use openzeppelin::account::utils::{MIN_TRANSACTION_VERSION, QUERY_VERSION, QUERY_OFFSET}; use openzeppelin::account::utils::{execute_calls, is_valid_stark_signature}; use openzeppelin::introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait; @@ -156,8 +157,12 @@ mod AccountComponent { /// - The caller must be the contract itself. /// /// Emits an `OwnerRemoved` event. - fn set_public_key(ref self: ComponentState, new_public_key: felt252) { + fn set_public_key(ref self: ComponentState, new_public_key: felt252, signature: Span) { self.assert_only_self(); + + let hash = AddOwner::build_hash(new_public_key); + assert(self._is_valid_signature(hash, signature), Errors::INVALID_SIGNATURE); + self.emit(OwnerRemoved { removed_owner_guid: self.Account_public_key.read() }); self._set_public_key(new_public_key); } @@ -190,8 +195,8 @@ mod AccountComponent { self.Account_public_key.read() } - fn setPublicKey(ref self: ComponentState, newPublicKey: felt252) { - self.set_public_key(newPublicKey); + fn setPublicKey(ref self: ComponentState, newPublicKey: felt252, signature: Span) { + self.set_public_key(newPublicKey, signature); } } diff --git a/src/account/interface.cairo b/src/account/interface.cairo index 7ba173a8d..ed3005576 100644 --- a/src/account/interface.cairo +++ b/src/account/interface.cairo @@ -35,7 +35,7 @@ trait IDeployable { #[starknet::interface] trait IPublicKey { fn get_public_key(self: @TState) -> felt252; - fn set_public_key(ref self: TState, new_public_key: felt252); + fn set_public_key(ref self: TState, new_public_key: felt252, signature: Span); } #[starknet::interface] @@ -46,7 +46,7 @@ trait ISRC6CamelOnly { #[starknet::interface] trait IPublicKeyCamel { fn getPublicKey(self: @TState) -> felt252; - fn setPublicKey(ref self: TState, newPublicKey: felt252); + fn setPublicKey(ref self: TState, newPublicKey: felt252, signature: Span); } // @@ -73,7 +73,7 @@ trait AccountABI { // IPublicKey fn get_public_key(self: @TState) -> felt252; - fn set_public_key(ref self: TState, new_public_key: felt252); + fn set_public_key(ref self: TState, new_public_key: felt252, signature: Span); // ISRC6CamelOnly fn isValidSignature(self: @TState, hash: felt252, signature: Array) -> felt252; @@ -83,7 +83,7 @@ trait AccountABI { // IPublicKeyCamel fn getPublicKey(self: @TState) -> felt252; - fn setPublicKey(ref self: TState, newPublicKey: felt252); + fn setPublicKey(ref self: TState, newPublicKey: felt252, signature: Span); } // diff --git a/src/account/utils.cairo b/src/account/utils.cairo index 814631f4d..f64ec322b 100644 --- a/src/account/utils.cairo +++ b/src/account/utils.cairo @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts for Cairo v0.9.0 (account/utils.cairo) +mod add_owner; mod secp256k1; mod signature; diff --git a/src/account/utils/add_owner.cairo b/src/account/utils/add_owner.cairo new file mode 100644 index 000000000..b44513185 --- /dev/null +++ b/src/account/utils/add_owner.cairo @@ -0,0 +1,52 @@ + +mod AddOwner { + use hash::{HashStateTrait, HashStateExTrait}; + use pedersen::PedersenTrait; + use starknet::ContractAddress; + use starknet::get_contract_address; + use starknet::get_tx_info; + + #[derive(Copy, Drop, Hash)] + struct StarkNetDomain { + name: felt252, + version: felt252, + chain_id: felt252 + } + + #[derive(Copy, Drop, Serde)] + struct AddOwner { + account: ContractAddress, + owner: felt252 + } + + fn build_hash(new_owner: felt252) -> felt252 { + let domain = StarkNetDomain { + name: 'Account.add_owner', version: 1, chain_id: get_tx_info().unbox().chain_id, + }; + + PedersenTrait::new(0) + .update('StarkNet Message') + .update(hash_domain(@domain)) + .update(get_contract_address().into()) + .update(hash_add_owner_message(new_owner)) + .update(4) + .finalize() + } + + fn hash_domain(domain: @StarkNetDomain) -> felt252 { + PedersenTrait::new(0) + .update(selector!("StarkNetDomain(name:felt,version:felt,chainId:felt)")) + .update_with(*domain) + .update(4) + .finalize() + } + + fn hash_add_owner_message(new_owner: felt252) -> felt252 { + PedersenTrait::new(0) + .update(selector!("AddOwner(account:felt,owner:felt)")) + .update(get_contract_address().into()) + .update(new_owner) + .update(3) + .finalize() + } +}