This skill should be used when the user asks about "access control", "onlyOwner", "onlyOperator", "ownership transfer", "MultiStepOwnable", "ERC8023", "operable pattern", "function-level permissions", "reentrancy protection", "reentrancy lock", or needs to restrict function access in Crane Diamond contracts.
Scanned 9/10/2026
Install to Claude Code
npx -y skills add cyotee/indexedex --skill crane-access --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Crane Access?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/cyotee-crane-access)More formats (shields.io, HTML) on the badges page.
---
name: crane-access
description: This skill should be used when the user asks about "access control", "onlyOwner", "onlyOperator", "ownership transfer", "MultiStepOwnable", "ERC8023", "operable pattern", "function-level permissions", "reentrancy protection", "reentrancy lock", or needs to restrict function access in Crane Diamond contracts.
license: MIT
---
# Crane Access Control Components
Crane provides three access control patterns for Diamond proxies: MultiStepOwnable (ERC-8023), Operable, and ReentrancyLock.
## Component Selection
| Need | Component | Purpose |
|------|-----------|---------|
| Ownership with time-lock | MultiStepOwnable | Two-step ownership transfer with buffer period |
| Delegated permissions | Operable | Global and function-level operator authorization |
| Reentrancy protection | ReentrancyLock | Transient storage lock for cross-function reentrancy |
## Quick Start: Add Access Control
```solidity
// Import modifiers
import {MultiStepOwnableModifiers} from "@crane/contracts/access/ERC8023/MultiStepOwnableModifiers.sol";
import {OperableModifiers} from "@crane/contracts/access/operable/OperableModifiers.sol";
import {ReentrancyLockModifiers} from "@crane/contracts/access/reentrancy/ReentrancyLockModifiers.sol";
// Use in your Target contract
contract MyTarget is MultiStepOwnableModifiers, OperableModifiers, ReentrancyLockModifiers {
function adminOnly() external onlyOwner {
// Only owner can call
}
function operatorOnly() external onlyOperator {
// Global operators or function-specific operators
}
function ownerOrOperator() external onlyOwnerOrOperator {
// Either owner or operator can call
}
function noReentrant() external nonReentrant {
// Protected from reentrancy
}
}
```
## MultiStepOwnable (ERC-8023)
Time-locked two-step ownership transfer with buffer period.
### Storage
```solidity
struct Storage {
address owner;
address pendingOwner;
bool pendingOwnerConfirmed;
uint256 ownershipBufferPeriod; // e.g., 1 days
uint256 bufferPeriodEnd;
}
```
### Ownership Transfer Flow
1. **Initiate**: Owner calls `initiateOwnershipTransfer(newOwner)`
2. **Wait**: Buffer period must elapse
3. **Confirm**: Owner calls `confirmOwnershipTransfer(newOwner)`
4. **Accept**: New owner calls `acceptOwnershipTransfer()`
```solidity
// Step 1: Current owner initiates
MultiStepOwnableRepo._initiateOwnershipTransfer(newOwner);
// Step 2: Wait for buffer period (e.g., 1 day)
// Step 3: Current owner confirms
MultiStepOwnableRepo._confirmOwnershipTransfer(newOwner);
// Step 4: New owner accepts
MultiStepOwnableRepo._acceptOwnershipTransfer();
// Owner can cancel anytime before acceptance
MultiStepOwnableRepo._cancelPendingOwnershipTransfer();
```
### Guard Functions
```solidity
// Revert if msg.sender is not owner
MultiStepOwnableRepo._onlyOwner();
// Revert if msg.sender is not pending owner
MultiStepOwnableRepo._onlyPendingOwner();
```
### Modifiers
```solidity
modifier onlyOwner() {
MultiStepOwnableRepo._onlyOwner();
_;
}
```
### Initialization
```solidity
// In DFPkg.initAccount()
MultiStepOwnableRepo._initialize(
initialOwner, // First owner
1 days // Buffer period for transfers
);
```
## Operable Pattern
Delegated authorization for global and function-level permissions.
### Storage
```solidity
struct Storage {
mapping(address => bool) isOperator; // Global operators
mapping(bytes4 func => mapping(address => bool)) isOperatorFor; // Function-level
}
```
### Authorization Levels
1. **Global Operator**: Can call any function protected by `onlyOperator`
2. **Function Operator**: Can only call specific functions
### Setting Permissions (Owner Only)
```solidity
// Grant/revoke global operator status
OperableRepo._setOperatorStatus(operatorAddress, true); // Grant
OperableRepo._setOperatorStatus(operatorAddress, false); // Revoke
// Grant/revoke function-level operator
OperableRepo._setFunctionOperatorStatus(
IMyContract.someFunction.selector, // Function selector
operatorAddress, // Operator
true // Approval
);
```
### Checking Permissions
```solidity
// Check global operator
bool isGlobal = OperableRepo._isOperator(account);
// Check function operator
bool isForFunc = OperableRepo._isFunctionOperator(
IMyContract.someFunction.selector,
account
);
```
### Guard Functions
```solidity
// Revert if not global OR function operator for msg.sig
OperableRepo._onlyOperator();
// Revert if not owner AND not operator
OperableRepo._onlyOwnerOrOperator();
```
### Modifiers
```solidity
// Only global or function-level operators
modifier onlyOperator() {
OperableRepo._onlyOperator();
_;
}
// Owner OR any operator
modifier onlyOwnerOrOperator() {
OperableRepo._onlyOwnerOrOperator();
_;
}
```
## ReentrancyLock
Transient storage-based reentrancy protection (EIP-1153).
### Usage
```solidity
modifier nonReentrant() {
ReentrancyLockRepo._onlyUnlocked();
ReentrancyLockRepo._lock();
_;
ReentrancyLockRepo._unlock();
}
```
### Functions
```solidity
// Lock the reentrancy guard
ReentrancyLockRepo._lock();
// Unlock the reentrancy guard
ReentrancyLockRepo._unlock();
// Check if locked
bool locked = ReentrancyLockRepo._isLocked();
// Revert if locked (guard function)
ReentrancyLockRepo._onlyUnlocked();
```
### Benefits
- Uses transient storage (cleared after transaction)
- Gas efficient compared to storage-based guards
- Protects against cross-function reentrancy
## Component Files
| Component | Files |
|-----------|-------|
| MultiStepOwnable | `MultiStepOwnableRepo.sol`, `MultiStepOwnableModifiers.sol`, `MultiStepOwnableTarget.sol`, `MultiStepOwnableFacet.sol` |
| Operable | `OperableRepo.sol`, `OperableModifiers.sol`, `OperableTarget.sol`, `OperableFacet.sol` |
| ReentrancyLock | `ReentrancyLockRepo.sol`, `ReentrancyLockModifiers.sol`, `ReentrancyLockTarget.sol`, `ReentrancyLockFacet.sol` |
## AccessFacetFactoryService
Deploy access control facets:
```solidity
import {AccessFacetFactoryService} from "@crane/contracts/access/AccessFacetFactoryService.sol";
// Deploy MultiStepOwnable facet
IFacet ownerFacet = AccessFacetFactoryService.deployMultiStepOwnableFacet(create3Factory);
// Deploy Operable facet
IFacet operableFacet = AccessFacetFactoryService.deployOperableFacet(create3Factory);
// Deploy ReentrancyLock facet
IFacet reentrancyFacet = AccessFacetFactoryService.deployReentrancyLockFacet(create3Factory);
```
## Additional Resources
### Reference Files
For detailed patterns and examples:
- **`references/access-patterns.md`** - Complete access control integration patterns
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!