Skip to content

Commit ba166df

Browse files
authored
Merge pull request #3423 from OffchainLabs/tw-739-p4-compliance-filtering-sanctioned-address-chain-owner-guide
Compliance filtering chain owner guide
2 parents 1437c8e + 0b6180a commit ba166df

5 files changed

Lines changed: 205 additions & 1 deletion

File tree

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
---
2+
title: 'Compliance filtering'
3+
sidebar_label: 'Compliance filtering'
4+
description: 'How chain owners configure protocol-level transaction filtering to restrict sanctioned addresses on their Arbitrum chain.'
5+
user_story: 'As a chain owner, I want to configure compliance rules so that transactions involving restricted addresses are filtered before execution.'
6+
content_type: how-to
7+
author: gmehta2
8+
sme: gmehta2
9+
target_audience: 'Developers who want to configure compliance rules on their chain'
10+
---
11+
12+
<VanillaAdmonition type="note">This feature is available through the ArbOS 61 upgrade, however off by default. We recommend adopting this feature at least 30 days after the release of ArbOS 61 on Arbitrum One.</VanillaAdmonition>
13+
14+
New, optional components can be added to the <a data-quicklook-from='sequencer'>Sequencer</a> and <a data-quicklook-from='state-transition-function'>State Transition Function</a> (STF) to enable protocol-level transaction filtering for regulatory or compliance purposes, at the discretion of the chain owner.
15+
The chain owner may configure an external compliance service (e.g., TRM or Chainalysis) to define address-level policies. Any transaction that originates from, targets, or otherwise involves a restricted address is filtered prior to execution, including transactions submitted via the <a data-quicklook-from='delayed-inbox'>Delayed Inbox</a> on the parent chain.
16+
17+
## Rationale
18+
19+
The Arbitrum platform must evolve to meet the needs of a new wave of teams looking to come onchain—specifically teams who have an obligation to comply with regulatory frameworks and rules in their respective jurisdictions.
20+
This feature represents the first of many to ensure that the Arbitrum platform can serve the needs of enterprises and institutions looking to tap into internet-scale, blockchain technology to increase margins, reduce risk, and improve transparency across their businesses.
21+
22+
While this feature is not intended or proposed to be used by Arbitrum One, its inclusion in ArbOS 61 Elara is intended to simplify the codebase and canonicalize this feature in the node software.
23+
This feature is instead intended to be used by Arbitrum chains who have compliance and regulatory obligations to restrict onchain activity from sanctioned entities or actors.
24+
25+
## How it works
26+
27+
Compliance Filtering operates across two layers: the Sequencer and the State Transition Function (STF). Together, these layers ensure that restricted activity is blocked regardless of how a transaction enters the system.
28+
29+
### Restricted address list
30+
31+
The chain owner configures an external compliance provider (e.g., TRM Labs, Chainalysis) to define which addresses are restricted. This produces a restricted address list, which is:
32+
33+
1. Stored in-memory on any node performing compliance screening
34+
2. Encoded as salted hashes in the form `sha256(salt || address)` to protect address privacy
35+
3. Refreshed periodically via a synchronization pipeline
36+
37+
When evaluating a transaction, the compliance engine hashes all relevant addresses and checks them against this list.
38+
39+
### Sequencer-level filtering
40+
41+
The Compliance Rules Engine runs inside the Sequencer and simulates each transaction before it is sequenced. If a transaction violates any compliance rule, it is rejected at the Sequencer level and never included in a block.
42+
This is the primary enforcement layer and handles the vast majority of cases.
43+
44+
### Compliance rules
45+
46+
Specific rules can be defined by the chain owner for any address found on the restricted list.
47+
These rules apply to direct transfers as well as delegated approval mechanisms. A few examples:
48+
49+
- Block any transaction originating from or to a restricted address
50+
- Block execution of ERC-20, ERC-721, and ERC-1155 transfers from or to a restricted address
51+
- Block execution of the following opcodes targeting a restricted address: `CALL`, `CREATE`, `CREATE2`, `SELFDESTRUCT`
52+
53+
### Delayed Inbox filtering (STF level)
54+
55+
Transactions submitted via the Delayed Inbox cannot be filtered at the Sequencer layer alone, since they are eligible for force inclusion after a timeout window.
56+
To handle this, Compliance Filtering introduces two additional components:
57+
58+
#### Transaction Guardian Precompile
59+
60+
A new precompile allows authorized entities (e.g., the Sequencer) to register the hash of a restricted transaction onchain before it is force-included. When the STF processes a transaction from the delayed inbox, it checks whether that transaction's hash has been registered in the guardian.
61+
If so, the transaction is forcibly failed on inclusion, consuming any gas attached to prevent spam.
62+
63+
#### Delayed Inbox Sentinel
64+
65+
The sentinel is responsible for monitoring the delayed inbox for restricted transactions. When a restricted transaction is detected, the sentinel:
66+
67+
1. Submits the transaction's hash to the Transaction Guardian Precompile
68+
2. Ensures this occurs before the force inclusion window closes
69+
3. Allows the Sequencer to then process the transaction, which will fail at the STF level as expected
70+
71+
This ensures that even transactions submitted through the parent chain → child chain messaging path are subject to compliance enforcement.
72+
73+
### Exception rules (burn allowance)
74+
75+
Certain DeFi protocols (e.g., lending protocols like Aave, Morpho) require the ability to liquidate or burn token balances associated with restricted accounts in order to maintain solvency and prevent exploits.
76+
To support this, a narrow exception is available:
77+
ERC-20, ERC-721, and ERC-1155 transfers where the `to` field of the Transfer event is the zero address (`0x0`) (a burn operation) are permitted even if the `from` address is restricted.
78+
79+
Important constraints:
80+
81+
- If a "burn" transaction includes any other compliance violation, the entire transaction will fail.
82+
- A restricted address cannot initiate a burn themselves — their `tx.origin` is blocked at the Sequencer level regardless.
83+
84+
This design allows third-party liquidators and protocol contracts (e.g., Paxos, Aave) to burn non-compliant balances while preventing the restricted address from taking any action on the chain.
85+
86+
### Synchronization pipeline
87+
88+
The restricted address list is distributed to Sequencer and <a data-quicklook-from='prechecker-node'>prechecker nodes</a> via a cloud-based pipeline:
89+
90+
- The compliance provider periodically publishes a new hash list to a designated S3 bucket.
91+
- An SNS notification triggers ingestion into the chain operator's own S3 bucket.
92+
- Nodes subscribe to updates and load the new list into memory, fully replacing the prior list once the new one is validated and complete.
93+
94+
Nodes are expected to always have a valid list in memory. On startup or restart, a node will fetch the most recent list before beginning to sequence or precheck transactions.
95+
96+
## Deployment considerations
97+
98+
| Component | Availability | Notes |
99+
| ------------------------------- | -------------- | ----------------------------------------------- |
100+
| Sequencer-level filtering | ArbOS 61 Elara | Opcode and event filtering |
101+
| Transaction Guardian Precompile | ArbOS 61 Elara | Required for Delayed Inbox enforcement |
102+
| Delayed Inbox Sentinel (STF) | ArbOS 61 Elara | Requires audit; must be activated at deployment |
103+
| Burn exception rules | ArbOS 61 Elara | Covers Aave, Paxos, and similar protocols |
104+
105+
Compliance Filtering is disabled by default. Chain owners must explicitly configure and enable each component. Activation after chain deployment may require an ArbOS upgrade.
106+
107+
## Security considerations
108+
109+
- **Force inclusion protection:** Without STF-level enforcement via the Transaction Guardian, a restricted user could bypass Sequencer filtering by waiting for the force inclusion window. The sentinel + precompile combination closes this gap.
110+
- **Parent chain bridge deposits:** If a restricted address deposits ETH via `depositEth()` on the parent chain, the ETH enters the bridge contract on the parent chain before any filtering occurs on the child chain. If the corresponding credit is dropped on the child chain, the ETH may become locked in the bridge with no corresponding child chain asset. Chain owners should account for this in their compliance design and user communication strategy.
111+
- **Address privacy:** Restricted addresses are never stored in plaintext. Salted hashing ensures that the list cannot be trivially reversed to enumerate sanctioned addresses.
112+
113+
## Configuration
114+
115+
To set up transaction filters, Arbitrum Nitro nodes provide a few configuration options for both address level filtering and event filtering. Event filters are optional, but address filters must both be enabled and configured properly before transactions will be properly filtered.
116+
117+
### Address filter
118+
119+
To define the addresses that are to be restricted from executing or receiving onchain transactions, an S3-compatible file store must be used. When address filtering is enabled, Arbitrum Nitro will poll and read the latest file from the S3 bucket. The addresses are defined as hashes where `hashed_address = SHA256(salt16Byte || address20Byte)`.
120+
121+
- `--execution.transaction-filtering.address-filter.enable`: true/false value that enables address filtering
122+
- `--execution.transaction-filtering.address-filter.poll-interval`: how often to resync from S3 (e.g. `60m`)
123+
- `--execution.transaction-filtering.address-filter.s3.bucket`: S3 bucket holding the hashed list
124+
- `--execution.transaction-filtering.address-filter.s3.object-key`: S3 object key for the hash list
125+
- `--execution.transaction-filtering.address-filter.s3.region`: AWS region where S3 bucket is hosted (e.g. `us-east-1`)
126+
- `--execution.address-filter.s3.access-key`: AWS access key
127+
- `--execution.address-filter.s3.secret-key`: AWS secret key
128+
- `--execution.address-filter.s3.endpoint`: S3-compatible endpoint where file is hosted (if not using AWS S3)
129+
130+
The hash list of restricted addresses should be provided as a JSON file with the following format:
131+
132+
```json
133+
{
134+
salt: string, # UUID
135+
hashes: [string], # list of 32-byte hashes as hex encoded strings
136+
issued_at: string, # timestamp
137+
hashing_scheme: string # sha256-stringinput or sha256-rawbytesinput.
138+
}
139+
```
140+
141+
Note: `sha256-stringinput` assumes that the string-based representation of the UUID salt is concatenated with the string-based version of the hex-encoded address (e.g. `sha256("d35e8ac5-9775-44af-878e-bad86409e80c" || "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")`). Raw bytes uses the raw 16 bytes of the UUID and raw 20 bytes of the address concatenated as input to the sha256 function to produce the 32-byte hash.
142+
143+
### Event filters
144+
145+
Event filters allow for chain owners to filter out transactions based on an arbitrary list of emitted events. For example, a chain owner might want to block all ERC20 transfers involving a restricted address. A chain owner can setup their nodes to listen for `Transfer(address,address,uint256)` events and block any transactions that target a restricted address in either the `from` or `to` field. To setup event filters, two CLI flags are provided:
146+
147+
- `--execution.transaction-filtering.event-filter.rules`: optional inline list of event rules (passed as a JSON string)
148+
- `--execution.transaction-filtering.event-filter.path`: optional path to a JSON file containing event filter rules. If both `path` and `rules` are provided, the file rules are loaded first and then inline rules are appended after them. Generally, path-based JSON rules should be preferred.
149+
150+
Each entry in the rules is an `EventRule` with the following shape:
151+
152+
- `event`: human-readable event signature (e.g. `Transfer(address,address,uint256)`
153+
- `selector`: hex string of the first 4 bytes of `keccak256(event)`; the canonical signature of the event type
154+
- `topicAddresses`: list of 1-indexed topic positions (1-3) whose values should be treated as addresses for filtering
155+
- `bypass`: defines an optional exception condition that allows the transaction to execute if a specific value is true (example would be transfers to `0x0` burn address). It is a nested object with:
156+
- `topicIndex`: 1-indexed topic position (1-3)
157+
- `equals`: conditional value for the exception at the topic position defined
158+
159+
An example JSON file to provide to `--execution.transaction-filtering.event-filter.path`:
160+
161+
```json
162+
{
163+
"rules": [
164+
{
165+
"event": "Transfer(address,address,uint256)",
166+
"selector": "0xddf252ad",
167+
"topicAddresses": [1, 2],
168+
"bypass": {
169+
"topicIndex": 2,
170+
"equals": "0x0000000000000000000000000000000000000000"
171+
}
172+
},
173+
{
174+
"event": "Approval(address,address,uint256)",
175+
"selector": "0x8c5be1e5",
176+
"topicAddresses": [1, 2]
177+
}
178+
]
179+
}
180+
```

docs/partials/_glossary-partial.mdx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ partial_type: glossary
33
title: 'Arbitrum Glossary Definitions'
44
description: 'Comprehensive glossary of Arbitrum terminology and definitions'
55
author: anegg0
6-
last_reviewed: 2026-06-08
6+
last_reviewed: 2026-06-17
77
---
88

99
### Activation {#activation}
@@ -409,6 +409,12 @@ Anyone can become a validator by running an Arbitrum node, without permission.
409409

410410
A web application maintained by [Offchain Labs](/intro/glossary#offchain-labs) showcasing the Arbitrum ecosystem; visit it [here](https://portal.arbitrum.io/).
411411

412+
### Prechecker Node {#prechecker-node}
413+
414+
An [Arbitrum full node](/intro/glossary#arbitrum-full-node) configured to pre-validate transactions before forwarding `eth_sendRawTransaction` to the [Sequencer](/intro/glossary#sequencer), insulating it from transactions that would fail.
415+
416+
At a configurable strictness level, a prechecker verifies the transaction type, signature, intrinsic gas (including L1 calldata gas), fee cap, nonce, sender balance, and any `eth_sendRawTransactionConditional` storage conditions. When [compliance filtering](/launch-arbitrum-chain/configure-your-chain/advanced/compliance-filtering) is enabled, it also rejects transactions that touch restricted addresses.
417+
412418
### Precompile {#precompile}
413419

414420
A precompile is a predefined smart contract with a special address that provides specific functionality executed natively by the Arbitrum client, rather than at the EVM bytecode level. Precompiles are used to introduce functions that would be computationally expensive if run in EVM bytecode, or to facilitate interactions between the parent and child chains. Arbitrum supports all Ethereum precompiles and also provides additional precompiles specific to Arbitrum chains, which can be called from smart contracts like regular Solidity functions[(1)](https://docs.arbitrum.io/build-decentralized-apps/precompiles/overview).
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: Prechecker Node
3+
key: prechecker-node
4+
titleforSort: Prechecker Node
5+
---
6+
7+
An [Arbitrum full node](/intro/glossary#arbitrum-full-node) configured to pre-validate transactions before forwarding `eth_sendRawTransaction` to the [Sequencer](/intro/glossary#sequencer), insulating it from transactions that would fail.
8+
9+
At a configurable strictness level, a prechecker verifies the transaction type, signature, intrinsic gas (including L1 calldata gas), fee cap, nonce, sender balance, and any `eth_sendRawTransactionConditional` storage conditions. When [compliance filtering](/launch-arbitrum-chain/configure-your-chain/advanced/compliance-filtering) is enabled, it also rejects transactions that touch restricted addresses.

sidebars.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,11 @@ const sidebars = {
391391
id: 'launch-arbitrum-chain/chain-config/validation/fast-withdrawals',
392392
label: `Fast withdrawals`,
393393
},
394+
{
395+
type: 'doc',
396+
id: 'launch-arbitrum-chain/configure-your-chain/advanced/compliance-filtering',
397+
label: 'Compliance filtering',
398+
},
394399
],
395400
},
396401
{

static/glossary.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,10 @@
379379
"title": "Portal",
380380
"text": "<p>A web application maintained by <a href=\"/intro/glossary#offchain-labs\">Offchain Labs</a> showcasing the Arbitrum ecosystem; visit it <a href=\"https://portal.arbitrum.io/\">here</a>.</p>\n"
381381
},
382+
"prechecker-node": {
383+
"title": "Prechecker Node",
384+
"text": "<p>An <a href=\"/intro/glossary#arbitrum-full-node\">Arbitrum full node</a> configured to pre-validate transactions before forwarding <code>eth_sendRawTransaction</code> to the <a href=\"/intro/glossary#sequencer\">Sequencer</a>, insulating it from transactions that would fail.</p>\n<p>At a configurable strictness level, a prechecker verifies the transaction type, signature, intrinsic gas (including L1 calldata gas), fee cap, nonce, sender balance, and any <code>eth_sendRawTransactionConditional</code> storage conditions. When <a href=\"/launch-arbitrum-chain/configure-your-chain/advanced/compliance-filtering\">compliance filtering</a> is enabled, it also rejects transactions that touch restricted addresses.</p>\n"
385+
},
382386
"precompile": {
383387
"title": "Precompile",
384388
"text": "<p>A precompile is a predefined smart contract with a special address that provides specific functionality executed natively by the Arbitrum client, rather than at the EVM bytecode level. Precompiles are used to introduce functions that would be computationally expensive if run in EVM bytecode, or to facilitate interactions between the parent and child chains. Arbitrum supports all Ethereum precompiles and also provides additional precompiles specific to Arbitrum chains, which can be called from smart contracts like regular Solidity functions<a href=\"https://docs.arbitrum.io/build-decentralized-apps/precompiles/overview\">(1)</a>.</p>\n"

0 commit comments

Comments
 (0)