Skip to content

Commit

Permalink
first try
Browse files Browse the repository at this point in the history
  • Loading branch information
josojo committed Jan 19, 2024
1 parent 698bde5 commit 38b1b37
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 76 deletions.
19 changes: 16 additions & 3 deletions contracts/AdjudicationFramework/MinimalAdjudicationFramework.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pragma solidity ^0.8.20;
import {IRealityETH} from "./../lib/reality-eth/interfaces/IRealityETH.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {IL2ForkArbitrator} from "../interfaces/IL2ForkArbitrator.sol";
/*
Minimal Adjudication framework every framework should implement.
Contains an enumerableSet of Arbitrators.
Expand Down Expand Up @@ -76,6 +76,7 @@ contract MinimalAdjudicationFramework {
// When they're all cleared they can be unfrozen.
mapping(address => uint256) public countArbitratorFreezePropositions;

uint256 public arbitrationDelayForCollectingEvidence;
IRealityETH public realityETH;

modifier onlyArbitrator() {
Expand All @@ -89,15 +90,18 @@ contract MinimalAdjudicationFramework {
/// @param _forkArbitrator The arbitrator contract that escalates to an L1 fork, used for our governance
/// @param _initialArbitrators Arbitrator contracts we initially support
/// @param _allowReplacementModification Whether to allow multiple modifications at once
/// @param _arbitrationDelayForCollectingEvidence The delay before arbitration can be requested
constructor(
address _realityETH,
address _forkArbitrator,
address[] memory _initialArbitrators,
bool _allowReplacementModification
bool _allowReplacementModification,
uint256 _arbitrationDelayForCollectingEvidence
) {
allowReplacementModification = _allowReplacementModification;
realityETH = IRealityETH(_realityETH);
forkArbitrator = _forkArbitrator;
arbitrationDelayForCollectingEvidence = _arbitrationDelayForCollectingEvidence;
// Create reality.eth templates for our add questions
// We'll identify ourselves in the template so we only need a single parameter for questions, the arbitrator in question.
// TODO: We may want to specify a document with the terms that guide this decision here, rather than just leaving it implicit.
Expand Down Expand Up @@ -163,14 +167,23 @@ contract MinimalAdjudicationFramework {
templateId = templateIdReplaceArbitrator;
}
bytes32 questionId = realityETH.askQuestionWithMinBond(
templateIdRemoveArbitrator,
templateId,
question,
forkArbitrator,
REALITY_ETH_TIMEOUT,
uint32(block.timestamp),
0,
REALITY_ETH_BOND_ARBITRATOR_REMOVE
);
IL2ForkArbitrator(forkArbitrator).storeInformation(
templateId,
uint32(block.timestamp),
question,
REALITY_ETH_TIMEOUT,
REALITY_ETH_BOND_ARBITRATOR_REMOVE,
0,
arbitrationDelayForCollectingEvidence
);
if (
propositions[questionId].arbitratorToAdd != address(0) ||
propositions[questionId].arbitratorToRemove != address(0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,22 @@ contract AdjudicationFrameworkRequests is
/// @param _disputeFee The dispute fee we charge reality.eth users
/// @param _forkArbitrator The arbitrator contract that escalates to an L1 fork, used for our governance
/// @param _initialArbitrators Arbitrator contracts we initially support
/// @param _arbitrationDelayForCollectingEvidence The delay before arbitration can be requested

constructor(
address _realityETH,
uint256 _disputeFee,
address _forkArbitrator,
address[] memory _initialArbitrators,
bool _allowReplacementModification
bool _allowReplacementModification,
uint256 _arbitrationDelayForCollectingEvidence
)
MinimalAdjudicationFramework(
_realityETH,
_forkArbitrator,
_initialArbitrators,
_allowReplacementModification
_allowReplacementModification,
_arbitrationDelayForCollectingEvidence
)
{
dispute_fee = _disputeFee;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,19 @@ contract AdjudicationFrameworkFeeds is MinimalAdjudicationFramework {
/// @param _realityETH The reality.eth instance we adjudicate for
/// @param _forkArbitrator The arbitrator contract that escalates to an L1 fork, used for our governance
/// @param _initialArbitrators Arbitrator contracts we initially support
/// @param _arbitrationDelayForCollectingEvidence The delay before arbitration can be requested
constructor(
address _realityETH,
address _forkArbitrator,
address[] memory _initialArbitrators
address[] memory _initialArbitrators,
uint256 _arbitrationDelayForCollectingEvidence
)
MinimalAdjudicationFramework(
_realityETH,
_forkArbitrator,
_initialArbitrators,
true // replace method can be used to switch out arbitrators
true, // replace method can be used to switch out arbitrators
_arbitrationDelayForCollectingEvidence
)
{}

Expand Down
86 changes: 54 additions & 32 deletions contracts/L2ForkArbitrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import {IRealityETH} from "./lib/reality-eth/interfaces/IRealityETH.sol";
import {CalculateMoneyBoxAddress} from "./lib/CalculateMoneyBoxAddress.sol";

import {IPolygonZkEVMBridge} from "@RealityETH/zkevm-contracts/contracts/interfaces/IPolygonZkEVMBridge.sol";
import {IBridgeMessageReceiver} from "@RealityETH/zkevm-contracts/contracts/interfaces/IBridgeMessageReceiver.sol";

import {IL2ForkArbitrator} from "./interfaces/IL2ForkArbitrator.sol";
/*
This contract is the arbitrator used by governance propositions for AdjudicationFramework contracts.
It charges a dispute fee of 5% of total supply [TODO], which it forwards to L1 when requesting a fork.
Expand All @@ -22,33 +21,7 @@ we are in the 1 week period before a fork) the new one will be queued.

// NB This doesn't implement IArbitrator because that requires slightly more functions than we need
// TODO: Would be good to make a stripped-down IArbitrator that only has the essential functions
contract L2ForkArbitrator is IBridgeMessageReceiver {
// @dev Error thrown when the arbitration fee is 0
error ArbitrationFeeMustBePositive();
// @dev Error thrown when the arbitration request has already been made
error ArbitrationAlreadyRequested();
// @dev Error thrown when the fork is already in progress over something else
error ForkInProgress();
// @dev Error thrown when the L2 bridge is not set
error L2BridgeNotSet();
// @dev Error thrown when the fork is not in progress
error QuestionNotForked();
// @dev Error thrown when status is not FORK_REQUESTED
error StatusNotForkRequested();
// @dev Error thrown when status is not FORK_REQUEST_FAILED
error StatusNotForkRequestFailed();
// @dev Error thrown when the fork is not in progress
error WrongStatus();
// @dev Error thrown when called with wrong network
error WrongNetwork();
// @dev Error thrown when called with wrong sender
error WrongSender();
// @dev Error thrown when called from the wrong bridge
error WrongBridge();
// @dev Error thrown when the fork is not in progress
error ForkNotInProgress();
// @dev Error thrown when contract is not awaiting activation
error NotAwaitingActivation();
contract L2ForkArbitrator is IL2ForkArbitrator {

bool public isForkInProgress;
IRealityETH public realitio;
Expand All @@ -65,6 +38,16 @@ contract L2ForkArbitrator is IBridgeMessageReceiver {
address payable payer;
uint256 paid;
bytes32 result;
uint256 timeOfRequest;
}

enum ArbitrationStatus {
NONE,
SOME
}
struct ArbitrationData {
ArbitrationStatus status;
uint256 delay; // Delay in seconds before the fork is activated
}

event LogRequestArbitration(
Expand All @@ -75,6 +58,8 @@ contract L2ForkArbitrator is IBridgeMessageReceiver {
);

mapping(bytes32 => ArbitrationRequest) public arbitrationRequests;
mapping(bytes32 => ArbitrationData) public arbitrationData;

mapping(address => uint256) public refundsDue;

L2ChainInfo public chainInfo;
Expand Down Expand Up @@ -121,7 +106,8 @@ contract L2ForkArbitrator is IBridgeMessageReceiver {
RequestStatus.QUEUED,
payable(msg.sender),
msg.value,
bytes32(0)
bytes32(0),
block.timestamp
);

realitio.notifyOfArbitrationRequest(
Expand All @@ -131,21 +117,57 @@ contract L2ForkArbitrator is IBridgeMessageReceiver {
);
emit LogRequestArbitration(questionId, msg.value, msg.sender, 0);

if (!isForkInProgress) {
if (!isForkInProgress && arbitrationData[questionId].delay == 0) {
requestActivateFork(questionId);
}
return true;
}

function storeInformation(
uint256 templateId,
uint32 openingTs,
string calldata question,
uint32 timeout,
uint32 minBond,
uint256 nonce,
uint256 delay
) public {
bytes32 contentHash = keccak256(
abi.encodePacked(templateId, openingTs, question)
);
bytes32 question_id = keccak256(
abi.encodePacked(
contentHash,
address(this),
timeout,
minBond,
address(realitio),
msg.sender,
nonce
)
);
arbitrationData[question_id] = ArbitrationData(ArbitrationStatus.SOME, delay);
}

/// @notice Request a fork via the bridge
/// @dev Talks to the L1 ForkingManager asynchronously, and may fail.
/// @param question_id The question in question
function requestActivateFork(bytes32 question_id) public {
if (arbitrationData[question_id].status == ArbitrationStatus.NONE)
revert ArbitrationDataNotSet();
if (arbitrationRequests[question_id].timeOfRequest + arbitrationData[question_id].delay > block.timestamp)
revert RequestStillInWaitingPeriod();
if (isForkInProgress) {
revert ForkInProgress(); // Forking over something else
}

if (msg.sender != arbitrationRequests[question_id].payer) {
if (
arbitrationRequests[question_id].status ==
RequestStatus.FORK_REQUEST_FAILED &&
msg.sender != arbitrationRequests[question_id].payer
) {
// If the fork request is done for the first time, anyone can call it. This ensures that a request will be processed even if the original payer is not available.
// Though, if the fork request failed, only the original payer can reinitiate it.
revert WrongSender();
}

Expand Down
3 changes: 2 additions & 1 deletion test/AdjudicationFramework/AdjudicationFrameworkFeeds.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ contract FeedsTest is Test {
feeds = new AdjudicationFrameworkFeeds(
address(l2RealityEth),
l2Arbitrator,
initialArbitrators
initialArbitrators,
0
);
}

Expand Down
6 changes: 4 additions & 2 deletions test/AdjudicationFramework/AdjudicationFrameworkMinimal.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ contract AdjudicationIntegrationTest is Test {
123,
address(l2ForkArbitrator),
initialArbitrators,
true
true,
0
);

l2Arbitrator1 = new Arbitrator();
Expand Down Expand Up @@ -256,7 +257,8 @@ contract AdjudicationIntegrationTest is Test {
123,
address(l2ForkArbitrator),
initialArbs,
true
true,
0
);

// NB The length and indexes of this may change if we add unrelated log entries to the AdjudicationFramework constructor
Expand Down
Loading

0 comments on commit 38b1b37

Please sign in to comment.