PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/gnoswap/access/v1

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v1
Namespace
gnoswap / access
Files
5 (README)(gnomod.toml)
Exported functions
22
Module
gno.land/r/gnoswap/access/v1
gno
0.9

Files (5)

  • README.mdmarkdown
  • gnomod.tomltoml
  • access.gnogno
  • assert.gnogno
  • errors.gnogno
README.mdPreviewRaw
# Access

Centralized role-based access control system for GnoSwap protocol contracts.

## Overview

The Access package provides a unified permission management system for all GnoSwap protocol contracts. It manages role-to-address mappings and provides convenient assertion functions for authorization checks throughout the protocol.

This package acts as a centralized registry where protocol components and user-controlled accounts can be assigned role addresses. Other contracts can then query this registry to verify permissions before executing privileged operations.
Admin role ownership is managed by the RBAC realm and is updated on ownership transfer; this package only stores the latest role address.
The `admin` and `devops` roles are initialized with user-controlled addresses. Most other system roles use deterministic package addresses, while custom roles may use any valid address.

## Architecture

The access control system consists of:

1. **Role Registry**: Maps role names (strings) to role addresses (contracts or accounts)
2. **Role Management**: Functions to set/remove roles (RBAC-only)
3. **Authorization Checks**: Functions to verify if an address has a specific role
4. **Assert Helpers**: Convenience functions that panic on authorization failure

## System Roles

The following roles are used across the GnoSwap protocol:

- **admin**: Protocol administrator with elevated privileges
- **devops**: DevOps operations for system maintenance
- **governance**: Governance contract for protocol decisions
- **router**: Swap router for token exchanges
- **pool**: Pool management contract
- **position**: Position NFT management
- **staker**: Liquidity staking contract
- **emission**: GNS token emission controller
- **protocol_fee**: Protocol fee collection and distribution
- **community_pool**: Community treasury management
- **launchpad**: Token launchpad for new projects
- **gov_staker**: Governance staking contract
- **xgns**: xGNS token contract for governance

## Key Functions

### Role Management (RBAC Only)

#### `SetRoleAddress`

Sets or updates a role's address. Creates new role if it doesn't exist.
The `admin` role is updated by RBAC ownership transfers and should not be managed directly by other contracts.

```go
// Only callable by RBAC contract
access.SetRoleAddress(cross(cur), "router", routerAddress)
```

#### `RemoveRole`

Removes a role from the system.

```go
// Only callable by RBAC contract
access.RemoveRole(cross(cur), "old_role")
```

### Role Query Functions

#### `GetAddress`

Returns the address for a role and whether it exists.

```go
addr, exists := access.GetAddress("router")
if !exists {
    // Handle missing role
}
```

#### `MustGetAddress`

Returns the address for a role or panics if it doesn't exist.

```go
// Panics if role doesn't exist
routerAddr := access.MustGetAddress("router")
```

#### `GetRoleAddresses`

Returns a copy of all role-to-address mappings.

```go
allRoles := access.GetRoleAddresses()
for roleName, addr := range allRoles {
    println(roleName, "->", addr)
}
```

### Authorization Functions

#### `IsAuthorized`

Checks if an address has a specific role (non-panicking).

```go
if access.IsAuthorized("admin", caller) {
    // Caller is admin
}
```

### Assert Functions (Panic on Failure)

These functions panic with a descriptive error if authorization fails:

#### `AssertIsAdmin`

Requires admin role.

```go
access.AssertIsAdmin(caller)
```

#### `AssertIsGovernance`

Requires governance role.

```go
access.AssertIsGovernance(caller)
```

#### `AssertIsAdminOrGovernance`

Requires either admin or governance role.

```go
access.AssertIsAdminOrGovernance(caller)
```

#### Role-Specific Assertions

```go
access.AssertIsRouter(caller)
access.AssertIsPool(caller)
access.AssertIsPosition(caller)
access.AssertIsStaker(caller)
access.AssertIsEmission(caller)
access.AssertIsProtocolFee(caller)
access.AssertIsLaunchpad(caller)
access.AssertIsGovStaker(caller)
access.AssertIsGovXGNS(caller)
```

#### `AssertIsAuthorized`

Generic authorization check for any role.

```go
access.AssertIsAuthorized("custom_role", caller)
```

#### `AssertHasAnyRole`

Requires the caller to have at least one of the specified roles.

```go
access.AssertHasAnyRole(caller, "admin", "governance", "devops")
```

