Skip to content

Commit

Permalink
remove iterable list and replace it with ennumberableAddress set from…
Browse files Browse the repository at this point in the history
… openzepplin
  • Loading branch information
josojo committed Jan 9, 2024
1 parent c82f1ed commit 30fb979
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 267 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
pragma solidity ^0.8.20;

import {Feeds} from "./Push/Feeds.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

/**
Feeds arbitration framework, which allows arbitrators to manage themselves.
*/

contract AdjudicationFrameworkForFeedsWithSelfManagement is Feeds {
using EnumerableSet for EnumerableSet.AddressSet;
/// @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
Expand All @@ -22,13 +24,13 @@ contract AdjudicationFrameworkForFeedsWithSelfManagement is Feeds {
@dev Allows an arbitrator to add another arbitrator to the allowlist
*/
function addArbitrator(address arbitrator) external onlyArbitrator {
_addToList(arbitrator);
arbitrators.add(arbitrator);
}

/**
@dev Allows an arbitrator to remove another arbitrator from the allowlist
*/
function removeArbitrator(address arbitrator) external onlyArbitrator {
_removeFromList(arbitrator);
arbitrators.remove(arbitrator);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {Requests} from "./Pull/Requests.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

/*
This contract sits between a Reality.eth instance and an Arbitrator.
It manages a allowlist of arbitrators, and makes sure questions can be sent to an arbitrator on the allowlist.
Expand All @@ -22,6 +24,8 @@ To the normal Arbitrator contracts that does its arbitration jobs, it looks like
*/

contract AdjudicationFramework is Requests {
using EnumerableSet for EnumerableSet.AddressSet;

uint32 public constant REALITY_ETH_BOND_ARBITRATOR_ADD = 10000;

uint256 public templateIdAddArbitrator;
Expand Down Expand Up @@ -94,14 +98,17 @@ contract AdjudicationFramework is Requests {
"Wrong Proposition type"
);
address arbitrator = propositions[questionId].newArbitrator;
require(!contains(arbitrator), "Arbitrator already on allowlist");
require(

Check warning on line 101 in contracts/AdjudicationFramework/AdjudicationFrameworkForRequestsWithChallengeManagement.sol

View workflow job for this annotation

GitHub Actions / Code linting (16.x, ubuntu-latest)

Use Custom Errors instead of require statements
!arbitrators.contains(arbitrator),
"Arbitrator already on allowlist"
);
require(

Check warning on line 105 in contracts/AdjudicationFramework/AdjudicationFrameworkForRequestsWithChallengeManagement.sol

View workflow job for this annotation

GitHub Actions / Code linting (16.x, ubuntu-latest)

Use Custom Errors instead of require statements
realityETH.resultFor(questionId) == bytes32(uint256(1)),
"Question did not return yes"
);
delete (propositions[questionId]);

// NB They may still be in a frozen state because of some other proposition
_addToList(arbitrator);
arbitrators.add(arbitrator);
}
}
21 changes: 14 additions & 7 deletions contracts/AdjudicationFramework/MinimalAdjudicationFramework.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ pragma solidity ^0.8.20;
import {IRealityETH} from "./../lib/reality-eth/interfaces/IRealityETH.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

Check warning on line 10 in contracts/AdjudicationFramework/MinimalAdjudicationFramework.sol

View workflow job for this annotation

GitHub Actions / Code linting (16.x, ubuntu-latest)

imported name IERC20 is not used
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {IterableList} from "./utils/IterableList.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
/*
Minimal Adjudication framework every framework should implement
Contains an iterableList of Arbitrators.
Arbitrators can be frozen by providing a bond and be removed by
a realityETH question with forking as a final arbitration.
*/

contract MinimalAdjudicationFramework is IterableList {
contract MinimalAdjudicationFramework {
using EnumerableSet for EnumerableSet.AddressSet;

EnumerableSet.AddressSet internal arbitrators;
/// @dev Error thrown when non-allowlisted actor tries to call a function
error OnlyAllowlistedActor();

Expand Down Expand Up @@ -57,7 +60,7 @@ contract MinimalAdjudicationFramework is IterableList {
IRealityETH public realityETH;

modifier onlyArbitrator() {
if (!contains(msg.sender)) {
if (!arbitrators.contains(msg.sender)) {
revert OnlyAllowlistedActor();
}
_;
Expand Down Expand Up @@ -92,7 +95,7 @@ contract MinimalAdjudicationFramework is IterableList {

// Allowlist the initial arbitrators
for (uint256 i = 0; i < _initialArbitrators.length; i++) {
_addToList(_initialArbitrators[i]);
arbitrators.add(_initialArbitrators[i]);
}
}

Expand Down Expand Up @@ -147,12 +150,12 @@ contract MinimalAdjudicationFramework is IterableList {
bytes32 realityEthResult = realityETH.resultFor(questionId);
require(realityEthResult == bytes32(uint256(1)), "Result was not 1");

_removeFromList(arbitratorToRemove);
arbitrators.remove(arbitratorToRemove);
if (propositions[questionId].isFrozen) {
countArbitratorFreezePropositions[arbitratorToRemove] -= 1;
}
if (newArbitrator != address(0)) {
_addToList(newArbitrator);
arbitrators.add(newArbitrator);
}
delete (propositions[questionId]);
}
Expand All @@ -173,7 +176,7 @@ contract MinimalAdjudicationFramework is IterableList {
address arbitrator = propositions[questionId].arbitratorToRemove;

require(
contains(arbitrator),
arbitrators.contains(arbitrator),
"Arbitrator not allowlisted" // Not allowlisted in the first place
);
require(
Expand Down Expand Up @@ -231,4 +234,8 @@ contract MinimalAdjudicationFramework is IterableList {
function realitio() external view returns (address) {
return address(realityETH);
}

function isArbitrator(address arbitrator) external view returns (bool) {
return arbitrators.contains(arbitrator);
}
}
14 changes: 11 additions & 3 deletions contracts/AdjudicationFramework/Pull/Requests.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {MinimalAdjudicationFramework} from "../MinimalAdjudicationFramework.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

/*
This contract sits between a Reality.eth instance and an Arbitrator.
Expand All @@ -24,6 +25,8 @@ To the normal Arbitrator contracts that does its arbitration jobs, it looks like
*/

contract Requests is MinimalAdjudicationFramework, BalanceHolder {
using EnumerableSet for EnumerableSet.AddressSet;

event LogRequestArbitration(
bytes32 indexed questionId,
uint256 feePaid,
Expand Down Expand Up @@ -129,7 +132,9 @@ contract Requests is MinimalAdjudicationFramework, BalanceHolder {
// The only time you can pick up a question that's already being arbitrated is if it's been removed from the allowlist
if (questionArbitrations[questionId].arbitrator != address(0)) {
require(
!contains(questionArbitrations[questionId].arbitrator),
!arbitrators.contains(
questionArbitrations[questionId].arbitrator
),
"Question under arbitration" // Question already taken, and the arbitrator who took it is still active
);

Expand All @@ -152,7 +157,7 @@ contract Requests is MinimalAdjudicationFramework, BalanceHolder {
address old_arbitrator = questionArbitrations[questionId].arbitrator;
require(old_arbitrator != address(0), "No arbitrator to remove");
require(
!contains(old_arbitrator),
!arbitrators.contains(old_arbitrator),
"Arbitrator not removed" // Arbitrator must no longer be on the allowlist
);

Expand Down Expand Up @@ -231,7 +236,10 @@ contract Requests is MinimalAdjudicationFramework, BalanceHolder {
) external {
address arbitrator = questionArbitrations[questionId].arbitrator;

require(contains(arbitrator), "Arbitrator must be allowlisted");
require(
arbitrators.contains(arbitrator),
"Arbitrator must be allowlisted"
);
require(
countArbitratorFreezePropositions[arbitrator] == 0,
"Arbitrator under dispute"
Expand Down
22 changes: 12 additions & 10 deletions contracts/AdjudicationFramework/Push/Feeds.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {MinimalAdjudicationFramework} from "./../MinimalAdjudicationFramework.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

/*
This contract is an example implementation of price feeds using the backstop's arbitration framework.
*/

contract Feeds is MinimalAdjudicationFramework {
using EnumerableSet for EnumerableSet.AddressSet;

uint256 public constant INPUT_SIZE = 5;

// Input struct from oracle price providers
Expand Down Expand Up @@ -87,19 +90,19 @@ contract Feeds is MinimalAdjudicationFramework {
address token,
uint256 deplay
) public view returns (uint256) {
address[] memory arbitrators = getAllListMembers();
uint256[] memory prices = new uint256[](arbitrators.length);
for (uint i = 0; i < arbitrators.length; i++) {
if (countArbitratorFreezePropositions[arbitrators[i]] > 0) {
uint256 arbitratorCount = arbitrators.length();
uint256[] memory prices = new uint256[](arbitratorCount);
for (uint i = 0; i < arbitratorCount; i++) {
address arbitrator = arbitrators.at(i);
if (countArbitratorFreezePropositions[arbitrator] > 0) {
continue;
}
uint256 lastEntry = 0;
for (uint j = 0; j < INPUT_SIZE; j++) {
if (
arbitratorInputs[token][arbitrators[i]][j].timestamp <
arbitratorInputs[token][arbitrators[i]][lastEntry]
.timestamp &&
arbitratorInputs[token][arbitrators[i]][j].timestamp >
arbitratorInputs[token][arbitrator][j].timestamp <
arbitratorInputs[token][arbitrator][lastEntry].timestamp &&
arbitratorInputs[token][arbitrator][j].timestamp >
block.timestamp - deplay
) {
lastEntry = j;
Expand All @@ -108,8 +111,7 @@ contract Feeds is MinimalAdjudicationFramework {
break;
}
}
prices[i] = arbitratorInputs[token][arbitrators[i]][lastEntry]
.price;
prices[i] = arbitratorInputs[token][arbitrator][lastEntry].price;
}

return calculateAvgerage(prices);
Expand Down
119 changes: 0 additions & 119 deletions contracts/AdjudicationFramework/utils/IterableList.sol

This file was deleted.

Loading

0 comments on commit 30fb979

Please sign in to comment.