or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

access-control.mdaccount-abstraction.mdfinance.mdgovernance.mdindex.mdmathematical-utilities.mdmeta-transactions.mdproxy-patterns.mdsecurity-utilities.mdtoken-standards.md

access-control.mddocs/

0

# Access Control

1

2

Comprehensive access control mechanisms including single-owner patterns and flexible role-based access control systems for secure smart contract administration.

3

4

## Capabilities

5

6

### Single Owner Pattern

7

8

Simple ownership model with transfer and renouncement capabilities for contracts requiring single administrator access.

9

10

```solidity { .api }

11

/**

12

* @dev Contract module which provides a basic access control mechanism, where

13

* there is an account (an owner) that can be granted exclusive access to

14

* specific functions.

15

*/

16

abstract contract Ownable is Context {

17

/**

18

* @dev Sets the initial owner to the address provided by the deployer

19

*/

20

constructor(address initialOwner);

21

22

/**

23

* @dev Returns the address of the current owner

24

*/

25

function owner() public view virtual returns (address);

26

27

/**

28

* @dev Transfers ownership of the contract to a new account (`newOwner`)

29

* Can only be called by the current owner

30

*/

31

function transferOwnership(address newOwner) public virtual onlyOwner;

32

33

/**

34

* @dev Leaves the contract without owner. It will not be possible to call

35

* `onlyOwner` functions anymore. Can only be called by the current owner

36

*/

37

function renounceOwnership() public virtual onlyOwner;

38

39

/**

40

* @dev Throws if called by any account other than the owner

41

*/

42

modifier onlyOwner();

43

}

44

```

45

46

**Usage Example:**

47

48

```solidity

49

import "@openzeppelin/contracts/access/Ownable.sol";

50

51

contract MyContract is Ownable {

52

uint256 private _value;

53

54

constructor(address initialOwner) Ownable(initialOwner) {}

55

56

function setValue(uint256 newValue) public onlyOwner {

57

_value = newValue;

58

}

59

60

function getValue() public view returns (uint256) {

61

return _value;

62

}

63

}

64

```

65

66

### Two-Step Ownership Transfer

67

68

Enhanced ownership pattern that requires new owner acceptance to prevent accidental transfers to invalid addresses.

69

70

```solidity { .api }

71

/**

72

* @dev Contract module which provides access control mechanism, where

73

* there is an account (an owner) that can be granted exclusive access to

74

* specific functions, and ownership transfer is a two-step process.

75

*/

76

abstract contract Ownable2Step is Ownable {

77

/**

78

* @dev Returns the address of the pending owner

79

*/

80

function pendingOwner() public view virtual returns (address);

81

82

/**

83

* @dev Starts the ownership transfer of the contract to a new account

84

* Replaces the pending transfer if there is one

85

*/

86

function transferOwnership(address newOwner) public virtual override onlyOwner;

87

88

/**

89

* @dev The new owner accepts the ownership transfer

90

*/

91

function acceptOwnership() public virtual;

92

}

93

```

94

95

**Usage Example:**

96

97

```solidity

98

import "@openzeppelin/contracts/access/Ownable2Step.sol";

99

100

contract SecureContract is Ownable2Step {

101

constructor(address initialOwner) Ownable(initialOwner) {}

102

103

// Contract functions requiring ownership

104

function sensitiveOperation() public onlyOwner {

105

// Protected operation

106

}

107

}

108

109

// Transfer process:

110

// 1. Current owner calls transferOwnership(newOwnerAddress)

111

// 2. New owner calls acceptOwnership() to complete transfer

112

```

113

114

### Role-Based Access Control

115

116

Flexible role-based access control system supporting multiple roles with hierarchical administration.

117

118

```solidity { .api }

119

/**

120

* @dev Contract module that allows children to implement role-based access

121

* control mechanisms. Roles are referred to by their `bytes32` identifier.

122

*/

123

abstract contract AccessControl is Context, IAccessControl, ERC165 {

124

/**

125

* @dev Returns `true` if `account` has been granted `role`

126

*/

127

function hasRole(bytes32 role, address account) public view virtual returns (bool);

128

129

/**

130

* @dev Returns the admin role that controls `role`

131

*/

132

function getRoleAdmin(bytes32 role) public view virtual returns (bytes32);

133

134

/**

135

* @dev Grants `role` to `account`

136

* If `account` had not been already granted `role`, emits a {RoleGranted} event

137

*/

138

function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role));

139

140

/**

141

* @dev Revokes `role` from `account`

142

* If `account` had been granted `role`, emits a {RoleRevoked} event

143

*/

144

function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role));

145

146

/**

147

* @dev Revokes `role` from the calling account

148

*/

149

function renounceRole(bytes32 role, address callerConfirmation) public virtual;

150

151

/**

152

* @dev Sets `adminRole` as ``role``'s admin role

153

* Internal function without access restriction

154

*/

155

function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual;

156

157

/**

158

* @dev Grants `role` to `account`

159

* Internal function without access restriction

160

*/

161

function _grantRole(bytes32 role, address account) internal virtual;

162

163

/**

164

* @dev Revokes `role` from `account`

165

* Internal function without access restriction

166

*/

167

function _revokeRole(bytes32 role, address account) internal virtual;

168

169

/**

170

* @dev Modifier that checks that an account has a specific role

171

*/

172

modifier onlyRole(bytes32 role);

173

}

174

```