### Validation Functions

#### `AssertIsValidAddress`

Panics if the address is invalid.

```go
access.AssertIsValidAddress(addr)
```

## Usage Examples

### Example 1: Protecting Admin Functions

```go
package pool

import "gno.land/r/gnoswap/access/v1"

func SetPoolFeeRate(cur realm, rate uint64) {
    caller := cur.Previous().Address()
    access.AssertIsAdminOrGovernance(caller)

    // Admin/governance authorized, proceed
    setFeeRate(rate)
}
```

### Example 2: Role-Based Function Access

```go
package staker

import "gno.land/r/gnoswap/access/v1"

func DistributeRewards(cur realm, amount uint64) {
    caller := cur.Previous().Address()
    access.AssertIsEmission(caller)

    // Only emission contract can distribute
    distributeToStakers(amount)
}
```

### Example 3: Multi-Role Authorization

```go
package common

import "gno.land/r/gnoswap/access/v1"

func EmergencyPause(cur realm) {
    caller := cur.Previous().Address()
    access.AssertHasAnyRole(caller, "admin", "devops", "governance")

    // Any of the authorized roles can pause
    pauseProtocol()
}
```

### Example 4: Non-Panicking Authorization Check

```go
package router

import "gno.land/r/gnoswap/access/v1"

func GetSwapFee(caller address) uint64 {
    // Lower fee for admin
    if access.IsAuthorized("admin", caller) {
        return 0 // Admin gets free swaps
    }

    return standardFee
}
```

## Security Model

### Centralized Management

- All role assignments are managed through this single contract
- Provides a unified view of permissions across the entire protocol
- Prevents inconsistencies in authorization logic

### RBAC-Only Updates

- Only the RBAC contract can modify role assignments
- Uses package address verification to enforce this restriction
- Prevents unauthorized role manipulation

### Explicit Authorization

- All authorization checks are explicit and auditable
- Panic-based assertions make authorization failures obvious
- No implicit or default permissions

## Integration with RBAC

The Access contract works in conjunction with the RBAC (Role-Based Access Control) package:

1. **RBAC**: Manages role definitions and ownership transfer
2. **Access**: Provides centralized role-to-address registry and authorization checks

Role updates flow: `RBAC.UpdateRoleAddress()` → `Access.SetRoleAddress()`

## Best Practices

1. **Use Assertions for Critical Functions**: Always use assert functions for operations that should only proceed with proper authorization
2. **Check Existence Before Use**: Use `GetAddress` when you need to handle missing roles gracefully
3. **Document Role Requirements**: Clearly document which roles are required for each function
4. **Avoid Hardcoding Addresses**: Always use role-based checks instead of hardcoding addresses
5. **Test Authorization**: Thoroughly test all authorization paths in your contracts

## Error Handling

Authorization failures result in panics with descriptive error messages:

- `"unauthorized: caller X is not Y"` - Caller doesn't have required role
- `"role X not found"` - Role lookup failed because the role has not been registered
- `"role X does not exist"` - `RemoveRole` was asked to remove an unknown role
- `"invalid address: X"` - Address validation failed

## Limitations

- Role names are case-sensitive strings
- Each role can only map to one address at a time
- Role changes take effect immediately (no timelock)

Functions

  • AssertHasAnyRole(caller string, roleNames ...string)

  • AssertIsAdmin(caller string)

  • AssertIsAdminOrGovernance(caller string)

  • AssertIsAuthorized(roleName string, caller string)

  • AssertIsEmission(caller string)

  • AssertIsGovernance(caller string)

  • AssertIsGovStaker(caller string)

  • AssertIsGovXGNS(caller string)

  • AssertIsLaunchpad(caller string)

  • AssertIsPool(caller string)

  • AssertIsPosition(caller string)

  • AssertIsProtocolFee(caller string)

  • AssertIsRlmCurrent(int, rlm interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • AssertIsRouter(caller string)

  • AssertIsStaker(caller string)

  • AssertIsValidAddress(addr string)

  • GetAddress(role string) (string, bool)

  • GetRoleAddresses() map[string].uverse.address

  • IsAuthorized(role string, caller string) bool

  • MustGetAddress(role string) string

  • RemoveRole(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, roleName string)

  • SetRoleAddress(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, roleName string, roleAddress string)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

Rendered

RenderedRawgnoweb ↗

Render unavailable

rate limit exceeded — the render query is served by the Gnoland archive RPC.

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.