> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layerzero.network/llms.txt
> Use this file to discover all available pages before exploring further.

# RBAC Reference

> Complete role-based access control reference for Stablecoin OFT and ERC20Plus with role definitions, function matrices, and recommended assignment strategies.

Complete role-based access control reference for Stablecoin OFT and `ERC20Plus`. All roles use `AccessControl2StepUpgradeable` with two-step admin transfer and `keccak256` identifiers.

## Stablecoin OFT

Applies to `OFTBurnMint`, `OFTBurnSelfMint`, `OFTLockUnlock`, `OFTNative`, and the alt variants of `OFTBurnMint`, `OFTBurnSelfMint`, and `OFTLockUnlock`.

| Role                        | Source                          | Used For                                                                                                                         |
| --------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `DEFAULT_ADMIN_ROLE`        | `AccessControl2StepUpgradeable` | `setPeer`, `setEnforcedOptions`, `setMsgInspector`, `setFeeDeposit`, delegate operations                                         |
| `FEE_CONFIG_MANAGER_ROLE`   | `FeeConfigRBACUpgradeable`      | `setDefaultFeeBps`, `setFeeBps`                                                                                                  |
| `RATE_LIMITER_MANAGER_ROLE` | `RateLimiterRBACUpgradeable`    | `setRateLimitGlobalConfig`, `setRateLimitConfigs`, `setRateLimitStates`, `setRateLimitAddressExemptions`, `checkpointRateLimits` |
| `PAUSER_ROLE`               | `PauseByIDRBACUpgradeable`      | `setDefaultPaused` (when pausing), `setPaused` (when effectively pausing)                                                        |
| `UNPAUSER_ROLE`             | `PauseByIDRBACUpgradeable`      | `setDefaultPaused` (when unpausing), `setPaused` (when effectively unpausing or no-op)                                           |

<Warning>
  `DEFAULT_ADMIN_ROLE` is synchronized with `delegate`. The `setDelegate` function always reverts.
</Warning>

## ERC20Plus

| Role                 | Source                          | Used For                                           |
| -------------------- | ------------------------------- | -------------------------------------------------- |
| `DEFAULT_ADMIN_ROLE` | `AccessControl2StepUpgradeable` | Admin transfer, set allowlist mode, `recoverFunds` |
| `MINTER_ROLE`        | Declared locally                | `mint`                                             |
| `BURNER_ROLE`        | Declared locally                | `burn`                                             |
| `BLACKLISTER_ROLE`   | `AllowlistRBACUpgradeable`      | Blacklist addresses                                |
| `WHITELISTER_ROLE`   | `AllowlistRBACUpgradeable`      | Whitelist addresses                                |
| `PAUSER_ROLE`        | `PauseRBACUpgradeable`          | Pause                                              |
| `UNPAUSER_ROLE`      | `PauseRBACUpgradeable`          | Unpause                                            |

## Role-to-Function Matrix

### ERC20Plus Functions

| Function                                  | Required Role        |
| ----------------------------------------- | -------------------- |
| `mint(address, uint256)`                  | `MINTER_ROLE`        |
| `burn(address, uint256)`                  | `BURNER_ROLE`        |
| `recoverFunds(address, address, uint256)` | `DEFAULT_ADMIN_ROLE` |
| `setAllowlistMode(AllowlistMode)`         | `DEFAULT_ADMIN_ROLE` |
| `setBlacklisted(SetAllowlistParam[])`     | `BLACKLISTER_ROLE`   |
| `setWhitelisted(SetAllowlistParam[])`     | `WHITELISTER_ROLE`   |
| `pause()`                                 | `PAUSER_ROLE`        |
| `unpause()`                               | `UNPAUSER_ROLE`      |

### OFT Functions

