8000 GitHub - eco/permit3: πŸ” Permit3: One-Click Cross-Chain Token Permissions
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

eco/permit3

Repository files navigation

πŸ” Permit3: One-Click Cross-Chain Token Permissions

License: MIT

Permit3 is a revolutionary protocol that enables cross-chain token approvals and transfers with a single signature. It unlocks a one-signature cross-chain future through innovative UnhingedProofs and non-sequential nonces, while maintaining Permit2 compatibility.

"Permit3 unlocks a one-click/signature cross-chain future."

✨ Key Features

  • πŸŒ‰ Cross-Chain Operations: Authorize token operations across multiple blockchains with one signature
  • πŸ” Direct Permit Execution: Execute permit operations without signatures when caller has authority
  • πŸ”— ERC-7702 Integration: Account Abstraction support for enhanced user experience
  • 🌲 Unhinged Merkle Trees: A novel two-part data structure that combines:
                 [H1] β†’ [H2] β†’ [H3] β†’ ROOT  ← Sequential chain (top part)
              /      \      \      \
            [BR]    [D5]   [D6]   [D7]      ← Additional chain data
           /     \
       [BH1]     [BH2]                      ← Balanced tree (bottom part)
      /    \     /    \
    [D1]  [D2] [D3]  [D4]                   ← Leaf data
    
    • πŸ”½ Bottom part: Standard balanced tree for efficient membership proofs within a chain
    • πŸ”Ό Top part: Sequential hash chain incorporating the balanced root and cross-chain data
    • 🎯 Benefits: Optimal gas usage by processing only what each chain needs
    • πŸ’° Calldata Optimization: Chains should be ordered by calldata cost (cheapest first, most expensive last)
    • ⚑ Gas Efficiency: Expensive chains (like Ethereum) only need to verify a minimal preHash value
  • 🧩 Witness Functionality: Attach arbitrary data to permits for enhanced verification and complex permission patterns
  • πŸ”„ Flexible Allowance Management:
    • ⬆️ Increase/decrease allowances asynchronously
    • ⏱️ Time-bound permissions with automatic expiration
    • πŸ”’ Account locking for enhanced security
  • ⚑ Gas-Optimized Design:
    • πŸ”’ Non-sequential nonces for concurrent operations
    • πŸ—ƒοΈ Bitmap-based nonce tracking for efficient gas usage
    • πŸ” UnhingedProofs for efficient and secure cross-chain verification
  • πŸ›‘οΈ Emergency Security Controls:
    • 🚫 Cross-chain revocation system
    • πŸ” Account locking mechanism
    • ⏳ Time-bound permissions
  • πŸ”„ Full Permit2 Compatibility:
    • πŸ“„ Implements all Permit2 interfaces
    • πŸ”Œ Drop-in replacement for existing integrations

πŸ“š Documentation

Comprehensive documentation is available in the docs directory:

Section Description Quick Links
🏠 Overview Getting started with Permit3 Introduction
πŸ—οΈ Core Concepts Understanding the fundamentals Architecture Β· Witnesses Β· Cross-Chain Β· Merkle Trees Β· Nonces Β· Allowances
πŸ“š Guides Step-by-step tutorials Quick Start Β· ERC-7702 Β· Witness Integration Β· Cross-Chain Β· Signatures Β· Security
πŸ“‹ API Reference Technical specifications Full API Β· Data Structures Β· Interfaces Β· Events Β· Error Codes
πŸ’» Examples Code samples ERC-7702 Β· Witness Β· Cross-Chain Β· Allowance Β· Security Β· Integration

πŸ”„ Permit2 Compatibility

Permit3 implements IPermit for Permit2 transfer compatibility:

// Existing contracts using Permit2 can work without changes
IPermit2 permit2 = IPermit2(PERMIT3_ADDRESS);
permit2.transferFrom(msg.senΞ©zΞ©der, recipient, 1000e6, USDC);

βœ… Supported Permit2 Functions

// Standard approvals
function approve(address token, address spender, uint160 amount, uint48 expiration) external;

// Direct transfers
function transferFrom(address from, address to, uint160 amount, address token) external;

// Batched transfers
function transferFrom(AllowanceTransferDetails[] calldata transfers) external;

// Permission management
function allowance(address user, address token, address spender) 
    external view returns (uint160 amount, uint48 expiration, uint48 nonce);
function lockdown(TokenSpenderPair[] calldata approvals) external;

πŸ”— Enhanced Functions (Permit3 Exclusive)

// Direct permit execution (no signatures required, caller is owner)
function permit(AllowanceOrTransfer[] memory permits) external;

// Single-chain permit operations with signatures  
function permit(address owner, bytes32 salt, uint256 deadline, uint48 timestamp, 
                ChainPermits memory chain, bytes calldata signature) external;

// Cross-chain operations with UnhingedProofs and signatures
function permit(address owner, bytes32 salt, uint256 deadline, uint48 timestamp,
                UnhingedPermitProof calldata proof, bytes calldata signature) external;

Direct Permit Usage:

// Execute permit operations directly (msg.sender becomes token owner)
AllowanceOrTransfer[] memory operations = [
    AllowanceOrTransfer({
        modeOrExpiration: 1735689600, // expiration timestamp
        token: USDC_ADDRESS,
        account: DEX_ADDRESS,
        amountDelta: 1000e6 // 1000 USDC allowance
    })
];

