> For the complete documentation index, see [llms.txt](https://spree-finance.gitbook.io/spreefinance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://spree-finance.gitbook.io/spreefinance/developer-guides/stable-points-sp/security-role-management.md).

# Security & Role Management

All Spree contracts use OpenZeppelin AccessControl for RBAC and UUPS proxies for upgradeability.

### Role Reference

#### Factory

| Role                 | Hex Constant         | Permissions                               |
| -------------------- | -------------------- | ----------------------------------------- |
| DEFAULT\_ADMIN\_ROLE | `0x00`               | Grant/revoke all roles, upgrade           |
| MANAGER\_ROLE        | `readManagerRole()`  | Whitelist management, set rates, set caps |
| EXECUTOR\_ROLE       | `readExecutorRole()` | Finalize and reject redemptions           |
| PAUSER\_ROLE         | `readPauserRole()`   | Pause/unpause contract                    |

#### SpreeVault4626

| Role                 | Hex Constant          | Permissions                               |
| -------------------- | --------------------- | ----------------------------------------- |
| DEFAULT\_ADMIN\_ROLE | `0x00`                | Grant/revoke, emergency withdraw, upgrade |
| OPERATOR\_ROLE       | `readOperatorRole()`  | Rebalance vault                           |
| HARVESTER\_ROLE      | `readHarvesterRole()` | Harvest yield from adapter                |
| DEPOSITOR\_ROLE      | `readDepositorRole()` | Deposit into vault                        |
| PAUSER\_ROLE         | `readPauserRole()`    | Pause/unpause                             |
| UPGRADER\_ROLE       | `readUpgraderRole()`  | Upgrade implementation                    |

#### BonusRewardsVault

| Role                 | Hex Constant            | Permissions                         |
| -------------------- | ----------------------- | ----------------------------------- |
| DEFAULT\_ADMIN\_ROLE | `0x00`                  | Grant/revoke, upgrade               |
| HARVESTER\_ROLE      | `readHarvesterRole()`   | Record harvests, take TVL snapshots |
| DISTRIBUTOR\_ROLE    | `readDistributorRole()` | Manage reward distribution          |
| PAUSER\_ROLE         | `readPauserRole()`      | Pause/unpause                       |
| UPGRADER\_ROLE       | `readUpgraderRole()`    | Upgrade implementation              |

#### PendingSPVault

| Role              | Permissions                               |
| ----------------- | ----------------------------------------- |
| CAMPAIGN\_ADMIN   | Create campaigns, set campaign parameters |
| ISSUING\_ADMIN    | Fund campaigns                            |
| SETTLEMENT\_ADMIN | Settle and expire pSP                     |
| TRANSFER\_ADMIN   | Manage pSP transfer permissions           |
| MANAGER           | Global configuration                      |

#### PythPriceOracle

| Role                 | Hex Constant        | Permissions                      |
| -------------------- | ------------------- | -------------------------------- |
| DEFAULT\_ADMIN\_ROLE | `0x00`              | Grant/revoke, upgrade            |
| MANAGER\_ROLE        | `readManagerRole()` | Set price feeds, set Pyth source |

### Granting and Revoking Roles

#### Via SDK

```typescript
import { Factory } from '@spree-finance/spree-evm-sdk';

const factory = new Factory(config);

// Get the role constant
const executorRole = await factory.readExecutorRole();

// Grant role
const grantTx = await factory.grantRole(executorRole, '0xNewExecutor');

// Revoke role
const revokeTx = await factory.revokeRole(executorRole, '0xOldExecutor');

// Check role
const hasRole = await factory.readHasRole(executorRole, '0xAddress');

// Get role admin (which role can grant/revoke this role)
const adminRole = await factory.readGetRoleAdmin(executorRole);
```

#### Via API

```bash
# Grant
curl -X PUT https://api.stg.spree.finance/api/v1/roles/grant \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "contract": "factory",
      "role": "EXECUTOR_ROLE",
      "account": "0xTargetAddress"
    },
    "key": "0xAdminAddress"
  }'

# Revoke
curl -X DELETE https://api.stg.spree.finance/api/v1/roles/revoke \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "contract": "factory",
      "role": "EXECUTOR_ROLE",
      "account": "0xTargetAddress"
    },
    "key": "0xAdminAddress"
  }'

# Check
curl https://api.stg.spree.finance/api/v1/roles/check/factory/EXECUTOR_ROLE/0xAddress
```

### Renouncing Roles

An address can renounce its own role. This is irreversible unless the admin grants it again.

```typescript
const myRole = await factory.readExecutorRole();
const renounceTx = await factory.renounceRole(myRole, '0xMyAddress');
```

The second parameter must match `msg.sender` on-chain (a safety check to prevent accidental renunciation).

### Pausability

Every core contract supports pause/unpause. Pausing blocks all state-changing operations.

```typescript
// Factory
const pauseTx = await factory.pause();
const unpauseTx = await factory.unpause();
const isPaused = await factory.readPaused();

// SpreeVault4626
const vaultPauseTx = await vault.pause();
const vaultIsPaused = await vault.readPaused();

// BonusRewardsVault
const rewardsPauseTx = await rewards.pause();
const rewardsIsPaused = await rewards.readPaused();
```

Required role: PAUSER\_ROLE (or FREEZER\_ROLE on Factory via API).

### UUPS Upgradeability

All contracts are UUPS proxies. Upgrades replace the implementation while preserving state and address.

```typescript
// Upgrade to a new implementation
const upgradeTx = await factory.upgradeToAndCall(
  '0xNewImplementation',
  '0x', // no initialization data
);
```

Required role: DEFAULT\_ADMIN\_ROLE (or UPGRADER\_ROLE on vault contracts).

### Security Checklist

* Grant the minimum required roles per address. A single address should not hold ADMIN and EXECUTOR.
* Use separate addresses for operations (EXECUTOR, HARVESTER) and administration (ADMIN).
* Test role changes on Base Sepolia before mainnet.
* Monitor for unexpected `RoleGranted` and `RoleRevoked` events.
* Keep the ADMIN key in a multisig or hardware wallet.
