# Deployments API

> Machine-readable JSON registry of every deployed Grunt contract, tagged with its contract kind, layer and role bit values, with CORS enabled for any origin.


The [deployments pages](/protocol/deployments/) are generated from a single
typed config. The same config is published as JSON so tooling such as a Safe
transaction verifier, a dashboard or a monitoring bot can resolve any address
to what it is without scraping HTML.

## Endpoints

| Endpoint | Description |
|----------|-------------|
| [`/deployments.json`](/deployments.json) | Every deployed address on every network, tagged with its **contract kind** and **layer**, plus Morpho market ids and the **role bit values** behind `grantRoles` on each contract. |
| [`/search-addresses.json`](/search-addresses.json) | A flat exact-match index (address or market id to label and docs link) that powers the site search. Prefer `deployments.json` for anything beyond a lookup. |

Both endpoints are static files regenerated on every deploy, and both are served
with `Access-Control-Allow-Origin: *`, so they can be fetched from a browser on
any origin as well as from a server.

```bash
curl -s https://docs.3f.xyz/deployments.json \
  | jq '.contracts[] | select(.address | ascii_downcase == "0x4e013ca8ff612a58f53c822904cdd0ec538a4a4f")'
```

## Why kinds matter

Many selectors are shared across contracts. `grantRoles(address,uint256)` exists
on the Facility, every PositionManager, every fund, the TransferGuard and more,
and the `uint256` bitmask means something different on each. The `to` address
of a call is therefore the identifier that disambiguates it: resolve
`(chainId, to)` to a `kind`, then decode the selector and arguments against that
kind's role table.

Suggested resolution order for an arbitrary address:

1. **Known address.** Look it up in `contracts` by `chainId` and lowercased
   `address`. The entry carries `kind`, `layer`, a human `label`, the
   integration it belongs to and, for position manager tiers, the leverage,
   symbol, LTVs and sibling addresses.
2. **Beacon proxy.** If unknown, read the EIP-1967 beacon slot of the address
   and match it against entries with `layer: "beacon"`. Their `of` field is the
   kind of every proxy pointing at that beacon, which classifies instances the
   factories created after the docs were last updated.
3. **Transparent proxy.** Otherwise read the EIP-1967 implementation slot and
   match it against entries with `layer: "implementation"`, which also gives
   the `version`.
4. **Still unknown.** Treat the target as unrecognised and surface it as such.

## Schema

Top-level fields of `deployments.json`:

| Field | Contents |
|-------|----------|
| `schemaVersion` | Integer, bumped on breaking changes to this shape. |
| `contractsVersion` | Contracts release the role values were read from. |
| `networks` | `id`, `chainId`, `label`, `explorer`, `status` per network. |
| `kinds`, `layers` | The distinct `kind` and `layer` values present in `contracts`. |
| `contracts` | One entry per address: `chainId`, `network`, checksummed `address`, `kind`, `layer`, optional `of` (beacons), `version` (implementations), `label`, `integration`, `section`, `notes`, tier fields, `docs` and `explorer` links. An address listed in several tables appears once, under the first table that lists it. |
| `markets` | Morpho market ids with `chainId`, `label`, `integration` and links. |
| `roleModels` | For each access-control model, the function signatures that change access. |
| `roles` | Per kind: the model (`OwnableRoles`, `EnumerableRoles`, `Ownable`, `none`), the source file and each role's `name`, `index`, on-chain `value` and `description`. |

`layer` values: `proxy` (what transactions target), `implementation`, `beacon`,
`factory`, `singleton`, `external` and `account`.

## Role bit values

Solady `OwnableRoles` stores roles as a bitmask where role *n* has value
`1 << n`; a `grantRoles` argument may combine several. The Upgrade Timelock uses
Solady `EnumerableRoles` instead, where the role is a plain index passed to
`setRole`. The table below is rendered from the same registry that feeds the
JSON.

<RoleBits />

See [Roles](/developer/roles/) for what each role can do in context.