Permissions

All thirty-four Swap permission keys, the console each one opens, and the four that let a delegate move revenue, commit operator capital or change what a user signs against.

5 min readUpdated 6 August 2026permissions, roles, admin, delegation

Thirty-four keys, all seeded by the platform's permissions seeder, all beginning dex. They follow the standing convention: the admin path with / as . and - as _. /admin/dex/chain is access.dex.chain; the read and write keys on the same screen are view.dex.chain and edit.dex.chain.

Two different gates enforce them, and both have to pass:

  • The access. key gates reaching the screen at all. It is what frontend/middlewares/permissions.json matches the URL against, and it is what the megamenu entry carries.
  • The view. / create. / edit. / delete. keys are declared on each backend route and on the DataTable's own permissions prop. They are what actually decide whether a request succeeds.

A role holding access.dex.chain and not edit.dex.chain can open the chain console, read every row, and have every save refused.

The eleven access keys, and the thirteen screens

Key Opens
access.dex The overview dashboard, /admin/dex. Also the megamenu entry for the whole console
access.dex.provider /admin/dex/provider — aggregator activation and credentials
access.dex.chain /admin/dex/chain, and /admin/dex/requirements, and /admin/dex/wallet
access.dex.token /admin/dex/token — the curated token catalogue
access.dex.pair /admin/dex/pair — the featured markets
access.dex.pool /admin/dex/pool and /admin/dex/pool/{id}
access.dex.position /admin/dex/position and /admin/dex/position/{id}
access.dex.swap /admin/dex/swap — swap history
access.dex.quote /admin/dex/quote — the quote log
access.dex.fee /admin/dex/fee and /admin/dex/fee/accrual
access.dex.settings /admin/dex/settings

Three of those cover more than one screen on purpose:

  • Requirements and Wallets sit under access.dex.chain. Requirements is the diagnosis half of the same decision the chain console is the fix half of, and a separate key would let a role reach the fix and not the diagnosis. Wallets edits nothing the chain console does not already edit — the fee recipient is a dexChain column — so minting a separate wallet key would be a second gate on one decision, and the two would eventually be granted differently.
  • The pool and position detail screens share their list's key. Without that, the detail path matched nothing in the manifest and fell back to the broad access.admin, so a role scoped to the Swap console could open the register and not any row in it.
  • The fee accrual ledger shares access.dex.fee. It is the same screen's detail view.

Read

Ten view. keys. Each is declared on the list endpoint behind its console.

Key Covers
view.dex.chain GET /api/admin/dex/chain, the requirements report, and the fee-wallet report
view.dex.provider The aggregator registry and its readiness columns
view.dex.token The token catalogue
view.dex.pair The market list, and pool discovery (POST .../pair/discover, which only returns candidates)
view.dex.pool The pool register, one pool, and the create/seed transaction plan
view.dex.position Positions, one position, and the position analytics
view.dex.swap Swap history
view.dex.quote The quote log
view.dex.fee The revenue console, the accrual ledger, and the on-chain reconciliation scan
view.dex.settings Reading the settings screen

Two POST routes deliberately sit on a view. key because they write nothing: pair discovery returns candidate pools, and POST /api/admin/dex/revenue/reconcile scans the chain and reports. Neither is audited, because an audit log full of probes buries the writes that matter.

Write

Seven edit. keys, three create. and three delete..

Key Allows
edit.dex.chain The chain PUT, the live network probe on Requirements, and creating a Solana fee token account
edit.dex.provider Switching an aggregator on or off and reordering priority
edit.dex.token Status, listing and risk edits; the on-chain decimals() probe; an on-demand re-screen
edit.dex.pair The pair edit dialog and the pair status switch
edit.dex.pool Everything about a registered pool except registering one: verify, refresh, seed, withdraw, acknowledge, status
edit.dex.fee Recording a sweep
edit.dex.settings Saving the settings screen
create.dex.token Adding one token, and the bulk token-list import
create.dex.pair Adding a market
create.dex.pool Registering a pool, and the create-verification that follows it
delete.dex.token Soft-deleting a token row
delete.dex.pair Deleting a market
delete.dex.pool Deleting a pool row

Chains and providers have no create. or delete. key at all — both registries are code, so the console configures rows it cannot make or destroy. Positions have no edit. key either: a position is opened by a receipt and closed by a receipt, and nothing on that screen may write one.

