Week 14 at Blockfuse Labs
This week was all about building. Here’s a deep dive into what we worked on:


Building a Token Bridge: Lock & Mint Cross-Chain Transfers for ERC-20 Tokens

As blockchain ecosystems evolve, interoperability across chains is becoming increasingly important. Token bridges are the infrastructure that enable seamless asset transfers between networks.

In this post, I’ll walk through how we implemented a Lock & Mint token bridge for ERC-20 tokens, including the smart contract logic, the relayer role, and how we bridged tokens between Base and Sepolia testnets.


Use Case

Bridge an ERC-20 token (BBT) from Base to Sepolia, and back.


What Is a Lock & Mint Bridge?

The Lock & Mint pattern works by:

  1. Locking tokens on the source chain
  2. Minting equivalent wrapped tokens on the destination chain

This ensures a controlled token supply — no tokens are created out of thin air, just value moved across chains.

Flow (Base → Sepolia):
Lock → Emit Event → Relayer → Mint
Return (Sepolia → Base):
Burn → Emit Event → Relayer → Release


Step 1: Locking on the Source Chain (Base)

function lockTokens(uint256 amount, string calldata targetChain) external nonReentrant {
    // Validations
    ...
    token.transferFrom(msg.sender, address(this), amount);
    
    bytes32 opId = keccak256(abi.encodePacked(msg.sender, destAmount, block.timestamp));
    bridgeOperations[opId] = BridgeOperation(...);
    
    emit Event.BridgeInitiated(...);
}

This function:

  • Transfers tokens from the user to the contract
  • Emits a BridgeInitiated event for the relayer
  • Stores metadata in bridgeOperations

Step 2: Bridging the Gap with a Relayer

Smart contracts on different chains can’t communicate directly. A relayer listens for BridgeInitiated events on Base and then calls mintTokens on Sepolia to complete the transfer.


Step 3: Minting on the Destination Chain (Sepolia)

function mintTokens(address to, uint256 amount, bytes32 sourceTx) external nonReentrant {
    ...
    token.mint(to, finalAmount);
    emit Event.BridgeFinalized(...);
}

The user receives wBBT on Sepolia, fully backed by the 30 BBT locked on Base.


Bridging Back: Burn and Release

To reverse the bridge, we follow a mirrored process.


Step 4: Burn Tokens on Sepolia

function burnTokens(uint256 amount, string calldata targetChain) external nonReentrant {
    ...
    token.burnFromBridge(msg.sender, amount);
    emit Event.BridgeInitiated(...);
}

This burns the wrapped tokens and emits a new BridgeInitiated event.


Step 5: Release Tokens on Base

function releaseTokens(address to, uint256 amount, bytes32 sourceTx) external onlyOnce(sourceTx) {
    ...
    token.transfer(to, amount);
    emit Event.BridgeFinalized(...);
}

The original tokens are released from the Base contract and returned to the user.


Open Source Code

The full working implementation is available here:
https://github.com/chain-builders/Token-Bridge


Closing Thoughts

Token bridges like this unlock real utility, especially in ecosystems where different chains are optimized for different goals — such as low-fee L2s or isolated testnets.

By combining event-driven smart contracts with a trusted relayer, our Lock & Mint bridge offers a simple, secure, and extensible way to move tokens between networks.