Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
957b00f
docs: Upgrade the router contract
dianab-cl Oct 16, 2026
89a27c8
Update
dianab-cl Oct 16, 2026
00eb229
Merge branch 'main' into diana/fou-1881-document-the-contract-upgrade…
dianab-cl Oct 16, 2026
53a1449
Update
dianab-cl Oct 16, 2026
65dcd16
Merge branch 'main' into diana/fou-1881-document-the-contract-upgrade…
dianab-cl Oct 19, 2026
7cb673a
Merge branch 'main' into diana/fou-1881-document-the-contract-upgrade…
dianab-cl Oct 19, 2026
b794934
Merge branch 'main' into diana/fou-1881-document-the-contract-upgrade…
dianab-cl Oct 19, 2026
9e76015
Add docs "Grant, change, and revoke a role"
dianab-cl Oct 19, 2026
a2df54c
After code review
dianab-cl Oct 19, 2026
97ec260
Merge branch 'main' into diana/fou-1881-document-the-contract-upgrade…
dianab-cl Oct 20, 2026
92e4800
After code review
dianab-cl Oct 20, 2026
09269d7
Merge branch 'main' into diana/fou-1881-document-the-contract-upgrade…
dianab-cl Oct 21, 2026
67b93fd
Merge branch 'main' into diana/fou-1881-document-the-contract-upgrade…
dianab-cl Oct 26, 2026
565e815
Bump to go 1.26.10
dianab-cl Oct 21, 2026
1c1d348
After code review
dianab-cl Oct 26, 2026
9759f30
Merge branch 'main' into diana/fou-1881-document-the-contract-upgrade…
dianab-cl Oct 26, 2026
ff7276f
Merge branch 'main' into diana/fou-1881-document-the-contract-upgrade…
dianab-cl Oct 26, 2026
e6f4174
Merge branch 'main' into diana/fou-1881-document-the-contract-upgrade…
dianab-cl Oct 26, 2026
d178046
Merge main into contract upgrade documentation
dhfang Oct 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/2-how-ibc-works/2-packets-and-applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ The application is responsible for supplying the source client, the timeout, and

An application is registered with the IBC router on its chain, under a port. Each port identifies one application, and ports are how the router knows which application a packet is for and how to route it.

