Skip to content

Commit c0167e7

Browse files
committed
feat: latest docs and config
1 parent d896b40 commit c0167e7

7 files changed

Lines changed: 1275 additions & 2 deletions

File tree

CLAUDE.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Socket DL (Data Layer) is a protocol for generic message passing between blockchains. It enables dapps ("plugs") to send and receive cross-chain messages with configurable security/speed tradeoffs. The protocol is deployed across 70+ EVM chains.
8+
9+
## Build and Test Commands
10+
11+
```bash
12+
# Install dependencies
13+
forge install && yarn install
14+
15+
# Compile contracts
16+
forge build # or: yarn compile
17+
18+
# Run tests (formats changed files first)
19+
yarn test # runs: prettier + forge test
20+
21+
# Run specific test file
22+
forge test --match-path test/socket/SocketSrc.t.sol
23+
24+
# Run specific test function
25+
forge test --match-test testOutbound
26+
27+
# Lint/format
28+
yarn lint
29+
30+
# Export ABIs
31+
yarn abi # or: hardhat export-abi
32+
33+
# Build TypeScript package
34+
yarn build # exports ABIs + compiles TS
35+
```
36+
37+
## Deployment
38+
39+
Deployment uses Hardhat. Three modes exist: `dev`, `surge`, `prod` (set via `DEPLOYMENT_MODE` env var).
40+
41+
```bash
42+
# Full deployment flow
43+
bash deploy.sh
44+
45+
# Individual steps
46+
npx hardhat run scripts/deploy/deploy.ts # Deploy contracts
47+
npx hardhat run scripts/deploy/verify.ts # Verify on explorers
48+
```
49+
50+
Key deployment files:
51+
52+
- [scripts/deploy/config/config.ts](scripts/deploy/config/config.ts) - Chain configuration, role addresses
53+
- [deployments/{mode}\_addresses.json](deployments/) - Deployed contract addresses
54+
- `.env` - Private keys, RPC URLs, API keys (see `.env.example`)
55+
56+
## Architecture
57+
58+
### Core Message Flow
59+
60+
1. **Source Chain**: Plug calls `Socket.outbound()` → message packed into Capacitor → Transmitter seals packet
61+
2. **Destination Chain**: Transmitter proposes packet root → Switchboard verifies → Executor calls `Socket.execute()` → Plug receives `inbound()`
62+
63+
### Contract Hierarchy
64+
65+
```
66+
Socket (main entry point)
67+
├── SocketSrc - Outbound message handling, packet sealing
68+
├── SocketDst - Inbound execution, packet verification
69+
├── SocketConfig - Plug configuration, switchboard registration
70+
└── SocketBase - Shared state (hasher, capacitorFactory, managers)
71+
```
72+
73+
### Key Contracts
74+
75+
- **Socket** ([contracts/socket/Socket.sol](contracts/socket/Socket.sol)): Core contract combining source and destination logic
76+
- **Capacitors** ([contracts/capacitors/](contracts/capacitors/)): Accumulate messages into packets (SingleCapacitor for 1:1, HashChainCapacitor for batching)
77+
- **Switchboards** ([contracts/switchboard/](contracts/switchboard/)): Verify packets. Types:
78+
- `FastSwitchboard` - Watcher-based attestation
79+
- `OptimisticSwitchboard` - Timeout-based
80+
- Native bridges (Arbitrum, Optimism, Polygon) - Use L1↔L2 messaging
81+
- **ExecutionManager** ([contracts/ExecutionManager.sol](contracts/ExecutionManager.sol)): Fee handling, executor verification
82+
- **TransmitManager** ([contracts/TransmitManager.sol](contracts/TransmitManager.sol)): Transmitter signature verification
83+
84+
### Integration Pattern
85+
86+
Dapps implement the `IPlug` interface:
87+
88+
```solidity
89+
interface IPlug {
90+
function inbound(
91+
uint32 srcChainSlug_,
92+
bytes calldata payload_
93+
) external payable;
94+
}
95+
```
96+
97+
Plugs connect to Socket specifying: sibling plug address, switchboard for inbound/outbound, and capacitor type.
98+
99+
### TypeScript SDK (`src/`)
100+
101+
Published as `@socket.tech/dl-core`. Exports:
102+
103+
- Chain enums (`ChainSlug`, `ChainId`)
104+
- Contract addresses by deployment mode
105+
- Transmission utilities
106+
107+
## Code Style (Solidity)
108+
109+
- Private/internal variables and functions: underscore prefix (`_foo`, `_bar()`)
110+
- Function parameters: underscore postfix (`param_`)
111+
- Contract instances: double underscore postfix (`contract__`)
112+
- Events: past tense, emitted immediately after state change
113+
- All state variables should be private/internal with explicit getters where needed
114+
115+
## Environment Variables
116+
117+
Required in `.env`:
118+
119+
- `DEPLOYMENT_MODE` - dev/surge/prod
120+
- `SOCKET_SIGNER_KEY` - Deployer private key
121+
- `SOCKET_OWNER_ADDRESS` - Contract owner
122+
- Chain-specific RPCs and explorer API keys

