Skip to content

Commit

Permalink
feat(contracts): update vea gateways
Browse files Browse the repository at this point in the history
  • Loading branch information
shotaronowhere authored and jaybuidl committed Jun 12, 2023
1 parent da920e1 commit 3c7e8f8
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 496 deletions.
2 changes: 1 addition & 1 deletion contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@
"typescript": "^4.9.5"
},
"dependencies": {
"@kleros/vea-contracts": "^0.1.12"
"@kleros/vea-contracts": "^0.3.2"
}
}
37 changes: 11 additions & 26 deletions contracts/src/gateway/ForeignGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,18 @@ contract ForeignGateway is IForeignGateway {
uint256 internal localDisputeID = 1; // The disputeID must start from 1 as the KlerosV1 proxy governor depends on this implementation. We now also depend on localDisputeID not ever being zero.
mapping(uint96 => uint256) public feeForJuror; // feeForJuror[courtID], it mirrors the value on KlerosCore.
address public governor;
IFastBridgeReceiver public fastBridgeReceiver;
uint256 public immutable override senderChainID;
address public veaOutbox;
uint256 public immutable senderChainID;
address public override senderGateway;
IFastBridgeReceiver public depreciatedFastbridge;
uint256 public depreciatedFastBridgeExpiration;
mapping(bytes32 => DisputeData) public disputeHashtoDisputeData;

// ************************************* //
// * Function Modifiers * //
// ************************************* //

modifier onlyFromFastBridge() {
require(
address(fastBridgeReceiver) == msg.sender ||
((block.timestamp < depreciatedFastBridgeExpiration) && address(depreciatedFastbridge) == msg.sender),
"Access not allowed: Fast Bridge only."
);
modifier onlyFromVea(address _messageSender) {
require(veaOutbox == msg.sender, "Access not allowed: Fast Bridge only.");
require(_messageSender == senderGateway, "Access not allowed: Sender Gateway only.");
_;
}

Expand All @@ -74,14 +69,9 @@ contract ForeignGateway is IForeignGateway {
_;
}

constructor(
address _governor,
IFastBridgeReceiver _fastBridgeReceiver,
address _senderGateway,
uint256 _senderChainID
) {
constructor(address _governor, address _veaOutbox, address _senderGateway, uint256 _senderChainID) {
governor = _governor;
fastBridgeReceiver = _fastBridgeReceiver;
veaOutbox = _veaOutbox;
senderGateway = _senderGateway;
senderChainID = _senderChainID;
}
Expand All @@ -98,13 +88,9 @@ contract ForeignGateway is IForeignGateway {
}

/// @dev Changes the fastBridge, useful to increase the claim deposit.
/// @param _fastBridgeReceiver The address of the new fastBridge.
/// @param _gracePeriod The duration to accept messages from the deprecated bridge (if at all).
function changeFastbridge(IFastBridgeReceiver _fastBridgeReceiver, uint256 _gracePeriod) external onlyByGovernor {
// grace period to relay remaining messages in the relay / bridging process
depreciatedFastBridgeExpiration = block.timestamp + _fastBridgeReceiver.epochPeriod() + _gracePeriod; // 2 weeks
depreciatedFastbridge = fastBridgeReceiver;
fastBridgeReceiver = _fastBridgeReceiver;
/// @param _veaOutbox The address of the new fastBridge.
function changeVea(address _veaOutbox) external onlyByGovernor {
veaOutbox = _veaOutbox;
}

/// @dev Changes the sender gateway.
Expand Down Expand Up @@ -180,8 +166,7 @@ contract ForeignGateway is IForeignGateway {
bytes32 _disputeHash,
uint256 _ruling,
address _relayer
) external override onlyFromFastBridge {
require(_messageSender == senderGateway, "Only the homegateway is allowed.");
) external override onlyFromVea(_messageSender) {
DisputeData storage dispute = disputeHashtoDisputeData[_disputeHash];

require(dispute.id != 0, "Dispute does not exist");
Expand Down
37 changes: 8 additions & 29 deletions contracts/src/gateway/ForeignGatewayOnGnosis.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,18 @@ contract ForeignGatewayOnGnosis is IForeignGateway {
uint256 internal localDisputeID = 1; // The disputeID must start from 1 as the KlerosV1 proxy governor depends on this implementation. We now also depend on localDisputeID not ever being zero.
mapping(uint96 => uint256) public feeForJuror; // feeForJuror[courtID], it mirrors the value on KlerosCore.
address public governor;
IFastBridgeReceiver public fastBridgeReceiver;
uint256 public immutable override senderChainID;
address public veaOutbox;
uint256 public immutable senderChainID;
address public override senderGateway;
IFastBridgeReceiver public depreciatedFastbridge;
uint256 public depreciatedFastBridgeExpiration;
mapping(bytes32 => DisputeData) public disputeHashtoDisputeData;

// ************************************* //
// * Function Modifiers * //
// ************************************* //

modifier onlyFromFastBridge() {
require(
address(fastBridgeReceiver) == msg.sender ||
((block.timestamp < depreciatedFastBridgeExpiration) && address(depreciatedFastbridge) == msg.sender),
"Access not allowed: Fast Bridge only."
);
modifier onlyFromVea(address _messageSender) {
require(veaOutbox == msg.sender, "Access not allowed: Fast Bridge only.");
require(_messageSender == senderGateway, "Access not allowed: Sender Gateway only.");
_;
}

Expand All @@ -76,15 +71,9 @@ contract ForeignGatewayOnGnosis is IForeignGateway {
_;
}

constructor(
address _governor,
IFastBridgeReceiver _fastBridgeReceiver,
address _senderGateway,
uint256 _senderChainID,
IERC20 _weth
) {
constructor(address _governor, address _veaOutbox, address _senderGateway, uint256 _senderChainID, IERC20 _weth) {
governor = _governor;
fastBridgeReceiver = _fastBridgeReceiver;
veaOutbox = _veaOutbox;
senderGateway = _senderGateway;
senderChainID = _senderChainID;
weth = _weth;
Expand All @@ -101,16 +90,6 @@ contract ForeignGatewayOnGnosis is IForeignGateway {
governor = _governor;
}

/// @dev Changes the fastBridge, useful to increase the claim deposit.
/// @param _fastBridgeReceiver The address of the new fastBridge.
/// @param _gracePeriod The duration to accept messages from the deprecated bridge (if at all).
function changeFastbridge(IFastBridgeReceiver _fastBridgeReceiver, uint256 _gracePeriod) external onlyByGovernor {
// grace period to relay remaining messages in the relay / bridging process
depreciatedFastBridgeExpiration = block.timestamp + _fastBridgeReceiver.epochPeriod() + _gracePeriod; // 2 weeks
depreciatedFastbridge = fastBridgeReceiver;
fastBridgeReceiver = _fastBridgeReceiver;
}

/// @dev Changes the sender gateway.
/// @param _senderGateway The address of the new sender gateway.
function changeReceiverGateway(address _senderGateway) external {
Expand Down Expand Up @@ -185,7 +164,7 @@ contract ForeignGatewayOnGnosis is IForeignGateway {
bytes32 _disputeHash,
uint256 _ruling,
address _relayer
) external override onlyFromFastBridge {
) external override onlyFromVea(_messageSender) {
require(_messageSender == senderGateway, "Only the homegateway is allowed.");
DisputeData storage dispute = disputeHashtoDisputeData[_disputeHash];

Expand Down
21 changes: 10 additions & 11 deletions contracts/src/gateway/HomeGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
pragma solidity 0.8.18;

import "../arbitration/IArbitrator.sol";
import "@kleros/vea-contracts/interfaces/IFastBridgeSender.sol";
import "./interfaces/IForeignGateway.sol";
import "./interfaces/IHomeGateway.sol";

Expand All @@ -31,23 +30,23 @@ contract HomeGateway is IHomeGateway {

address public governor;
IArbitrator public arbitrator;
IFastBridgeSender public fastBridgeSender;
IVeaInbox public veaInbox;
address public override receiverGateway;
uint256 public immutable override receiverChainID;
uint256 public immutable receiverChainID;
mapping(uint256 => bytes32) public disputeIDtoHash;
mapping(bytes32 => uint256) public disputeHashtoID;
mapping(bytes32 => RelayedData) public disputeHashtoRelayedData;

constructor(
address _governor,
IArbitrator _arbitrator,
IFastBridgeSender _fastBridgeSender,
IVeaInbox _veaInbox,
address _receiverGateway,
uint256 _receiverChainID
) {
governor = _governor;
arbitrator = _arbitrator;
fastBridgeSender = _fastBridgeSender;
veaInbox = _veaInbox;
receiverGateway = _receiverGateway;
receiverChainID = _receiverChainID;

Expand All @@ -72,11 +71,11 @@ contract HomeGateway is IHomeGateway {
arbitrator = _arbitrator;
}

/// @dev Changes the fastBridge, useful to increase the claim deposit.
/// @param _fastBridgeSender The address of the new fastBridge.
function changeFastbridge(IFastBridgeSender _fastBridgeSender) external {
/// @dev Changes the vea inbox, useful to increase the claim deposit.
/// @param _veaInbox The address of the new vea inbox.
function changeVea(IVeaInbox _veaInbox) external {
require(governor == msg.sender, "Access not allowed: Governor only.");
fastBridgeSender = _fastBridgeSender;
veaInbox = _veaInbox;
}

/// @dev Changes the receiver gateway.
Expand Down Expand Up @@ -144,8 +143,8 @@ contract HomeGateway is IHomeGateway {
// The first parameter of relayRule() `_messageSender` is missing from the encoding below
// because Vea takes care of inserting it for security reasons.
bytes4 methodSelector = IForeignGateway.relayRule.selector;
bytes memory data = abi.encodeWithSelector(methodSelector, disputeHash, _ruling, relayedData.relayer);
fastBridgeSender.sendFast(receiverGateway, data);
bytes memory data = abi.encode(disputeHash, _ruling, relayedData.relayer);
veaInbox.sendMessage(receiverGateway, methodSelector, data);
}

/// @dev Looks up the local home disputeID for a disputeHash. For cross-chain Evidence standard.
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/gateway/interfaces/IForeignGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
pragma solidity 0.8.18;

import "../../arbitration/IArbitrator.sol";
import "@kleros/vea-contracts/interfaces/IReceiverGateway.sol";
import "@kleros/vea-contracts/src/interfaces/gateways/IReceiverGateway.sol";

interface IForeignGateway is IArbitrator, IReceiverGateway {
/// Relay the rule call from the home gateway to the arbitrable.
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/gateway/interfaces/IHomeGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pragma solidity 0.8.18;

import "../../arbitration/IArbitrable.sol";
import "../../evidence/IMetaEvidence.sol";
import "@kleros/vea-contracts/interfaces/ISenderGateway.sol";
import "@kleros/vea-contracts/src/interfaces/gateways/ISenderGateway.sol";

interface IHomeGateway is IArbitrable, IMetaEvidence, ISenderGateway {
/// @dev Provide the same parameters as on the foreignChain while creating a dispute. Providing incorrect parameters will create a different hash than on the foreignChain and will not affect the actual dispute/arbitrable's ruling.
Expand Down
117 changes: 34 additions & 83 deletions contracts/src/gateway/mock/VeaMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,105 +2,56 @@

pragma solidity 0.8.18;

import "@kleros/vea-contracts/interfaces/IFastBridgeSender.sol";
import "@kleros/vea-contracts/interfaces/IFastBridgeReceiver.sol";
import "@kleros/vea-contracts/src/interfaces/inboxes/IVeaInbox.sol";
import "@kleros/vea-contracts/src/interfaces/outboxes/IVeaOutboxOnL1.sol";

contract VeaMock is IFastBridgeSender, IFastBridgeReceiver {
contract VeaMock is IVeaOutboxOnL1, IVeaInbox {
/* solhint-disable */

// ************************************* //
// * Function Modifiers * //
// ************************************* //

/// Note: Access must be restricted by the receiving gateway by checking the sender argument.
/// @dev Sends an arbitrary message across domain using the Fast Bridge.
/// @param _receiver The cross-domain contract address which receives the calldata.
/// @param _calldata The receiving domain encoded message data.
function sendFast(address _receiver, bytes memory _calldata) external {
// Dirty workaround: Solidity does not support array slices for memory arrays and the sender interface cannot be changed.
(bytes4 selector, bytes memory payload) = this.decode(_calldata);

bytes32 sender = bytes32(uint256(uint160(msg.sender)));
bytes memory data = abi.encodePacked(selector, sender, payload);
(bool success, bytes memory res) = _receiver.call(data);
/// @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 _fnSelector 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 _fnSelector, bytes memory _data) external returns (uint64 msgId) {
bytes memory data = abi.encodePacked( // abi.encodeWithSelector(fnSelector, msg.sender, data)
_fnSelector,
bytes32(uint256(uint160(msg.sender))), // big endian padded encoding of msg.sender, simulating abi.encodeWithSelector
_data
);

(bool success, bytes memory res) = _to.call(data);
require(success, "Call failure");
}

function decode(bytes calldata data) external pure returns (bytes4, bytes memory) {
return (bytes4(data[:4]), data[4:]);
}

/// Sends a batch of arbitrary message from one domain to another
/// via the fast bridge mechanism.
function sendBatch() external {
revert("Not Implemented");
}

/// @dev Sends a markle root representing an arbitrary batch of messages across domain using the Safe Bridge, which relies on the chain's canonical bridge. It is unnecessary during normal operations but essential only in case of challenge.
/// @param _epoch block number of batch
function sendSafeFallback(uint256 _epoch) external payable {
revert("Not Implemented");
}

/// @dev Submit a claim about the `_batchMerkleRoot` for the latests completed Fast bridge epoch and submit a deposit. The `_batchMerkleRoot` should match the one on the sending side otherwise the sender will lose his deposit.
/// @param _epoch The epoch of the claim to claim.
/// @param _batchMerkleRoot The hash claimed for the ticket.
function claim(uint256 _epoch, bytes32 _batchMerkleRoot) external payable {
revert("Not Implemented");
}

/// @dev Submit a challenge for the claim of the current epoch's Fast Bridge batch merkleroot state and submit a deposit. The `batchMerkleRoot` in the claim already made for the last finalized epoch should be different from the one on the sending side, otherwise the sender will lose his deposit.
/// @param _epoch The epoch of the claim to challenge.
function challenge(uint256 _epoch) external payable {
/// @dev Snapshots can be saved a maximum of once per epoch.
/// Saves snapshot of state root.
/// `O(log(count))` where count number of messages in the inbox.
function saveSnapshot() external {
revert("Not Implemented");
}

/// @dev Resolves the optimistic claim for '_epoch'.
/// @param _epoch The epoch of the optimistic claim.
function verifyBatch(uint256 _epoch) external {
revert("Not Implemented");
}

/// @dev Verifies merkle proof for the given message and associated nonce for the most recent possible epoch and relays the message.
/// @param _epoch The epoch in which the message was batched by the bridge.
/// @param _proof The merkle proof to prove the membership of the message and nonce in the merkle tree for the epoch.
/// @param _message The data on the cross-domain chain for the message.
function verifyAndRelayMessage(uint256 _epoch, bytes32[] calldata _proof, bytes calldata _message) external {
revert("Not Implemented");
}

/// @dev Sends the deposit back to the Bridger if their claim is not successfully challenged. Includes a portion of the Challenger's deposit if unsuccessfully challenged.
/// @param _epoch The epoch associated with the claim deposit to withraw.
function withdrawClaimDeposit(uint256 _epoch) external {
revert("Not Implemented");
}

/// @dev Sends the deposit back to the Challenger if his challenge is successful. Includes a portion of the Bridger's deposit.
/// @param _epoch The epoch associated with the challenge deposit to withraw.
function withdrawChallengeDeposit(uint256 _epoch) external {
revert("Not Implemented");
}

// ************************************* //
// * Public Views * //
// ************************************* //

/// @dev Returns the `start` and `end` time of challenge period for this `epoch`.
/// @param _epoch The epoch of the claim to request the challenge period.
/// @return start The start time of the challenge period.
/// @return end The end time of the challenge period.
function claimChallengePeriod(uint256 _epoch) external view returns (uint256 start, uint256 end) {
revert("Not Implemented");
}

/// @dev Returns the epoch period.

function epochPeriod() external view returns (uint256 epochPeriod) {
/// @dev Verifies and relays the message.
/// Note: Gateways expect first argument of message call to be the arbitrum message sender, used for authentication.
/// @param _proof The merkle proof to prove the message.
/// @param _msgId The zero based index of the message in the inbox.
/// @param _to The address to send the message to.
/// @param _message The message to relay.
function sendMessage(bytes32[] calldata _proof, uint64 _msgId, address _to, bytes calldata _message) external {
revert("Not Implemented");
}

/// @dev Returns the challenge period.
function challengePeriod() external view returns (uint256 challengePeriod) {
/// @dev Resolves any challenge of the optimistic claim for 'epoch' using the canonical bridge.
/// Note: Access restricted to canonical bridge.
/// @param _epoch The epoch to verify.
/// @param _stateRoot The true state root for the epoch.
/// @param _claim The claim associated with the epoch.
function resolveDisputedClaim(uint256 _epoch, bytes32 _stateRoot, Claim memory _claim) external {
revert("Not Implemented");
}

Expand Down
Loading

0 comments on commit 3c7e8f8

Please sign in to comment.