Permission Rules
Cocoon's PermissionRegistry contract enforces argument-level permissions — constraints on the values of method arguments, not just whether a role can call a method. This page documents the rule format, the default role matrix, and how to manage rules.
Argument-level permissions are a key Cocoon differentiator. Most permissioning systems enforce function-level access ("Trader can call transfer"). Cocoon's PermissionRegistry enforces argument-level constraints ("Trader can call transfer, but only with amount ≤ $1,000,000").
Rule Format
A permission rule is a tuple of:
(role, method, argument, constraint_type, constraint_value)role
string
The user role this rule applies to: Trader, SeniorTrader, Compliance, Auditor, Regulator, Admin
method
string
The JSON-RPC method name (e.g. token_transfer)
argument
string
The argument name to constrain (e.g. amount)
constraint_type
string
One of: max_value, min_value, exact_value, blocked, allowed
constraint_value
string (numeric)
The constraint threshold, encoded as a decimal string
Constraint Types
max_value
Argument must be ≤ this value
Trader transfer ≤ $1M
min_value
Argument must be ≥ this value
Minimum subscription amount
exact_value
Argument must equal this value
Token address must be a specific contract
blocked
This role may not call this method at all
Auditor cannot call token_transfer
allowed
No constraint; this role may call freely
Admin is allowed all methods
Encoding Amounts
Amounts in permission rules are stored in the token's smallest unit (18 decimals for most ERC-20 tokens). Human-readable values:
$1,000
1000000000000000000000 (1,000 × 10^18)
$1,000,000
1000000000000000000000000 (1,000,000 × 10^18)
$5,000,000
5000000000000000000000000 (5,000,000 × 10^18)
The admin dashboard's permission editor handles this encoding automatically — enter amounts in human-readable form and the dashboard converts them.
Default Role Matrix
The following rules are deployed by default in contracts/deploy.sh. They reflect the intended demo permission structure for the MVP.
Trader
token_transfer
amount
≤ $1,000,000
Trader
token_batchTransfer
amounts[*]
Each ≤ $1,000,000
SeniorTrader
token_transfer
amount
≤ $5,000,000
SeniorTrader
token_batchTransfer
amounts[*]
Each ≤ $5,000,000
Compliance
token_freeze
—
allowed
Compliance
token_unfreeze
—
allowed
Compliance
All write methods except freeze
—
blocked
Auditor
All write methods
—
blocked
Regulator
All write methods
—
blocked
Admin
All methods
—
allowed (unrestricted)
Managing Rules
Via the Admin Dashboard
Navigate to http://localhost:3000/permissions
The rule table shows all active rules
Click Add Rule to create a new constraint
Click any rule row to edit the constraint value
Toggle the Active switch to disable a rule without deleting it
Via the PermissionRegistry Contract
Rules are stored on-chain in the PermissionRegistry contract. The contract address is in deployments.json.
Via the Backend Proxy API
Permission Enforcement
When a request arrives at the backend proxy:
The caller's role is read from the validated session token.
The proxy queries the
PermissionRegistryfor rules matching(role, method, argument).For each matching rule, the corresponding argument value from the request is compared against the constraint.
If any rule is violated, the proxy returns JSON-RPC error
-32001 TransferNotAllowedwith a message describing the violated rule.The blocked request is logged to the audit database with
status: blocked.
Error Response Format
The message field is human-readable and includes the violated rule in plain language, making it suitable for direct display in investor-facing UIs.
Adding a Custom Rule
Scenario: Your compliance team requires that no single investor can redeem more than $500,000 worth of MMF tokens in a single transaction.
In the admin dashboard, navigate to Permissions → Add Rule.
Set:
Role:
TraderMethod:
token_redeemArgument:
sharesConstraint: Max Value = $500,000 (the dashboard converts to
500000000000000000000000)
Click Save. The rule is written to the
PermissionRegistrycontract and takes effect immediately.
Alternatively, via the contract:
Security Notes
Rules are stored on-chain and cannot be silently modified — any change is a contract transaction and is auditable.
The backend proxy enforces rules before forwarding to the chain. This is a defense-in-depth measure; the chain itself does not enforce argument-level rules.
To enforce rules at the chain level (without relying on the proxy), the
PermissionRegistrycan be called directly from token transfer hooks — this is a planned enhancement.
Last updated