This bridge contract facilitates cross-chain asset transfers using a secure Multi-Party Computation (MPC) system for validation. Let me explain how it functions:
-
Domain IDs: Each blockchain has a unique domain identifier. The bridge contract is deployed on each chain with its corresponding domain ID.
-
MPC System: Provides security through distributed signature generation - no single entity can authorize transfers.
-
Resource IDs: Unique 32-byte identifiers that map to specific assets across different chains.
-
Handlers: Specialized contracts that process different types of assets (ERC20, ERC721, etc.).
User (Chain A) → Bridge Contract → Handler → MPC Nodes → Bridge Contract → Handler → User (Chain B)
- Deposit Initiation:
function deposit(
uint8 destinationDomainID,
bytes32 resourceID,
bytes calldata depositData,
bytes calldata feeData
)
- User calls deposit() on Chain A's bridge
- Bridge collects fees through the fee handler (if configured)
- Bridge finds the appropriate handler using the resourceID mapping
- Handler locks or burns the tokens on Chain A
- Bridge emits a Deposit event with a unique deposit nonce
- Off-Chain Processing:
- MPC nodes monitor for Deposit events
- The MPC system reaches consensus and creates a signature
- Execution on Destination Chain:
function executeProposals(Proposal[] memory proposals, bytes calldata signature)
- A relayer submits the proposal(s) and MPC signature to Chain B's bridge
- Bridge verifies the signature using the EIP-712 standard
- Bridge calls the appropriate handler to release tokens on Chain B
- Bridge marks the proposal as executed (prevents replay attacks)
- Bridge emits a ProposalExecution event
The bridge includes functions to manage the MPC system:
function startKeygen() external
function endKeygen(address MPCAddress) external
function refreshKey(string memory hash) external
function retry(string memory txHash) external
- startKeygen() and endKeygen(): Initialize the MPC system
- refreshKey(): Rotates MPC keys for security
- retry(): Re-attempts failed transfers
- Signature Verification: All proposals require valid MPC signatures
- Nonce Tracking: The usedNonces mapping prevents replay attacks
- Pausability: Bridge can be paused in emergencies
- Access Control: Fine-grained permissions via IAccessControlSegregator
For a token transfer from Selendra (Domain 1) to Ethereum (Domain 2):
- User calls deposit() on Selendra bridge
- Selendra handler locks tokens
- MPC nodes observe the Deposit event
- MPC nodes generate a signature
- Relayer calls executeProposals() on Ethereum bridge
- Ethereum handler mints/unlocks tokens for recipient
selendra bridge with rust
- go to smart contract directory
cd smart-contracts
- compile smart contract
truffle compile
- run ganache for testing
./scripts/start_ganache.sh
- run test all
truffle test
- run test witg specific file
truffle test <test-file>