Skip to content

Commit

Permalink
Merge pull request #81 from gnosis/feat/vea
Browse files Browse the repository at this point in the history
feat: vea adapter & reporter
  • Loading branch information
allemanfredi authored Nov 25, 2024
2 parents 76ae42a + 92b44ec commit 32606b3
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 0 deletions.
46 changes: 46 additions & 0 deletions packages/evm/contracts/adapters/Vea/VeaAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.20;

import { BlockHashAdapter } from "../BlockHashAdapter.sol";
import { IReceiverGateway } from "./interfaces/IReceiverGateway.sol";

contract VeaAdapter is IReceiverGateway, BlockHashAdapter {
string public constant PROVIDER = "vea";

address public immutable VEA_OUTBOX;
address public immutable REPORTER;
uint256 public immutable SOURCE_CHAIN_ID;

error ArrayLengthMissmatch();
error InvalidVeaOutbox(address veaOutbox, address expectedVeaOutboux);
error InvalidReporter(address reporter, address expectedReporter);

constructor(address veaOutbox_, address reporter, uint256 sourceChainId) {
VEA_OUTBOX = veaOutbox_;
REPORTER = reporter;
SOURCE_CHAIN_ID = sourceChainId;
}

modifier onlyFromAuthenticatedVeaSender(address sourceMsgSender) {
if (msg.sender != VEA_OUTBOX) revert InvalidVeaOutbox(msg.sender, VEA_OUTBOX);
if (sourceMsgSender != REPORTER) revert InvalidReporter(REPORTER, sourceMsgSender);
_;
}

function senderGateway() external view override returns (address) {
return REPORTER;
}

function veaOutbox() external view override returns (address) {
return VEA_OUTBOX;
}

function storeHashes(
address sourceMsgSender,
uint256[] memory ids,
bytes32[] memory _hashes
) external onlyFromAuthenticatedVeaSender(sourceMsgSender) {
if (ids.length != _hashes.length) revert ArrayLengthMissmatch();
_storeHashes(uint256(SOURCE_CHAIN_ID), ids, _hashes);
}
}
51 changes: 51 additions & 0 deletions packages/evm/contracts/adapters/Vea/VeaReporter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.20;

import { VeaAdapter } from "./VeaAdapter.sol";
import { Reporter } from "../Reporter.sol";
import { ISenderGateway } from "./interfaces/ISenderGateway.sol";
import { IVeaInbox } from "./interfaces/IVeaInbox.sol";