create.dex.token, delete.dex.token, create.dex.pair and delete.dex.pair are real, enforced keys, but the Tokens and Pairs consoles both ship with create and delete switched off — a token is added by the probing POST or the list importer, and delisting is listing: DENYLISTED rather than a delete, because historic swaps resolve their token through that row.

So those four are reachable through the API only. Granting them changes nothing a delegate can do from the admin panel; withholding them does not take a button away from anyone.

The four keys to treat as privileged

edit.dex.chain — where your revenue lands, and which endpoints are trusted

This is the one to reason about the way you would reason about a withdrawal-approval permission. It writes dexChain.feeRecipient, which is the only address the integrator fee on that chain is paid to — there is no global fallback and no second approval step. A holder can point every future swap fee on Ethereum at an address you do not control, and nothing about the saved row looks wrong afterwards.

It also writes both RPC fields — including the server-side override, which is never returned to a browser and can be pointed at any endpoint.

What it does not reach is the router allowlist. That list is the static code list, plus every registered AMM deployment, plus dexChain.metadata.extraRouters[] — and metadata is written by no admin route in this addon. The chain PUT accepts six columns and ignores everything else, so holding this key cannot add a contract address to the list that is checked against the to and the approval spender of a quote before a user is asked to sign it. Changing that list is a direct database edit today.

Two mitigations exist and neither is a substitute for granting the key carefully: feeRecipientUpdatedAt is stamped only when the address actually changes, so "when did our revenue destination move" is answerable; and the audit trail records the zero-fee acknowledgement in words rather than as a boolean.

edit.dex.fee — the key that credits your books

The revenue console shows accrued, swept and on-chain figures. Reading them takes view.dex.fee. Recording a sweepPOST /api/admin/dex/revenue/sweep — takes edit.dex.fee, and that is the action that starts the settlement chain: the covered accruals move to SWEEP_SUBMITTED, and the settlement cron waits for the recorded transaction to confirm and then books an adminProfit row.

The platform holds no key here and signs nothing; the route records a transfer the operator made themselves. But an incorrect record is a credit to your own books against a transaction that did not carry what it claims, so grant it to whoever is accountable for revenue rather than to everyone with access.dex.fee.

create.dex.pool and edit.dex.pool — the operator's own capital

These two are the only keys in the addon that let somebody commit your money. Registering a pool is inert. edit.dex.pool is not: it covers the seed verification and the withdraw verification, which is to say the whole of taking and unwinding a market position.

Seeding is not a configuration change. The operator holds the impermanent loss and becomes the counterparty to everyone who trades against the pool, and on a V2 pool the LP fee can never be withdrawn as revenue at all. See Direct pools and Liquidity positions.

dexPoolRiskAckRequired (on by default, Super Admin only) means a seed with no current, unrevoked acknowledgement is refused; switching it off removes the dialog but not the record — the seed still writes an attributed waiver naming the admin who allowed it.

edit.dex.settings — and the five keys it does not reach

Saving the Swap settings screen takes edit.dex.settings. Five settings are protected and need the Super Admin role, resolved server-side on every request, in addition to the permission:

Protected key What it governs
dexEnabled Whether the swap surface exists at all
dexAllowlistMode Whether curation is the allowlist or something looser
dexKycRequired Whether swapping requires a verified account
dexDirectPoolsEnabled Whether a swap may be filled from a pool you seeded
dexPoolRiskAckRequired Whether seeding requires the risk acknowledgement

A payload touching any of them from a caller without the role is refused with a 403 and nothing is saved — the whole change, not just the protected key, so a save is never half-applied.

Admin → System → Settings carries dexEnabled, dexAllowlistMode and dexKycRequired. It has never carried dexDirectPoolsEnabled or dexPoolRiskAckRequired. Those two are editable from the Swap settings screen's Liquidity tab and nowhere else, and only by a Super Admin.

dexEnabled is a special case in the other direction: the Swap settings screen refuses to load while the switch is off, so that screen can never be the place it is turned on. Use the platform settings screen for that.

What none of these keys does

Nothing here affects what a customer can do. Connecting a wallet, quoting and swapping are gated by the master switch, the token allowlist, the geo list and — where you switched it on — KYC. These keys control the admin side only.

There is also no key that moves funds, reverses a swap or signs anything, because no such route exists. The most a holder of every key on this page can do is stop offering new swaps.

See Roles and permissions for how keys are attached to roles, and The admin surfaces for what each console answers.