| Function                                                             | Required Role                    |
| -------------------------------------------------------------------- | -------------------------------- |
| `setDefaultFeeBps(uint16)`                                           | `FEE_CONFIG_MANAGER_ROLE`        |
| `setFeeBps(uint256, uint16, bool)`                                   | `FEE_CONFIG_MANAGER_ROLE`        |
| `setRateLimitGlobalConfig(RateLimitGlobalConfig)`                    | `RATE_LIMITER_MANAGER_ROLE`      |
| `setRateLimitConfigs(SetRateLimitConfigParam[])`                     | `RATE_LIMITER_MANAGER_ROLE`      |
| `setRateLimitStates(SetRateLimitStateParam[])`                       | `RATE_LIMITER_MANAGER_ROLE`      |
| `setRateLimitAddressExemptions(SetRateLimitAddressExceptionParam[])` | `RATE_LIMITER_MANAGER_ROLE`      |
| `checkpointRateLimits(uint256[])`                                    | `RATE_LIMITER_MANAGER_ROLE`      |
| `setDefaultPaused(bool)`                                             | `PAUSER_ROLE` or `UNPAUSER_ROLE` |
| `setPaused(SetPausedParam[])`                                        | `PAUSER_ROLE` or `UNPAUSER_ROLE` |
| `setPeer(uint32, bytes32)`                                           | `DEFAULT_ADMIN_ROLE`             |
| `setEnforcedOptions(EnforcedOptionParam[])`                          | `DEFAULT_ADMIN_ROLE`             |
| `setMsgInspector(address)`                                           | `DEFAULT_ADMIN_ROLE`             |
| `setFeeDeposit(address)`                                             | `DEFAULT_ADMIN_ROLE`             |

### Permissionless Functions

These functions can be called by anyone:

| Function                                  | Contract                                   |
| ----------------------------------------- | ------------------------------------------ |
| `send(SendParam, MessagingFee, address)`  | OFTs                                       |
| `quoteSend(SendParam, bool)`              | OFTs                                       |
| `quoteOFT(SendParam)`                     | OFTs                                       |
| `token()`                                 | OFTs                                       |
| `approvalRequired()`                      | OFTs                                       |
| `oftVersion()`                            | OFTs                                       |
| `sharedDecimals()`                        | OFTs                                       |
| `transfer(address, uint256)`              | `ERC20Plus` (subject to allowlist + pause) |
| `transferFrom(address, address, uint256)` | `ERC20Plus` (subject to allowlist + pause) |
| `approve(address, uint256)`               | `ERC20Plus`                                |
| `permit(...)`                             | `ERC20Plus`                                |
| `defaultFeeBps()`                         | OFTs                                       |
| `feeBps(uint256)`                         | OFTs                                       |
| `getRateLimitGlobalConfig()`              | OFTs                                       |
| `rateLimits(uint256)`                     | OFTs                                       |
| `getRateLimitUsages(uint256)`             | OFTs                                       |
| `isRateLimitAddressExempt(address)`       | OFTs                                       |
| `isPaused(uint256)`                       | OFTs                                       |
| `defaultPaused()`                         | OFTs                                       |
| `pauseConfig(uint256)`                    | OFTs                                       |
| `allowlistMode()`                         | `ERC20Plus`                                |
| `isAllowlisted(address)`                  | `ERC20Plus`                                |
| `isBlacklisted(address)`                  | `ERC20Plus`                                |
| `isWhitelisted(address)`                  | `ERC20Plus`                                |
| `blacklistedCount()`                      | `ERC20Plus`                                |
| `whitelistedCount()`                      | `ERC20Plus`                                |
| `getBlacklist(uint256, uint256)`          | `ERC20Plus`                                |
| `getWhitelist(uint256, uint256)`          | `ERC20Plus`                                |

## Role Separation Principles

**Pauser / Unpauser** — A compromised pauser key can halt the system (disruptive, but funds remain safe). If that same key could also unpause, an attacker could undo a legitimate security pause. Keeping them separate means the security team can pause fast, and unpausing requires a different authorization path (typically a governance multisig).

**Fee config manager** — A compromised `FEE_CONFIG_MANAGER_ROLE` can set high fee rates, but fee proceeds are pushed to the fee deposit address during `_debit` as part of the send path; the fee config manager cannot retarget that destination. Use a multisig for fee administration and monitor `DefaultFeeBpsSet` / `FeeBpsSet` events.

**Minter / Burner** — Different risk profiles. A compromised minter inflates supply; a compromised burner destroys user funds. In practice, both roles should only be granted to OFT contracts, never to EOAs.

**Blacklister / Whitelister** — Different compliance functions and different teams. Blacklisting is reactive (sanctions, fraud), typically handled by compliance or security. Whitelisting is proactive (KYC onboarding), typically handled by an onboarding team. Separating them matches the org chart.

## Next Steps

* [ERC20Plus](/v2/developers/evm/stablecoin-oft/erc20plus) for token-layer behavior and interfaces
* [Extensions](/v2/developers/evm/stablecoin-oft/extensions) for fee, rate limit, and pause configuration on OFTs
* [Security and Compliance](/v2/developers/evm/stablecoin-oft/security-compliance) for operational security recommendations