permit3.permit(operations); // No signature needed, no chainId needed!

πŸ’‘ Core Concepts

πŸ”„ Allowance Operations

The protocol centers around the AllowanceOrTransfer structure:

struct AllowanceOrTransfer {
    uint48 modeOrExpiration;    // Operation mode/expiration
    address token;              // Token address
    address account;            // Approved spender/recipient
    uint160 amountDelta;        // Amount change/transfer amount
}

βš™οΈ Operation Modes

  1. πŸ“€ Transfer Mode (modeOrExpiration = 0)

    • Executes immediate token transfer
    • account is recipient
    • amountDelta is transfer amount
  2. πŸ“‰ Decrease Mode (modeOrExpiration = 1)

    • Reduces existing allowance
    • amountDelta: regular decrease amount
    • Special: type(uint160).max resets to 0
  3. πŸ”’ Lock Mode (modeOrExpiration = 2)

    • Enters special locked state
    • Blocks increases/transfers
    • Rejects all operations until unlocked
    • Sets approval to 0 for that token/account pair
  4. πŸ”“ Unlock Mode (modeOrExpiration = 3)

    • Cancels locked state
    • Tracks unlock timestamp
    • Sets allowance to provided amount
  5. πŸ“ˆ Increase Mode (modeOrExpiration > 3)

    • Value acts as expiration timestamp
    • Updates if timestamp is newer
    • amountDelta: increase amount
    • Special cases:
      • 0: Updates expiration only
      • type(uint160).max: Unlimited approval

⏱️ Timestamp Management

struct Allowance {
    uint160 amount;
    uint48 expiration;
    uint48 timestamp;
}
  • ⏰ Timestamps order operations across chains
  • πŸ”„ Most recent timestamp takes precedence in expiration updates
  • 🚧 Prevents cross-chain race conditions
  • πŸ”‘ Critical for async allowance updates

πŸ” Account Locking

Locked accounts have special restrictions:

  • 🚫 Cannot increase/decrease allowances
  • 🚫 Cannot execute transfers
  • πŸ”‘ Must submit unlock command with timestamp validation to disable
  • πŸ›‘οΈ Provides emergency security control

πŸ”Œ Integration

πŸ› οΈ Basic Setup

// Access Permit2 compatibility
IPermit permit = IPermit(PERMIT3_ADDRESS);
permit.transferFrom(msg.senΞ©zΞ©der, recipient, 1000e6, USDC);

// Access Permit3 features
IPermit3 permit3 = IPermit3(PERMIT3_ADDRESS);

πŸ“ Example Operations

// 1. Increase Allowance
ChainPermits memory permitData = ChainPermits({
    chainId: block.chainid,
    permits: [AllowanceOrTransfer({
        modeOrExpiration: block.timestamp + 1 days,
        token: USDC,
        account: DEX,
        amountDelta: 1000e6
    })]
});

// 2. Lock Account
permitData.permits.push(AllowanceOrTransfer({
    modeOrExpiration: 2,
    token: USDC,
    account: address(0),
    amountDelta: 0
}));

// 3. Execute Transfer
permitData.permits.push(AllowanceOrTransfer({
    modeOrExpiration: 0,
    token: USDC,
    account: recipient,
    amountDelta: 500e6
}));

πŸŒ‰ Cross-Chain Usage with UnhingedProofs

// Create permits for each chain
const ethPermits = {
    chainId: 1,
    permits: [{
        modeOrExpiration: futureTimestamp,
        token: USDC_ETH,
        account: DEX_ETH,
        amountDelta: 1000e6
    }]
};

const arbPermits = {
    chainId: 42161,
    permits: [{
        modeOrExpiration: 1, // Decrease mode
        token: USDC_ARB,
        account: DEX_ARB,
        amountDelta: 500e6
    }]
};

// Generate subtree roots for each chain
const ethRoot = permit3.hashChainPermits(ethPermits);
const arbRoot = permit3.hashChainPermits(arbPermits);

// Create unhinged root and proof using UnhingedMerkleTree library
const unhingedRoot = UnhingedMerkleTree.hashLink(ethRoot, arbRoot);
const unhingedProof = UnhingedMerkleTree.createOptimizedProof(ethRoot, [], [arbRoot]);
// Note: Implementation uses calldata for optimal gas efficiency

// Create and sign with the unhinged root
const signature = signPermit3(owner, salt, deadline, timestamp, unhingedRoot);

πŸ›‘οΈ Security Guidelines

  1. πŸ”‘ Allowance Management

    • ⏱️ Set reasonable expiration times
    • πŸ”’ Use lock mode for sensitive accounts
    • πŸ“Š Monitor allowance changes across chains
  2. ⏰ Timestamp Validation

    • πŸ“‹ Validate operation ordering
    • ⏳ Check for expired timestamps
    • πŸ” Handle locked state properly
  3. 🌐 Cross-Chain Security

    • πŸ” Verify chain IDs match
    • πŸ”’ Use unique nonces
    • πŸ‘€ Monitor pending operations

πŸ‘¨β€πŸ’» Development

# Install
forge install

# Test
forge test

# Deploy
forge script script/DeployPermit3.s.sol:DeployPermit3 \
    --rpc-url <RPC_URL> \
    --private-key <KEY> \
    --broadcast

πŸ“„ License

MIT License - see LICENSE

About

πŸ” Permit3: One-Click Cross-Chain Token Permissions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  
0