Cross-Chain Bridge Events Matching

This Gatelang script matches a "ReceivedMessage" event on onechain to a sent message on the other chain.

Note that it fetches all sent messages from genesis and thanks to our optimized caching, it is able to do all of that very effectively, running for every block and still performing at the speed of the chain.

use Contains, Events, HistoricalEvents, MapContains from hexagate;

// Hyperlane bridge addresses */
source sourceBridge: address = 0xF51Aa4067CDabb5Aa970dF435B54e25366bF73C5;
source destinationBridge: address = 0xF51Aa4067CDabb5Aa970dF435B54e25366bF73C5;

// Get all `SentMessage` events from source chain since genesis
source allSourceChainSendEvents: list < tuple < integer, bytes, integer, string, string >> = HistoricalEvents {
  contract: sourceBridge,
  signature: "event SentMessage(uint32 indexed _destination, bytes32 indexed _recipient, uint256 _value, string _message, string _metadata)",
  chainId: 10,
};

// Save all source chain events in a map for efficient lookup
source sourceChainEventMap: map < string, boolean > = {
  ev[3]: true
  for ev in allSourceChainSendEvents
};

// Get all `ReceivedMessage` events from the destination chain in the current block
source destinationChainExecuteEvents: list < tuple < integer, bytes, integer, string >> = Events {
  contract: destinationBridge,
  signature: "event ReceivedMessage(uint32 indexed origin, bytes32 indexed sender, uint256 value, string msg)"
};

// For each received message event, validate that the message exists in the map
source eventsFound: list < boolean > = [
  MapContains {
    map: sourceChainEventMap,
    item: ev[3]
  }
  for ev in destinationChainExecuteEvents
];

// Ensure all events in destination chain matched a payload from a previous source chain event
rule {
  description: "Detected received messages that do not have matching sent message events",
  condition: !Contains {
    sequence: eventsFound,
    item: false
  }
};

Last updated