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

# Eligibility and attestations

Which wallets may borrow, lend, liquidate or relay on Gimbal, what an attestation holds, how the registry answers, and the calls that stop when the answer is no.

Every gate in the protocol is built from one view function:

```solidity
function isEligible(address account, bytes32 role) external view returns (bool);
```

A Stock Token places no limit on who may hold it. Robinhood does its screening at the app boundary and at the KYC'd desks where tokens are minted and redeemed, so on chain the token moves freely. A protocol lending against it has to draw a boundary of its own, and Gimbal draws it with this function: a wallet without a valid record for the role it needs cannot fund a loan, open one, join a rollover, buy at a collateral auction or take a slice token. The revert comes before any balance moves. Views carry no such check, so an indexer, an explorer or an aggregator reads the entire book without holding a role.

## The five roles

Roles are `bytes32` keys. `Roles.BORROWER` is `keccak256("gimbal.role.BORROWER")`; the other four are built the same way.

| Key                   | Status  | Held by                                                                                                                                                                   |
| --------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BORROWER`            | Live    | KYC'd wallets outside every restricted jurisdiction, the same list the Stock Tokens use. Today: verified businesses, professional clients and high-net-worth individuals. |
| `LENDER_PROFESSIONAL` | Live    | Clients classed as professional under the regime that applies to them: credit funds, market makers, family offices                                                        |
| `LENDER_RETAIL`       | Roadmap | Retail lenders, enabled market by market wherever the rules allow                                                                                                         |
| `LIQUIDATOR`          | Live    | Any address allowed to buy collateral at auction or receive it in an in-kind settlement                                                                                   |
| `RELAYER`             | Live    | Services that submit a signed borrow request for the borrower                                                                                                             |

## Where a call can stop

| Call                                   | Who must hold a role                                                                                                                  |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `TermDesk.originate`                   | The borrower on the request (`BORROWER`); the sender, when it is not the borrower (`RELAYER`); every offer maker (either lender role) |
| `RolloverAuction.accept`               | The maker of the incoming offer (either lender role)                                                                                  |
| `TermDesk.clearRefinance`              | Each lender of the new syndicate, checked again as slices are minted                                                                  |
| `CollateralAuction.buy`                | The buyer (`LIQUIDATOR`)                                                                                                              |
| `LenderSlice` transfer between holders | The recipient (either lender role). Mints and burns by the desk skip the check                                                        |

Two paths carry no check by design: `repay` returns the escrow to the borrower on record, and nothing can hold that transfer; a lender paid in kind was checked when the slice was minted, and again if it ever moved.

## How the registry answers

`RoleRegistry` holds no rules. It forwards each question to the adapter that `PolicyBoard.eligibilityAdapter()` names, resolved on every call and never cached, so a policy change applies immediately; with no adapter set it reverts with `AdapterNotSet`. It also exposes `isLender`, the reverting forms `requireRole` and `requireLender` (error `NotEligible`), and `attestationOf` for a record's uid and expiry.

## What a record holds

A role is proved by an attestation the KYC provider issues after identity, sanctions and residency screening all pass. The record follows the shape the Ethereum Attestation Service defines and is ONCHAINID-compatible. Inside it:

* the wallet;
* the role;
* a jurisdiction class (the country itself only if the user elects to reveal it);
* an investor class, when one is relevant;
* an expiry date.

Nothing more. No name, no document, nothing that identifies a person. A record lapses at its expiry and is kept current by re-screening on a rolling basis; revoking one takes effect the moment it is written.

A wallet can instead present a Privado ID or zkPass credential which shows it is eligible under jurisdiction class X with investor class Y, revealing neither the provider behind the check nor any attribute beneath it. To the registry both proofs count the same.

## The bundled ledger

The adapter the deploy script installs is `AttestationLedger`, Gimbal's own EAS-shaped store for chains where EAS is not available. Only issuers approved in `PolicyBoard` may write, and approval is read from policy on each call: dropping an issuer takes effect at once and disables every record it wrote.

`attest(account, role, bytes2 jurisdictionClass, uint8 investorClass, uint64 expiry)` writes a record and emits `Attested`; the expiry must be in the future (`BadExpiry` otherwise), and a later call for the same wallet and role overwrites the record whole. `revoke(account, role)` marks it revoked and emits `Revoked`; any approved issuer may revoke any record, so one can clean up after another that was compromised. `isEligible` is true only while the record exists, is unrevoked, is unexpired and its issuer is still approved. The class codes are the issuer's own; the protocol stores them for indexers and never interprets them.

## Swapping the engine

Because the registry only delegates, the backend can change without touching the contracts that depend on it:

* an **EAS adapter** that looks attestations up by their schema and their issuer;
* an **ONCHAINID adapter** for ERC-3643-compatible identities;
* a **Chainlink ACE / CCID adapter** as a second policy engine that governance can enable.

The approved issuers (`setAttestationIssuer`) and the active adapter (`setEligibilityAdapter`) are `PolicyBoard` settings. Narrowing the issuer list or moving to another provider is a parameter change, timelocked and logged, never a redeployment. See [How parameters change](/transparency/parameter-changes.md). The platform mirrors the records in its `attestations` table so the settings page can show a wallet its roles; see [How the platform is built](/architecture/platform.md).

## Tokens with rules of their own

If ERC-7943 (uRWA) or ERC-3643 hooks arrive on Stock Tokens or on bridged RWAs, the escrow calls `canTransfer` and `canReceive` before moving anything and is itself placed on the issuer's allowlist. Both rule sets hold at once, and neither side depends on the other being right. [Collateral still to come](/collateral/next-markets.md) has more.

## Restricted jurisdictions, four times over

Four layers stand between a restricted jurisdiction and the protocol, and none relies on another:

1. Wallets from restricted jurisdictions are refused an attestation outright.
2. During onboarding each wallet self-attests where it is based.
3. IP geo-fencing in the front-end blocks restricted jurisdictions.
4. The sequencer screens for sanctions independently.

[Jurisdictions](/compliance/jurisdictions.md) has the specifics.


---

# 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.usegimbal.app/architecture/eligibility.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.
