# Guard system

For the risk-model framing — what the Guard System prevents and why — see [Security: guard system](/security/guard-system.md). This page is the integrator's side: how to write calls that don't revert, how to enumerate what's supported, and how to surface failures back to users.

## Call flow

Every vault interaction flows through `PoolLogic.execTransaction(address to, bytes data)`:

1. The vault looks up the **contract guard** registered for `to` via the factory.
2. The guard's `txGuard(poolManagerLogic, to, data)` is called. It decodes the calldata, enforces protocol-specific rules, and returns a `txType` plus `isPublic` flag.
3. If the contract guard returns `txType == 0` (no match or rejection), or isn't registered, the vault falls back to the **asset guard** for `to`. If no asset guard is registered either, it defaults to the governance-configured `ERC20Guard` as a last resort. A revert with `dh23` means every layer returned `txType == 0`.
4. On approval, the external call executes.
5. Some guards implement `afterTxGuard` to track post-call state (for example, recording open perp positions).

The manager/trader permission check happens at the vault layer before the guard runs. The guard itself doesn't distinguish manager from trader — see [trader delegation](/manage/trader-delegation.md) for how that's enforced.

## Two guard categories

**Contract guards** — registered against a destination contract address (a swap router, a lending pool, a position manager). They govern *what calls* can be made to that contract. Examples: `OneInchV6Guard`, `AaveLendingPoolGuardV3`, `UniswapV3NonfungiblePositionGuard`, `GmxExchangeRouterContractGuard`.

**Asset guards** — registered against an asset type (a token, an LP NFT, a perp position). They govern *how the vault holds and unwinds that asset* — balance calculation, USD pricing, withdrawal behavior. Examples: `ERC20Guard`, `UniswapV3AssetGuard`, `AaveLendingPoolAssetGuard`, `HyperliquidPositionGuard`.

A single vault operation may touch both. A Uniswap V3 mint needs the position manager contract guard to approve the call and an asset guard registered for the resulting LP NFT so the vault can price and withdraw it.

## Enumerating support

**Is this protocol callable from a vault?**

```solidity
address guard = PoolFactory(factory).getContractGuard(destination);
// guard == address(0)  → call will revert with dh23
// guard != address(0)  → call MAY succeed, depending on the guard's rules
```

**Is this asset supported?**

```solidity
address assetGuard = PoolFactory(factory).getAssetGuard(asset);
// assetGuard == address(0)  → asset cannot be added to a vault
```

**Is this asset enabled on a specific vault?**

```solidity
PoolManagerLogic(pml).isSupportedAsset(asset);   // can be traded/held
PoolManagerLogic(pml).isDepositAsset(asset);     // can be used to deposit
```

A guard being registered globally is necessary but not sufficient — the manager also has to have enabled that asset on their vault.

## Common revert codes

Vault reverts use `dh`-prefixed strings. The full list of codes with descriptions is maintained in the contracts repo:

[`dHEDGEV2ErrorCodes.json`](https://github.com/dhedge/V2-Public/blob/master/readmes/errorCodes/dHEDGEV2ErrorCodes.json)

## Guard registry

The exact set of guards differs per chain (see [deployment matrix](/build/deployment-matrix.md)). The full per-chain lists of contract guards, asset guards, and deprecated guards are maintained in the [`config/`](https://github.com/dhedge/V2-Public/tree/master/config) directory of the contracts repo — each chain folder contains:

* `dHEDGE Governance Contract Guards.csv` — registered contract guards
* `dHEDGE Governance Asset Guards.csv` — registered asset guards
* `dHEDGE Assets list.json` — supported assets

You can also query `getContractGuard()` and `getAssetGuard()` on the factory at runtime.

## See also

* [Security: guard system](/security/guard-system.md) — the risk framing
* [Contract addresses](/build/contract-addresses.md) — where to find the factory
* [SDK](/build/sdk.md) — typed helpers for guard queries
* [Deployment matrix](/build/deployment-matrix.md) — per-chain guard availability


---

# Agent Instructions: 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:

```
GET https://docs.chamberfi.com/build/guard-system.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
