rwa-token-bridge

module
v0.0.0-...-0b06c0c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2024 License: MIT

README

RWA Token Bridge Example

Context

This repository demonstrates a one-way burn-and-mint RWA token bridge from Ethereum to a Cosmos chain of your choice. The bridge will rely on a set of geographically diverse attestation servers running proprietary software to confirm events on the Ethereum blockchain.

System Overview

Token Burn on Ethereum

A user initiates a transaction via a web app that interacts with a "source bridge" smart contract written in Solidity on Ethereum. During the transaction, the contract receives tokens, burns them, and emits an on-chain event containing a bridge data packet. The packet includes encoded amount and destination-address data, which specifies the amount of tokens and the address that should receive the tokens on the Cosmos chain.

Event Validation

The attestation servers independently observe the bridge event on the Ethereum blockchain, waiting for 65 block confirmations to ensure finality. Upon confirming the event, each server generates an attestation in the form of a digital signature and exposes it via a public API.

Token Mint on Cosmos

The user is then guided via the same web app to submit a transaction on the Cosmos chain. This transaction includes the bridge data packet and the collected signatures. The destination bridge contract on the Cosmos chain will verify the signatures, ensure they are from trusted validators, and then mint the appropriate amount of tokens to the specified destination address.

Destination Bridge Contract Design

The main "contract" implementation of the bridge can be found in the x/rwabridge module. There are two primary files/components:

  • keeper/keeper.go - The keeper is responsible for managing the bridge's state, performing rate limiting, verifying signatures, and minting/transferring tokens.
  • types/ - This package contains all the types used in the bridge module. The most important types are MsgBridgeTransfer, Params and BridgeDataPacket. It also contains the signature verification logic.

Note, the simple bridge implementation could have been implemented as a standalone CosmWasm (WASM) contract. However, we chose to implement it as a native Cosmos SDK module in the interest of time, simplicity and performance. However, the module can be implemented in a CosmWasm contract if desired.

Bridge Data Encoding

While there are many ways to encode the bridge data packet, e.g. Protobuf, Borsh, SSZ, etc., we have chosen to use Ethereum's RLP encoding mechanism. The RLP scheme is simple and widely used in the Ethereum ecosystem. The bridge data packet is relatively compact and can be easily decoded by both the Ethereum and Cosmos chains. Encoding should also be deterministic such the same data packet will always produce the same encoded bytes to sign over.

Contract Ownership & Dynamic Set of Attestors

The Cosmos SDK natively support each module having an "authority". This authority is typically used to authorize who can submit governance-based messages such as updating module parameters. However, it can also be extended to authorize other actions.

For the purposes of this example, everything we need to support the mint and transfer mechanism along with the attestors is defined in the Params structure. The Params type can be modified by the admin/authority of the module. This can be the governance module account (by default on most SDK modules) or it can be a custom account like a foundation multisig account.

Another possible mechanism to consider is instead overriding the authority of the module, we keep the module's authority as the governance module account and have a dedicated separate admin account in Params. However, this would require additional logic to ensure that only the admin can change the attestors.

We found that the current implementation is simplest for demonstration purposes.

Signature Algorithm & Threshold Signing

We chose to use the threshold BLS signature scheme for the attestation servers via the kyber library. The threshold scheme allows for a subset of the attestation servers to attest to the bridge event.

During setup, a group of n participants (attesting validators) runs a distributed key generation algorithm (DKG) to compute a joint public signing key X and one secret key share Xi for each of the n signers. To compute a signature S on a message m, at least t ouf of n signers have to provide partial (BLS) signatures Si on m using their individual key shares Xi which can then be used to recover the full (regular) BLS signature S via Lagrange interpolation. The signature S can be verified with the initially established group key X.

This means that on-chain, the bridge contract only needs to store the public key shares of each attesting validator. Note that the DKG process must happen out-of-band off-chain. The attestors can also be rotated and updated over time but this requires a DKG process to happen beforehand.

While there are other threshold signature schemes we could have used, e.g. a basic secp256k1 multisig used by Cosmos accounts, we chose BLS due to the fact that they are deterministic in the sense they depend only on the message and the signer’s key, unlike other signature schemes, such as ECDSA, that require a fresh random value for each signed message to be secure. In addition, BLS produces smaller signature data and allows for signature aggregation. This means a single signature can be aggregated from multiple attestors and an aggregator can aggregate them (e.g. the webapp)and submit a single signature to the chain instead of multiple individual signatures.

Note, in the example we submit multiple signatures to the chain (see MsgBridgeTransfer.Signatures) instead of a single aggregated signature as to demonstrate how the aggregation process would work. However, in a production environment, we would recommend aggregating the signatures before submitting them to the chain, such as during the user submission process in the webapp.

Bonus “amount-based” Threshold Signing

To extend the threshold signing mechanism to be amount-based, e.g. 2 signature threshold for amounts less than 1 million, 3 for 1 million to 10 million, and 4 for over 10 million, we could extend the Params struct to include multiple sets of attestors. This is because threshold BLS requires the threshold as input as part of the DKG process. However, the attestors would be the same, but the threshold would differ.

Rate Limiting

The bridge contract contains a basic rate limiting mechanism. As part of the bridge contract's Params, we define:

  • rate_limit_quota - The maximum number of tokens that can be transferred during the rate_limit_duration.
  • rate_limit_duration - The duration of a rate limit quota. Any transfer after this duration will reset the quota. If a transfer exceeds the quota during this duration, the bridge contract will reject the transfer.

As part of the contract's state, we store a RateLimiter struct that contains when the last transfer was made and the total flow of tokens. Upon a bridge transfer, we evaluate the current block time and the last transfer time. If that duration exceeds the rate_limit_duration, we reset the flow of tokens and the last transfer time. Otherwise, we increment the flow of tokens and check if it exceeds the rate_limit_quota. If it does, we reject the transfer.

Note, this rate limiter is a naive and simple approach. A more sophisticated rate limiter could be implemented that takes into account the flow of tokens over time such as taking a moving average.

Tests

To execute the tests:

$ make test-unit

Note: You may need to run $ go mod tidy before running the tests.

Directories

Path Synopsis
x

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL