diff --git a/Scarb.lock b/Scarb.lock index ecca394..7b026fb 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -58,9 +58,15 @@ name = "allo" version = "0.0.1" dependencies = [ "alexandria_math", + "openzeppelin", "snforge_std", ] +[[package]] +name = "openzeppelin" +version = "0.13.0" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.13.0#978b4e75209da355667d8954d2450e32bd71fe49" + [[package]] name = "snforge_std" version = "0.23.0" diff --git a/Scarb.toml b/Scarb.toml index a2e32df..a193836 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -6,6 +6,7 @@ edition = "2023_11" [dependencies] starknet = "2.6.3" alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git" } +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.13.0" } [dev-dependencies] snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.23.0" } diff --git a/src/core/libraries.cairo b/src/core/libraries.cairo index 47a2261..f77b474 100644 --- a/src/core/libraries.cairo +++ b/src/core/libraries.cairo @@ -1,2 +1,2 @@ mod clone; -mod errors; +pub mod errors; diff --git a/src/core/libraries/errors.cairo b/src/core/libraries/errors.cairo index d238fdf..447eccd 100644 --- a/src/core/libraries/errors.cairo +++ b/src/core/libraries/errors.cairo @@ -1,6 +1,6 @@ use starknet::{ContractAddress, contract_address_const}; -mod Errors { +pub mod Errors { /// Throws as an general error when input / data is invalid. const INVALID: felt252 = 'Data is invalid'; /// Thrown when mismatch in decoding data. @@ -10,7 +10,7 @@ mod Errors { /// Thrown when user is not authorized const UNAUTHORIZED: felt252 = 'Not authorized'; // // /// Thrown when address is the zero address - // const ZERO_ADDRESS : ContractAddress = contract_address_const::<'0'>(); + pub const ZERO_ADDRESS: felt252 = 'Address is Zero'; /// Thrown when the function is not implemented const NOT_IMPLEMENTED: felt252 = 'Not implemented'; /// Thrown when the value is non-zero diff --git a/src/core/registry.cairo b/src/core/registry.cairo index 5d7c7cd..ea497d6 100644 --- a/src/core/registry.cairo +++ b/src/core/registry.cairo @@ -26,27 +26,59 @@ pub trait IRegistry {} #[starknet::contract] pub mod Registry { use starknet::ContractAddress; + use core::poseidon::PoseidonTrait; + use core::hash::HashStateTrait; + use allo::core::libraries::errors::Errors; + use openzeppelin::access::accesscontrol::AccessControlComponent; + use openzeppelin::introspection::src5::SRC5Component; + + component!(path: SRC5Component, storage: SRC5_supported_interfaces, event: SRC5ComponentEvent); + + #[abi(embed_v0)] + impl SRC5Impl = SRC5Component::SRC5Impl; + + component!( + path: AccessControlComponent, storage: accessControl, event: AccessControlComponentEvent + ); + + #[abi(embed_v0)] + impl AccessControlComponentImpl = + AccessControlComponent::AccessControlImpl; + impl AccessControlComponentInternalImpl = AccessControlComponent::InternalImpl; + // ========================== // === Storage Variables ==== // ========================== #[storage] - struct Storage {} + struct Storage { + #[substorage(v0)] + SRC5_supported_interfaces: SRC5Component::Storage, + #[substorage(v0)] + accessControl: AccessControlComponent::Storage, + } /// ====================== /// ======= Events ======= /// ====================== #[event] #[derive(Drop, starknet::Event)] - enum Event {} + enum Event { + #[flat] + SRC5ComponentEvent: SRC5Component::Event, + #[flat] + AccessControlComponentEvent: AccessControlComponent::Event, + } #[constructor] - fn constructor(ref self: ContractState) { // Issue no #19 - // https://github.com/allo-protocol/allo-v2/blob/4dd0ea34a504a16ac90e80f49a5570b8be9b30e9/contracts/core/Registry.sol#L78C40-L79C9 - // Implement the functionality of making sure the address is not zero and - // grant the Allo owner role to the owner. - // You can use the posiedon hashing for hasing storing Allo owner + fn constructor(ref self: ContractState, _owner: ContractAddress) { + assert(_owner.into() == 0, Errors::ZERO_ADDRESS); + + let allo_owner_role = PoseidonTrait::new().update('ALLO_OWNER').finalize(); + + self.accessControl.initializer(); + self.accessControl._grant_role(allo_owner_role, _owner) }