> For the complete documentation index, see [llms.txt](https://docs.enzyme.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.enzyme.finance/onyx-protocol/architecture/compliance.md).

# Compliance

Onyx vaults can enforce on-chain compliance through the [Chainlink Automated Compliance Engine (ACE)](https://docs.chain.link/ace). When enabled, compliance-relevant actions — shares transfers, deposits, redemptions, and direct mints and burns — are checked against a set of policies before they take effect. Any action that a policy rejects reverts, so it never happens.

Compliance gating is opt-in and configured per vault. A vault with no validators attached performs no ACE checks; a vault can also gate only a subset of actions, leaving the others ungated.

#### How Validation Works

Every gated action follows the same pattern. The contract that owns the action — an issuance handler, or the Shares contract itself for transfers — calls a dedicated validator before (or, for some actions, immediately after) committing the action. The validator forwards the check to its attached policy engine. The engine looks up the extractor registered for that action, which decodes the action's details from the call data, and then evaluates its ordered chain of policies against those details. If every check passes, execution continues; if any policy rejects, the entire transaction reverts and the action does not happen. If the chain produces no explicit result, the engine's configured default (allow or reject) applies.

```mermaid
sequenceDiagram
    participant Caller
    participant Component as Handler or Shares
    participant Validator
    participant Engine as Policy Engine
    participant Extractor
    participant Policy as Policies

    Caller->>Component: action (transfer, deposit request, mint, ...)
    Component->>Validator: validate action
    Validator->>Engine: run policy check
    Engine->>Extractor: extract action details from call data
    Extractor-->>Engine: decoded details
    loop ordered policy chain
        Engine->>Policy: evaluate
        Policy-->>Engine: allow / reject
    end
    alt all policies allow
        Engine-->>Validator: allowed
        Validator-->>Component: continue
        Note over Component: action proceeds
    else any policy rejects
        Note over Caller,Policy: transaction reverts and the action does not happen
    end
```

Each gated action has its own validator. An issuance validator is bound to exactly one handler and only accepts calls from it, and the shares transfer validator only accepts calls from the Shares contract. Each validator carries its own policy engine attachment, so different actions can be pointed at the same engine or at different ones.

#### Shares Transfers

The Shares contract can be configured with a shares transfer validator. When one is set, every shares transfer — direct transfers and approved third-party transfers alike — is run through the policy engine before the balances move. A rejected transfer reverts. When no validator is set, transfers are unrestricted.

#### Deposits and Redemptions

The async deposit queue and redeem queue each expose two gating points:

* **Before a request is accepted.** When a depositor submits a deposit or redemption request, the request is validated before it is committed to the queue and before any assets or shares are taken from the depositor. A rejection reverts the request transaction, so nothing is escrowed.
* **After a request is executed.** When the vault operator executes queued requests, each executed request is validated again in the same transaction, after shares are issued (for deposits) or after the redemption settles. A rejection reverts the execution, undoing the settlement. Because requests are executed in batches, one rejected request reverts the whole batch.

The two hooks are independent: a vault can gate only request submission, only execution, or both.

Sync deposits have a single gating point: the deposit is validated in the same transaction that settles it, immediately after shares are minted and the deposit assets are transferred. A rejection unwinds the entire deposit atomically — the depositor keeps their assets and no shares are issued.

#### Direct Mint and Burn

Vaults that mirror off-chain settlement use the mint handler and burn handler to issue and destroy shares directly. Both are gated the same way: each mint or burn is validated before it is committed. When a batch of mints or burns is submitted, a single rejection reverts the whole batch.

#### Configuration and Roles

Two parties control the two sides of the system:

* **The vault admin or owner** controls the Onyx side: setting or unsetting the shares transfer validator on the Shares contract, setting or unsetting each handler's hooks (an empty value disables gating for that action), and replacing the policy engine attached to any validator.
* **The policy engine's own administrator** controls the compliance rules themselves: which policies run, their order, the extractors, and the engine's default allow-or-reject behavior. Policies can be added, removed, or reordered on the engine without any change to the vault's contracts.

#### Policies

Policies are composable rule modules that live in the policy engine, outside of Onyx. What a given vault enforces depends entirely on which policies its engine runs. Illustrative examples of what policies can express — not a statement of what any particular vault has deployed — include:

* allowlists or denylists of addresses permitted to transact,
* volume caps that limit amounts per transaction or per time window,
* a pause policy that temporarily rejects all activity.

For the full policy model, the library of prebuilt policies, and guidance on composing them, see the [Chainlink ACE documentation](https://docs.chain.link/ace).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.enzyme.finance/onyx-protocol/architecture/compliance.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