docs/CHAIN_SPECIFIC_FEES.md

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
# Chain-Specific Fee Collection
2+
3+
This document explains how to collect extra fees for specific chain paths (e.g., to/from Reya) using existing Socket DL contract parameters without any code changes.
4+
5+
## Overview
6+
7+
Socket DL allows collecting additional fees for specific chains by adjusting existing fee parameters. This is useful for:
8+
9+
- Charging premium fees for specific destination chains
10+
- Collecting protocol fees for messages from specific source chains
11+
- Implementing tiered pricing based on chain pairs
12+
13+
## Recommended Parameter: `transmissionFees` (with single-message packets)
14+
15+
If packets always contain exactly one message (`maxPacketLength = 1`), then transmission fees become per-message. That makes `transmissionFees` the cleanest mechanism for a flat surcharge with separate accounting.
16+
17+
### Why `transmissionFees` is Best (when `maxPacketLength = 1`)
18+
19+
| Criteria | overhead | verificationOverheadFees | transmissionFees |
20+
| -------------------- | ------------------ | ------------------------ | ----------------------------------- |
21+
| Per-message | ✅ Yes | ✅ Yes | ✅ Yes (with `maxPacketLength = 1`) |
22+
| Per-destination | ✅ Yes | ✅ Yes | ✅ Yes |
23+
| Easy to update | ⚠️ Struct | ⚠️ Two params | ✅ Single value |
24+
| Separate accounting | ❌ Mixed with exec | ❌ Mixed with exec | ✅ Separate bucket |
25+
| Batch update support | ✅ SocketBatcher | ❌ No batcher | ❌ No batcher |
26+
27+
### How `transmissionFees` Works
28+
29+
**Storage** ([ExecutionManagerDF.sol:166](../contracts/ExecutionManagerDF.sol#L166)):
30+
31+
```solidity
32+
mapping(address => mapping(uint32 => uint128)) public transmissionMinFees;
33+
```
34+
35+
**Fee Calculation** ([ExecutionManagerDF.sol:350-358](../contracts/ExecutionManagerDF.sol#L350-L358)):
36+
37+
```solidity
38+
transmissionFees =
39+
transmissionMinFees[transmitManager_][siblingChainSlug_] / maxPacketLength_;
40+
```
41+
42+
With `maxPacketLength = 1`, `transmissionFees` equals the per-message surcharge.
43+
44+
---
45+
46+
## Implementation Guide
47+
48+
### Scenario: Charge $2 Extra for Messages TO and FROM Reya
49+
50+
#### 1. Messages TO Reya (Inbound to Reya)
51+
52+
On **each source chain's** `TransmitManager`, increase `transmissionFees` for Reya's chainSlug:
53+
54+
```solidity
55+
// Example: On Ethereum's TransmitManager
56+
TransmitManager.setTransmissionFees(
57+
nonce,
58+
REYA_CHAIN_SLUG, // 1324967486
59+
currentTransmissionFees + surchargeInSourceNativeToken,
60+
signature
61+
);
62+
```
63+
64+
**Off-chain calculation**: `surcharge = $2 / sourceChainNativeTokenPriceUSD`
65+
66+
Example: If ETH = $2500, surcharge = 0.0008 ETH = 800000000000000 wei
67+
68+
#### 2. Messages FROM Reya (Outbound from Reya)
69+
70+
On **Reya's** `TransmitManager`, increase `transmissionFees` for ALL destination chains:
71+
72+
```solidity
73+
// On Reya's TransmitManager
74+
TransmitManager.setTransmissionFees(
75+
nonce,
76+
DESTINATION_CHAIN_SLUG, // e.g., Ethereum = 1
77+
currentTransmissionFees + surchargeInReyaNativeToken,
78+
signature
79+
);
80+
```
81+
82+
This must be done for each destination chain that Reya can send to.
83+
84+
---
85+
86+
## Fee Flow Visualization
87+
88+
```
89+
┌─────────────────────────────────────────────────────────────────┐
90+
│ TO DESTINATION CHAIN (surcharge) │
91+
├─────────────────────────────────────────────────────────────────┤
92+
│ │
93+
│ Source Chain A ──┐ │
94+
│ Source Chain B ──┼──► transmissionFees[DEST_SLUG] += $X ─► Dest│
95+
│ Source Chain C ──┘ (set on each source chain) │
96+
│ │
97+
└─────────────────────────────────────────────────────────────────┘
98+
99+
┌─────────────────────────────────────────────────────────────────┐
100+
│ FROM SOURCE CHAIN (surcharge) │
101+
├─────────────────────────────────────────────────────────────────┤
102+
│ │
103+
│ transmissionFees[DEST_A] += $X ──► Dest A │
104+
│ Source ─► transmissionFees[DEST_B] += $X ──► Dest B │
105+
│ transmissionFees[DEST_C] += $X ──► Dest C │
106+
│ (set on source chain's TransmitManager) │
107+
│ │
108+
└─────────────────────────────────────────────────────────────────┘
109+
```
110+
111+
---
112+
113+
## Batch Updates
114+
115+
There is no batch setter for `transmissionFees`. Updates must be sent per destination chain.
116+
117+
---
118+
119+
## Setter Function Details
120+
121+
### TransmitManager.setTransmissionFees()
122+
123+
**Location**: [contracts/TransmitManager.sol:94-126](../contracts/TransmitManager.sol#L94-L126)
124+
125+
```solidity
126+
function setTransmissionFees(
127+
uint256 nonce_,
128+
uint32 siblingChainSlug_,
129+
uint128 transmissionFees_,
130+
bytes calldata signature_
131+
) external
132+
```
133+
134+
**Parameters**:
135+
136+
- `nonce_`: Incrementing nonce for the fee updater (replay protection)
137+
- `siblingChainSlug_`: Destination chain identifier
138+
- `transmissionFees_`: Fee per packet (equals per-message when `maxPacketLength = 1`)
139+
- `signature_`: Signature from `FEES_UPDATER_ROLE` holder
140+
141+
**Signature Digest**:
142+
143+
```solidity
144+
keccak256(abi.encode(
145+
FEES_UPDATE_SIG_IDENTIFIER,
146+
address(this), // TransmitManager address
147+
chainSlug, // Source chain slug
148+
siblingChainSlug_, // Destination chain slug
149+
nonce_,
150+
transmissionFees_
151+
))
152+
```
153+
154+
---
155+
156+
## Where Surcharge Fees Go
157+
158+
The surcharge added via `transmissionFees` becomes part of **transmission fees**:
159+
160+
| Aspect | Details |
161+
| ---------- | -------------------------------------------------------------------- |
162+
| Storage | `totalExecutionAndTransmissionFees[chainSlug].totalTransmissionFees` |
163+
| Withdrawal | `withdrawTransmissionFees(chainSlug, amount)` |
164+
| Access | Requires `WITHDRAW_ROLE` |
165+
| Recipient | Managed by `TransmitManager.withdrawFees()` |
166+
167+
**Note**: Surcharge is combined with base transmission fees, but remains in a separate bucket from execution fees.
168+
169+
---
170+
171+
## Off-Chain Service Requirements
172+
173+
To maintain USD-denominated surcharges, the off-chain service needs to:
174+
175+
1. **Track token prices**: Native token price in USD for each chain
176+
2. **Calculate surcharge**: `surchargeWei = $USD_AMOUNT / nativeTokenPriceUSD * 1e18`
177+
3. **Sign updates**: Generate signature using `FEES_UPDATER_ROLE` private key
178+
4. **Submit transactions**: Call `setTransmissionFees()` per destination chain
179+
5. **Update frequency**: When token price moves >X% (e.g., 5%)
180+
181+
### Example Calculation
182+
183+
```javascript
184+
const USD_SURCHARGE = 2; // $2
185+
const ethPriceUSD = 2500;
186+
const surchargeWei = BigInt((USD_SURCHARGE / ethPriceUSD) * 1e18);
187+
// surchargeWei = 800000000000000n (0.0008 ETH)
188+
```
189+
190+
---
191+
192+
## Alternative: Use verificationOverheadFees
193+
194+
If you want surcharge fees to go to the **switchboard** instead of executors:
195+
196+
```solidity
197+
FastSwitchboard.setFees(
198+
nonce,
199+
DESTINATION_CHAIN_SLUG,
200+
switchboardFees, // unchanged
201+
verificationOverheadFees + surchargeAmount, // add surcharge here
202+
signature
203+
);
204+
```
205+
206+
**Difference**:
207+
208+
- `transmissionFees` → goes to transmission fees bucket → withdrawn by transmit manager
209+
- `verificationOverheadFees` → goes to switchboard fees bucket → withdrawn by switchboard
210+
211+
---
212+
213+
## Limitations
214+
215+
1. **No batch setter**: Must update each destination chain separately
216+
2. **Multi-chain updates**: TO a chain requires updates on all source chains
217+
3. **Price volatility**: USD value fluctuates with native token price
218+
4. **All destinations**: FROM a chain applies surcharge to all destinations equally
219+
220+
---
221+
222+
## Summary
223+
224+
| Use Case | Where to Set | Parameter | Function |
225+
| ------------------------- | ----------------- | ------------------------------------- | ----------------------- |
226+
| Charge extra TO Chain X | All source chains | `transmissionFees` for X's slug | `setTransmissionFees()` |
227+
| Charge extra FROM Chain Y | Chain Y | `transmissionFees` for all dest slugs | `setTransmissionFees()` |
228+
| Batch update | Any chain | N/A | N/A |
229+
230+
**Key Files**:
231+
232+
- [contracts/ExecutionManagerDF.sol](../contracts/ExecutionManagerDF.sol) - Fee storage
233+
- [contracts/TransmitManager.sol](../contracts/TransmitManager.sol) - Transmission fee setters
234+
- [contracts/interfaces/ITransmitManager.sol](../contracts/interfaces/ITransmitManager.sol) - Interface definitions

0 commit comments

Comments
 (0)