Skip to content

Commit

Permalink
feat(evm): adds onlyYaho within MessageRelay, refactors Sygma tests a…
Browse files Browse the repository at this point in the history
…nd comments not working ones
  • Loading branch information
allemanfredi committed Nov 7, 2023
1 parent 4f6c539 commit 1a6b206
Show file tree
Hide file tree
Showing 23 changed files with 404 additions and 555 deletions.
50 changes: 33 additions & 17 deletions packages/evm/contracts/Yaho.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ contract Yaho is IYaho, MessageHashCalculator, MessageIdCalculator {
/// @param data The message data.
/// @return messageId A message ID corresponding to the dispatched message.
function dispatchMessage(uint256 toChainId, address to, bytes calldata data) external returns (bytes32 messageId) {
messageId = _dispatchMessage(toChainId, to, data);
(messageId, ) = _dispatchMessage(toChainId, to, data);
}

/// @dev Dispatches a message using the EIP-5164 standard on more chains, putting their into storage and emitting their contents as an event.
Expand All @@ -37,16 +37,17 @@ contract Yaho is IYaho, MessageHashCalculator, MessageIdCalculator {
uint256[] calldata toChainIds,
address[] calldata tos,
bytes calldata data
) public returns (bytes32[] memory) {
) public returns (bytes32[] memory, bytes32[] memory) {
if (toChainIds.length != tos.length) revert UnequalArrayLengths(address(this));
bytes32[] memory messageIds = new bytes32[](toChainIds.length);
bytes32[] memory messageHashes = new bytes32[](toChainIds.length);
for (uint256 i = 0; i < toChainIds.length; ) {
messageIds[i] = _dispatchMessage(toChainIds[i], tos[i], data);
(messageIds[i], messageHashes[i]) = _dispatchMessage(toChainIds[i], tos[i], data);
unchecked {
++i;
}
}
return messageIds;
return (messageIds, messageHashes);
}

/// @dev Dispatches a batch of messages, putting their into storage and emitting their contents as an event.
Expand All @@ -58,19 +59,20 @@ contract Yaho is IYaho, MessageHashCalculator, MessageIdCalculator {
uint256[] calldata toChainIds,
address[] calldata tos,
bytes[] calldata data
) public returns (bytes32[] memory) {
) public returns (bytes32[] memory, bytes32[] memory) {
if (toChainIds.length != tos.length || toChainIds.length != data.length)
revert UnequalArrayLengths(address(this));

bytes32[] memory messageIds = new bytes32[](toChainIds.length);
bytes32[] memory messageHashes = new bytes32[](toChainIds.length);
for (uint256 i = 0; i < toChainIds.length; ) {
messageIds[i] = _dispatchMessage(toChainIds[i], tos[i], data[i]);
(messageIds[i], messageHashes[i]) = _dispatchMessage(toChainIds[i], tos[i], data[i]);

unchecked {
++i;
}
}
return messageIds;
return (messageIds, messageHashes);
}

/// @dev Relays hashes of the given message ids to the given messageRelays.
Expand All @@ -89,14 +91,16 @@ contract Yaho is IYaho, MessageHashCalculator, MessageIdCalculator {
if (messages.length != messageIds.length) revert UnequalArrayLengths(address(this));

uint256[] memory toChainIds = new uint256[](messageIds.length);
bytes32[] memory messageHashes = new bytes32[](messageIds.length);
for (uint256 i = 0; i < messageIds.length; i++) {
bytes32 expectedMessageHash = hashes[messageIds[i]];
bytes32 messageHash = calculateMessageHash(messages[i], address(this));
if (messageHash != expectedMessageHash) revert MessageHashMismatch(messageHash, expectedMessageHash);
messageHashes[i] = calculateMessageHash(messages[i], address(this));
if (messageHashes[i] != expectedMessageHash)
revert MessageHashMismatch(messageHashes[i], expectedMessageHash);
toChainIds[i] = messages[i].toChainId;
}

adapterReciepts = _relayMessages(toChainIds, messageIds, messageRelays, adapters);
adapterReciepts = _relayMessages(toChainIds, messageIds, messageHashes, messageRelays, adapters);
return adapterReciepts;
}

Expand All @@ -115,8 +119,9 @@ contract Yaho is IYaho, MessageHashCalculator, MessageIdCalculator {
address[] calldata messageRelays,
address[] calldata adapters
) external payable returns (bytes32[] memory messageIds, bytes32[] memory adapterReciepts) {
messageIds = dispatchMessages(toChainIds, tos, data);
adapterReciepts = _relayMessages(toChainIds, messageIds, messageRelays, adapters);
bytes32[] memory messageHashes = new bytes32[](messageIds.length);
(messageIds, messageHashes) = dispatchMessages(toChainIds, tos, data);
adapterReciepts = _relayMessages(toChainIds, messageIds, messageHashes, messageRelays, adapters);
return (messageIds, adapterReciepts);
}

Expand All @@ -135,17 +140,22 @@ contract Yaho is IYaho, MessageHashCalculator, MessageIdCalculator {
address[] calldata messageRelays,
address[] calldata adapters
) external payable returns (bytes32[] memory messageIds, bytes32[] memory adapterReciepts) {
messageIds = dispatchMessages(toChainIds, tos, data);
adapterReciepts = _relayMessages(toChainIds, messageIds, messageRelays, adapters);
bytes32[] memory messageHashes = new bytes32[](messageIds.length);
(messageIds, messageHashes) = dispatchMessages(toChainIds, tos, data);
adapterReciepts = _relayMessages(toChainIds, messageIds, messageHashes, messageRelays, adapters);
return (messageIds, adapterReciepts);
}

function _dispatchMessage(uint256 toChainId, address to, bytes calldata data) internal returns (bytes32 messageId) {
function _dispatchMessage(
uint256 toChainId,
address to,
bytes calldata data
) internal returns (bytes32 messageId, bytes32 messageHash) {
bool isHeaderReporter = msg.sender == headerReporter;
address from = isHeaderReporter ? address(0) : msg.sender;
// NOTE: in case of isHeaderReporter = true -> to = address(0)
Message memory message = Message(block.chainid, toChainId, from, to, data);
bytes32 messageHash = calculateMessageHash(message, address(this));
messageHash = calculateMessageHash(message, address(this));
bytes32 salt = keccak256(
abi.encode(
isHeaderReporter ? MESSAGE_BHR : MESSAGE_MPI,
Expand All @@ -160,6 +170,7 @@ contract Yaho is IYaho, MessageHashCalculator, MessageIdCalculator {
function _relayMessages(
uint256[] memory toChainIds,
bytes32[] memory messageIds,
bytes32[] memory messageHashes,
address[] calldata messageRelays,
address[] calldata adapters
) internal returns (bytes32[] memory) {
Expand All @@ -169,7 +180,12 @@ contract Yaho is IYaho, MessageHashCalculator, MessageIdCalculator {

bytes32[] memory adapterReciepts = new bytes32[](messageRelays.length);
for (uint256 i = 0; i < messageRelays.length; ) {
adapterReciepts[i] = IMessageRelay(messageRelays[i]).relayMessages(toChainIds, messageIds, adapters[i]);
adapterReciepts[i] = IMessageRelay(messageRelays[i]).relayMessages(
toChainIds,
messageIds,
messageHashes,
adapters[i]
);
unchecked {
++i;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/evm/contracts/Yaru.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ contract Yaru is IYaru, MessageHashCalculator, MessageIdCalculator, ReentrancyGu
bytes32 messageHash = calculateMessageHash(message, _yahos[message.fromChainId]);
bytes32 messageId = messageIds[i];

if (message.toChainId != block.chainid)
revert MessageFailure(messageId, abi.encode(keccak256("InvalidToChainId")));
if (executed[messageId]) revert MessageIdAlreadyExecuted(messageId);
executed[messageId] = true;

Expand Down
16 changes: 8 additions & 8 deletions packages/evm/contracts/adapters/AMB/AMBMessageRelayer.sol
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

import { IMessageRelay } from "../../interfaces/IMessageRelay.sol";
import { MessageRelay } from "../MessageRelay.sol";
import { IAMB } from "./IAMB.sol";
import { Yaho } from "../../Yaho.sol";
import { IYaho } from "../../interfaces/IYaho.sol";
import { AMBAdapter } from "./AMBAdapter.sol";

contract AMBMessageRelay is IMessageRelay {
contract AMBMessageRelay is MessageRelay {
IAMB public immutable amb;
Yaho public immutable yaho;

event MessageRelayed(address indexed emitter, bytes32 indexed messageId);

constructor(IAMB _amb, Yaho _yaho) {
constructor(IAMB _amb, address yaho) MessageRelay(yaho) {
amb = _amb;
yaho = _yaho;
}

function relayMessages(
uint256[] memory,
bytes32[] memory messageIds,
bytes32[] calldata messageHashes,
address ambAdapter
) public payable returns (bytes32 receipt) {
) external payable override onlyYaho returns (bytes32 receipt) {
bytes32[] memory hashes = new bytes32[](messageIds.length);
for (uint256 i = 0; i < messageIds.length; i++) {
hashes[i] = yaho.hashes(messageIds[i]);
hashes[i] = messageHashes[i];
emit MessageRelayed(address(this), messageIds[i]);
}

bytes memory data = abi.encodeCall(AMBAdapter.storeHashes, (messageIds, hashes));
receipt = amb.requireToPassMessage(ambAdapter, data, 0);
}
Expand Down
27 changes: 27 additions & 0 deletions packages/evm/contracts/adapters/MessageRelay.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

import { IMessageRelay } from "../interfaces/IMessageRelay.sol";

abstract contract MessageRelay is IMessageRelay {
address public immutable yaho;

error NotYaho(address yaho, address expectedYaho);
error UnequalArrayLengths(address emitter);

constructor(address yaho_) {
yaho = yaho_;
}

modifier onlyYaho() {
if (msg.sender != yaho) revert NotYaho(msg.sender, yaho);
_;
}

function relayMessages(
uint256[] memory toChainIds,
bytes32[] memory messageIds,
bytes32[] calldata messageHashes,
address adapter
) external payable virtual returns (bytes32 receipts);
}
34 changes: 21 additions & 13 deletions packages/evm/contracts/adapters/Sygma/SygmaMessageRelayer.sol
Original file line number Diff line number Diff line change
@@ -1,39 +1,47 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

import { IMessageRelay } from "../../interfaces/IMessageRelay.sol";
import { MessageRelay } from "../MessageRelay.sol";
import { SygmaReporter } from "./SygmaReporter.sol";
import { Yaho } from "../../Yaho.sol";

contract SygmaMessageRelayer is SygmaReporter, IMessageRelay {
Yaho public immutable _yaho;

contract SygmaMessageRelayer is SygmaReporter, MessageRelay {
event MessageRelayed(address indexed emitter, bytes32 indexed messageId);

constructor(
address bridge,
Yaho yaho,
address yaho,
bytes32 resourceID,
address defaultSygmaAdapter
) SygmaReporter(bridge, resourceID, defaultSygmaAdapter) {
_yaho = yaho;
}
) SygmaReporter(bridge, resourceID, defaultSygmaAdapter) MessageRelay(yaho) {}

/**
@dev Relays the messages via the Sygma bridge to default domain.
@param toChainIds Chain ids.
@param messageIds IDs of the messages to pass over the Sygma bridge.
@param messageHashes Hashes of the messages to pass over the Sygma bridge.
@param sygmaAdapter Address of the Sygma adapter on the target chain.
*/
function relayMessages(
uint256[] calldata toChainIds,
bytes32[] calldata messageIds,
bytes32[] calldata messageHashes,
address sygmaAdapter
) public payable returns (bytes32) {
// TODO: group messages by toChainId
) external payable override onlyYaho returns (bytes32) {
if (toChainIds.length != messageIds.length || toChainIds.length != messageHashes.length)
revert UnequalArrayLengths(address(this));
uint256[] memory depositNonces = new uint256[](messageIds.length);
for (uint256 i = 0; i < messageIds.length; i++) {
bytes32 messageHash = _yaho.hashes(messageIds[i]);
(depositNonces[i], ) = _reportData(messageIds[i], messageHash, sygmaAdapter, uint8(toChainIds[i]), "");
bytes32[] memory singleMessageIds = new bytes32[](1);
bytes32[] memory singleMessageHashes = new bytes32[](1);
singleMessageIds[0] = messageIds[i];
singleMessageHashes[0] = messageHashes[i];
(depositNonces[i], ) = _reportData(
singleMessageIds,
singleMessageHashes,
sygmaAdapter,
uint8(toChainIds[i]),
""
);
emit MessageRelayed(address(this), messageIds[i]);
}

Expand Down
28 changes: 0 additions & 28 deletions packages/evm/contracts/adapters/Sygma/SygmaReporter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,6 @@ contract SygmaReporter {
_defaultSygmaAdapter = defaultSygmaAdapter;
}

function _reportData(
bytes32 messageId,
bytes32 messageHash,
address sygmaAdapter,
uint8 destinationDomainID,
bytes memory feeData
) internal returns (uint64 depositNonce, bytes memory handlerResponse) {
bytes memory depositData = abi.encodePacked(
// uint256 maxFee
uint256(0),
// uint16 len(executeFuncSignature)
uint16(4),
// bytes executeFuncSignature
ISygmaAdapter(address(0)).storeHashes.selector,
// uint8 len(executeContractAddress)
uint8(20),
// bytes executeContractAddress
sygmaAdapter,
// uint8 len(executionDataDepositor)
uint8(20),
// bytes executionDataDepositor
address(this),
// bytes executionDataDepositor + executionData
prepareDepositData(messageId, messageHash)
);
return IBridge(_bridge).deposit{ value: msg.value }(destinationDomainID, _resourceID, depositData, feeData);
}

function _reportData(
bytes32[] memory messageIds,
bytes32[] memory messageHashes,
Expand Down
5 changes: 3 additions & 2 deletions packages/evm/contracts/interfaces/IMessageRelay.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ pragma solidity ^0.8.17;

interface IMessageRelay {
function relayMessages(
uint256[] memory toChainIds,
bytes32[] memory messageIds,
uint256[] calldata toChainIds,
bytes32[] calldata messageIds,
bytes32[] calldata messageHashes,
address adapter
) external payable returns (bytes32 receipts);
}
10 changes: 6 additions & 4 deletions packages/evm/contracts/interfaces/IYaho.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@ pragma solidity ^0.8.17;
import { IMessageDispatcher, Message } from "./IMessageDispatcher.sol";

interface IYaho is IMessageDispatcher {
function dispatchMessage(uint256 toChainId, address to, bytes calldata data) external returns (bytes32 messageId);

error NoMessageIdsGiven(address emitter);
error NoMessageRelaysGiven(address emitter);
error NoAdaptersGiven(address emitter);
error UnequalArrayLengths(address emitter);
error MessageHashMismatch(bytes32 messageHash, bytes32 expectedMessageHash);

function dispatchMessage(uint256 toChainId, address to, bytes calldata data) external returns (bytes32);

function dispatchMessages(
uint256[] calldata toChainIds,
address[] calldata tos,
bytes calldata data
) external returns (bytes32[] memory);
) external returns (bytes32[] memory, bytes32[] memory);

function dispatchMessages(
uint256[] calldata toChainIds,
address[] calldata tos,
bytes[] calldata data
) external returns (bytes32[] memory);
) external returns (bytes32[] memory, bytes32[] memory);

function relayMessagesToAdapters(
Message[] calldata messages,
Expand All @@ -46,4 +46,6 @@ interface IYaho is IMessageDispatcher {
address[] calldata adapters,
address[] calldata destinationAdapters
) external payable returns (bytes32[] memory, bytes32[] memory);

function hashes(bytes32 messageId) external view returns (bytes32);
}
9 changes: 6 additions & 3 deletions packages/evm/contracts/test/MockMessageRealy.sol
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

import { IMessageRelay } from "../interfaces/IMessageRelay.sol";
import { MessageRelay } from "../adapters/MessageRelay.sol";

contract MockMessageRelay is IMessageRelay {
contract MockMessageRelay is MessageRelay {
uint256 public count;

event MessageRelayed(bytes32 messageId);

constructor(address yaho) MessageRelay(yaho) {}

function relayMessages(
uint256[] calldata,
bytes32[] calldata messageIds,
bytes32[] calldata,
address
) external payable returns (bytes32 receipts) {
) external payable override onlyYaho returns (bytes32 receipts) {
for (uint256 i = 0; i < messageIds.length; i++) {
count++;
emit MessageRelayed(messageIds[i]);
Expand Down
Loading

0 comments on commit 1a6b206

Please sign in to comment.