Skip to content
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
1 change: 1 addition & 0 deletions packages/testing/src/constants.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub const APP_ROLE_ADMIN: ContractAddress = 'APP_ROLE_ADMIN'.try_into().unwrap()
pub const APP_GOVERNOR: ContractAddress = 'APP_GOVERNOR'.try_into().unwrap();
pub const OPERATOR: ContractAddress = 'OPERATOR'.try_into().unwrap();
pub const TOKEN_ADMIN: ContractAddress = 'TOKEN_ADMIN'.try_into().unwrap();
pub const UPGRADE_AGENT: ContractAddress = 'UPGRADE_AGENT'.try_into().unwrap();
pub const UPGRADE_GOVERNOR: ContractAddress = 'UPGRADE_GOVERNOR'.try_into().unwrap();
pub const SECURITY_AGENT: ContractAddress = 'SECURITY_AGENT'.try_into().unwrap();
pub const DUMMY_ADDRESS: ContractAddress = 'DUMMY_ADDRESS'.try_into().unwrap();
4 changes: 4 additions & 0 deletions packages/utils/src/components/roles/errors.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ pub enum AccessErrors {
ONLY_OPERATOR,
ONLY_TOKEN_ADMIN,
ONLY_UPGRADE_GOVERNOR,
ONLY_UPGRADER,
ONLY_SECURITY_ADMIN,
ONLY_SECURITY_AGENT,
ONLY_SECURITY_GOVERNOR,
ONLY_MINTER,
ONLY_SELF_CAN_RENOUNCE,
GOV_ADMIN_CANNOT_RENOUNCE,
Expand All @@ -33,8 +35,10 @@ impl DescribableError of Describable<AccessErrors> {
AccessErrors::ONLY_OPERATOR => "ONLY_OPERATOR",
AccessErrors::ONLY_TOKEN_ADMIN => "ONLY_TOKEN_ADMIN",
AccessErrors::ONLY_UPGRADE_GOVERNOR => "ONLY_UPGRADE_GOVERNOR",
AccessErrors::ONLY_UPGRADER => "ONLY_UPGRADER",
AccessErrors::ONLY_SECURITY_ADMIN => "ONLY_SECURITY_ADMIN",
AccessErrors::ONLY_SECURITY_AGENT => "ONLY_SECURITY_AGENT",
AccessErrors::ONLY_SECURITY_GOVERNOR => "ONLY_SECURITY_GOVERNOR",
AccessErrors::ONLY_MINTER => "MINTER_ONLY",
AccessErrors::ONLY_SELF_CAN_RENOUNCE => "ONLY_SELF_CAN_RENOUNCE",
AccessErrors::GOV_ADMIN_CANNOT_RENOUNCE => "GOV_ADMIN_CANNOT_SELF_REMOVE",
Expand Down
44 changes: 44 additions & 0 deletions packages/utils/src/components/roles/event_test_utils.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,50 @@ pub(crate) fn assert_upgrade_governor_added_event(
}
}

pub(crate) fn assert_upgrade_agent_added_event(
spied_event: @(ContractAddress, Event),
added_account: ContractAddress,
added_by: ContractAddress,
) {
let expected_event = @MockContract::Event::RolesEvent(
RolesEvent::UpgradeAgentAdded(
RolesInterface::UpgradeAgentAdded { added_account, added_by },
),
);
let (expected_emitted_by, raw_event) = spied_event;
let wrapped_spied_event = Events { events: array![(*expected_emitted_by, raw_event.clone())] };
let emitted = is_emitted(self: @wrapped_spied_event, :expected_emitted_by, :expected_event);
if !emitted {
let details = format!(
"UpgradeAgentAdded{{added_account: {:?}, added_by: {:?}}}", added_account, added_by,
);
panic_with_event_details(:expected_emitted_by, :details);
}
}

pub(crate) fn assert_upgrade_agent_removed_event(
spied_event: @(ContractAddress, Event),
removed_account: ContractAddress,
removed_by: ContractAddress,
) {
let expected_event = @MockContract::Event::RolesEvent(
RolesEvent::UpgradeAgentRemoved(
RolesInterface::UpgradeAgentRemoved { removed_account, removed_by },
),
);
let (expected_emitted_by, raw_event) = spied_event;
let wrapped_spied_event = Events { events: array![(*expected_emitted_by, raw_event.clone())] };
let emitted = is_emitted(self: @wrapped_spied_event, :expected_emitted_by, :expected_event);
if !emitted {
let details = format!(
"UpgradeAgentRemoved{{removed_account: {:?}, removed_by: {:?}}}",
removed_account,
removed_by,
);
panic_with_event_details(:expected_emitted_by, :details);
}
}

pub(crate) fn assert_upgrade_governor_removed_event(
spied_event: @(ContractAddress, Event),
removed_account: ContractAddress,
Expand Down
42 changes: 42 additions & 0 deletions packages/utils/src/components/roles/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ pub type RoleId = felt252;
// ----------------------------------------
// GOVERNANCE_ADMIN | GOVERNANCE_ADMIN
// UPGRADE_GOVERNOR | GOVERNANCE_ADMIN
// UPGRADE_AGENT | APP_ROLE_ADMIN
// APP_ROLE_ADMIN | GOVERNANCE_ADMIN
// APP_GOVERNOR | APP_ROLE_ADMIN
// OPERATOR | APP_ROLE_ADMIN
// TOKEN_ADMIN | APP_ROLE_ADMIN
// SECURITY_ADMIN | SECURITY_ADMIN
// SECURITY_AGENT | SECURITY_ADMIN.
// SECURITY_GOVERNOR | SECURITY_ADMIN.

// int.from_bytes(Web3.keccak(text="ROLE_APP_GOVERNOR"), "big") & MASK_250 .
pub const APP_GOVERNOR: RoleId = 0xd2ead78c620e94b02d0a996e99298c59ddccfa1d8a0149080ac3a20de06068;
Expand All @@ -29,6 +31,9 @@ pub const OPERATOR: RoleId = 0x023edb77f7c8cc9e38e8afe78954f703aeeda7fffe014eeb6
// int.from_bytes(Web3.keccak(text="ROLE_TOKEN_ADMIN"), "big") & MASK_250 .
pub const TOKEN_ADMIN: RoleId = 0x0128d63adbf6b09002c26caf55c47e2f26635807e3ef1b027218aa74c8d61a3e;

// int.from_bytes(Web3.keccak(text="ROLE_UPGRADE_AGENT"), "big") & MASK_250 .
pub const UPGRADE_AGENT: RoleId = 0x1d8034a6db21585e9d97ca912eb8113361e6858f64c45c9b321a4d01e949484;

// int.from_bytes(Web3.keccak(text="ROLE_UPGRADE_GOVERNOR"), "big") & MASK_250 .
pub const UPGRADE_GOVERNOR: RoleId =
0x251e864ca2a080f55bce5da2452e8cfcafdbc951a3e7fff5023d558452ec228;
Expand All @@ -41,16 +46,22 @@ pub const SECURITY_ADMIN: RoleId =
pub const SECURITY_AGENT: RoleId =
0x37693ba312785932d430dccf0f56ffedd0aa7c0f8b6da2cc4530c2717689b96;

// int.from_bytes(Web3.keccak(text="ROLE_SECURITY_GOVERNOR"), "big") & MASK_250 .
pub const SECURITY_GOVERNOR: RoleId =
0xa5a83e9807e87f281d865ab54b7b0ed2f7f4bbfef73888810ca16e95e734eb;

#[starknet::interface]
pub trait IRoles<TContractState> {
fn is_app_governor(self: @TContractState, account: ContractAddress) -> bool;
fn is_app_role_admin(self: @TContractState, account: ContractAddress) -> bool;
fn is_governance_admin(self: @TContractState, account: ContractAddress) -> bool;
fn is_operator(self: @TContractState, account: ContractAddress) -> bool;
fn is_token_admin(self: @TContractState, account: ContractAddress) -> bool;
fn is_upgrade_agent(self: @TContractState, account: ContractAddress) -> bool;
fn is_upgrade_governor(self: @TContractState, account: ContractAddress) -> bool;
fn is_security_admin(self: @TContractState, account: ContractAddress) -> bool;
fn is_security_agent(self: @TContractState, account: ContractAddress) -> bool;
fn is_security_governor(self: @TContractState, account: ContractAddress) -> bool;
fn register_app_governor(ref self: TContractState, account: ContractAddress);
fn remove_app_governor(ref self: TContractState, account: ContractAddress);
fn register_app_role_admin(ref self: TContractState, account: ContractAddress);
Expand All @@ -61,13 +72,17 @@ pub trait IRoles<TContractState> {
fn remove_operator(ref self: TContractState, account: ContractAddress);
fn register_token_admin(ref self: TContractState, account: ContractAddress);
fn remove_token_admin(ref self: TContractState, account: ContractAddress);
fn register_upgrade_agent(ref self: TContractState, account: ContractAddress);
fn remove_upgrade_agent(ref self: TContractState, account: ContractAddress);
fn register_upgrade_governor(ref self: TContractState, account: ContractAddress);
fn remove_upgrade_governor(ref self: TContractState, account: ContractAddress);
fn renounce(ref self: TContractState, role: RoleId);
fn register_security_admin(ref self: TContractState, account: ContractAddress);
fn remove_security_admin(ref self: TContractState, account: ContractAddress);
fn register_security_agent(ref self: TContractState, account: ContractAddress);
fn remove_security_agent(ref self: TContractState, account: ContractAddress);
fn register_security_governor(ref self: TContractState, account: ContractAddress);
fn remove_security_governor(ref self: TContractState, account: ContractAddress);
fn has_legacy_role(self: @TContractState, account: ContractAddress, role: RoleId) -> bool;
fn reclaim_legacy_roles(ref self: TContractState);
}
Expand All @@ -76,10 +91,13 @@ pub trait IRoles<TContractState> {
pub trait IMinimalRoles<TContractState> {
fn is_governance_admin(self: @TContractState, account: ContractAddress) -> bool;
fn is_upgrade_governor(self: @TContractState, account: ContractAddress) -> bool;
fn is_upgrade_agent(self: @TContractState, account: ContractAddress) -> bool;
fn register_governance_admin(ref self: TContractState, account: ContractAddress);
fn remove_governance_admin(ref self: TContractState, account: ContractAddress);
fn register_upgrade_governor(ref self: TContractState, account: ContractAddress);
fn remove_upgrade_governor(ref self: TContractState, account: ContractAddress);
fn register_upgrade_agent(ref self: TContractState, account: ContractAddress);
fn remove_upgrade_agent(ref self: TContractState, account: ContractAddress);
fn renounce(ref self: TContractState, role: RoleId);
}

Expand Down Expand Up @@ -136,6 +154,18 @@ pub(crate) struct SecurityAgentRemoved {
pub removed_by: ContractAddress,
}

#[derive(Copy, Drop, PartialEq, starknet::Event)]
pub(crate) struct SecurityGovernorAdded {
pub added_account: ContractAddress,
pub added_by: ContractAddress,
}

#[derive(Copy, Drop, PartialEq, starknet::Event)]
pub(crate) struct SecurityGovernorRemoved {
pub removed_account: ContractAddress,
pub removed_by: ContractAddress,
}

#[derive(Copy, Drop, PartialEq, starknet::Event)]
pub(crate) struct SecurityAdminAdded {
pub added_account: ContractAddress,
Expand Down Expand Up @@ -177,3 +207,15 @@ pub(crate) struct UpgradeGovernorRemoved {
pub removed_account: ContractAddress,
pub removed_by: ContractAddress,
}

#[derive(Copy, Drop, PartialEq, starknet::Event)]
pub(crate) struct UpgradeAgentAdded {
pub added_account: ContractAddress,
pub added_by: ContractAddress,
}

#[derive(Copy, Drop, PartialEq, starknet::Event)]
pub(crate) struct UpgradeAgentRemoved {
pub removed_account: ContractAddress,
pub removed_by: ContractAddress,
}
84 changes: 81 additions & 3 deletions packages/utils/src/components/roles/roles.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ pub(crate) mod RolesComponent {
APP_GOVERNOR, APP_ROLE_ADMIN, AppGovernorAdded, AppGovernorRemoved, AppRoleAdminAdded,
AppRoleAdminRemoved, GOVERNANCE_ADMIN, GovernanceAdminAdded, GovernanceAdminRemoved, IRoles,
OPERATOR, OperatorAdded, OperatorRemoved, RoleId, SECURITY_ADMIN, SECURITY_AGENT,
SecurityAdminAdded, SecurityAdminRemoved, SecurityAgentAdded, SecurityAgentRemoved,
TOKEN_ADMIN, TokenAdminAdded, TokenAdminRemoved, UPGRADE_GOVERNOR, UpgradeGovernorAdded,
UpgradeGovernorRemoved,
SECURITY_GOVERNOR, SecurityAdminAdded, SecurityAdminRemoved, SecurityAgentAdded,
SecurityAgentRemoved, SecurityGovernorAdded, SecurityGovernorRemoved, TOKEN_ADMIN,
TokenAdminAdded, TokenAdminRemoved, UPGRADE_AGENT, UPGRADE_GOVERNOR, UpgradeAgentAdded,
UpgradeAgentRemoved, UpgradeGovernorAdded, UpgradeGovernorRemoved,
};
use core::num::traits::Zero;
use starknet::storage::StorageMapReadAccess;
Expand Down Expand Up @@ -36,10 +37,14 @@ pub(crate) mod RolesComponent {
SecurityAdminRemoved: SecurityAdminRemoved,
SecurityAgentAdded: SecurityAgentAdded,
SecurityAgentRemoved: SecurityAgentRemoved,
SecurityGovernorAdded: SecurityGovernorAdded,
SecurityGovernorRemoved: SecurityGovernorRemoved,
TokenAdminAdded: TokenAdminAdded,
TokenAdminRemoved: TokenAdminRemoved,
UpgradeGovernorAdded: UpgradeGovernorAdded,
UpgradeGovernorRemoved: UpgradeGovernorRemoved,
UpgradeAgentAdded: UpgradeAgentAdded,
UpgradeAgentRemoved: UpgradeAgentRemoved,
}
use openzeppelin::access::accesscontrol::AccessControlComponent;
use openzeppelin::access::accesscontrol::AccessControlComponent::{
Expand Down Expand Up @@ -95,11 +100,25 @@ pub(crate) mod RolesComponent {
access_comp.has_role(role: SECURITY_AGENT, :account)
}

fn is_security_governor(
self: @ComponentState<TContractState>, account: ContractAddress,
) -> bool {
let access_comp = get_dep_component!(self, Access);
access_comp.has_role(role: SECURITY_GOVERNOR, :account)
}

fn is_token_admin(self: @ComponentState<TContractState>, account: ContractAddress) -> bool {
let access_comp = get_dep_component!(self, Access);
access_comp.has_role(role: TOKEN_ADMIN, :account)
}

fn is_upgrade_agent(
self: @ComponentState<TContractState>, account: ContractAddress,
) -> bool {
let access_comp = get_dep_component!(self, Access);
access_comp.has_role(role: UPGRADE_AGENT, :account)
}

fn is_upgrade_governor(
self: @ComponentState<TContractState>, account: ContractAddress,
) -> bool {
Expand Down Expand Up @@ -177,6 +196,25 @@ pub(crate) mod RolesComponent {
self._revoke_role_and_emit(role: SECURITY_AGENT, :account, :event);
}

fn register_security_governor(
ref self: ComponentState<TContractState>, account: ContractAddress,
) {
let event = Event::SecurityGovernorAdded(
SecurityGovernorAdded { added_account: account, added_by: get_caller_address() },
);
self._grant_role_and_emit(role: SECURITY_GOVERNOR, :account, :event);
}

fn remove_security_governor(
ref self: ComponentState<TContractState>, account: ContractAddress,
) {
let event = Event::SecurityGovernorRemoved(
SecurityGovernorRemoved {
removed_account: account, removed_by: get_caller_address(),
},
);
self._revoke_role_and_emit(role: SECURITY_GOVERNOR, :account, :event);
}

fn register_governance_admin(
ref self: ComponentState<TContractState>, account: ContractAddress,
Expand Down Expand Up @@ -230,6 +268,24 @@ pub(crate) mod RolesComponent {
self._revoke_role_and_emit(role: TOKEN_ADMIN, :account, :event);
}

fn register_upgrade_agent(
ref self: ComponentState<TContractState>, account: ContractAddress,
) {
let event = Event::UpgradeAgentAdded(
UpgradeAgentAdded { added_account: account, added_by: get_caller_address() },
);
self._grant_role_and_emit(role: UPGRADE_AGENT, :account, :event);
}

fn remove_upgrade_agent(
ref self: ComponentState<TContractState>, account: ContractAddress,
) {
let event = Event::UpgradeAgentRemoved(
UpgradeAgentRemoved { removed_account: account, removed_by: get_caller_address() },
);
self._revoke_role_and_emit(role: UPGRADE_AGENT, :account, :event);
}

fn register_upgrade_governor(
ref self: ComponentState<TContractState>, account: ContractAddress,
) {
Expand Down Expand Up @@ -349,26 +405,31 @@ pub(crate) mod RolesComponent {
access_comp.set_role_admin(role: GOVERNANCE_ADMIN, admin_role: GOVERNANCE_ADMIN);
access_comp.set_role_admin(role: OPERATOR, admin_role: APP_ROLE_ADMIN);
access_comp.set_role_admin(role: TOKEN_ADMIN, admin_role: APP_ROLE_ADMIN);
access_comp.set_role_admin(role: UPGRADE_AGENT, admin_role: APP_ROLE_ADMIN);
access_comp.set_role_admin(role: UPGRADE_GOVERNOR, admin_role: GOVERNANCE_ADMIN);

access_comp._grant_role(role: SECURITY_ADMIN, account: governance_admin);
access_comp.set_role_admin(role: SECURITY_ADMIN, admin_role: SECURITY_ADMIN);
access_comp.set_role_admin(role: SECURITY_AGENT, admin_role: SECURITY_ADMIN);
access_comp.set_role_admin(role: SECURITY_GOVERNOR, admin_role: SECURITY_ADMIN);
}

fn only_app_governor(self: @ComponentState<TContractState>) {
assert!(
self.is_app_governor(get_caller_address()), "{}", AccessErrors::ONLY_APP_GOVERNOR,
);
}

fn only_operator(self: @ComponentState<TContractState>) {
assert!(self.is_operator(get_caller_address()), "{}", AccessErrors::ONLY_OPERATOR);
}

fn only_token_admin(self: @ComponentState<TContractState>) {
assert!(
self.is_token_admin(get_caller_address()), "{}", AccessErrors::ONLY_TOKEN_ADMIN,
);
}

fn only_upgrade_governor(self: @ComponentState<TContractState>) {
assert!(
self.is_upgrade_governor(get_caller_address()),
Expand All @@ -377,6 +438,15 @@ pub(crate) mod RolesComponent {
);
}

fn only_upgrader(self: @ComponentState<TContractState>) {
assert!(
self.is_upgrade_agent(get_caller_address())
|| self.is_upgrade_governor(get_caller_address()),
"{}",
AccessErrors::ONLY_UPGRADER,
);
}

fn only_security_admin(self: @ComponentState<TContractState>) {
assert!(
self.is_security_admin(get_caller_address()),
Expand All @@ -392,5 +462,13 @@ pub(crate) mod RolesComponent {
AccessErrors::ONLY_SECURITY_AGENT,
);
}

fn only_security_governor(self: @ComponentState<TContractState>) {
assert!(
self.is_security_governor(get_caller_address()),
"{}",
AccessErrors::ONLY_SECURITY_GOVERNOR,
);
}
}
}
Loading