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

Migrate SRC5 to component #767

Merged
Merged
Show file tree
Hide file tree
Changes from 107 commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
331844d
fix: link (#545)
ericnordelo Jan 20, 2023
b9ec20b
add submodule
andrew-fleming Feb 18, 2023
bb40124
update cairo
andrew-fleming Feb 18, 2023
a0c3157
add Cargo and Makefile
andrew-fleming Feb 18, 2023
3a6e20d
update cairo
andrew-fleming Feb 18, 2023
96431de
add deps in cairo_project, create lib
andrew-fleming Feb 18, 2023
7b38706
add presets
andrew-fleming Feb 18, 2023
2fa00dd
add base lib
andrew-fleming Feb 18, 2023
f0036e7
add tests
andrew-fleming Feb 18, 2023
8d781a8
remove old cairo lib and interface
andrew-fleming Feb 18, 2023
ae37b1c
remove unused import
andrew-fleming Feb 18, 2023
da57a91
fix vars
andrew-fleming Feb 18, 2023
fd42fdd
change external funcs to snake case
andrew-fleming Feb 18, 2023
1cb1252
remove unused import
andrew-fleming Feb 18, 2023
f0330cd
update cairo
andrew-fleming Feb 21, 2023
abc737a
add tests for externals
andrew-fleming Feb 21, 2023
4ca2620
add bool assertions
andrew-fleming Feb 21, 2023
8dd8ed3
update cairo
andrew-fleming Feb 22, 2023
091a29c
remove preset mods
andrew-fleming Feb 22, 2023
1c866f2
add IERC20 trait
andrew-fleming Feb 22, 2023
3405063
update cairo
andrew-fleming Feb 22, 2023
8fe3c82
clean up test
andrew-fleming Feb 22, 2023
ad928bc
remove assertion
andrew-fleming Feb 23, 2023
d883eb5
update cairo
andrew-fleming Feb 23, 2023
543501b
simplify max_u256
andrew-fleming Feb 23, 2023
2ecba91
clarify error msg
andrew-fleming Feb 23, 2023
6c3978b
add erc165 + tests
martriay Mar 3, 2023
60365c8
kickstart account module
martriay Mar 3, 2023
be1e9df
clean up python project. ready for rust/cairo1
martriay Mar 7, 2023
c20fd02
rebase to cairo-1
martriay Mar 7, 2023
bce2506
re-structure project
martriay Mar 7, 2023
35ede09
re-structure project
martriay Mar 8, 2023
e55889a
re-structure project
martriay Mar 8, 2023
9d5079c
update makefile
martriay Mar 8, 2023
ae89fa5
bump submodule
martriay Mar 8, 2023
a54e98c
Update erc20 migration branch (#586)
andrew-fleming Mar 28, 2023
91dcad3
Migrate security/initializable (#592)
andrew-fleming Mar 31, 2023
f48da2c
Use zeroable::zero() instead of contract_address_const::<0>() (#598)
Amxx Mar 31, 2023
d671d4c
Migrate security/pausable (#593)
andrew-fleming Mar 31, 2023
e86bcd2
add utils and constants
andrew-fleming Apr 18, 2023
42a160f
Revert "add utils and constants"
andrew-fleming Apr 18, 2023
598c232
Migrate ERC165 (#582)
martriay Apr 26, 2023
b2624ee
Migrate constants (#611)
andrew-fleming Apr 26, 2023
4a4bca9
Set up new CI (#599)
andrew-fleming Apr 27, 2023
0962051
fix formatting (#613)
andrew-fleming Apr 28, 2023
a1950ee
Normalize error message style (#606)
andrew-fleming Apr 28, 2023
c29b45c
Add `BoundedInt` and internal macros, update cairo (#600)
andrew-fleming Apr 28, 2023
e48a682
Migrate ownable (#604)
andrew-fleming May 11, 2023
5f86f65
Migrate security/reentrancyguard (#590)
andrew-fleming May 19, 2023
897facb
Migrate access control (#605)
andrew-fleming May 19, 2023
372de37
Migrate account (#620)
andrew-fleming May 23, 2023
d86eb73
Migrate ERC721 (#619)
martriay May 30, 2023
62688e7
Dual interface dispatcher for ERC721 (#623)
martriay Jul 2, 2023
ba69328
Replace ERC-165 with SRC-5 (Update Interface Ids) (#637)
ericnordelo Jul 2, 2023
8534ec6
Fix conflicts from the dual721 and src5 merge (#641)
andrew-fleming Jul 3, 2023
bc90bd5
Add camel support for ownable (#625)
andrew-fleming Jul 3, 2023
c8fa9f9
Add camel support for access control (#626)
andrew-fleming Jul 5, 2023
3a8e3e7
erc20 dual dispatcher (#622)
andrew-fleming Jul 5, 2023
6a1f729
Add `UnwrapAndCast` trait (#644)
andrew-fleming Jul 6, 2023
bbcb875
add test_dual721 mod (#648)
andrew-fleming Jul 8, 2023
5a27baa
Update account interface (#646)
ericnordelo Jul 10, 2023
ba29133
Add camel support for Account (#647)
ericnordelo Jul 12, 2023
b44f7dc
Add src5 dual dispatcher (#659)
andrew-fleming Jul 12, 2023
33dbd56
Add dual case erc721 receiver (#649)
andrew-fleming Jul 13, 2023
65d03ae
Add owner param to ownable initializer (#660)
ericnordelo Jul 13, 2023
a863859
Migrate SRC5 to Cairo 2 (#664)
ericnordelo Jul 18, 2023
c4590b9
Migrate initializable to cairo2 (#661)
andrew-fleming Jul 18, 2023
f18fcdb
Migrate Account to Cairo 2 (#666)
ericnordelo Jul 20, 2023
dc4a233
Migrate pausable to cairo2 (#662)
andrew-fleming Jul 20, 2023
27514b1
Migrate reentrancyguard to cairo2 (#663)
andrew-fleming Jul 20, 2023
8e10821
Migrate ERC721 to Cairo2 (#667)
ericnordelo Jul 21, 2023
a00a9d3
Migrate ownable to cairo2 (#665)
andrew-fleming Jul 21, 2023
0b40485
Migrate ERC20 to Cairo 2 (#669)
ericnordelo Jul 22, 2023
4e64434
Migrate access control to cairo2 (#668)
andrew-fleming Jul 22, 2023
79fe2db
Migrate to Scarb for cairo-2 (#671)
maciektr Aug 4, 2023
177ad63
Add spdx (#684)
andrew-fleming Aug 4, 2023
495ed8a
feat: sort imports (#679)
ericnordelo Aug 4, 2023
c28c758
Migrate upgrades (#603)
andrew-fleming Aug 10, 2023
f9c30da
Add testing for Ownable events (#675)
ericnordelo Aug 11, 2023
457b98b
Add account events (#687)
andrew-fleming Aug 11, 2023
544ddac
Add testing for AccessControl events (#674)
ericnordelo Aug 15, 2023
4473243
Add testing for Pausable events (#676)
ericnordelo Aug 15, 2023
e95def8
Add testing for ERC20 events (#677)
ericnordelo Aug 15, 2023
77089c1
Add mint to erc721 preset constructor (#700)
andrew-fleming Aug 15, 2023
3e08fa6
Add testing for ERC721 events (#678)
ericnordelo Aug 16, 2023
8307644
Update README and fix scarb package (#688)
martriay Aug 18, 2023
cece32b
Bump scarb and fix dual721 test context (#703)
andrew-fleming Aug 23, 2023
32f9974
add rc version (#708)
martriay Aug 23, 2023
b40c35b
remove unused imports (#707)
andrew-fleming Aug 23, 2023
fbdd759
Upgrade Cairo version and Scarb version to latest releases (#712)
bal7hazar Aug 24, 2023
05429e4
bump antora (#715)
martriay Aug 28, 2023
adac09f
Add selector inline macro/fix `tokenURI` (#724)
andrew-fleming Sep 8, 2023
90be39f
fix: naming convention (#732)
ericnordelo Sep 14, 2023
fcdd6d1
feat: add Errors modules (#691)
ericnordelo Sep 14, 2023
7373daa
Update account docs (#709)
ericnordelo Sep 15, 2023
cbb5bf5
Add Interface & Dispatchers docs (#730)
martriay Sep 20, 2023
4e388f5
Update overview docs (#735)
ericnordelo Sep 20, 2023
a1b559c
remove underscore from name_ and symbol_ (#738)
andrew-fleming Sep 21, 2023
74eb4e8
Add prefixes to storage members (#743)
ericnordelo Sep 26, 2023
420f320
Sanitizing for release. (#736)
ericnordelo Sep 27, 2023
715e473
feat: update logic
ericnordelo Sep 28, 2023
f1241b5
Merge branch 'main' of github.com:OpenZeppelin/cairo-contracts into f…
ericnordelo Oct 2, 2023
9a274be
feat: apply review updates
ericnordelo Oct 5, 2023
4d116ad
Merge branch 'main' of github.com:OpenZeppelin/cairo-contracts into f…
ericnordelo Oct 5, 2023
f0d8c6f
feat: remove unnecesary imports
ericnordelo Oct 5, 2023
cb5b828
feat: add in-code comments
ericnordelo Oct 5, 2023
09c47ad
feat: apply review updates
ericnordelo Oct 6, 2023
ec68494
Update docs/modules/ROOT/pages/introspection.adoc
ericnordelo Oct 6, 2023
8870cfe
Update src/introspection/src5.cairo
ericnordelo Oct 6, 2023
748e725
feat: apply review updates
ericnordelo Oct 6, 2023
4d86b18
Merge branch 'feat/migrate-src5-to-component' of github.com:ericnorde…
ericnordelo Oct 6, 2023
fef31c2
feat: bump scarb
ericnordelo Oct 10, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@v3
- uses: software-mansion/setup-scarb@v1
with:
scarb-version: "0.7.0"
scarb-version: "2.3.0-rc0"
- name: Markdown lint
uses: DavidAnson/markdownlint-cli2-action@5b7c9f74fec47e6b15667b2cc23c63dff11e449e # v9
with:
Expand Down
7 changes: 5 additions & 2 deletions Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "openzeppelin"
version = "0.7.0"
cairo-version = "2.2.0"
cairo-version = "2.3.0-rc0"
authors = ["OpenZeppelin Community <maintainers@openzeppelin.org>"]
description = "OpenZeppelin Contracts written in Cairo for StarkNet, a decentralized ZK Rollup"
documentation = "https://docs.openzeppelin.com/contracts-cairo"
Expand All @@ -11,11 +11,14 @@ license-file = "LICENSE"
keywords = ["openzeppelin", "starknet", "cairo", "contracts", "security", "standards"]

[dependencies]
starknet = ">=2.2.0"
starknet = "=2.3.0-rc0"

[lib]

[[target.starknet-contract]]
allowed-libfuncs-list.name = "experimental"
sierra = true
casm = false

[tool.fmt]
sort-module-level-items = true
8 changes: 4 additions & 4 deletions docs/modules/ROOT/pages/api/introspection.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ on how to compute this ID.
use openzeppelin::introspection::src5::SRC5;
```

SRC5 contract implementation extending xref:ISRC5[`ISRC5`].
SRC5 component extending xref:ISRC5[`ISRC5`].

[.contract-index]
.External Functions
.Embeddable Implementations
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the Ownable API, the index name is Embeddable Implementations Functions. We should normalize

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's stick with just Embeddable Implementations then if you agree.

--
.SRC5Impl

Expand All @@ -69,8 +69,8 @@ SRC5 contract implementation extending xref:ISRC5[`ISRC5`].
* xref:#SRC5-deregister_interface[`++deregister_interface(self, interface_id)++`]
--

[#SRC5-External-Functions]
==== External Functions
[#SRC5-Embeddable-Implementations-Functions]
==== Embeddable Implementations Functions
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we change the self type in the functions below to ComponentState<TContractState>?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about leaving just ComponentState? I think the generic TState is implicit since TContractState is always required, and this will appear frequently in the APIs.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, and it's much less noisy. +1

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think we should leave just ContractState, because the embeddable implementation generated when you use embeddable_as is the one having just ContractState, like this:

#[starknet::embeddable]
impl SRC5Impl<
            TContractState, +HasComponent<TContractState>
, impl TContractStateDrop: Drop<TContractState>
> of interface::ISRC5<TContractState> {
    
    fn supports_interface(self: @TContractState, interface_id: felt252
) -> bool {
        let component = HasComponent::get_component(self);
        SRC5::supports_interface(component, interface_id, )
    }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The impl we embed is not the one we write in the component, but the one the compiler generates from the embeddable_as attribute. And this is the one the user would usually use. Is different for InternalImpl though, because this doesn't use embeddable_as. For this one I think we should use ComponentState.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm if we go that route, should we include a NOTE or something to explain the rationale behind using ContractState for embeddables and ComponentState for internals? IMO it'd be weird to not say anything about it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it can be confusing, but where can we add such note? It seems we would need to add it to every component API

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repeating the same note is definitely not ideal. Even though this is about reading the API, it's IMO more about understanding the component architecture (as you described above). Maybe this can be addressed in the Extensibility doc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, let's stick with ContractState for embeddable impls functions, and ComponentState for InternalImpl in components, at least until we revisit how we present this in the Extensibility PR. wdyt?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the title: Embeddable Implementations Functions, it reads kind of awkward. This is nitpicky, I know. I don't have a good alternative, just throwing it out there

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call it just Embeddable Functions in the meantime (I think it reads better). Any suggestion is more than welcome.


[.contract-item]
[[SRC5-supports_interface]]
Expand Down
28 changes: 20 additions & 8 deletions docs/modules/ROOT/pages/introspection.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,37 @@ extended function selectors. There are tools such as {src5-rs} that can help wit

=== Registering interfaces

For a contract to declare its support for a given interface, the contract should import the SRC5 module and
register its support. It's recommended to register interface support upon contract deployment through a constructor
either directly or indirectly (as an initializer) like this:
For a contract to declare its support for a given interface, we recommend using the the SRC5 component to do it upon contract deployment through a constructor either directly or indirectly (as an initializer) like this:
ericnordelo marked this conversation as resolved.
Show resolved Hide resolved

[,javascript]
----
#[starknet::contract]
mod MyContract {
use openzeppelin::account::interface;
use openzeppelin::introspection::src5::SRC5;
use openzeppelin::introspection::src5::SRC5 as src5_component;

component!(path: src5_component, storage: src5, event: SRC5Event);

#[abi(embed_v0)]
impl SRC5Impl = src5_component::SRC5Impl<ContractState>;
impl InternalImpl = src5_component::InternalImpl<ContractState>;

#[storage]
struct Storage {}
struct Storage {
#[substorage(v0)]
src5: src5_component::Storage
}

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
SRC5Event: src5_component::Event
}

#[constructor]
fn constructor(ref self: ContractState) {
let mut unsafe_state = SRC5::unsafe_new_contract_state();
SRC5::InternalImpl::register_interface(ref unsafe_state, interface::ISRC6_ID);
// Register the contract's support for the ISRC6 interface
self.src5.register_interface(interface::ISRC6_ID);
}

(...)
Expand All @@ -70,7 +83,6 @@ mod MyContract {
use openzeppelin::account::interface;
use openzeppelin::introspection::interface::ISRC5DispatcherTrait;
use openzeppelin::introspection::interface::ISRC5Dispatcher;
use openzeppelin::introspection::src5::SRC5;
use starknet::ContractAddress;

#[storage]
Expand Down
33 changes: 13 additions & 20 deletions src/access/accesscontrol/accesscontrol.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,24 @@
#[starknet::contract]
mod AccessControl {
use openzeppelin::access::accesscontrol::interface;
use openzeppelin::introspection::interface::ISRC5;
use openzeppelin::introspection::interface::ISRC5Camel;
use openzeppelin::introspection::src5::SRC5;
use openzeppelin::introspection::src5::unsafe_state as src5_state;
use openzeppelin::introspection::src5::SRC5 as src5_component;
use starknet::ContractAddress;
use starknet::get_caller_address;

component!(path: src5_component, storage: src5, event: SRC5Event);

#[abi(embed_v0)]
impl SRC5Impl = src5_component::SRC5Impl<ContractState>;
#[abi(embed_v0)]
impl SRC5CamelImpl = src5_component::SRC5CamelImpl<ContractState>;
impl SRC5InternalImpl = src5_component::InternalImpl<ContractState>;

#[storage]
struct Storage {
AccessControl_role_admin: LegacyMap<felt252, felt252>,
AccessControl_role_member: LegacyMap<(felt252, ContractAddress), bool>,
#[substorage(v0)]
src5: src5_component::Storage
}

#[event]
Expand All @@ -23,6 +30,7 @@ mod AccessControl {
RoleGranted: RoleGranted,
RoleRevoked: RoleRevoked,
RoleAdminChanged: RoleAdminChanged,
SRC5Event: src5_component::Event
}

/// Emitted when `account` is granted `role`.
Expand Down Expand Up @@ -64,20 +72,6 @@ mod AccessControl {
const MISSING_ROLE: felt252 = 'Caller is missing role';
}

#[external(v0)]
impl SRC5Impl of ISRC5<ContractState> {
fn supports_interface(self: @ContractState, interface_id: felt252) -> bool {
SRC5::SRC5Impl::supports_interface(@src5_state(), interface_id)
}
}

#[external(v0)]
impl SRC5CamelImpl of ISRC5Camel<ContractState> {
fn supportsInterface(self: @ContractState, interfaceId: felt252) -> bool {
SRC5::SRC5CamelImpl::supportsInterface(@src5_state(), interfaceId)
}
}

#[external(v0)]
impl AccessControlImpl of interface::IAccessControl<ContractState> {
fn has_role(self: @ContractState, role: felt252, account: ContractAddress) -> bool {
Expand Down Expand Up @@ -137,8 +131,7 @@ mod AccessControl {
#[generate_trait]
impl InternalImpl of InternalTrait {
fn initializer(ref self: ContractState) {
let mut unsafe_state = src5_state();
SRC5::InternalImpl::register_interface(ref unsafe_state, interface::IACCESSCONTROL_ID);
self.src5.register_interface(interface::IACCESSCONTROL_ID);
}

fn assert_only_role(self: @ContractState, role: felt252) {
Expand Down
43 changes: 15 additions & 28 deletions src/account/account.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,8 @@ trait PublicKeyCamelTrait<TState> {
#[starknet::contract]
mod Account {
use ecdsa::check_ecdsa_signature;

use openzeppelin::account::interface;
use openzeppelin::introspection::interface::ISRC5;
use openzeppelin::introspection::interface::ISRC5Camel;
use openzeppelin::introspection::src5::SRC5;
use openzeppelin::introspection::src5::unsafe_state as src5_state;
use openzeppelin::introspection::src5::SRC5 as src5_component;
use starknet::account::Call;
use starknet::get_caller_address;
use starknet::get_contract_address;
Expand All @@ -29,16 +25,27 @@ mod Account {
// 2**128 + TRANSACTION_VERSION
const QUERY_VERSION: felt252 = 0x100000000000000000000000000000001;

component!(path: src5_component, storage: src5, event: SRC5Event);

#[abi(embed_v0)]
impl SRC5Impl = src5_component::SRC5Impl<ContractState>;
#[abi(embed_v0)]
impl SRC5CamelImpl = src5_component::SRC5CamelImpl<ContractState>;
impl SRC5InternalImpl = src5_component::InternalImpl<ContractState>;

#[storage]
struct Storage {
Account_public_key: felt252
Account_public_key: felt252,
#[substorage(v0)]
src5: src5_component::Storage
}

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
OwnerAdded: OwnerAdded,
OwnerRemoved: OwnerRemoved,
SRC5Event: src5_component::Event
}

#[derive(Drop, starknet::Event)]
Expand Down Expand Up @@ -116,20 +123,6 @@ mod Account {
}
}

#[external(v0)]
impl SRC5Impl of ISRC5<ContractState> {
fn supports_interface(self: @ContractState, interface_id: felt252) -> bool {
SRC5::SRC5Impl::supports_interface(@src5_state(), interface_id)
}
}

#[external(v0)]
impl SRC5CamelImpl of ISRC5Camel<ContractState> {
fn supportsInterface(self: @ContractState, interfaceId: felt252) -> bool {
SRC5::SRC5CamelImpl::supportsInterface(@src5_state(), interfaceId)
}
}

#[external(v0)]
impl PublicKeyImpl of super::PublicKeyTrait<ContractState> {
fn get_public_key(self: @ContractState) -> felt252 {
Expand Down Expand Up @@ -171,8 +164,7 @@ mod Account {
#[generate_trait]
impl InternalImpl of InternalTrait {
fn initializer(ref self: ContractState, _public_key: felt252) {
let mut unsafe_state = src5_state();
SRC5::InternalImpl::register_interface(ref unsafe_state, interface::ISRC6_ID);
self.src5.register_interface(interface::ISRC6_ID);
self._set_public_key(_public_key);
}

Expand Down Expand Up @@ -204,14 +196,12 @@ mod Account {
}
}

#[internal]
fn assert_only_self() {
let caller = get_caller_address();
let self = get_contract_address();
assert(self == caller, Errors::UNAUTHORIZED);
}

#[private]
fn _execute_calls(mut calls: Array<Call>) -> Array<Span<felt252>> {
let mut res = ArrayTrait::new();
loop {
Expand All @@ -220,15 +210,12 @@ mod Account {
let _res = _execute_single_call(call);
res.append(_res);
},
Option::None(_) => {
break ();
},
Option::None(_) => { break (); },
};
};
res
}

#[private]
fn _execute_single_call(call: Call) -> Span<felt252> {
let Call{to, selector, calldata } = call;
starknet::call_contract_syscall(to, selector, calldata.span()).unwrap()
Expand Down
43 changes: 26 additions & 17 deletions src/introspection/src5.cairo
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts for Cairo v0.7.0 (introspection/src5.cairo)

#[starknet::contract]
///
/// # SRC5 Component
///
/// The SRC5 component allows contracts to expose the interfaces they implement.
ericnordelo marked this conversation as resolved.
Show resolved Hide resolved
#[starknet::component]
mod SRC5 {
use openzeppelin::introspection::interface;

Expand All @@ -14,37 +17,43 @@ mod SRC5 {
const INVALID_ID: felt252 = 'SRC5: invalid id';
}

#[external(v0)]
impl SRC5Impl of interface::ISRC5<ContractState> {
fn supports_interface(self: @ContractState, interface_id: felt252) -> bool {
#[embeddable_as(SRC5Impl)]
impl SRC5<
TContractState, +HasComponent<TContractState>
> of interface::ISRC5<ComponentState<TContractState>> {
/// Returns whether the contract implements the given interface.
fn supports_interface(
self: @ComponentState<TContractState>, interface_id: felt252
) -> bool {
if interface_id == interface::ISRC5_ID {
return true;
}
self.SRC5_supported_interfaces.read(interface_id)
}
}

#[external(v0)]
impl SRC5CamelImpl of interface::ISRC5Camel<ContractState> {
fn supportsInterface(self: @ContractState, interfaceId: felt252) -> bool {
SRC5Impl::supports_interface(self, interfaceId)
#[embeddable_as(SRC5CamelImpl)]
impl SRC5Camel<
TContractState, +HasComponent<TContractState>
> of interface::ISRC5Camel<ComponentState<TContractState>> {
fn supportsInterface(self: @ComponentState<TContractState>, interfaceId: felt252) -> bool {
self.supports_interface(interfaceId)
ericnordelo marked this conversation as resolved.
Show resolved Hide resolved
}
}

#[generate_trait]
impl InternalImpl of InternalTrait {
fn register_interface(ref self: ContractState, interface_id: felt252) {
impl InternalImpl<
TContractState, +HasComponent<TContractState>
> of InternalTrait<TContractState> {
/// Registers the given interface as supported by the contract.
fn register_interface(ref self: ComponentState<TContractState>, interface_id: felt252) {
self.SRC5_supported_interfaces.write(interface_id, true);
}

fn deregister_interface(ref self: ContractState, interface_id: felt252) {
/// Deregisters the given interface as supported by the contract.
fn deregister_interface(ref self: ComponentState<TContractState>, interface_id: felt252) {
assert(interface_id != interface::ISRC5_ID, Errors::INVALID_ID);
self.SRC5_supported_interfaces.write(interface_id, false);
}
}
}

#[inline(always)]
fn unsafe_state() -> SRC5::ContractState {
SRC5::unsafe_new_contract_state()
}
5 changes: 2 additions & 3 deletions src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ mod access;
mod account;
mod introspection;
mod security;
#[cfg(test)]
mod tests;
mod token;
mod upgrades;
mod utils;

#[cfg(test)]
mod tests;
16 changes: 8 additions & 8 deletions src/tests/access/test_dual_accesscontrol.cairo
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use openzeppelin::access::accesscontrol::DEFAULT_ADMIN_ROLE;
use openzeppelin::access::accesscontrol::dual_accesscontrol::DualCaseAccessControl;
use openzeppelin::access::accesscontrol::dual_accesscontrol::DualCaseAccessControlTrait;
use openzeppelin::access::accesscontrol::interface::IACCESSCONTROL_ID;
use openzeppelin::access::accesscontrol::interface::IAccessControlDispatcherTrait;
use openzeppelin::access::accesscontrol::interface::IAccessControlDispatcher;
use openzeppelin::access::accesscontrol::interface::IAccessControlCamelDispatcherTrait;
use openzeppelin::access::accesscontrol::interface::IAccessControlCamelDispatcher;
use openzeppelin::access::accesscontrol::dual_accesscontrol::DualCaseAccessControlTrait;
use openzeppelin::access::accesscontrol::dual_accesscontrol::DualCaseAccessControl;
use openzeppelin::tests::mocks::snake_accesscontrol_mock::SnakeAccessControlMock;
use openzeppelin::tests::mocks::camel_accesscontrol_mock::CamelAccessControlMock;
use openzeppelin::tests::mocks::accesscontrol_panic_mock::SnakeAccessControlPanicMock;
use openzeppelin::access::accesscontrol::interface::IAccessControlCamelDispatcherTrait;
use openzeppelin::access::accesscontrol::interface::IAccessControlDispatcher;
use openzeppelin::access::accesscontrol::interface::IAccessControlDispatcherTrait;
use openzeppelin::tests::mocks::accesscontrol_panic_mock::CamelAccessControlPanicMock;
use openzeppelin::tests::mocks::accesscontrol_panic_mock::SnakeAccessControlPanicMock;
use openzeppelin::tests::mocks::camel_accesscontrol_mock::CamelAccessControlMock;
use openzeppelin::tests::mocks::non_implementing_mock::NonImplementingMock;
use openzeppelin::tests::mocks::snake_accesscontrol_mock::SnakeAccessControlMock;
use openzeppelin::tests::utils::constants::{ADMIN, AUTHORIZED, ROLE};
use openzeppelin::tests::utils;
use openzeppelin::utils::serde::SerializedAppend;
Expand Down
Loading