A port is either the application's own address as a hex string, which anyone may claim, or a readable name like GMP's `gmpport`, which the [access manager](../5-ibc-solidity-contracts/6-permissions-and-upgrades.md#the-access-manager-and-its-roles) gates. Once registered, the port identifier remains with that application permanently.
A port is either the application's own address as a hex string or a readable name like GMP's `gmpport`. The [access manager](../5-ibc-solidity-contracts/6-permissions-and-upgrades.md#the-access-manager-and-its-roles) decides who may register each kind. Once registered, the port identifier remains with that application permanently.

Every payload names two ports:
- `destPort` says which application the payload is for.
Expand Down
2 changes: 1 addition & 1 deletion docs/2-how-ibc-works/3-core-router-and-store.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ flowchart LR

The application registry maps a port to its application, and the client registry maps a client identifier to the light client that verifies a counterparty chain, along with the [counterparty information](4-clients-and-counterparties.md) recorded for it. Between them the router can find which application an arriving payload belongs to, and which client can verify the proof that came with it.

In IBC-solidity anyone can register an application under its address-derived port or a client under a generated identifier. Custom identifiers and client migration are role-gated. For how an application claims a port, see [ports and registration](2-packets-and-applications.md#ports-and-registration). For the client side, see [connecting two chains](4-clients-and-counterparties.md#connecting-two-chains).
In IBC-solidity, registering an application or a client and migrating a client are all role-gated. Each deployment decides who holds those roles, as [permissions and upgrades](../5-ibc-solidity-contracts/6-permissions-and-upgrades.md#what-a-deployment-assigns) describes. For how an application claims a port, see [ports and registration](2-packets-and-applications.md#ports-and-registration). For the client side, see [connecting two chains](4-clients-and-counterparties.md#connecting-two-chains).

## The store

Expand Down
9 changes: 6 additions & 3 deletions docs/5-ibc-solidity-contracts/1-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ flowchart TB
IFT["IFT token"]
GMP["ICS27GMP"]
ACC["ICS27Account<br/>one per account identifier"]
MC["IBCMulticall"]
R["ICS26Router<br/>client registry + commitment store"]
ALC["AttestationLightClient"]

IFT -- "sendCall" --> GMP
GMP -- "executes from" --> ACC
GMP <-- "sendPacket / callbacks" --> R
REL -- "updateClient, recvPacket,<br/>ackPacket, timeoutPacket" --> R
REL -- "multicall" --> MC
MC -- "updateClient, recvPacket,<br/>ackPacket, timeoutPacket" --> R
R -- "updateClient, verify" --> ALC
```

Expand All @@ -46,6 +48,7 @@ Documented in [core](2-ics26-router.md).
| Contract | Kind | What it does | Source |
|---|---|---|---|
| ICS26Router | Deployed contract | Packet router: holds the application and client registries, drives send, receive, acknowledge, and timeout | [ICS26Router.sol](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/contracts/ICS26Router.sol) |
| IBCMulticall | Deployed contract | Batches a relayer's calls to the router, so a failed packet delivery does not revert the rest of the batch | [IBCMulticall.sol](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/contracts/utils/IBCMulticall.sol) |
| ICS02ClientUpgradeable | Abstract base, compiled into ICS26Router | The light client registry: client identifiers, their client contracts, and their counterparty information | [ICS02ClientUpgradeable.sol](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/contracts/utils/ICS02ClientUpgradeable.sol) |
| IBCStoreUpgradeable | Abstract base, compiled into ICS26Router | The provable store of packet commitments, receipts, and acknowledgements | [IBCStoreUpgradeable.sol](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/contracts/utils/IBCStoreUpgradeable.sol) |
| ICS24Host | Library | Commitment path and commitment-hash generators, plus the universal error acknowledgement | [ICS24Host.sol](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/contracts/utils/ICS24Host.sol) |
Expand Down Expand Up @@ -99,11 +102,11 @@ Documented in [access control](6-permissions-and-upgrades.md).

Deployment splits three ways:

- **An operator** stands up the core: an AccessManager, then ICS26Router and the applications, then one light client per counterparty, each registered on the router with `addClient`.
- **An operator** stands up the core: an AccessManager, then ICS26Router, IBCMulticall, and the applications, then one light client per counterparty, each registered on the router with `addClient`.
- **A token issuer** deploys its own IFT, initialized with an already-deployed ICS27GMP address plus the token's name and symbol, and one send-call constructor registered per counterparty client it bridges to.
- **The contracts themselves** create the rest. ICS27GMP makes an account proxy for each `(clientId, sender, salt)` on first use, behind the beacon it creates over the account logic it was handed. The ICS02 precompile is chain-native at `0x...0807`, so only its wrapper is deployed.

The IBC CLI deploys the contract set. `ibc deploy core` stands up the access manager and the router on one chain. `ibc deploy client` deploys a light client tracking one counterparty and registers it. A connection between two chains takes four of those invocations, two per chain.
The IBC CLI deploys the contract set. `ibc deploy core` stands up the access manager, the router, and IBCMulticall on one chain. `ibc deploy client` deploys a light client tracking one counterparty and registers it. A connection between two chains takes four of those invocations, two per chain.

[Permissions and upgrades](6-permissions-and-upgrades.md) has what each deployment fixes for good and who can change it later.

Expand Down
16 changes: 9 additions & 7 deletions docs/5-ibc-solidity-contracts/2-ics26-router.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Interacts with: [AttestationLightClient](5-attestation-light-client.md), [ICS27G
| Contract | Kind | What it does | Source |
|---|---|---|---|
| ICS26Router | Deployed contract | The packet router itself | [ICS26Router.sol](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/contracts/ICS26Router.sol) |
| IBCMulticall | Deployed contract | Batches a relayer's calls to the router, so a failed packet delivery does not revert the rest of the batch | [IBCMulticall.sol](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/contracts/utils/IBCMulticall.sol) |
| ICS02ClientUpgradeable | Abstract base, compiled into ICS26Router | The light client and counterparty registry | [ICS02ClientUpgradeable.sol](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/contracts/utils/ICS02ClientUpgradeable.sol) |
| IBCStoreUpgradeable | Abstract base, compiled into ICS26Router | The provable commitment store | [IBCStoreUpgradeable.sol](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/contracts/utils/IBCStoreUpgradeable.sol) |
| ICS24Host | Library | Commitment paths, commitment hashes, and the universal error acknowledgement constant | [ICS24Host.sol](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/contracts/utils/ICS24Host.sol) |
Expand All @@ -37,15 +38,15 @@ flowchart LR

## Registering an application

Every IBC application is registered on a port by whoever deploys it, and implements three router-only callbacks. A port belongs permanently to the first application registered on it.
Every IBC application is registered on a port, and implements three router-only callbacks. A port belongs permanently to the first application registered on it.

| Function | What it does |
|---|---|
| `addIBCApp(address app)` | Registers an application under its own address, as a hex string, for a port identifier. Permissionless. |
| `addIBCApp(address app)` | Registers an application under its own address, as a hex string, for a port identifier. Role-gated. The ibc-contracts deployment script, [`DeployAccessManagerWithRoles`](https://github.com/cosmos/ibc-contracts/blob/main/ibc-solidity/scripts/deployments/DeployAccessManagerWithRoles.sol), opens it to every address. |
| `addIBCApp(string calldata portId, address app)` | Registers an application under a custom port identifier. Role-gated. |
| `getIBCApp(string calldata portId)` | Returns the application registered on a port. |

The role map names `ID_CUSTOMIZER_ROLE` for the role-gated function. The port that function picks must pass identifier validation, and it must not parse as an address, so a chosen name can never collide with one derived from a contract address. Custom identifiers may not start with `client-` or `channel-`, so a chosen name can never collide with a generated one.
The role map names `ID_CUSTOMIZER_ROLE` for the custom-port function. The port that function picks must pass identifier validation, and it must not parse as an address, so a chosen name can never collide with one derived from a contract address. Custom identifiers may not start with `client-` or `channel-`, so a chosen name can never collide with a generated one.

Either function reverts if the port already exists.

Expand Down Expand Up @@ -134,11 +135,11 @@ The failures differ in what becomes of the packet. A revert with a reason settle

## Client and counterparty registry

The router carries the client registry it inherits from ICS02ClientUpgradeable. Anyone may register a client there, while keeping one fresh and replacing one are both gated.
The router carries the client registry it inherits from ICS02ClientUpgradeable. Registering a client, keeping one fresh, and replacing one are all role-gated.

| Function | What it does |
|---|---|
| `addClient(CounterpartyInfo calldata counterpartyInfo, address client)` | Registers a client under a generated identifier and returns it. Permissionless. |
| `addClient(CounterpartyInfo calldata counterpartyInfo, address client)` | Registers a client under a generated identifier and returns it. Role-gated. The ibc-contracts deployment script opens it to every address. |
| `addClient(string calldata clientId, CounterpartyInfo calldata counterpartyInfo, address client)` | Registers a client under a custom identifier. Role-gated. |
| `updateClient(string calldata clientId, bytes calldata updateMsg)` | Forwards an opaque update to the client contract. Role-gated. |
| `migrateClient(string calldata clientId, CounterpartyInfo calldata counterpartyInfo, address client)` | Replaces the client contract and counterparty info under the same identifier. Admin-gated by default. |
Expand All @@ -147,7 +148,7 @@ The router carries the client registry it inherits from ICS02ClientUpgradeable.
| `getCounterparty(string calldata clientId)` | Returns the counterparty identifier and merkle prefix. |
| `getNextClientSeq()` | Returns the next sequential client number. |

Two things are stored per client identifier: the address of a light-client contract, and counterparty info, which is the counterparty's own client identifier plus its merkle prefix. The permissionless registration generates the identifier as `client-` plus a counter, and the role-gated overload lets an ID customizer supply one instead.
Two things are stored per client identifier: the address of a light-client contract, and counterparty info, which is the counterparty's own client identifier plus its merkle prefix. The generated-identifier overload builds the identifier as `client-` plus a counter. The custom-identifier overload lets an ID customizer supply one instead.

Misbehaviour submission is open to any address, and the router forwards the evidence to the client registered under the identifier. What comes of it is the client's decision. A client that has gone wrong is replaced under its own identifier: an admin-gated `migrateClient` swaps in a new client contract and counterparty info.

Expand Down Expand Up @@ -238,12 +239,13 @@ Each gate below is a function selector granted to a role in an external OpenZepp
|---|---|---|
| Relayer | `recvPacket`, `timeoutPacket`, `ackPacket`, `updateClient` | Assigned in the deployment's role map |
| ID customizer | `addIBCApp(string,address)` and the custom-identifier `addClient` | Assigned in the deployment's role map |
| Public | `addIBCApp(address)` and the generated-identifier `addClient` | Every address, once the deployment assigns them to `PUBLIC_ROLE` |
| Admin | `migrateClient` and the UUPS upgrade authorization | A security council paired with a governance admin, in the security model the repository documents |

Authorization itself happens outside the router. One external `AccessManager` is passed as `authority` at initialization, and a deployment decides which selectors it binds to which role. The router only asks the access manager whether the caller holds the role assigned to the selector, so who may relay is a deployment decision rather than a property of the contract.

<Note>
On a chain the IBC CLI brings up, any address may relay. `ibc deploy core` binds the router's relaying calls to the public role, and it never grants the relayer role. The selectors it binds are listed under [the access manager and its roles](6-permissions-and-upgrades.md#the-access-manager-and-its-roles).
On a chain the IBC CLI brings up, any address may relay. `ibc deploy core` binds the router's relaying calls to the public role, and it never grants the relayer role. It leaves `addIBCApp(address)` and the generated-identifier `addClient` unassigned, so only the admin may register an application or a client. The selectors it binds are listed under [what a deployment assigns](6-permissions-and-upgrades.md#what-a-deployment-assigns).
</Note>

## Deployment and upgrade
Expand Down
Loading
Loading