contract VeaReporter is ISenderGateway, Reporter {
string public constant PROVIDER = "vea";

IVeaInbox public immutable VEA_INBOX;
address public immutable ADAPTER;
uint256 public immutable EXPECTED_TARGET_CHAIN_ID;

error InvalidAdapter(address adapter, address expectedAdapter);
error InvalidTargetChainId(uint256 targetChainId, uint256 expectedTargetChainId);

constructor(
address headerStorage,
address yaho,
IVeaInbox veaInbox_,
address adapter,
uint256 expectedTargetChainId
) Reporter(headerStorage, yaho) {
VEA_INBOX = veaInbox_;
ADAPTER = adapter;
EXPECTED_TARGET_CHAIN_ID = expectedTargetChainId;
}

function receiverGateway() external view override returns (address) {
return ADAPTER;
}

function veaInbox() external view override returns (IVeaInbox) {
return VEA_INBOX;
}

function _dispatch(
uint256 targetChainId,
address adapter,
uint256[] memory ids,
bytes32[] memory hashes
) internal override returns (bytes32) {
if (targetChainId != EXPECTED_TARGET_CHAIN_ID)
revert InvalidTargetChainId(targetChainId, EXPECTED_TARGET_CHAIN_ID);
if (adapter != ADAPTER) revert InvalidAdapter(adapter, ADAPTER);
uint64 msgId = VEA_INBOX.sendMessage(ADAPTER, VeaAdapter.storeHashes.selector, abi.encode(ids, hashes));
return bytes32(uint256(msgId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.20;

interface IReceiverGateway {
function veaOutbox() external view returns (address);
function senderGateway() external view returns (address);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.20;

import { IVeaInbox } from "./IVeaInbox.sol";

interface ISenderGateway {
function veaInbox() external view returns (IVeaInbox);
function receiverGateway() external view returns (address);
}
12 changes: 12 additions & 0 deletions packages/evm/contracts/adapters/Vea/interfaces/IVeaInbox.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.20;

interface IVeaInbox {
/// @dev Sends an arbitrary message to receiving chain.
/// Note: Calls authenticated by receiving gateway checking the sender argument.
/// @param _to The cross-domain contract address which receives the calldata.
/// @param _fnSelection The function selector of the receiving contract.
/// @param _data The message calldata, abi.encode(...)
/// @return msgId The index of the message in the inbox, as a message Id, needed to relay the message.
function sendMessage(address _to, bytes4 _fnSelection, bytes memory _data) external returns (uint64 msgId);
}
1 change: 1 addition & 0 deletions packages/evm/tasks/deploy/adapters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ import "./pnetwork"
import "./router"
import "./sygma"
import "./telepathy"
import "./vea"
import "./wormhole"
import "./zetachain"
64 changes: 64 additions & 0 deletions packages/evm/tasks/deploy/adapters/vea.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"
import { task, types } from "hardhat/config"
import type { TaskArguments } from "hardhat/types"

import { verify } from ".."
import type { VeaAdapter } from "../../../types/contracts/adapters/Vea/VeaAdapter"
import type { VeaReporter } from "../../../types/contracts/adapters/Vea/VeaReporter"
import type { VeaAdapter__factory } from "../../../types/factories/contracts/adapters/Vea/VeaAdapter__factory"
import { VeaReporter__factory } from "../../../types/factories/contracts/adapters/Vea/VeaReporter__factory"

// Deploy on destination chain
task("deploy:Vea:Adapter")
.addParam("veaOutbox", "address of the Vea Outbox contract", undefined, types.string)
.addParam("reporter", "address of the hash reporter", undefined, types.string)
.addParam("sourceChainId", "sourceChainId of the source chain", undefined, types.int)
.addFlag("verify", "whether to verify the contract on Etherscan")
.setAction(async function (taskArguments: TaskArguments, hre) {
console.log("Deploying VeaAdapter...")
const signers: SignerWithAddress[] = await hre.ethers.getSigners()
const veaAdapterFactory: VeaAdapter__factory = <VeaAdapter__factory>(
await hre.ethers.getContractFactory("VeaAdapter")
)

const constructorArguments = [
taskArguments.veaOutbox,
taskArguments.reporter,
"0x" + taskArguments.sourceChainId.toString(16).padStart(64, "0"),
] as const
const veaAdapter: VeaAdapter = <VeaAdapter>(
await veaAdapterFactory.connect(signers[0]).deploy(...constructorArguments)
)
await veaAdapter.deployed()
console.log("VeaAdapter deployed to:", veaAdapter.address)
if (taskArguments.verify) await verify(hre, veaAdapter, constructorArguments)
})

// Deploy source chain
task("deploy:Vea:Reporter")
.addParam("headerStorage", "address of the header storage contract", undefined, types.string)
.addParam("yaho", "address of the Yaho contract", undefined, types.string)
.addParam("veaInbox", "address of the Vea inbox contract", undefined, types.string)
.addParam("adapter", "address of adapter contract", undefined, types.string)
.addParam("targetChainId", "target chain id", undefined, types.int)
.addFlag("verify", "whether to verify the contract on Etherscan")
.setAction(async function (taskArguments: TaskArguments, hre) {
console.log("Deploying VeaReporter...")
const signers: SignerWithAddress[] = await hre.ethers.getSigners()
const veaReporterFactory: VeaReporter__factory = <VeaReporter__factory>(
await hre.ethers.getContractFactory("VeaReporter")
)
const constructorArguments = [
taskArguments.headerStorage,
taskArguments.yaho,
taskArguments.veaInbox,
taskArguments.adapter,
taskArguments.targetChainId,
] as const
const veaReporter: VeaReporter = <VeaReporter>(
await veaReporterFactory.connect(signers[0]).deploy(...constructorArguments)
)
await veaReporter.deployed()
console.log("VeaReporter deployed to:", veaReporter.address)
if (taskArguments.verify) await verify(hre, veaReporter, constructorArguments)
})

0 comments on commit 32606b3

Please sign in to comment.