From 3b6a08c3ccc22f93df135315863bc88bc3311013 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 29 Sep 2023 16:36:33 -0400 Subject: [PATCH 01/21] fix account abi --- src/account.cairo | 2 - src/account/account.cairo | 56 ++++++++++++----------- src/account/interface.cairo | 32 +++++++------ src/tests/account/test_dual_account.cairo | 7 +-- 4 files changed, 49 insertions(+), 48 deletions(-) diff --git a/src/account.cairo b/src/account.cairo index 501227b0b..74a58229d 100644 --- a/src/account.cairo +++ b/src/account.cairo @@ -5,5 +5,3 @@ mod interface; use account::Account; use interface::AccountABIDispatcher; use interface::AccountABIDispatcherTrait; -use interface::AccountCamelABIDispatcher; -use interface::AccountCamelABIDispatcherTrait; diff --git a/src/account/account.cairo b/src/account/account.cairo index ef73ef44a..646c01b6a 100644 --- a/src/account/account.cairo +++ b/src/account/account.cairo @@ -101,11 +101,10 @@ mod Account { } #[external(v0)] - impl SRC6CamelOnlyImpl of interface::ISRC6CamelOnly { - fn isValidSignature( - self: @ContractState, hash: felt252, signature: Array - ) -> felt252 { - SRC6Impl::is_valid_signature(self, hash, signature) + impl SRC5Impl of ISRC5 { + fn supports_interface(self: @ContractState, interface_id: felt252) -> bool { + let unsafe_state = SRC5::unsafe_new_contract_state(); + SRC5::SRC5Impl::supports_interface(@unsafe_state, interface_id) } } @@ -117,17 +116,13 @@ mod Account { } #[external(v0)] - impl SRC5Impl of ISRC5 { - fn supports_interface(self: @ContractState, interface_id: felt252) -> bool { - SRC5::SRC5Impl::supports_interface(@src5_state(), interface_id) - } - } - - #[external(v0)] - impl SRC5CamelImpl of ISRC5Camel { - fn supportsInterface(self: @ContractState, interfaceId: felt252) -> bool { - SRC5::SRC5CamelImpl::supportsInterface(@src5_state(), interfaceId) - } + fn __validate_deploy__( + self: @ContractState, + class_hash: felt252, + contract_address_salt: felt252, + _public_key: felt252 + ) -> felt252 { + self.validate_transaction() } #[external(v0)] @@ -143,6 +138,23 @@ mod Account { } } + #[external(v0)] + impl SRC6CamelOnlyImpl of interface::ISRC6CamelOnly { + fn isValidSignature( + self: @ContractState, hash: felt252, signature: Array + ) -> felt252 { + SRC6Impl::is_valid_signature(self, hash, signature) + } + } + + #[external(v0)] + impl SRC5CamelImpl of ISRC5Camel { + fn supportsInterface(self: @ContractState, interfaceId: felt252) -> bool { + let unsafe_state = SRC5::unsafe_new_contract_state(); + SRC5::SRC5CamelImpl::supportsInterface(@unsafe_state, interfaceId) + } + } + #[external(v0)] impl PublicKeyCamelImpl of super::PublicKeyCamelTrait { fn getPublicKey(self: @ContractState) -> felt252 { @@ -154,16 +166,6 @@ mod Account { } } - #[external(v0)] - fn __validate_deploy__( - self: @ContractState, - class_hash: felt252, - contract_address_salt: felt252, - _public_key: felt252 - ) -> felt252 { - self.validate_transaction() - } - // // Internal // @@ -171,7 +173,7 @@ mod Account { #[generate_trait] impl InternalImpl of InternalTrait { fn initializer(ref self: ContractState, _public_key: felt252) { - let mut unsafe_state = src5_state(); + let mut unsafe_state = SRC5::unsafe_new_contract_state(); SRC5::InternalImpl::register_interface(ref unsafe_state, interface::ISRC6_ID); self._set_public_key(_public_key); } diff --git a/src/account/interface.cairo b/src/account/interface.cairo index e58c5bb30..103f5e55c 100644 --- a/src/account/interface.cairo +++ b/src/account/interface.cairo @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts for Cairo v0.7.0 (account/interface.cairo) +use array::ArrayTrait; +use array::SpanTrait; use starknet::ContractAddress; use starknet::account::Call; @@ -23,31 +25,33 @@ trait IDeclarer { fn __validate_declare__(self: @TState, class_hash: felt252) -> felt252; } +// +// Account ABI +// + #[starknet::interface] trait AccountABI { + // ISRC6 fn __execute__(self: @TState, calls: Array) -> Array>; fn __validate__(self: @TState, calls: Array) -> felt252; + fn is_valid_signature(self: @TState, hash: felt252, signature: Array) -> felt252; + + // ISRC5 + fn supports_interface(self: @TState, interface_id: felt252) -> bool; + + // IDeclarer fn __validate_declare__(self: @TState, class_hash: felt252) -> felt252; + + // Non-Standard fn __validate_deploy__( self: @TState, class_hash: felt252, contract_address_salt: felt252, _public_key: felt252 ) -> felt252; fn set_public_key(ref self: TState, new_public_key: felt252); fn get_public_key(self: @TState) -> felt252; - fn is_valid_signature(self: @TState, hash: felt252, signature: Array) -> felt252; - fn supports_interface(self: @TState, interface_id: felt252) -> bool; -} -// Entry points case-convention is enforced by the protocol -#[starknet::interface] -trait AccountCamelABI { - fn __execute__(self: @TState, calls: Array) -> Array>; - fn __validate__(self: @TState, calls: Array) -> felt252; - fn __validate_declare__(self: @TState, classHash: felt252) -> felt252; - fn __validate_deploy__( - self: @TState, classHash: felt252, contractAddressSalt: felt252, _publicKey: felt252 - ) -> felt252; - fn setPublicKey(ref self: TState, newPublicKey: felt252); - fn getPublicKey(self: @TState) -> felt252; + // Camel case compatibility fn isValidSignature(self: @TState, hash: felt252, signature: Array) -> felt252; fn supportsInterface(self: @TState, interfaceId: felt252) -> bool; + fn setPublicKey(ref self: TState, newPublicKey: felt252); + fn getPublicKey(self: @TState) -> felt252; } diff --git a/src/tests/account/test_dual_account.cairo b/src/tests/account/test_dual_account.cairo index 2c2156ed6..313528e6e 100644 --- a/src/tests/account/test_dual_account.cairo +++ b/src/tests/account/test_dual_account.cairo @@ -1,7 +1,5 @@ use openzeppelin::account::AccountABIDispatcher; use openzeppelin::account::AccountABIDispatcherTrait; -use openzeppelin::account::AccountCamelABIDispatcher; -use openzeppelin::account::AccountCamelABIDispatcherTrait; use openzeppelin::account::dual_account::DualCaseAccount; use openzeppelin::account::dual_account::DualCaseAccountABI; use openzeppelin::introspection::interface::ISRC5_ID; @@ -34,12 +32,12 @@ fn setup_snake() -> (DualCaseAccount, AccountABIDispatcher) { ) } -fn setup_camel() -> (DualCaseAccount, AccountCamelABIDispatcher) { +fn setup_camel() -> (DualCaseAccount, AccountABIDispatcher) { let mut calldata = array![PUBLIC_KEY]; let target = utils::deploy(CamelAccountMock::TEST_CLASS_HASH, calldata); ( DualCaseAccount { contract_address: target }, - AccountCamelABIDispatcher { contract_address: target } + AccountABIDispatcher { contract_address: target } ) } @@ -252,4 +250,3 @@ fn test_dual_supportsInterface_exists_and_panics() { let (_, dispatcher) = setup_account_panic(); dispatcher.supports_interface(ISRC5_ID); } - From e6633205de737483a48522a1cfd5a3ba136bda52 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 29 Sep 2023 16:36:46 -0400 Subject: [PATCH 02/21] fix erc20 abi --- src/token/erc20/erc20.cairo | 100 ++++++++++++++++---------------- src/token/erc20/interface.cairo | 17 +++--- 2 files changed, 58 insertions(+), 59 deletions(-) diff --git a/src/token/erc20/erc20.cairo b/src/token/erc20/erc20.cairo index ee1204d36..c0fe5aa09 100644 --- a/src/token/erc20/erc20.cairo +++ b/src/token/erc20/erc20.cairo @@ -121,6 +121,20 @@ mod ERC20 { } } + #[external(v0)] + fn increase_allowance( + ref self: ContractState, spender: ContractAddress, added_value: u256 + ) -> bool { + self._increase_allowance(spender, added_value) + } + + #[external(v0)] + fn decrease_allowance( + ref self: ContractState, spender: ContractAddress, subtracted_value: u256 + ) -> bool { + self._decrease_allowance(spender, subtracted_value) + } + #[external(v0)] impl ERC20CamelOnlyImpl of IERC20CamelOnly { fn totalSupply(self: @ContractState) -> u256 { @@ -141,13 +155,6 @@ mod ERC20 { } } - #[external(v0)] - fn increase_allowance( - ref self: ContractState, spender: ContractAddress, added_value: u256 - ) -> bool { - self._increase_allowance(spender, added_value) - } - #[external(v0)] fn increaseAllowance( ref self: ContractState, spender: ContractAddress, addedValue: u256 @@ -155,13 +162,6 @@ mod ERC20 { increase_allowance(ref self, spender, addedValue) } - #[external(v0)] - fn decrease_allowance( - ref self: ContractState, spender: ContractAddress, subtracted_value: u256 - ) -> bool { - self._decrease_allowance(spender, subtracted_value) - } - #[external(v0)] fn decreaseAllowance( ref self: ContractState, spender: ContractAddress, subtractedValue: u256 @@ -180,6 +180,42 @@ mod ERC20 { self.ERC20_symbol.write(symbol); } + fn _transfer( + ref self: ContractState, + sender: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) { + assert(!sender.is_zero(), Errors::TRANSFER_FROM_ZERO); + assert(!recipient.is_zero(), Errors::TRANSFER_TO_ZERO); + self.ERC20_balances.write(sender, self.ERC20_balances.read(sender) - amount); + self.ERC20_balances.write(recipient, self.ERC20_balances.read(recipient) + amount); + self.emit(Transfer { from: sender, to: recipient, value: amount }); + } + + fn _approve( + ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 + ) { + assert(!owner.is_zero(), Errors::APPROVE_FROM_ZERO); + assert(!spender.is_zero(), Errors::APPROVE_TO_ZERO); + self.ERC20_allowances.write((owner, spender), amount); + self.emit(Approval { owner, spender, value: amount }); + } + + fn _mint(ref self: ContractState, recipient: ContractAddress, amount: u256) { + assert(!recipient.is_zero(), Errors::MINT_TO_ZERO); + self.ERC20_total_supply.write(self.ERC20_total_supply.read() + amount); + self.ERC20_balances.write(recipient, self.ERC20_balances.read(recipient) + amount); + self.emit(Transfer { from: Zeroable::zero(), to: recipient, value: amount }); + } + + fn _burn(ref self: ContractState, account: ContractAddress, amount: u256) { + assert(!account.is_zero(), Errors::BURN_FROM_ZERO); + self.ERC20_total_supply.write(self.ERC20_total_supply.read() - amount); + self.ERC20_balances.write(account, self.ERC20_balances.read(account) - amount); + self.emit(Transfer { from: account, to: Zeroable::zero(), value: amount }); + } + fn _increase_allowance( ref self: ContractState, spender: ContractAddress, added_value: u256 ) -> bool { @@ -204,42 +240,6 @@ mod ERC20 { true } - fn _mint(ref self: ContractState, recipient: ContractAddress, amount: u256) { - assert(!recipient.is_zero(), Errors::MINT_TO_ZERO); - self.ERC20_total_supply.write(self.ERC20_total_supply.read() + amount); - self.ERC20_balances.write(recipient, self.ERC20_balances.read(recipient) + amount); - self.emit(Transfer { from: Zeroable::zero(), to: recipient, value: amount }); - } - - fn _burn(ref self: ContractState, account: ContractAddress, amount: u256) { - assert(!account.is_zero(), Errors::BURN_FROM_ZERO); - self.ERC20_total_supply.write(self.ERC20_total_supply.read() - amount); - self.ERC20_balances.write(account, self.ERC20_balances.read(account) - amount); - self.emit(Transfer { from: account, to: Zeroable::zero(), value: amount }); - } - - fn _approve( - ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 - ) { - assert(!owner.is_zero(), Errors::APPROVE_FROM_ZERO); - assert(!spender.is_zero(), Errors::APPROVE_TO_ZERO); - self.ERC20_allowances.write((owner, spender), amount); - self.emit(Approval { owner, spender, value: amount }); - } - - fn _transfer( - ref self: ContractState, - sender: ContractAddress, - recipient: ContractAddress, - amount: u256 - ) { - assert(!sender.is_zero(), Errors::TRANSFER_FROM_ZERO); - assert(!recipient.is_zero(), Errors::TRANSFER_TO_ZERO); - self.ERC20_balances.write(sender, self.ERC20_balances.read(sender) - amount); - self.ERC20_balances.write(recipient, self.ERC20_balances.read(recipient) + amount); - self.emit(Transfer { from: sender, to: recipient, value: amount }); - } - fn _spend_allowance( ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 ) { diff --git a/src/token/erc20/interface.cairo b/src/token/erc20/interface.cairo index 8f0526299..3b3b4c248 100644 --- a/src/token/erc20/interface.cairo +++ b/src/token/erc20/interface.cairo @@ -41,8 +41,13 @@ trait IERC20CamelOnly { ) -> bool; } +// +// ERC20 ABI +// + #[starknet::interface] trait ERC20ABI { + // IERC20 fn name(self: @TState) -> felt252; fn symbol(self: @TState) -> felt252; fn decimals(self: @TState) -> u8; @@ -54,25 +59,19 @@ trait ERC20ABI { ref self: TState, sender: ContractAddress, recipient: ContractAddress, amount: u256 ) -> bool; fn approve(ref self: TState, spender: ContractAddress, amount: u256) -> bool; + + // Non-standard fn increase_allowance(ref self: TState, spender: ContractAddress, added_value: u256) -> bool; fn decrease_allowance( ref self: TState, spender: ContractAddress, subtracted_value: u256 ) -> bool; -} -#[starknet::interface] -trait ERC20CamelABI { - fn name(self: @TState) -> felt252; - fn symbol(self: @TState) -> felt252; - fn decimals(self: @TState) -> u8; + // Camel case compatibility fn totalSupply(self: @TState) -> u256; fn balanceOf(self: @TState, account: ContractAddress) -> u256; - fn allowance(self: @TState, owner: ContractAddress, spender: ContractAddress) -> u256; - fn transfer(ref self: TState, recipient: ContractAddress, amount: u256) -> bool; fn transferFrom( ref self: TState, sender: ContractAddress, recipient: ContractAddress, amount: u256 ) -> bool; - fn approve(ref self: TState, spender: ContractAddress, amount: u256) -> bool; fn increaseAllowance(ref self: TState, spender: ContractAddress, addedValue: u256) -> bool; fn decreaseAllowance(ref self: TState, spender: ContractAddress, subtractedValue: u256) -> bool; } From 5471a7dcdd778d7b6710fc085b9cf2b8462d2609 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 29 Sep 2023 16:36:55 -0400 Subject: [PATCH 03/21] fix erc721 abi --- src/token/erc721/erc721.cairo | 158 +++++++++++++++---------------- src/token/erc721/interface.cairo | 50 ++++++++++ 2 files changed, 129 insertions(+), 79 deletions(-) diff --git a/src/token/erc721/erc721.cairo b/src/token/erc721/erc721.cairo index 8572f50c8..3f7113abe 100644 --- a/src/token/erc721/erc721.cairo +++ b/src/token/erc721/erc721.cairo @@ -93,44 +93,6 @@ mod ERC721 { // External // - #[external(v0)] - impl SRC5Impl of ISRC5 { - fn supports_interface(self: @ContractState, interface_id: felt252) -> bool { - src5::SRC5::SRC5Impl::supports_interface(@src5_state(), interface_id) - } - } - - #[external(v0)] - impl SRC5CamelImpl of ISRC5Camel { - fn supportsInterface(self: @ContractState, interfaceId: felt252) -> bool { - src5::SRC5::SRC5CamelImpl::supportsInterface(@src5_state(), interfaceId) - } - } - - #[external(v0)] - impl ERC721MetadataImpl of interface::IERC721Metadata { - fn name(self: @ContractState) -> felt252 { - self.ERC721_name.read() - } - - fn symbol(self: @ContractState) -> felt252 { - self.ERC721_symbol.read() - } - - fn token_uri(self: @ContractState, token_id: u256) -> felt252 { - assert(self._exists(token_id), Errors::INVALID_TOKEN_ID); - self.ERC721_token_uri.read(token_id) - } - } - - #[external(v0)] - impl ERC721MetadataCamelOnlyImpl of interface::IERC721MetadataCamelOnly { - fn tokenURI(self: @ContractState, tokenId: u256) -> felt252 { - assert(self._exists(tokenId), Errors::INVALID_TOKEN_ID); - self.ERC721_token_uri.read(tokenId) - } - } - #[external(v0)] impl ERC721Impl of interface::IERC721 { fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { @@ -142,15 +104,26 @@ mod ERC721 { self._owner_of(token_id) } - fn get_approved(self: @ContractState, token_id: u256) -> ContractAddress { - assert(self._exists(token_id), Errors::INVALID_TOKEN_ID); - self.ERC721_token_approvals.read(token_id) + fn safe_transfer_from( + ref self: ContractState, + from: ContractAddress, + to: ContractAddress, + token_id: u256, + data: Span + ) { + assert( + self._is_approved_or_owner(get_caller_address(), token_id), Errors::UNAUTHORIZED + ); + self._safe_transfer(from, to, token_id, data); } - fn is_approved_for_all( - self: @ContractState, owner: ContractAddress, operator: ContractAddress - ) -> bool { - self.ERC721_operator_approvals.read((owner, operator)) + fn transfer_from( + ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256 + ) { + assert( + self._is_approved_or_owner(get_caller_address(), token_id), Errors::UNAUTHORIZED + ); + self._transfer(from, to, token_id); } fn approve(ref self: ContractState, to: ContractAddress, token_id: u256) { @@ -170,26 +143,38 @@ mod ERC721 { self._set_approval_for_all(get_caller_address(), operator, approved) } - fn transfer_from( - ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256 - ) { - assert( - self._is_approved_or_owner(get_caller_address(), token_id), Errors::UNAUTHORIZED - ); - self._transfer(from, to, token_id); + fn get_approved(self: @ContractState, token_id: u256) -> ContractAddress { + assert(self._exists(token_id), Errors::INVALID_TOKEN_ID); + self.ERC721_token_approvals.read(token_id) } - fn safe_transfer_from( - ref self: ContractState, - from: ContractAddress, - to: ContractAddress, - token_id: u256, - data: Span - ) { - assert( - self._is_approved_or_owner(get_caller_address(), token_id), Errors::UNAUTHORIZED - ); - self._safe_transfer(from, to, token_id, data); + fn is_approved_for_all( + self: @ContractState, owner: ContractAddress, operator: ContractAddress + ) -> bool { + self.ERC721_operator_approvals.read((owner, operator)) + } + } + + #[external(v0)] + impl SRC5Impl of ISRC5 { + fn supports_interface(self: @ContractState, interface_id: felt252) -> bool { + src5::SRC5::SRC5Impl::supports_interface(@src5_state(), interface_id) + } + } + + #[external(v0)] + impl ERC721MetadataImpl of interface::IERC721Metadata { + fn name(self: @ContractState) -> felt252 { + self.ERC721_name.read() + } + + fn symbol(self: @ContractState) -> felt252 { + self.ERC721_symbol.read() + } + + fn token_uri(self: @ContractState, token_id: u256) -> felt252 { + assert(self._exists(token_id), Errors::INVALID_TOKEN_ID); + self.ERC721_token_uri.read(token_id) } } @@ -203,6 +188,26 @@ mod ERC721 { ERC721Impl::owner_of(self, tokenId) } + fn safeTransferFrom( + ref self: ContractState, + from: ContractAddress, + to: ContractAddress, + tokenId: u256, + data: Span + ) { + ERC721Impl::safe_transfer_from(ref self, from, to, tokenId, data) + } + + fn transferFrom( + ref self: ContractState, from: ContractAddress, to: ContractAddress, tokenId: u256 + ) { + ERC721Impl::transfer_from(ref self, from, to, tokenId) + } + + fn setApprovalForAll(ref self: ContractState, operator: ContractAddress, approved: bool) { + ERC721Impl::set_approval_for_all(ref self, operator, approved) + } + fn getApproved(self: @ContractState, tokenId: u256) -> ContractAddress { ERC721Impl::get_approved(self, tokenId) } @@ -212,25 +217,20 @@ mod ERC721 { ) -> bool { ERC721Impl::is_approved_for_all(self, owner, operator) } + } - fn setApprovalForAll(ref self: ContractState, operator: ContractAddress, approved: bool) { - ERC721Impl::set_approval_for_all(ref self, operator, approved) - } - - fn transferFrom( - ref self: ContractState, from: ContractAddress, to: ContractAddress, tokenId: u256 - ) { - ERC721Impl::transfer_from(ref self, from, to, tokenId) + #[external(v0)] + impl SRC5CamelImpl of ISRC5Camel { + fn supportsInterface(self: @ContractState, interfaceId: felt252) -> bool { + src5::SRC5::SRC5CamelImpl::supportsInterface(@src5_state(), interfaceId) } + } - fn safeTransferFrom( - ref self: ContractState, - from: ContractAddress, - to: ContractAddress, - tokenId: u256, - data: Span - ) { - ERC721Impl::safe_transfer_from(ref self, from, to, tokenId, data) + #[external(v0)] + impl ERC721MetadataCamelOnlyImpl of interface::IERC721MetadataCamelOnly { + fn tokenURI(self: @ContractState, tokenId: u256) -> felt252 { + assert(self._exists(tokenId), Errors::INVALID_TOKEN_ID); + self.ERC721_token_uri.read(tokenId) } } diff --git a/src/token/erc721/interface.cairo b/src/token/erc721/interface.cairo index 6fdc68272..2a33e5f33 100644 --- a/src/token/erc721/interface.cairo +++ b/src/token/erc721/interface.cairo @@ -87,3 +87,53 @@ trait IERC721ReceiverCamel { data: Span ) -> felt252; } + +// +// ERC721 ABI +// + +#[starknet::interface] +trait ERC721ABI { + // IERC721 + fn balance_of(self: @TState, account: ContractAddress) -> u256; + fn owner_of(self: @TState, token_id: u256) -> ContractAddress; + fn safe_transfer_from( + ref self: TState, + from: ContractAddress, + to: ContractAddress, + token_id: u256, + data: Span + ); + fn transfer_from(ref self: TState, from: ContractAddress, to: ContractAddress, token_id: u256); + fn approve(ref self: TState, to: ContractAddress, token_id: u256); + fn set_approval_for_all(ref self: TState, operator: ContractAddress, approved: bool); + fn get_approved(self: @TState, token_id: u256) -> ContractAddress; + fn is_approved_for_all( + self: @TState, owner: ContractAddress, operator: ContractAddress + ) -> bool; + + // ISRC5 + fn supports_interface(self: @TState, interface_id: felt252) -> bool; + + // IERC721Metadata + fn name(self: @TState) -> felt252; + fn symbol(self: @TState) -> felt252; + fn token_uri(self: @TState, token_id: u256) -> felt252; + + // Camel case compatibility + fn balanceOf(self: @TState, account: ContractAddress) -> u256; + fn ownerOf(self: @TState, tokenId: u256) -> ContractAddress; + fn safeTransferFrom( + ref self: TState, + from: ContractAddress, + to: ContractAddress, + tokenId: u256, + data: Span + ); + fn transferFrom(ref self: TState, from: ContractAddress, to: ContractAddress, tokenId: u256); + fn setApprovalForAll(ref self: TState, operator: ContractAddress, approved: bool); + fn getApproved(self: @TState, tokenId: u256) -> ContractAddress; + fn isApprovedForAll(self: @TState, owner: ContractAddress, operator: ContractAddress) -> bool; + fn supportsInterface(self: @TState, interfaceId: felt252) -> bool; + fn tokenURI(self: @TState, tokenId: u256) -> felt252; +} From 79b044dc252e8f0e1998f6993205431e16ce1a9b Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 29 Sep 2023 16:44:23 -0400 Subject: [PATCH 04/21] reorder internal fns --- src/token/erc721/erc721.cairo | 78 +++++++++++++++++------------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/token/erc721/erc721.cairo b/src/token/erc721/erc721.cairo index 3f7113abe..136cdcf91 100644 --- a/src/token/erc721/erc721.cairo +++ b/src/token/erc721/erc721.cairo @@ -259,18 +259,34 @@ mod ERC721 { } } - fn _exists(self: @ContractState, token_id: u256) -> bool { - !self.ERC721_owners.read(token_id).is_zero() + fn _safe_transfer( + ref self: ContractState, + from: ContractAddress, + to: ContractAddress, + token_id: u256, + data: Span + ) { + self._transfer(from, to, token_id); + assert( + _check_on_erc721_received(from, to, token_id, data), Errors::SAFE_TRANSFER_FAILED + ); } - fn _is_approved_or_owner( - self: @ContractState, spender: ContractAddress, token_id: u256 - ) -> bool { + fn _transfer( + ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256 + ) { + assert(!to.is_zero(), Errors::INVALID_RECEIVER); let owner = self._owner_of(token_id); - let is_approved_for_all = ERC721Impl::is_approved_for_all(self, owner, spender); - owner == spender - || is_approved_for_all - || spender == ERC721Impl::get_approved(self, token_id) + assert(from == owner, Errors::WRONG_SENDER); + + // Implicit clear approvals, no need to emit an event + self.ERC721_token_approvals.write(token_id, Zeroable::zero()); + + self.ERC721_balances.write(from, self.ERC721_balances.read(from) - 1); + self.ERC721_balances.write(to, self.ERC721_balances.read(to) + 1); + self.ERC721_owners.write(token_id, to); + + self.emit(Transfer { from, to, token_id }); } fn _approve(ref self: ContractState, to: ContractAddress, token_id: u256) { @@ -292,31 +308,28 @@ mod ERC721 { self.emit(ApprovalForAll { owner, operator, approved }); } - fn _mint(ref self: ContractState, to: ContractAddress, token_id: u256) { - assert(!to.is_zero(), Errors::INVALID_RECEIVER); - assert(!self._exists(token_id), Errors::ALREADY_MINTED); - - self.ERC721_balances.write(to, self.ERC721_balances.read(to) + 1); - self.ERC721_owners.write(token_id, to); + fn _is_approved_or_owner( + self: @ContractState, spender: ContractAddress, token_id: u256 + ) -> bool { + let owner = self._owner_of(token_id); + let is_approved_for_all = ERC721Impl::is_approved_for_all(self, owner, spender); + owner == spender + || is_approved_for_all + || spender == ERC721Impl::get_approved(self, token_id) + } - self.emit(Transfer { from: Zeroable::zero(), to, token_id }); + fn _exists(self: @ContractState, token_id: u256) -> bool { + !self.ERC721_owners.read(token_id).is_zero() } - fn _transfer( - ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256 - ) { + fn _mint(ref self: ContractState, to: ContractAddress, token_id: u256) { assert(!to.is_zero(), Errors::INVALID_RECEIVER); - let owner = self._owner_of(token_id); - assert(from == owner, Errors::WRONG_SENDER); - - // Implicit clear approvals, no need to emit an event - self.ERC721_token_approvals.write(token_id, Zeroable::zero()); + assert(!self._exists(token_id), Errors::ALREADY_MINTED); - self.ERC721_balances.write(from, self.ERC721_balances.read(from) - 1); self.ERC721_balances.write(to, self.ERC721_balances.read(to) + 1); self.ERC721_owners.write(token_id, to); - self.emit(Transfer { from, to, token_id }); + self.emit(Transfer { from: Zeroable::zero(), to, token_id }); } fn _burn(ref self: ContractState, token_id: u256) { @@ -341,19 +354,6 @@ mod ERC721 { ); } - fn _safe_transfer( - ref self: ContractState, - from: ContractAddress, - to: ContractAddress, - token_id: u256, - data: Span - ) { - self._transfer(from, to, token_id); - assert( - _check_on_erc721_received(from, to, token_id, data), Errors::SAFE_TRANSFER_FAILED - ); - } - fn _set_token_uri(ref self: ContractState, token_id: u256, token_uri: felt252) { assert(self._exists(token_id), Errors::INVALID_TOKEN_ID); self.ERC721_token_uri.write(token_id, token_uri) From fc3872b542c5aad62a8e63f1b28b424a606a58da Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 29 Sep 2023 16:46:22 -0400 Subject: [PATCH 05/21] reorder internal fns --- src/account/account.cairo | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/account/account.cairo b/src/account/account.cairo index 646c01b6a..b085c99ac 100644 --- a/src/account/account.cairo +++ b/src/account/account.cairo @@ -186,11 +186,6 @@ mod Account { starknet::VALIDATED } - fn _set_public_key(ref self: ContractState, new_public_key: felt252) { - self.Account_public_key.write(new_public_key); - self.emit(OwnerAdded { new_owner_guid: new_public_key }); - } - fn _is_valid_signature( self: @ContractState, hash: felt252, signature: Span ) -> bool { @@ -204,6 +199,11 @@ mod Account { false } } + + fn _set_public_key(ref self: ContractState, new_public_key: felt252) { + self.Account_public_key.write(new_public_key); + self.emit(OwnerAdded { new_owner_guid: new_public_key }); + } } #[internal] From 2d279a0fdab0f3ee0b00e44ee65157c614b9b52f Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 29 Sep 2023 16:47:41 -0400 Subject: [PATCH 06/21] fix comment --- src/account/interface.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/account/interface.cairo b/src/account/interface.cairo index 103f5e55c..1a9a773fd 100644 --- a/src/account/interface.cairo +++ b/src/account/interface.cairo @@ -42,7 +42,7 @@ trait AccountABI { // IDeclarer fn __validate_declare__(self: @TState, class_hash: felt252) -> felt252; - // Non-Standard + // Non-standard fn __validate_deploy__( self: @TState, class_hash: felt252, contract_address_salt: felt252, _public_key: felt252 ) -> felt252; From 300723f53d3094a8638e4235bb7ef085ae992e9f Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Oct 2023 16:05:49 -0400 Subject: [PATCH 07/21] reorder fns --- docs/modules/ROOT/pages/api/account.adoc | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/docs/modules/ROOT/pages/api/account.adoc b/docs/modules/ROOT/pages/api/account.adoc index 74fd497c3..d8d48f172 100644 --- a/docs/modules/ROOT/pages/api/account.adoc +++ b/docs/modules/ROOT/pages/api/account.adoc @@ -82,8 +82,6 @@ Account contract implementation extending xref:ISRC6[`ISRC6`]. [.contract-index] .External Functions -- -* xref:#Account-\\__validate_deploy__[`++__validate_deploy__(self, hash, signature)++`] - .SRC6Impl * xref:#Account-\\__execute__[`++__execute__(self, calls)++`] @@ -98,8 +96,8 @@ Account contract implementation extending xref:ISRC6[`ISRC6`]. * xref:#Account-\\__validate_declare__[`++__validate_declare__(self, class_hash)++`] -.PublicKeyImpl - +.Non-standardImpl +* xref:#Account-\\__validate_deploy__[`++__validate_deploy__(self, hash, signature)++`] * xref:#Account-set_public_key[`++set_public_key(self, new_public_key)++`] * xref:#Account-get_public_key[`++get_public_key(self)++`] -- @@ -137,15 +135,6 @@ Emits an {OwnerAdded} event. [#Account-External-Functions] ==== External Functions -[.contract-item] -[[Account-__validate_deploy__]] -==== `[.contract-item-name]#++__validate_deploy__++#++(self: @ContractState, class_hash: felt252, contract_address_salt: felt252, _public_key: felt252) → felt252++` [.item-kind]#external# - -Validates a https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/Blocks/transactions/#deploy_account_transaction[`DeployAccount` transaction]. -See xref:/guides/deployment.adoc[Counterfactual Deployments]. - -Returns the short string `'VALID'` if valid, otherwise it reverts. - [.contract-item] [[Account-__execute__]] ==== `[.contract-item-name]#++__execute__++#++(ref self: ContractState, calls: Array) → Array>++` [.item-kind]#external# @@ -178,6 +167,15 @@ Validates a https://docs.starknet.io/documentation/architecture_and_concepts/Net Returns the short string `'VALID'` if valid, otherwise it reverts. +[.contract-item] +[[Account-__validate_deploy__]] +==== `[.contract-item-name]#++__validate_deploy__++#++(self: @ContractState, class_hash: felt252, contract_address_salt: felt252, _public_key: felt252) → felt252++` [.item-kind]#external# + +Validates a https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/Blocks/transactions/#deploy_account_transaction[`DeployAccount` transaction]. +See xref:/guides/deployment.adoc[Counterfactual Deployments]. + +Returns the short string `'VALID'` if valid, otherwise it reverts. + [.contract-item] [[Account-set_public_key]] ==== `[.contract-item-name]#++set_public_key++#++(ref self: ContractState, new_public_key: felt252)++` [.item-kind]#external# From 605e45447fc14131bcecdf69cea654aa763c3143 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Oct 2023 16:06:41 -0400 Subject: [PATCH 08/21] fix casing --- docs/modules/ROOT/pages/api/account.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/api/account.adoc b/docs/modules/ROOT/pages/api/account.adoc index d8d48f172..33431965d 100644 --- a/docs/modules/ROOT/pages/api/account.adoc +++ b/docs/modules/ROOT/pages/api/account.adoc @@ -172,7 +172,7 @@ Returns the short string `'VALID'` if valid, otherwise it reverts. ==== `[.contract-item-name]#++__validate_deploy__++#++(self: @ContractState, class_hash: felt252, contract_address_salt: felt252, _public_key: felt252) → felt252++` [.item-kind]#external# Validates a https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/Blocks/transactions/#deploy_account_transaction[`DeployAccount` transaction]. -See xref:/guides/deployment.adoc[Counterfactual Deployments]. +See xref:/guides/deployment.adoc[Counterfactual deployments]. Returns the short string `'VALID'` if valid, otherwise it reverts. From 9c2c16d8cd63096445e9551231db11975619866d Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Oct 2023 16:08:31 -0400 Subject: [PATCH 09/21] fix casing --- docs/modules/ROOT/pages/accounts.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/accounts.adoc b/docs/modules/ROOT/pages/accounts.adoc index da71bce85..eef5f0d49 100644 --- a/docs/modules/ROOT/pages/accounts.adoc +++ b/docs/modules/ROOT/pages/accounts.adoc @@ -1,7 +1,7 @@ :test-signers: https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.6.1/tests/signers.py :snip-5: https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-5.md :snip-6: https://github.com/ericnordelo/SNIPs/blob/feat/standard-account/SNIPS/snip-6.md -:counterfactual: xref:/guides/deployment.adoc[Counterfactual Deployments] +:counterfactual: xref:/guides/deployment.adoc[counterfactual deployments] = Accounts From 71b2bea7ae51ec0fd4eece02cb017b24fa306eb2 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Oct 2023 16:30:14 -0400 Subject: [PATCH 10/21] reorder api fns --- docs/modules/ROOT/pages/api/account.adoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/modules/ROOT/pages/api/account.adoc b/docs/modules/ROOT/pages/api/account.adoc index 33431965d..8df773a61 100644 --- a/docs/modules/ROOT/pages/api/account.adoc +++ b/docs/modules/ROOT/pages/api/account.adoc @@ -109,8 +109,8 @@ Account contract implementation extending xref:ISRC6[`ISRC6`]. * xref:#Account-initializer[`++initializer(self, _public_key)++`] * xref:#Account-validate_transaction[`++validate_transaction(self)++`] -* xref:#Account-_set_public_key[`++_set_public_key(self, new_public_key)++`] * xref:#Account-_is_valid_signature[`++_is_valid_signature(self, hash, signature)++`] +* xref:#Account-_set_public_key[`++_set_public_key(self, new_public_key)++`] * xref:#Account-assert_only_self[`++assert_only_self(self)++`] -- @@ -210,6 +210,12 @@ https://github.com/starkware-libs/cairo/blob/main/corelib/src/starknet/info.cair Returns the short string `'VALID'` if valid, otherwise it reverts. +[.contract-item] +[[Account-_is_valid_signature]] +==== `[.contract-item-name]#++_is_valid_signature++#++(self: @ContractState, hash: felt252, signature: Span)++ → bool` [.item-kind]#internal# + +Validates the provided `signature` for the `hash`, using the account current public key. + [.contract-item] [[Account-_set_public_key]] ==== `[.contract-item-name]#++_set_public_key++#++(ref self: ContractState, new_public_key: felt252)++` [.item-kind]#internal# @@ -220,12 +226,6 @@ Emits an {OwnerAdded} event. CAUTION: The usage of this method outside the `set_public_key` function is discouraged. -[.contract-item] -[[Account-_is_valid_signature]] -==== `[.contract-item-name]#++_is_valid_signature++#++(self: @ContractState, hash: felt252, signature: Span)++ → bool` [.item-kind]#internal# - -Validates the provided `signature` for the `hash`, using the account current public key. - [.contract-item] [[Account-assert_only_self]] ==== `[.contract-item-name]#++assert_only_self++#++(self: @ContractState)++` [.item-kind]#internal# From b00c017aa6d255be88e53e40ad62b52f7fbb08d2 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Oct 2023 19:00:37 -0400 Subject: [PATCH 11/21] add dual interfaces link --- src/account/interface.cairo | 1 + src/token/erc20/interface.cairo | 3 ++- src/token/erc721/interface.cairo | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/account/interface.cairo b/src/account/interface.cairo index 1a9a773fd..e60a59153 100644 --- a/src/account/interface.cairo +++ b/src/account/interface.cairo @@ -50,6 +50,7 @@ trait AccountABI { fn get_public_key(self: @TState) -> felt252; // Camel case compatibility + // See https://docs.openzeppelin.com/contracts-cairo/0.7.0/interfaces#dual_interfaces fn isValidSignature(self: @TState, hash: felt252, signature: Array) -> felt252; fn supportsInterface(self: @TState, interfaceId: felt252) -> bool; fn setPublicKey(ref self: TState, newPublicKey: felt252); diff --git a/src/token/erc20/interface.cairo b/src/token/erc20/interface.cairo index 3b3b4c248..21bd00594 100644 --- a/src/token/erc20/interface.cairo +++ b/src/token/erc20/interface.cairo @@ -60,13 +60,14 @@ trait ERC20ABI { ) -> bool; fn approve(ref self: TState, spender: ContractAddress, amount: u256) -> bool; - // Non-standard + /// Non-standard fn increase_allowance(ref self: TState, spender: ContractAddress, added_value: u256) -> bool; fn decrease_allowance( ref self: TState, spender: ContractAddress, subtracted_value: u256 ) -> bool; // Camel case compatibility + // See https://docs.openzeppelin.com/contracts-cairo/0.7.0/interfaces#dual_interfaces fn totalSupply(self: @TState) -> u256; fn balanceOf(self: @TState, account: ContractAddress) -> u256; fn transferFrom( diff --git a/src/token/erc721/interface.cairo b/src/token/erc721/interface.cairo index 2a33e5f33..6f8889378 100644 --- a/src/token/erc721/interface.cairo +++ b/src/token/erc721/interface.cairo @@ -121,6 +121,7 @@ trait ERC721ABI { fn token_uri(self: @TState, token_id: u256) -> felt252; // Camel case compatibility + // See https://docs.openzeppelin.com/contracts-cairo/0.7.0/interfaces#dual_interfaces fn balanceOf(self: @TState, account: ContractAddress) -> u256; fn ownerOf(self: @TState, tokenId: u256) -> ContractAddress; fn safeTransferFrom( From 278ccc4cf4b67a0fbc4eccdf31d8eb36a6129ecc Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 2 Oct 2023 20:38:09 -0400 Subject: [PATCH 12/21] add camel methods to api --- docs/modules/ROOT/pages/api/account.adoc | 42 +++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/api/account.adoc b/docs/modules/ROOT/pages/api/account.adoc index 8df773a61..0beec5335 100644 --- a/docs/modules/ROOT/pages/api/account.adoc +++ b/docs/modules/ROOT/pages/api/account.adoc @@ -67,6 +67,7 @@ Returns the short string `'VALID'` if valid, otherwise it reverts. :OwnerAdded: xref:Account-OwnerAdded[OwnerAdded] :OwnerRemoved: xref:Account-OwnerRemoved[OwnerRemoved] +:dual-interfaces: xref:interfaces.adoc#dual_interfaces[dual interfaces] ```javascript use openzeppelin::account::Account; @@ -96,10 +97,17 @@ Account contract implementation extending xref:ISRC6[`ISRC6`]. * xref:#Account-\\__validate_declare__[`++__validate_declare__(self, class_hash)++`] -.Non-standardImpl +.Non-standard * xref:#Account-\\__validate_deploy__[`++__validate_deploy__(self, hash, signature)++`] * xref:#Account-set_public_key[`++set_public_key(self, new_public_key)++`] * xref:#Account-get_public_key[`++get_public_key(self)++`] + +.camelcase-support + +* xref:#Account-isValidSignature[`++isValidSignature(self, hash, signature)++`] +* xref:#Account-supportsInterface[`++supportsInterface(self, interfaceId)++`] +* xref:#Account-setPublicKey[`++setPublicKey(self, newPublicKey)++`] +* xref:#Account-getPublicKey[`++getPublicKey(self)++`] -- [.contract-index] @@ -190,6 +198,38 @@ Emits both an {OwnerRemoved} and an {OwnerAdded} event. Returns the current public key of the account. +[.contract-item] +[[Account-isValidSignature]] +==== `[.contract-item-name]#++is_ValidSignature++#++(self: @ContractState, hash: felt252, signature: Array) → felt252++` [.item-kind]#external# + +See xref:ISRC6-is_valid_signature[ISRC6::is_valid_signature]. + +Supports the Cairo v0 convention of writing external methods in camelCase as mentioned in {dual-interfaces}. + +[.contract-item] +[[Account-supportsInterface]] +==== `[.contract-item-name]#++supportsInterface++#++(self: @ContractState, interfaceId: felt252) → bool++` [.item-kind]#external# + +See xref:api/introspection.adoc#ISRC5-supports_interface[ISRC5::supports_interface]. + +Supports the Cairo v0 convention of writing external methods in camelCase as mentioned in {dual-interfaces}. + +[.contract-item] +[[Account-setPublicKey]] +==== `[.contract-item-name]#++setPublicKey++#++(ref self: ContractState, newPublicKey: felt252)++` [.item-kind]#external# + +See xref:Account-set_public_key[Account::set_public_key]. + +Supports the Cairo v0 convention of writing external methods in camelCase as mentioned in {dual-interfaces}. + +[.contract-item] +[[Account-getPublicKey]] +==== `[.contract-item-name]#++getPublicKey++#++(self: @ContractState)++ → felt252` [.item-kind]#external# + +See xref:Account-get_public_key[Account::get_public_key]. + +Supports the Cairo v0 convention of writing external methods in camelCase as mentioned in {dual-interfaces}. + [#Account-Internal-Functions] ==== Internal Functions From 74d053cea3b20b646708b895c36d49e50a1f254a Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 3 Oct 2023 12:37:43 -0400 Subject: [PATCH 13/21] remove imports --- src/account/interface.cairo | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/account/interface.cairo b/src/account/interface.cairo index e60a59153..515bdc92a 100644 --- a/src/account/interface.cairo +++ b/src/account/interface.cairo @@ -1,8 +1,6 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts for Cairo v0.7.0 (account/interface.cairo) -use array::ArrayTrait; -use array::SpanTrait; use starknet::ContractAddress; use starknet::account::Call; From e11811a5410a2eb0db070c8db7d42253814e24be Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 3 Oct 2023 12:42:17 -0400 Subject: [PATCH 14/21] re-add src5_state --- src/account/account.cairo | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/account/account.cairo b/src/account/account.cairo index b085c99ac..da0631f19 100644 --- a/src/account/account.cairo +++ b/src/account/account.cairo @@ -103,8 +103,7 @@ mod Account { #[external(v0)] impl SRC5Impl of ISRC5 { fn supports_interface(self: @ContractState, interface_id: felt252) -> bool { - let unsafe_state = SRC5::unsafe_new_contract_state(); - SRC5::SRC5Impl::supports_interface(@unsafe_state, interface_id) + SRC5::SRC5Impl::supports_interface(@src5_state(), interface_id) } } @@ -150,8 +149,7 @@ mod Account { #[external(v0)] impl SRC5CamelImpl of ISRC5Camel { fn supportsInterface(self: @ContractState, interfaceId: felt252) -> bool { - let unsafe_state = SRC5::unsafe_new_contract_state(); - SRC5::SRC5CamelImpl::supportsInterface(@unsafe_state, interfaceId) + SRC5::SRC5CamelImpl::supportsInterface(@src5_state(), interfaceId) } } @@ -173,7 +171,7 @@ mod Account { #[generate_trait] impl InternalImpl of InternalTrait { fn initializer(ref self: ContractState, _public_key: felt252) { - let mut unsafe_state = SRC5::unsafe_new_contract_state(); + let mut unsafe_state = src5_state(); SRC5::InternalImpl::register_interface(ref unsafe_state, interface::ISRC6_ID); self._set_public_key(_public_key); } From 25b2dd8def963a86abf7b05c7663c71a250638fc Mon Sep 17 00:00:00 2001 From: Andrew Fleming Date: Fri, 6 Oct 2023 13:21:30 -0400 Subject: [PATCH 15/21] Apply suggestions from code review Co-authored-by: Eric Nordelo --- docs/modules/ROOT/pages/api/account.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/api/account.adoc b/docs/modules/ROOT/pages/api/account.adoc index 0beec5335..0b4e4d43c 100644 --- a/docs/modules/ROOT/pages/api/account.adoc +++ b/docs/modules/ROOT/pages/api/account.adoc @@ -102,7 +102,7 @@ Account contract implementation extending xref:ISRC6[`ISRC6`]. * xref:#Account-set_public_key[`++set_public_key(self, new_public_key)++`] * xref:#Account-get_public_key[`++get_public_key(self)++`] -.camelcase-support +.camelCase-support * xref:#Account-isValidSignature[`++isValidSignature(self, hash, signature)++`] * xref:#Account-supportsInterface[`++supportsInterface(self, interfaceId)++`] From 05c7936f5f75e3bc6405b9c400742d1ce85917ce Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 9 Oct 2023 18:50:32 -0400 Subject: [PATCH 16/21] add deployer trait/impl --- src/account/account.cairo | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/account/account.cairo b/src/account/account.cairo index da0631f19..d0653a232 100644 --- a/src/account/account.cairo +++ b/src/account/account.cairo @@ -11,6 +11,12 @@ trait PublicKeyCamelTrait { fn getPublicKey(self: @TState) -> felt252; } +trait DeployerTrait { + fn __validate_deploy__( + self: @TState, class_hash: felt252, contract_address_salt: felt252, _public_key: felt252 + ) -> felt252; +} + #[starknet::contract] mod Account { use ecdsa::check_ecdsa_signature; @@ -115,13 +121,15 @@ mod Account { } #[external(v0)] - fn __validate_deploy__( - self: @ContractState, - class_hash: felt252, - contract_address_salt: felt252, - _public_key: felt252 - ) -> felt252 { - self.validate_transaction() + impl DeployerImpl of super::DeployerTrait { + fn __validate_deploy__( + self: @ContractState, + class_hash: felt252, + contract_address_salt: felt252, + _public_key: felt252 + ) -> felt252 { + self.validate_transaction() + } } #[external(v0)] From e1543545ffdeea9f8ed0c1168c3c5fa4c55c4c85 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 9 Oct 2023 18:51:16 -0400 Subject: [PATCH 17/21] change non-standard to impls in fn list --- docs/modules/ROOT/pages/api/account.adoc | 42 +++++++++++++++--------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/docs/modules/ROOT/pages/api/account.adoc b/docs/modules/ROOT/pages/api/account.adoc index 0b4e4d43c..108ae55c0 100644 --- a/docs/modules/ROOT/pages/api/account.adoc +++ b/docs/modules/ROOT/pages/api/account.adoc @@ -97,17 +97,27 @@ Account contract implementation extending xref:ISRC6[`ISRC6`]. * xref:#Account-\\__validate_declare__[`++__validate_declare__(self, class_hash)++`] -.Non-standard +.DeployerImpl + * xref:#Account-\\__validate_deploy__[`++__validate_deploy__(self, hash, signature)++`] -* xref:#Account-set_public_key[`++set_public_key(self, new_public_key)++`] + +.PublicKeyImpl + * xref:#Account-get_public_key[`++get_public_key(self)++`] +* xref:#Account-set_public_key[`++set_public_key(self, new_public_key)++`] -.camelCase-support +.SRC6CamelOnlyImpl * xref:#Account-isValidSignature[`++isValidSignature(self, hash, signature)++`] + +.SRC5CamelImpl + * xref:#Account-supportsInterface[`++supportsInterface(self, interfaceId)++`] -* xref:#Account-setPublicKey[`++setPublicKey(self, newPublicKey)++`] + +.PublicKeyCamelImpl + * xref:#Account-getPublicKey[`++getPublicKey(self)++`] +* xref:#Account-setPublicKey[`++setPublicKey(self, newPublicKey)++`] -- [.contract-index] @@ -184,6 +194,12 @@ See xref:/guides/deployment.adoc[Counterfactual deployments]. Returns the short string `'VALID'` if valid, otherwise it reverts. +[.contract-item] +[[Account-get_public_key]] +==== `[.contract-item-name]#++get_public_key++#++(self: @ContractState)++ → felt252` [.item-kind]#external# + +Returns the current public key of the account. + [.contract-item] [[Account-set_public_key]] ==== `[.contract-item-name]#++set_public_key++#++(ref self: ContractState, new_public_key: felt252)++` [.item-kind]#external# @@ -192,12 +208,6 @@ Sets a new public key for the account. Only accesible by the account calling its Emits both an {OwnerRemoved} and an {OwnerAdded} event. -[.contract-item] -[[Account-get_public_key]] -==== `[.contract-item-name]#++get_public_key++#++(self: @ContractState)++ → felt252` [.item-kind]#external# - -Returns the current public key of the account. - [.contract-item] [[Account-isValidSignature]] ==== `[.contract-item-name]#++is_ValidSignature++#++(self: @ContractState, hash: felt252, signature: Array) → felt252++` [.item-kind]#external# @@ -215,18 +225,18 @@ See xref:api/introspection.adoc#ISRC5-supports_interface[ISRC5::supports_interfa Supports the Cairo v0 convention of writing external methods in camelCase as mentioned in {dual-interfaces}. [.contract-item] -[[Account-setPublicKey]] -==== `[.contract-item-name]#++setPublicKey++#++(ref self: ContractState, newPublicKey: felt252)++` [.item-kind]#external# +[[Account-getPublicKey]] +==== `[.contract-item-name]#++getPublicKey++#++(self: @ContractState)++ → felt252` [.item-kind]#external# -See xref:Account-set_public_key[Account::set_public_key]. +See xref:Account-get_public_key[Account::get_public_key]. Supports the Cairo v0 convention of writing external methods in camelCase as mentioned in {dual-interfaces}. [.contract-item] -[[Account-getPublicKey]] -==== `[.contract-item-name]#++getPublicKey++#++(self: @ContractState)++ → felt252` [.item-kind]#external# +[[Account-setPublicKey]] +==== `[.contract-item-name]#++setPublicKey++#++(ref self: ContractState, newPublicKey: felt252)++` [.item-kind]#external# -See xref:Account-get_public_key[Account::get_public_key]. +See xref:Account-set_public_key[Account::set_public_key]. Supports the Cairo v0 convention of writing external methods in camelCase as mentioned in {dual-interfaces}. From f0a167347c6514572d5094f7ed2a2a22477a994b Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 9 Oct 2023 21:59:51 -0400 Subject: [PATCH 18/21] fix in-code doc style --- src/token/erc20/erc20.cairo | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/token/erc20/erc20.cairo b/src/token/erc20/erc20.cairo index fa66fde44..c846a2144 100644 --- a/src/token/erc20/erc20.cairo +++ b/src/token/erc20/erc20.cairo @@ -1,12 +1,12 @@ -//! SPDX-License-Identifier: MIT -//! OpenZeppelin Contracts for Cairo v0.7.0 (token/erc20/erc20.cairo) -//! -//! # ERC20 Contract and Implementation -//! -//! This ERC20 contract includes both a library and a basic preset implementation. -//! The library is agnostic regarding how tokens are created; however, -//! the preset implementation sets the initial supply in the constructor. -//! A derived contract can use [_mint](_mint) to create a different supply mechanism. +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts for Cairo v0.7.0 (token/erc20/erc20.cairo) + +/// # ERC20 Contract and Implementation +/// +/// This ERC20 contract includes both a library and a basic preset implementation. +/// The library is agnostic regarding how tokens are created; however, +/// the preset implementation sets the initial supply in the constructor. +/// A derived contract can use [_mint](_mint) to create a different supply mechanism. #[starknet::contract] mod ERC20 { use integer::BoundedInt; From 50038b49fac79a1405701fda53cd7fbf976c4a55 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 9 Oct 2023 22:29:04 -0400 Subject: [PATCH 19/21] fix comments --- src/account/interface.cairo | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/account/interface.cairo b/src/account/interface.cairo index 515bdc92a..66b2dffc0 100644 --- a/src/account/interface.cairo +++ b/src/account/interface.cairo @@ -40,17 +40,22 @@ trait AccountABI { // IDeclarer fn __validate_declare__(self: @TState, class_hash: felt252) -> felt252; - // Non-standard + // DeployerTrait fn __validate_deploy__( self: @TState, class_hash: felt252, contract_address_salt: felt252, _public_key: felt252 ) -> felt252; + + // PublicKeyTrait fn set_public_key(ref self: TState, new_public_key: felt252); fn get_public_key(self: @TState) -> felt252; - // Camel case compatibility - // See https://docs.openzeppelin.com/contracts-cairo/0.7.0/interfaces#dual_interfaces + // ISRC6CamelOnly fn isValidSignature(self: @TState, hash: felt252, signature: Array) -> felt252; + + // ISRC5Camel fn supportsInterface(self: @TState, interfaceId: felt252) -> bool; + + // PublicKeyCamelTrait fn setPublicKey(ref self: TState, newPublicKey: felt252); fn getPublicKey(self: @TState) -> felt252; } From f3cf6af363aedf1b8441c5ea6f2c9a19cf05f972 Mon Sep 17 00:00:00 2001 From: Andrew Date: Sun, 26 Nov 2023 20:38:17 -0500 Subject: [PATCH 20/21] fix interface order --- src/account/interface.cairo | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/account/interface.cairo b/src/account/interface.cairo index aedc05d5b..8b58f101b 100644 --- a/src/account/interface.cairo +++ b/src/account/interface.cairo @@ -13,11 +13,6 @@ trait ISRC6 { fn is_valid_signature(self: @TState, hash: felt252, signature: Array) -> felt252; } -#[starknet::interface] -trait ISRC6CamelOnly { - fn isValidSignature(self: @TState, hash: felt252, signature: Array) -> felt252; -} - #[starknet::interface] trait IDeclarer { fn __validate_declare__(self: @TState, class_hash: felt252) -> felt252; @@ -36,6 +31,11 @@ trait IPublicKey { fn set_public_key(ref self: TState, new_public_key: felt252); } +#[starknet::interface] +trait ISRC6CamelOnly { + fn isValidSignature(self: @TState, hash: felt252, signature: Array) -> felt252; +} + #[starknet::interface] trait IPublicKeyCamel { fn getPublicKey(self: @TState) -> felt252; From f9bb3136b5a59f940bbad95a8fec40f64e4ee9d8 Mon Sep 17 00:00:00 2001 From: Andrew Date: Sun, 26 Nov 2023 20:41:08 -0500 Subject: [PATCH 21/21] remove unused impl --- docs/modules/ROOT/pages/api/account.adoc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/modules/ROOT/pages/api/account.adoc b/docs/modules/ROOT/pages/api/account.adoc index 4479154bc..188846a12 100644 --- a/docs/modules/ROOT/pages/api/account.adoc +++ b/docs/modules/ROOT/pages/api/account.adoc @@ -92,10 +92,6 @@ NOTE: Implementing xref:api/introspection.adoc#SRC5Component[SRC5Component] is a * xref:#AccountComponent-\\__validate_deploy__[`++__validate_deploy__(self, hash, signature)++`] -.DeployerImpl - -* xref:#Account-\\__validate_deploy__[`++__validate_deploy__(self, hash, signature)++`] - .PublicKeyImpl * xref:#AccountComponent-get_public_key[`++get_public_key(self)++`]