Skip to content

Commit a18f307

Browse files
committed
refactor: merge comptroller and admin tables
- combine comptroller address and admin address into a single per-chain table - delete the now-obsolete ComptrollersTable component
1 parent 835c9c3 commit a18f307

3 files changed

Lines changed: 47 additions & 61 deletions

File tree

docs/concepts/13-governance.mdx

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,22 @@ sidebar_position: 13
44
title: "Governance"
55
---
66

7-
import { AdminsTable, OldAdminsTable } from "@site/src/components/organisms/AdminsTable";
8-
import ComptrollersTable from "@site/src/components/organisms/ComptrollersTable";
7+
import { ComptrollerAdminsTable, OldAdminsTable } from "@site/src/components/organisms/AdminsTable";
98

10-
## Comptroller
9+
## Comptroller and Admins
1110

1211
The Sablier Comptroller is a smart contract that acts as an intermediary between the protocols and the Sablier admin
1312
addresses. It has exclusive access to specific protocol functions. This design provides a more flexible approach to
1413
access control across all protocols while maintaining security.
1514

16-
Admin addresses that control the Comptroller are listed below in the [Admin Addresses](#admin-addresses) section.
15+
### Current
1716

18-
<ComptrollersTable />
17+
Used in Lockup v2.0, v3.0 and v4.0, Flow v1.1, v2.0 and v3.0, and Airdrops v1.3, v2.0 and v3.0. The table below lists
18+
the deployed Comptroller and the admin that controls it on each chain.
1919

20-
## Admin Addresses
20+
<ComptrollerAdminsTable />
2121

22-
The Comptroller was introduced in Lockup v3.0, Airdrops v2.0, and Flow v2.0. Prior to these, we used a direct admin role
23-
for governance.
24-
25-
These admin accounts have the same authority as the current Comptroller contract, with direct access to specific
26-
protocol functions. More concretely, the admins are a collection of multisig wallets and EOAs currently in control of
27-
Sablier Labs.
28-
29-
### Current Admins
30-
31-
Used in Lockup v2.0, v3.0 and v4.0, Flow v1.1, v2.0 and v3.0, and Airdrops v1.3, v2.0 and v3.0. These addresses control
32-
the Comptroller on each chain.
33-
34-
<AdminsTable />
35-
36-
### Old Admins
22+
### Old
3723

3824
Used in all previous versions: Lockup v1.0, v1.1 and v1.2; Flow v1.0; and Airdrops v1.1 and v1.2. Each of these
3925
addresses had direct admin authority over the corresponding protocol contracts before the Comptroller was introduced.

src/components/organisms/AdminsTable.tsx

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,45 @@ function renderTable(rows: ReadonlyArray<readonly [Chain, Address]>): string {
143143
return content;
144144
}
145145

146-
export function AdminsTable() {
147-
const content = useMemo(() => renderTable(CURRENT_CHAIN_ADMINS), []);
146+
const CURRENT_ADMIN_BY_CHAIN_ID: ReadonlyMap<number, Address> = new Map(
147+
CURRENT_CHAIN_ADMINS.map(([chain, admin]) => [chain.id, admin])
148+
);
149+
150+
function renderComptrollerAdminsTable(): string {
151+
// Iterating the comptroller catalog (rather than CURRENT_CHAIN_ADMINS) keeps
152+
// the table in sync with deployments automatically; the admin lookup throws
153+
// at module load if the hand-maintained map falls out of step.
154+
const rows = sablier.comptroller
155+
.getAll()
156+
.flatMap((comptroller) => {
157+
const chain = sablier.chains.get(comptroller.chainId);
158+
if (!chain || chain.isTestnet || !chain.isSupportedByUI) {
159+
return [];
160+
}
161+
const admin = CURRENT_ADMIN_BY_CHAIN_ID.get(chain.id);
162+
if (!admin) {
163+
throw new Error(
164+
`AdminsTable: missing current admin for chain ${chain.name} (${chain.id}). ` +
165+
"Add it to CURRENT_CHAIN_ADMINS in src/components/organisms/AdminsTable.tsx."
166+
);
167+
}
168+
return [{ admin, chain, comptroller: comptroller.address }];
169+
})
170+
.sort((a, b) => a.chain.name.localeCompare(b.chain.name));
171+
172+
let content = "| Chain | Comptroller | Comptroller Admin |\n";
173+
content += "| :---- | :---------- | :---- |\n";
174+
for (const { admin, chain, comptroller } of rows) {
175+
const explorerBaseUrl = chain.blockExplorers.default.url;
176+
const comptrollerLink = `[${comptroller}](${explorerBaseUrl}/address/${comptroller})`;
177+
const adminLink = `[${admin}](${explorerBaseUrl}/address/${admin})`;
178+
content += `| ${chain.name} | ${comptrollerLink} | ${adminLink} |\n`;
179+
}
180+
return content;
181+
}
182+
183+
export function ComptrollerAdminsTable() {
184+
const content = useMemo(() => renderComptrollerAdminsTable(), []);
148185
return <GFMContent content={content} />;
149186
}
150187

@@ -153,4 +190,4 @@ export function OldAdminsTable() {
153190
return <GFMContent content={content} />;
154191
}
155192

156-
export default AdminsTable;
193+
export default ComptrollerAdminsTable;

src/components/organisms/ComptrollersTable.tsx

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)