175

176

**Usage Example:**

177

178

```solidity

179

import "@openzeppelin/contracts/access/AccessControl.sol";

180

181

contract MyContract is AccessControl {

182

bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

183

bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");

184

185

constructor(address defaultAdmin) {

186

_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);

187

}

188

189

function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {

190

// Minting logic

191

}

192

193

function burn(uint256 amount) public onlyRole(BURNER_ROLE) {

194

// Burning logic

195

}

196

197

function setupRoles(address minter, address burner) public onlyRole(DEFAULT_ADMIN_ROLE) {

198

_grantRole(MINTER_ROLE, minter);

199

_grantRole(BURNER_ROLE, burner);

200

}

201

}

202

```

203

204

### Enhanced Access Control Extensions

205

206

Advanced access control features including enumerable roles and default admin rules.

207

208

```solidity { .api }

209

// Enumerable Access Control - Track role members

210

abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {

211

/**

212

* @dev Returns one of the accounts that have `role`

213

*/

214

function getRoleMember(bytes32 role, uint256 index) public view virtual returns (address);

215

216

/**

217

* @dev Returns the number of accounts that have `role`

218

*/

219

function getRoleMemberCount(bytes32 role) public view virtual returns (uint256);

220

221

/**

222

* @dev Returns an array of all accounts that have `role`

223

*/

224

function getRoleMembers(bytes32 role) public view virtual returns (address[] memory);

225

}

226

227

// Default Admin Rules - Enhanced admin role management

228

abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRules, AccessControl {

229

/**

230

* @dev Returns the address of the current default admin

231

*/

232

function defaultAdmin() public view virtual returns (address);

233

234

/**

235

* @dev Returns the address of the pending default admin

236

*/

237

function pendingDefaultAdmin() public view virtual returns (address);

238

239

/**

240

* @dev Returns the remaining time in seconds until the default admin transfer delay ends

241

*/

242

function defaultAdminDelayIncreaseWait() public view virtual returns (uint48);

243

244

/**

245

* @dev Starts a default admin transfer by setting a pending default admin

246

*/

247

function beginDefaultAdminTransfer(address newAdmin) public virtual onlyRole(DEFAULT_ADMIN_ROLE);

248

249

/**

250

* @dev Accepts the pending default admin transfer

251

*/

252

function acceptDefaultAdminTransfer() public virtual;

253

254

/**

255

* @dev Cancels a pending default admin transfer

256

*/

257

function cancelDefaultAdminTransfer() public virtual onlyRole(DEFAULT_ADMIN_ROLE);

258

}

259

```

260

261

### Access Manager

262

263

Advanced access management system for complex authorization scenarios with time-based controls.

264

265

```solidity { .api }

266

/**

267

* @dev AccessManager is a central contract to store the permissions of a system.

268

* It provides a flexible and modular access control mechanism.

269

*/

270

contract AccessManager is Context, Multicall, IAccessManager {

271

/**

272

* @dev Check if an account can perform an operation

273

*/

274

function canCall(address caller, address target, bytes4 selector) public view virtual returns (bool immediate, uint32 delay);

275

276

/**

277

* @dev Get the role of an account

278

*/

279

function getAccess(uint64 roleId, address account) public view virtual returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect);

280

281

/**

282

* @dev Grant a role to an account

283

*/

284

function grantRole(uint64 roleId, address account, uint32 executionDelay) public virtual onlyAuthorized;

285

286

/**

287

* @dev Revoke a role from an account

288

*/

289

function revokeRole(uint64 roleId, address account) public virtual onlyAuthorized;

290

291

/**

292

* @dev Set the role required to call a function

293

*/

294

function setTargetFunctionRole(address target, bytes4[] calldata selectors, uint64 roleId) public virtual onlyAuthorized;

295

296

/**

297

* @dev Schedule an operation that is subject to a delay

298

*/

299

function schedule(address target, bytes calldata data, uint48 when) public virtual returns (bytes32 operationId);

300

301

/**

302

* @dev Execute a scheduled operation

303

*/

304

function execute(address target, bytes calldata data) public payable virtual returns (bytes32 operationId);

305

306

/**

307

* @dev Cancel a scheduled operation

308

*/

309

function cancel(address caller, address target, bytes calldata data) public virtual returns (bytes32 operationId);

310

}

311

```

312

313

## Access Control Interfaces

314

315

