Skip to content

Commit

Permalink
feat: improved distinction between the outbox and router implementati…
Browse files Browse the repository at this point in the history
…ons for L1 and L2
  • Loading branch information
jaybuidl committed May 22, 2023
1 parent 89f9c67 commit d8774d1
Show file tree
Hide file tree
Showing 16 changed files with 68 additions and 54 deletions.
1 change: 0 additions & 1 deletion contracts/deploy/02-inbox/02-arb-to-eth-inbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { DeployFunction } from "hardhat-deploy/types";

enum SenderChains {
ARBITRUM = 42161,
ARBITRUM_GOERLI = 421613,
HARDHAT = 31337,
}
const paramsByChainId = {
Expand Down
1 change: 0 additions & 1 deletion contracts/deploy/02-inbox/02-arb-to-gnosis-inbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { DeployFunction } from "hardhat-deploy/types";

enum SenderChains {
ARBITRUM = 42161,
ARBITRUM_GOERLI = 421613,
HARDHAT = 31337,
}
const paramsByChainId = {
Expand Down
6 changes: 3 additions & 3 deletions contracts/src/arbitrumToEth/VeaInboxArbToEth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pragma solidity 0.8.18;

import "../canonical/arbitrum/IArbSys.sol";
import "../interfaces/inboxes/IVeaInbox.sol";
import "../interfaces/outboxes/IVeaOutboxEthChain.sol";
import "../interfaces/outboxes/IVeaOutboxOnL1.sol";

/**
* Vea Bridge Inbox From Arbitrum to Ethereum.
Expand Down Expand Up @@ -213,12 +213,12 @@ contract VeaInboxArbToEth is IVeaInbox {
* @param epoch The epoch of the snapshot requested to send.
* @param claim The claim associated with the epoch.
*/
function sendSnapshot(uint256 epoch, IVeaOutboxEthChain.Claim memory claim) external virtual {
function sendSnapshot(uint256 epoch, Claim memory claim) external virtual {
unchecked {
require(epoch < block.timestamp / epochPeriod, "Can only send past epoch snapshot.");
}

bytes memory data = abi.encodeCall(IVeaOutboxEthChain.resolveDisputedClaim, (epoch, snapshots[epoch], claim));
bytes memory data = abi.encodeCall(IVeaOutboxOnL1.resolveDisputedClaim, (epoch, snapshots[epoch], claim));

// Arbitrum -> Ethereum message with native bridge
// docs: https://developer.arbitrum.io/for-devs/cross-chain-messsaging#arbitrum-to-ethereum-messaging
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/arbitrumToEth/VeaOutboxArbToEth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ pragma solidity 0.8.18;

import "../canonical/arbitrum/IBridge.sol";
import "../canonical/arbitrum/IOutbox.sol";
import "../interfaces/outboxes/IVeaOutboxEthChain.sol";
import "../interfaces/outboxes/IVeaOutboxOnL1.sol";

/**
* Vea Bridge Outbox From Arbitrum to Ethereum.
*/
contract VeaOutboxArbToEth is IVeaOutboxEthChain {
contract VeaOutboxArbToEth is IVeaOutboxOnL1 {
IBridge public immutable bridge; // The address of the Arbitrum bridge contract.
address public immutable veaInbox; // The address of the veaInbox on arbitrum.

Expand Down
10 changes: 5 additions & 5 deletions contracts/src/arbitrumToGnosis/RouterArbToGnosis.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ pragma solidity 0.8.18;
import "../canonical/gnosis-chain/IAMB.sol";
import "../canonical/arbitrum/IBridge.sol";
import "../canonical/arbitrum/IOutbox.sol";
import "../interfaces/routers/IRouterToEthChain.sol";
import "../interfaces/outboxes/IVeaOutboxEthChain.sol";
import "../interfaces/routers/IRouterToAltL1.sol";
import "../interfaces/outboxes/IVeaOutboxOnL1.sol";

/**
* Router on Ethereum from Arbitrum to Gnosis Chain.
*/
contract RouterArbToGnosis is IRouterToEthChain {
contract RouterArbToGnosis is IRouterToAltL1 {
// ************************************* //
// * Storage * //
// ************************************* //
Expand Down Expand Up @@ -60,7 +60,7 @@ contract RouterArbToGnosis is IRouterToEthChain {
* @param epoch The epoch to verify.
* @param stateroot The true batch merkle root for the epoch.
*/
function route(uint256 epoch, bytes32 stateroot, IVeaOutboxEthChain.Claim calldata claim) external {
function route(uint256 epoch, bytes32 stateroot, Claim calldata claim) external {
// Arbitrum -> Ethereum message sender authentication
// docs: https://developer.arbitrum.io/arbos/l2-to-l1-messaging/
// example: https://github.com/OffchainLabs/arbitrum-tutorials/blob/2c1b7d2db8f36efa496e35b561864c0f94123a5f/packages/greeter/contracts/ethereum/GreeterL1.sol#L50
Expand All @@ -73,7 +73,7 @@ contract RouterArbToGnosis is IRouterToEthChain {
// Ethereum -> Gnosis message passing with the AMB, the canonical Ethereum <-> Gnosis bridge.
// https://docs.tokenbridge.net/amb-bridge/development-of-a-cross-chain-application/how-to-develop-xchain-apps-by-amb#receive-a-method-call-from-the-amb-bridge

bytes memory data = abi.encodeCall(IVeaOutboxEthChain.resolveDisputedClaim, (epoch, stateroot, claim));
bytes memory data = abi.encodeCall(IVeaOutboxOnL1.resolveDisputedClaim, (epoch, stateroot, claim));
// Note: using maxGasPerTx here means the relaying txn on Gnosis will need to pass that (large) amount of gas, though almost all will be unused and refunded. This is preferred over hardcoding a gas limit.
bytes32 ticketID = amb.requireToPassMessage(veaOutbox, data, amb.maxGasPerTx());
emit Routed(epoch, ticketID);
Expand Down
6 changes: 3 additions & 3 deletions contracts/src/arbitrumToGnosis/VeaInboxArbToGnosis.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pragma solidity 0.8.18;

import "../canonical/arbitrum/IArbSys.sol";
import "../interfaces/inboxes/IVeaInbox.sol";
import "../interfaces/routers/IRouterToEthChain.sol";
import "../interfaces/routers/IRouterToAltL1.sol";

/**
* Vea Bridge Inbox From Arbitrum to Gnosis.
Expand Down Expand Up @@ -213,12 +213,12 @@ contract VeaInboxArbToGnosis is IVeaInbox {
* @param epoch The epoch of the snapshot requested to send.
* @param claim The claim associated with the epoch
*/
function sendSnapshot(uint256 epoch, IVeaOutboxEthChain.Claim memory claim) external virtual {
function sendSnapshot(uint256 epoch, Claim memory claim) external virtual {
unchecked {
require(epoch < block.timestamp / epochPeriod, "Can only send past epoch snapshot.");
}

bytes memory data = abi.encodeCall(IRouterToEthChain.route, (epoch, snapshots[epoch], claim));
bytes memory data = abi.encodeCall(IRouterToAltL1.route, (epoch, snapshots[epoch], claim));

// Arbitrum -> Ethereum message with native bridge
// docs: https://developer.arbitrum.io/for-devs/cross-chain-messsaging#arbitrum-to-ethereum-messaging
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/arbitrumToGnosis/VeaOutboxArbToGnosis.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
pragma solidity 0.8.18;

import "../canonical/gnosis-chain/IAMB.sol";
import "../interfaces/outboxes/IVeaOutboxEthChain.sol";
import "../interfaces/outboxes/IVeaOutboxOnL1.sol";

/**
* Vea Bridge Outbox From Arbitrum to Gnosis.
* Note: This contract is deployed on Gnosis.
*/
contract VeaOutboxArbToGnosis is IVeaOutboxEthChain {
contract VeaOutboxArbToGnosis is IVeaOutboxOnL1 {
IAMB public immutable amb; // The address of the AMB contract on Gnosis.
address public immutable routerArbToGnosis; // The address of the router from Arbitrum to Gnosis on ethereum.

Expand Down
8 changes: 4 additions & 4 deletions contracts/src/arbitrumToOptimism/RouterArbToOp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ pragma solidity 0.8.18;
// TODO: implement Optimism messaging.
import "../canonical/arbitrum/IBridge.sol";
import "../canonical/arbitrum/IOutbox.sol";
import "../interfaces/routers/IRouterToOptimisticRollup.sol";
import "../interfaces/outboxes/IVeaOutboxOptimisticRollup.sol";
import "../interfaces/routers/IRouterToL2.sol";
import "../interfaces/outboxes/IVeaOutboxOnL2.sol";

/**
* Router on Ethereum from Arbitrum to Optimism.
*/
contract RouterArbToOptimism is IRouterToOptimisticRollup {
contract RouterArbToOptimism is IRouterToL2 {
// ************************************* //
// * Storage * //
// ************************************* //
Expand Down Expand Up @@ -73,7 +73,7 @@ contract RouterArbToOptimism is IRouterToOptimisticRollup {

require(IOutbox(bridge.activeOutbox()).l2ToL1Sender() == veaInbox, "veaInbox only.");

bytes memory data = abi.encodeCall(IVeaOutboxOptimisticRollup.resolveDisputedClaim, (epoch, stateroot));
bytes memory data = abi.encodeCall(IVeaOutboxOnL2.resolveDisputedClaim, (epoch, stateroot));

// TODO: Send message to Optimism.
}
Expand Down
7 changes: 2 additions & 5 deletions contracts/src/arbitrumToOptimism/VeaInboxArbToOp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pragma solidity 0.8.18;

import "../canonical/arbitrum/IArbSys.sol";
import "../interfaces/inboxes/IVeaInbox.sol";
import "../interfaces/outboxes/IVeaOutboxOptimisticRollup.sol";
import "../interfaces/outboxes/IVeaOutboxOnL2.sol";

/**
* Vea Bridge Inbox From Arbitrum to Optimism.
Expand Down Expand Up @@ -206,10 +206,7 @@ contract VeaInboxArbToOpt is IVeaInbox {
require(epochSend < block.timestamp / epochPeriod, "Can only send past epoch snapshot.");
}

bytes memory data = abi.encodeCall(
IVeaOutboxOptimisticRollup.resolveDisputedClaim,
(epochSend, snapshots[epochSend])
);
bytes memory data = abi.encodeCall(IVeaOutboxOnL2.resolveDisputedClaim, (epochSend, snapshots[epochSend]));

bytes32 ticketID = bytes32(ARB_SYS.sendTxToL1(veaOutbox, data));

Expand Down
4 changes: 2 additions & 2 deletions contracts/src/arbitrumToOptimism/VeaOutboxArbToOp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ pragma solidity 0.8.18;
// warning: this is a work in progress
import "../canonical/arbitrum/IBridge.sol";
import "../canonical/arbitrum/IOutbox.sol";
import "../interfaces/outboxes/IVeaOutboxOptimisticRollup.sol";
import "../interfaces/outboxes/IVeaOutboxOnL2.sol";

/**
* Vea Bridge Outbox From Arbitrum to Optimism.
*/
contract VeaOutboxArbToOpt is IVeaOutboxOptimisticRollup {
contract VeaOutboxArbToOpt is IVeaOutboxOnL2 {
IBridge public immutable bridge; // The address of the Arbitrum bridge contract.
address public immutable veaInbox; // The address of the veaInbox on arbitrum.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,12 @@

pragma solidity 0.8.18;

import "../types/VeaClaim.sol";

/**
* @dev Interface of the Vea Outbox on Ethereum-like L1 chains eg Ethereum, Gnosis, Polygon POS
* @dev Interface of the Vea Outbox on L1 chains like Ethereum, Gnosis, Polygon POS where storage is expensive.
*/
interface IVeaOutboxEthChain {
enum Party {
None,
Claimer,
Challenger
}

struct Claim {
bytes32 stateRoot;
address claimer;
uint32 timestamp;
uint32 blocknumber;
Party honest;
address challenger;
}

interface IVeaOutboxOnL1 {
/**
* Note: Gateways expect first argument of message call to be the arbitrum message sender, used for authentication.
* @dev Verifies and relays the message.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
pragma solidity 0.8.18;

/**
* @dev Interface of the Vea Outbox on Optimistic Rollups eg. Arbitrum, Optimism, Base, Specular, etc.
* @dev Interface of the Vea Outbox on L2s like Arbitrum, Optimism, Base, Specular where storage is inexpensive.
*/
interface IVeaOutboxOptimisticRollup {
interface IVeaOutboxOnL2 {
/**
* Note: Gateways expect first argument of message call to be the inbox sender, used for authentication.
* @dev Verifies and relays the message.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@
* @deployments: []
*/

import "../outboxes/IVeaOutboxEthChain.sol";

pragma solidity 0.8.18;

interface IRouterToEthChain {
import "../types/VeaClaim.sol";

/**
* @dev Interface of the Vea Router on Ethereum L1 which routes messages to alt-L1 chains like Gnosis, Polygon POS etc.
*/
interface IRouterToAltL1 {

This comment has been minimized.

Copy link
@shotaronowhere

shotaronowhere May 23, 2023

Contributor

So here I don't think we need to distinguish AltL1 from L1.

for instance there can be optimistic rollups on gnosis which use vea to send messages to ethereum, we would use the same router.

The most accurate application of this router is routing to an Eth-like-consensus-chain, but i opted for just EthChain.

At the least, we should rename this to IRouterToL1

/**
* Note: Access restricted to arbitrum canonical bridge.
* @dev Routes state root snapshots from arbitrum to gnosis
* @param epoch The epoch to verify.
* @param stateRoot The true state root for the epoch.
* @param claim The claim associated with the epoch.
*/
function route(uint256 epoch, bytes32 stateRoot, IVeaOutboxEthChain.Claim memory claim) external;
function route(uint256 epoch, bytes32 stateRoot, Claim memory claim) external;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

pragma solidity 0.8.18;

interface IRouterToOptimisticRollup {
/**
* @dev Interface of the Vea Router on Ethereum L1 which routes messages to L2s like Arbitrum, Optimism, Base, Specular where storage is expensive.
*/
interface IRouterToL2 {
/**
* Note: Access restricted to canonical bridge.
* @dev Resolves any challenge of the optimistic claim for 'epoch' using the canonical bridge.
Expand Down
26 changes: 26 additions & 0 deletions contracts/src/interfaces/types/VeaClaim.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: MIT

/**
* @authors: [@jaybuidl, @shotaronowhere]
* @reviewers: []
* @auditors: []
* @bounties: []
* @deployments: []
*/

pragma solidity 0.8.18;

enum Party {
None,
Claimer,
Challenger
}

struct Claim {
bytes32 stateRoot;
address claimer;
uint32 timestamp;
uint32 blocknumber;
Party honest;
address challenger;
}
4 changes: 2 additions & 2 deletions contracts/src/test/ArbitrumToEth/VeaInboxMockArbToEth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ contract VeaInboxMockArbToEth is VeaInboxArbToEth {
/**
* @dev Sends the state root using Arbitrum's canonical bridge.
*/
function sendSnapshot(uint256 _epochSnapshot, IVeaOutboxEthChain.Claim calldata claim) external override {
function sendSnapshot(uint256 _epochSnapshot, Claim calldata claim) external override {
uint256 epoch = uint256(block.timestamp) / epochPeriod;
require(_epochSnapshot <= epoch, "Epoch in the future.");
bytes memory data = abi.encodeCall(
IVeaOutboxEthChain.resolveDisputedClaim,
IVeaOutboxOnL1.resolveDisputedClaim,
(_epochSnapshot, snapshots[_epochSnapshot], claim)
);

Expand Down

0 comments on commit d8774d1

Please sign in to comment.