Policies and Governance
Manage source policies, delayed configuration changes and coverage renewal.
Source policies and note attachments#
PolicySet decides source admission for screened Pending inputs. notePolicyCommitment is an opaque attachment used for holder-run queries; the Pool never reads it. A source-policy change can affect a Pending spend. A note attachment cannot restrict that spend.
A source policy records root, epoch, coverage, publication block, activation block, exclusive expiry and mode. Mode zero requires membership; mode one requires non-membership. Coverage is the latest completed deposit block included in the policy. The Pool's fixed minDelay sets the minimum Pending age in completed blocks, not seconds.
Update a source list#
The candidate source set is a depth-32 authenticated interval tree. Addresses are encoded as uint160(source) + 1, which lets the tree represent address zero without using its lower sentinel. publisherInsertPolicySource checks the predecessor path, then the next empty slot against the intermediate root. The publisher cannot supply an arbitrary replacement root.
Deletion checks the predecessor and target intervals. It updates the predecessor first and verifies the target against that intermediate root. Deleted slots stay unused. PolicyInserted and PolicyDeleted describe candidate changes; PolicyScheduled records the root, mode and schedule for screened spending.
publisherPublishPolicy requires coverage to precede the publication block, activation no earlier than the current block, and expiry after activation. An unactivated schedule cannot be replaced. effectivePolicy switches to the scheduled policy at activation. It can return an expired record, so also check its validity interval.
struct Policy {
uint256 root;
uint64 epoch;
uint32 coverage;
uint32 published;
uint32 activate;
uint32 expires;
uint8 mode;
}
function effectivePolicy() public view returns (Policy memory);
function publisherPublishPolicy(
uint8 _mode, uint32 _coverage, uint32 _activate, uint32 _expires
) external;Delayed proposals#
FuyuGovernor publishes Pool configuration and manages its own roles. Council and guardian must be contract accounts. Its fixed delay is at least seven days and no more than 90 days. councilPropose records an ordered array of target/data calls and salt. Once ready, anyone can execute those calls within the 14-day grace window.
After genesis, adding token or route support, widening source admission and changing roles require delayed proposals. The governor allows specific targets and selectors rather than arbitrary calls. During genesis, the fixed operator can configure the deployment without delay until genesis closes or 30 days pass.
governanceAdmitRoute checks the adapter code hash and can protect an exit route. successor announces a Pool for voluntary migration. Holders must choose to migrate; setting successor cannot replace their Pool or move their notes.
struct Call { address target; bytes data; }
function proposalId(Call[] calldata _calls, bytes32 _salt)
public view returns (bytes32);
function councilPropose(Call[] calldata _calls, bytes32 _salt)
external returns (bytes32 id);
function execute(Call[] calldata _calls, bytes32 _salt) external;
function governanceAdmitRoute(
address _adapter, uint8 _operation, address _assetIn,
address _assetOut, bytes32 _codeHash, bool _protected
) external;Guardian and reviewer permissions#
The guardian or council can immediately revoke an unprotected route and cancel eligible proposals. A standalone proposal replacing the guardian has special veto rules so the outgoing guardian cannot block its replacement indefinitely. Immediate source denial applies only to the effective DENY list, with a shared limit of 64 successful additions per UTC day.
This quota limits additions, not who can be targeted or how far the anonymity set can shrink. Calls on either side of a UTC midnight can use twice the daily quota in a short interval. Removing sources or widening admission still needs governance after genesis.
The reviewer can extend coverage only if the candidate root matches the effective root. Renewal keeps the mode and cannot reduce coverage or expiry. The reviewer cannot replace the list. Governance can schedule activation at most 300 blocks ahead, with policy lifetime between 7,200 and 2,628,000 blocks.
| Role | Permission | Constraint |
|---|---|---|
| Council | Propose wider admission and role changes | Wait for the execution delay; calls must pass validation |
| Guardian or council | Revoke routes and veto eligible proposals | Protected exits and guardian replacement have special rules |
| Guardian or council | Add sources to DENY | Current root/mode must match; at most 64 additions per UTC day |
| Reviewer | Extend coverage of the list in force | Keep root/mode and do not shorten coverage or expiry |
| Genesis operator | Configure the new deployment | Genesis closes explicitly or after 30 days |
Renew coverage when the operator stops#
Install FuyuCoverageRenewer as the governor's reviewer to enable a public renewal path. It fixes governor and optional operator at deployment, holds no funds and has no setters. operatorRenew forwards a schedule through the reviewer checks. operatorRenewAfter creates a schedule that activates when the transaction executes.
Anyone can call renew after 3,600 blocks without an operator renewal, if coverage lags by at least 3,600 blocks and the 3,600-block public rate limit permits it. Renewal covers the previous block and activates immediately. Expiry is at least 100,000 blocks later, while any longer existing expiry is preserved.
renewStatus returns a refusal selector, nextBlock, proposed coverage and expiry. nextBlock assumes no intervening state changes. A pending schedule, edited candidate list or replacement reviewer can change the result. Handle NotDue, OperatorActive, RateLimited, SchedulePending, ListChanged and NotReviewer instead of estimating readiness from time alone.
Prepared proofs and exits#
A screened proof works while its root and mode remain in force, the policy is active, and coverage reaches the block named by the proof. Renewing the same list keeps the proof and its controller approval usable. A denial or another root can require a new proof.
Anyone can still finalize an action that has already executed, regardless of new route admission or source coverage. A source-revealing exit publishes one full Pending deposit's original source and amount. The holder chooses the public withdrawal recipient separately. This exit does not require return to the original sender and gives no compliance verdict.
Governance cannot change the private ownership relation or transfer note custody. Publisher decisions can still affect new admission and whether Pending notes can be spent. Show your deployment's publisher and active schedule so users can see who controls those decisions.