# PreAuth ERC20: Solving Cross-Layer Fragmentation with Payment Card Inspired Pattern
## Abstract
We propose an L2-first token hold mechanism inspired by credit card pre-authorization patterns. Holds are recorded on L2 with zero L1 gas cost and settled in efficient batches, solving token fragmentation while maintaining L1 security. Each L1 account designates a single rollup for managing its holds, similar to how a credit card links to a single payment processor.
## Background and Motivation
The current state of cross-layer token operations suffers from:
1. Fragmented liquidity across L1/L2s
2. High L1 gas costs per operation
3. Complex bridging mechanisms
4. Poor UX due to lack of consistent
Credit card systems solved similar problems decades ago using pre-authorization holds. When you purchase a good, they place a hold on your card without moving any money. Settlement happens later in batches. This pattern is remarkably applicable to L1/L2 token transactions.
Further reading: [L1-L2-chain-fragmentation](https://hackmd.io/@sprintcheckout/L1-L2-chain-fragmentation)
## Key Innovation: L2-First Hold Pattern
Instead of traditional bridge-and-lock patterns, we propose:
1. Holds are recorded only on L2 (like credit card pre-auths)
2. L1 transfers check L2 hold state (like checking card authorization)
3. Settlement occurs in batches (like credit card batch processing)
4. Single rollup designation per account (like single payment processor per card)

### Overall Design
```mermaid
flowchart TB
subgraph L1[Layer 1 ERC20]
direction TB
BC[Base Contract]
SM[Settlement Manager]
end
subgraph L2s[Layer 2 Rollups]
direction TB
subgraph Holds[Hold Management]
HT[Hold Tracker]
HP[Hold Processor]
HV[Hold Validator]
end
subgraph Batch[Batch Management]
BA[Batch Aggregator]
BV[Batch Validator]
BP[Batch Processor]
end
end
User -->|1. Request Hold| HT
HT -->|2. Record Hold| HP
HP -->|3. Validate Balance| HV
HV -->|4. Confirm Hold| User
BA -->|5. Aggregate Holds| BV
BV -->|6. Prepare Batch| BP
BP -->|7. Submit Settlement| SM
SM -->|8. Process Batch| BC
BC -->|9. Update Balances| BC
style L1 fill:#f9f,stroke:#333,stroke-width:2px
style L2s fill:#bbf,stroke:#333,stroke-width:2px
```
## System Flows
### 1. L1 Transaction Flow
```mermaid
sequenceDiagram
participant User as User/Contract
participant L1T as L1 Token Contract
participant L2Q as L2 Hold Manager
User->>L1T: Request Transfer
activate L1T
Note over L1T: Check designated rollup
L1T->>L2Q: Query Total Holds
activate L2Q
Note over L2Q: Read-only call to L2<br/>for hold amount
L2Q-->>L1T: Total Hold Amount
deactivate L2Q
L1T->>L1T: Check Available Balance<br/>(balance - holds)
alt Sufficient Available Balance
L1T->>L1T: Execute Transfer
L1T-->>User: Transfer Success
else Insufficient Available Balance
L1T-->>User: Transfer Reverted
end
deactivate L1T
```
When an L1 transfer is initiated:
1. Contract checks the sender's designated rollup
2. Queries current holds from L2 (read-only)
3. Validates available balance (total - holds)
4. Executes or reverts based on available balance
### 2. Hold Creation Flow
```mermaid
sequenceDiagram
User->>L2: Request Hold
L2->>L2: Validate L1 Balance
L2->>L2: Record Hold
Note over L2: Zero L1 gas cost
```
### 3. Settlement Flow
```mermaid
sequenceDiagram
L2->>L2: Aggregate Holds
L2->>L1: Submit Batch
L1->>L1: Process Transfers
Note over L1,L2: Efficient batch settlement
```
## Technical Implementation
### 1. L1 Token Contract
```solidity
contract L1Token is ERC20 {
// Account → Hold Manager mapping
mapping(address => address) public designatedHoldManager;
function transfer(address to, uint256 amount) public override returns (bool) {
address holdManager = designatedHoldManager[msg.sender];
uint256 heldAmount = 0;
if (holdManager != address(0)) {
heldAmount = IL2HoldManager(holdManager).getTotalHolds(msg.sender);
}
require(balanceOf(msg.sender) >= amount + heldAmount,
"Insufficient available balance");
return super.transfer(to, amount);
}
function availableBalance(address account) public view returns (uint256) {
uint256 balance = balanceOf(account);
address holdManager = designatedHoldManager[account];
if (holdManager != address(0)) {
uint256 heldAmount = IL2HoldManager(holdManager).getTotalHolds(account);
return balance - heldAmount;
}
return balance;
}
}
```
### 2. L2 Hold Manager
```solidity
contract L2HoldManager {
struct Hold {
address owner;
address recipient;
uint256 amount;
uint256 timestamp;
bool processed;
uint256 batchId;
}
mapping(address => mapping(uint256 => Hold)) public holds;
mapping(uint256 => BatchMetadata) public batches;
function createHold(uint256 amount, address recipient) external {
require(checkL1Balance(msg.sender) >= amount +
totalHoldAmount[msg.sender],
"Insufficient L1 balance");
// Record hold with zero L1 gas cost
holds[msg.sender][holdCount[msg.sender]++] = Hold({
owner: msg.sender,
recipient: recipient,
amount: amount,
timestamp: block.timestamp,
processed: false,
batchId: 0
});
}
}
```
## Gas Efficiency
1. L1 Transfer with Hold Check: ~60k gas
2. Hold Creation: ~0 L1 gas
3. Batch Settlement: ~80k gas per batch (amortized across holds)
Comparison (costs per operation):
- Traditional Bridge: ~150k gas
- Lock-and-Mint: ~120k gas
- Our Approach: ~5k gas (amortized)
## Security Considerations
1. L1 Transaction Safety
- Real-time hold verification
- Atomic balance checks
- No double-spending risk
2. L2 Hold Management
- Single rollup designation
- Clear state transitions
- Efficient validation
3. Cross-Layer Security
- L1 balance as source of truth
- Secure message passing
- Batched settlement integrity
## Rollup Support
The system supports all major rollup types through their native message passing systems:
1. Type 1 ZK Rollups (ZK-Rollups with Ethereum-equivalent EVM):
* Taiko:
- TaikoL1 contract for message passing and signal service
- Cross-chain message protocol (CCMP) for L1↔L2 communication
- Synchronous proof generation and verification
- EIP-4844 blob support for data availability
- Deterministic L2 block proposing
2. Optimistic Rollups:
* Base (Optimism):
- CrossDomainMessenger for message passing
- 7-day challenge period
- Standard fault proof system
* Arbitrum:
- Delayed Inbox for message submission
- Sequencer batch posting
- Retryable ticket system for L1→L2 messages
- Custom fraud proof mechanism
3. Type 2 ZK Rollups:
* Scroll:
- ScrollMessenger for cross-layer communication
- zkEVM circuit verification
- Batch proof generation and verification
* zkSync:
- L1 Messenger contract
- Priority queue for L1→L2 messages
- zkPorter data availability
- Custom proof verification system
### Message Passing Implementation Specifics:
1. Taiko:
```solidity
interface ITaikoL1 {
function sendMessage(
address target,
uint256 value,
bytes calldata message
) external returns (bytes32);
function processMessage(
bytes calldata message,
bytes calldata proof
) external returns (bool);
}
interface ITaikoL2 {
function sendSignal(bytes32 signal) external returns (bytes32);
function verifySignal(
address app,
bytes32 signal,
bytes calldata proof
) external view returns (bool);
}
```
2. Base/Optimism:
```solidity
interface ICrossDomainMessenger {
function sendMessage(
address _target,
bytes memory _message,
uint32 _gasLimit
) external;
}
```
3. Arbitrum:
```solidity
interface IInbox {
function createRetryableTicket(
address to,
uint256 l2CallValue,
uint256 maxSubmissionCost,
address submissionRefundAddress,
address valueRefundAddress,
uint256 gasLimit,
uint256 maxFeePerGas,
bytes calldata data
) external payable returns (uint256);
}
```
4. Scroll/zkSync:
```solidity
interface IScrollMessenger {
function sendMessage(
address target,
bytes memory message
) external;
}
interface IZkSync {
function requestL2Transaction(
address _contract,
uint256 _l2Value,
bytes calldata _calldata,
uint256 _ergsLimit,
bytes[] calldata _factoryDeps
) external payable returns (bytes32);
}
```
### Key Differences in Message Handling:
1. Taiko:
- Immediate proof verification
- Synchronous message processing
- Built-in signal service for state verification
- EIP-4844 blob support for reduced calldata costs
2. Optimistic Rollups:
- Delayed finality (7-day window)
- Asynchronous message processing
- Fraud proof challenge system
3. Type 2 ZK Rollups:
- Custom proof generation systems
- Specialized verification circuits
- Asynchronous batch processing
This diversity in message passing systems requires careful implementation of the hold mechanism to handle each rollup's unique characteristics while maintaining consistent security and efficiency.
## Request for Feedback
Particularly interested in:
1. L1-Rollup native message passing posible limitations
- Hold message sync issues
3. Hold verification strategies on Rollups
4. Gas efficiency improvements
**Reach out to** [**t.me/joanseg**](https://t.me/joanseg) **or joan (at) sprintcheckout (dot) com**
Comment on this Ethereum Magicians topic: [Payments Use Case Working Group](https://ethereum-magicians.org/t/payments-use-case-working-group)
Author: Joan | Researcher at [Sprintcheckout](https://sprintcheckout.com/)