```solidity { .api }

316

// Core Access Control Interface

317

interface IAccessControl {

318

event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

319

event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

320

event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

321

322

function hasRole(bytes32 role, address account) external view returns (bool);

323

function getRoleAdmin(bytes32 role) external view returns (bytes32);

324

function grantRole(bytes32 role, address account) external;

325

function revokeRole(bytes32 role, address account) external;

326

function renounceRole(bytes32 role, address callerConfirmation) external;

327

}

328

329

// Enumerable Access Control Interface

330

interface IAccessControlEnumerable is IAccessControl {

331

function getRoleMember(bytes32 role, uint256 index) external view returns (address);

332

function getRoleMemberCount(bytes32 role) external view returns (uint256);

333

}

334

335

// Default Admin Rules Interface

336

interface IAccessControlDefaultAdminRules is IAccessControl {

337

event DefaultAdminTransferScheduled(address indexed newAdmin, uint48 acceptSchedule);

338

event DefaultAdminTransferCanceled();

339

event DefaultAdminDelayChangeScheduled(uint48 newDelay, uint48 effectSchedule);

340

event DefaultAdminDelayChangeCanceled();

341

342

function defaultAdmin() external view returns (address);

343

function pendingDefaultAdmin() external view returns (address, uint48);

344

function defaultAdminDelay() external view returns (uint48);

345

function pendingDefaultAdminDelay() external view returns (uint48, uint48);

346

function defaultAdminDelayIncreaseWait() external view returns (uint48);

347

}

348

349

// Access Manager Interface

350

interface IAccessManager {

351

event RoleGranted(uint64 indexed roleId, address indexed account, uint32 delay, uint48 since, address indexed caller);

352

event RoleRevoked(uint64 indexed roleId, address indexed account, address indexed caller);

353

event OperationScheduled(bytes32 indexed operationId, uint32 indexed nonce, uint48 schedule, address caller, address target, bytes data);

354

event OperationExecuted(bytes32 indexed operationId, uint32 indexed nonce, address caller, address target, bytes data);

355

event OperationCanceled(bytes32 indexed operationId, uint32 indexed nonce, address caller, address target, bytes data);

356

357

function canCall(address caller, address target, bytes4 selector) external view returns (bool allowed, uint32 delay);

358

function expiration() external view returns (uint32);

359

function minSetback() external view returns (uint32);

360

function isTargetClosed(address target) external view returns (bool);

361

function getTargetFunctionRole(address target, bytes4 selector) external view returns (uint64);

362

function getAccess(uint64 roleId, address account) external view returns (uint48, uint32, uint32, uint48);

363

function hasRole(uint64 roleId, address account) external view returns (bool, uint32);

364

}

365

```

366

367

## Common Patterns

368

369

### Basic Access Control Pattern

370

371

```solidity

372

import "@openzeppelin/contracts/access/Ownable.sol";

373

374

contract SimpleContract is Ownable {

375

mapping(address => bool) public authorized;

376

377

constructor(address initialOwner) Ownable(initialOwner) {}

378

379

function authorizeUser(address user) public onlyOwner {

380

authorized[user] = true;

381

}

382

383

function revokeUser(address user) public onlyOwner {

384

authorized[user] = false;

385

}

386

387

function protectedFunction() public {

388

require(authorized[msg.sender], "Not authorized");

389

// Function logic

390

}

391

}

392

```

393

394

### Multi-Role Pattern

395

396

```solidity

397

import "@openzeppelin/contracts/access/AccessControl.sol";

398

399

contract MultiRoleContract is AccessControl {

400

bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");

401

bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");

402

bytes32 public constant USER_ROLE = keccak256("USER_ROLE");

403

404

constructor(address defaultAdmin) {

405

_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);

406

_grantRole(ADMIN_ROLE, defaultAdmin);

407

408

// Set role hierarchy

409

_setRoleAdmin(OPERATOR_ROLE, ADMIN_ROLE);

410

_setRoleAdmin(USER_ROLE, OPERATOR_ROLE);

411

}

412

413

function adminFunction() public onlyRole(ADMIN_ROLE) {

414

// Admin-only functionality

415

}

416

417

function operatorFunction() public onlyRole(OPERATOR_ROLE) {

418

// Operator functionality

419

}

420

421

function userFunction() public onlyRole(USER_ROLE) {

422

// User functionality

423

}

424

}

425

```

426

427

### Combined Access Control Pattern

428

429

```solidity

430

import "@openzeppelin/contracts/access/Ownable.sol";

431

import "@openzeppelin/contracts/access/AccessControl.sol";

432

433

contract HybridAccessContract is Ownable, AccessControl {

434

bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");

435

436

constructor(address initialOwner) Ownable(initialOwner) {

437

_grantRole(DEFAULT_ADMIN_ROLE, initialOwner);

438

}

439

440

// Owner can grant roles

441

function grantManagerRole(address account) public onlyOwner {

442

grantRole(MANAGER_ROLE, account);

443

}

444

445

// Managers can perform operations

446

function manageOperation() public onlyRole(MANAGER_ROLE) {

447

// Management functionality

448

}

449

450

// Owner retains ultimate control

451

function emergencyFunction() public onlyOwner {

452

// Emergency functionality

453

}

454

}

455

```