Skip to main content

Metadollar Example

This document gives a simple example of a contract on DoveChain that can be used to track and reconcile value across several primary chains.

0. The Utility of Dove

A key idea of Dove is its ability to coordinate and assert a single global state across multiple chains. The MetaDollar example code represents a (deliberately trivial) multichain liquidity pool with cross-chain balancing and funds management via a central contract on Dove. The coordinating contract (MetaDollarVault.sol) accesses information via the UEL (Universal Event Locator). The UEL uniquely defines a specific event emitted by a specific contract on a specific chain:

function getUEL(string memory _chainName, address _contract, string memory _eventName)
public pure
returns (bytes32)
bytes32 UEL = keccak256(abi.encodePacked(

return UEL;

Once MetaDollarVault.sol has pulled all the data it needs, it can trivially determine and reconcile multichain account balances.

1. MetaDollarVault

When events are detected, contracts on Dove can look them up (via the UEL) and compute on the parsed data. This makes it easy to build things. For example, the core logic of a cross-chain metapool can be coded in a single line:

// Determine total MetaDollar holdings for msg.sender 
poolBalances[msg.sender] = balance_on_ETH + balance_on_SOL;

The entire core logic for determining a user's balance on multiple chains, each with different finality requirements, requires only a few lines of code:

/* Multichain account MetaBalance */ 
function metaDollarBalance()
public returns (int) {

// reconcile funds across chains
int balance_on_ETH = 0;
int balance_on_SOL = 0;

uint block_ETH = storageContract.getMostRecentObservedBlock("Ethereum");
uint block_SOL = storageContract.getMostRecentObservedBlock("Solana");

uint conf_ETH = 3; // wait three blocks for confirmation on Ethereum
uint conf_SOL = 2; // wait two blocks for confirmation on Solana

Storage.EventKernel memory ek_ETH = storageContract.getLatestEvent(msg.sender, UEL_Deposit_on_ETH);
if (ek_ETH.BlockNumber == 0) {
// no events/funds
} else if (ek_ETH.BlockNumber + conf_ETH >= block_ETH) {
// we have an event AND it's confirmed
balance_on_ETH = ek_ETH.ParsedInt;
} else {
emit TooEarly("Have Deposit event on Ethereum but not confirmed yet");

Storage.EventKernel memory ek_SOL = storageContract.getLatestEvent(msg.sender, UEL_Deposit_on_SOL);
if (ek_SOL.BlockNumber == 0) {
// no events/funds
} else if (ek_SOL.BlockNumber + conf_SOL >= block_SOL) {
// we have a Deposit event AND it's confirmed
balance_on_SOL = ek_SOL.ParsedInt;
} else {
emit TooEarly("Have Deposit event on Solana but not confirmed yet");

// Determine total MetaDollar holdings for msg.sender
poolBalances[msg.sender] = balance_on_ETH + balance_on_SOL;

emit PoolMetaBalance(msg.sender, poolBalances[msg.sender]);

return poolBalances[msg.sender];