Overview
TheCrossChainGuard contract provides a security pattern for cross-chain authorization. It allows contracts on L2 (Gnosis Chain) to verify that function calls originate from an authorized owner on L1 (Ethereum mainnet) via the Arbitrary Message Bridge (AMB).
This enables secure cross-chain governance where mainnet contracts or multisigs can control L2 deployments without deploying private keys on L2.
Contract Location: contracts/bridge/CrossChainGuard.sol:9
Use Case
Tornado Nova deploys the core TornadoPool contract on Gnosis Chain (L2) for lower transaction costs, but governance remains on Ethereum mainnet (L1). The CrossChainGuard allows L1 governance to:- Update pool parameters
- Change fee structures
- Upgrade proxy implementations
- Execute emergency functions
Architecture
State Variables
All state variables are immutable and set at deployment:Address of the AMB bridge contract on the current chain. For Gnosis Chain:
0x75Df5AF045d91108662D8080fD1FEFAd6aA0bb59Chain ID where the owner resides. For Ethereum mainnet:
bytes32(uint256(1))Address authorized to control this contract from the owner chain. Typically a governance multisig or DAO contract
Constructor
Parameters
AMB bridge contract address on the deployment chain
Chain ID of the chain where the owner resides (e.g., 1 for Ethereum mainnet)
Address that will be authorized to call protected functions
Implementation
Deployment Example
Core Function
isCalledByOwner
Verifies that the current call originates from the authorized owner on the correct chain via the AMB bridge.true if all three verification checks pass, false otherwise
Implementation
Triple Verification
The function performs three critical checks:Check Direct Caller
Verifies
msg.sender == address(ambBridge) - ensures only the AMB bridge can call this functionCheck Source Chain
Verifies
ambBridge.messageSourceChainId() == ownerChainId - ensures the message originated from the correct chain (e.g., Ethereum mainnet)All three checks must pass for authorization to succeed. This prevents:
- Direct calls from unauthorized addresses
- Cross-chain calls from wrong chains
- Cross-chain calls from unauthorized addresses on the correct chain
Usage Pattern
Contracts that need cross-chain authorization inherit fromCrossChainGuard and use the isCalledByOwner() check:
Basic Implementation
Modifier Pattern
Many contracts create a modifier for cleaner syntax:Cross-Chain Execution Flow
How governance executes a function from L1 to L2:Step 1: Encode Function Call
On L1, encode the target function call:Step 2: Send via AMB
Step 3: AMB Relays Message
The AMB validators:- Observe the message on L1
- Reach consensus
- Execute the message on L2 by calling the target contract
Step 4: Verification on L2
When the L2 contract receives the call:AMB Bridge Interface
The contract interacts with the AMB bridge through theIAMB interface:
Returns the address that initiated the cross-chain message on the source chain
Returns the chain ID where the message originated
These functions only return meaningful values during cross-chain message execution. Outside of that context, they may return zero or revert.
Security Considerations
Immutable Configuration
All configuration is immutable to prevent governance takeover:- Cannot change the AMB bridge address after deployment
- Cannot change which chain the owner resides on
- Cannot change the owner address
Design Decision: Immutability prevents malicious governance from changing the authorization mechanism. If ownership needs to transfer, deploy a new contract.
Virtual Function
TheisCalledByOwner() function is marked virtual, allowing inheriting contracts to:
- Add additional authorization logic
- Implement time-locks
- Add multi-signature requirements
- Create temporary permission grants
AMB Bridge Trust
The system relies on the security of the AMB bridge:- Bridge Validators: Small set of validators must be honest
- Bridge Upgrades: Bridge governance could change behavior
- Message Replay: AMB prevents replay, but verify in application logic if needed
Trust Assumption: Users trust that AMB validators will not collude to forge messages or halt the bridge.
Common Patterns
Pattern 1: Single Owner Function
Pattern 2: Owner or Local Admin
Pattern 3: Tiered Permissions
Chain IDs
Common chain IDs for cross-chain governance:| Chain | Chain ID | Hex |
|---|---|---|
| Ethereum Mainnet | 1 | 0x01 |
| Gnosis Chain | 100 | 0x64 |
| Polygon | 137 | 0x89 |
| Arbitrum One | 42161 | 0xa4b1 |
| Optimism | 10 | 0x0a |