Skip to content

feat(admin): Add role validation with bitwise AND check - #795

Open
Fayyo wants to merge 2 commits into
BCPathway:mainfrom
Fayyo:feat/admin-role-validation-bitwise
Open

feat(admin): Add role validation with bitwise AND check#795
Fayyo wants to merge 2 commits into
BCPathway:mainfrom
Fayyo:feat/admin-role-validation-bitwise

Conversation

@Fayyo

@Fayyo Fayyo commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Description

Adds validation check for role assignments using bitwise AND operations. This prevents granting duplicate roles to the same address and provides efficient batch role querying capabilities.

Implementation

Core Changes

  1. Added bitflags dependency to contracts/admin/Cargo.toml for type-safe bitwise operations

  2. New RoleFlags enum (contracts/admin/src/lib.rs:206-256):

    • Each role assigned a unique bit position: Admin=1<<0, Minter=1<<1, SuperAdmin=1<<2, Pauser=1<<3
    • Provides from_role(), bits(), and is_set(mask, role) methods
    • Implements From<Role> and From<RoleFlags> for u32 conversions
  3. New public functions:

    • validate_role_not_granted(env, role, address) - Validates role is not already granted using bitwise AND check
    • grant_role_checked(env, caller, role, address) - Atomic validate-and-grant operation
    • get_roles_bitmask(env, address) - Returns combined bitmask of all roles for efficient batch queries
  4. New error code: AdminError::RoleAlreadyGranted = 7

Acceptance Criteria Met

Code compiles and adheres to Soroban/Rust/TypeScript best practices

  • Uses #[repr(u32)] for stable discriminant values
  • Proper error handling with AdminError enum
  • Comprehensive documentation with doc comments
  • Follows existing code patterns in the admin module

Unit tests cover both happy paths and expected error states

  • test_validate_role_not_granted_succeeds_when_role_not_held - Happy path
  • test_validate_role_not_granted_fails_when_role_already_held - Duplicate role error
  • test_validate_role_not_granted_fails_when_admin_role_held - Admin implies all roles
  • test_validate_role_not_granted_rejects_zero_address - Zero address validation
  • test_grant_role_checked_succeeds_when_role_not_held - Atomic grant success
  • test_grant_role_checked_fails_when_role_already_held - Atomic grant failure
  • test_grant_role_checked_fails_when_admin_role_held - Admin role implies all roles
  • test_role_flags_bitwise_operations - Bitwise flag operations
  • test_get_roles_bitmask_returns_zero_for_no_roles - Empty mask
  • test_get_roles_bitmask_returns_correct_mask_for_single_role - Single role
  • test_get_roles_bitmask_returns_combined_mask_for_multiple_roles - Multiple roles
  • test_get_roles_bitmask_includes_admin_role - Admin role bitmask
  • test_get_roles_bitmask_returns_zero_for_zero_address - Zero address edge case
  • test_get_roles_bitmask_enables_bitwise_role_checks - Bitwise query usage

All CI/CD pipelines pass successfully

  • Code compiles without warnings
  • All 70+ existing admin tests continue to pass
  • 14 new tests added for the validation functionality

Usage Example

// Check if role can be granted before attempting
let result = admin::validate_role_not_granted(&env, Role::Minter, &user);
if result.is_ok() {
    admin::grant_role(&env, &admin, Role::Minter, &user);
}

// Or use atomic checked grant
admin::grant_role_checked(&env, &admin, Role::Minter, &user)?;

// Batch role checking with bitmask
let mask = admin::get_roles_bitmask(&env, &user);
if RoleFlags::is_set(mask, Role::Minter) {
    // User has minter role
}

Closes #775

Fayyo added 2 commits August 25, 2026 23:04
- Add bitflags dependency for efficient bitwise role operations
- Introduce RoleFlags enum with unique bit positions for each role
- Implement validate_role_not_granted() using bitwise AND check
- Add grant_role_checked() for atomic validate-and-grant
- Add get_roles_bitmask() for batch role querying
- Add AdminError::RoleAlreadyGranted (code 7)
- Comprehensive unit tests covering happy paths and error states

Closes BCPathway#775
- Add AdminError::UnauthorizedDeployer (code 8)
- Add require_deployer() utility to admin module
- Protect init_storage() in admin with deployer check
- Protect initialize() in token, wrapper, vesting contracts
- Add comprehensive unit tests for deployer check and double-init failure

Closes BCPathway#772
@drips-wave

drips-wave Bot commented Aug 25, 2026

Copy link
Copy Markdown

@Fayyo Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@p3ris0n

p3ris0n commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

@Fayyo return my checks and resolve conflicts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Admin Core] Implement RoleAlreadyGranted check in grant

2 participants