Skip to content

Commit

Permalink
Merge branch 'dev' into test/handler-cov
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-something authored Dec 18, 2024
2 parents c0ffeea + 2db351c commit a3b8f1c
Show file tree
Hide file tree
Showing 26 changed files with 972 additions and 341 deletions.
185 changes: 180 additions & 5 deletions LICENSE

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ The deployments are stored in ./broadcast
See the [Foundry Book for available options](https://book.getfoundry.sh/reference/forge/forge-create.html).

## Licensing
TODO
The primary license for EBO contracts is GPL-3.0, see [`LICENSE`](./LICENSE).

## Contributors

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"scripts": {
"build": "forge build",
"build:optimized": "FOUNDRY_PROFILE=optimized forge build",
"coverage": "forge coverage --report summary --report lcov --match-path 'test/unit/*'",
"coverage": "forge coverage --ir-minimum --report summary --report lcov --match-path 'test/unit/*'",
"deploy:arbitrum": "bash -c 'source .env && forge script Deploy --rpc-url arbitrum --account $ARBITRUM_DEPLOYER_NAME --broadcast --verify --chain arbitrum -vvvvv'",
"lint:check": "yarn lint:sol-tests && yarn lint:sol-logic && forge fmt --check",
"lint:fix": "sort-package-json && forge fmt && yarn lint:sol-tests --fix && yarn lint:sol-logic --fix",
Expand All @@ -34,8 +34,8 @@
"package.json": "sort-package-json"
},
"dependencies": {
"@defi-wonderland/prophet-core": "0.0.0-96d1084b",
"@defi-wonderland/prophet-modules": "0.0.0-b72dcda6"
"@defi-wonderland/prophet-core": "0.0.0-819e5fe9",
"@defi-wonderland/prophet-modules": "0.0.0-022dfec8"
},
"devDependencies": {
"@commitlint/cli": "19.3.0",
Expand Down
1 change: 0 additions & 1 deletion script/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ address constant _ARBITRUM_MAINNET_COUNCIL = address(0x101);
address constant _ARBITRUM_SEPOLIA_GRAPH_TOKEN = 0x1A1af8B44fD59dd2bbEb456D1b7604c7bd340702;
address constant _ARBITRUM_SEPOLIA_HORIZON_STAKING = 0x3F53F9f9a5d7F36dCC869f8D2F227499c411c0cf;
address constant _ARBITRUM_SEPOLIA_EPOCH_MANAGER = 0x7975475801BEf845f10Ce7784DC69aB1e0344f11;
address constant _ARBITRUM_SEPOLIA_GOVERNOR = 0xadE6B8EB69a49B56929C1d4F4b428d791861dB6f;
address constant _ARBITRUM_SEPOLIA_ARBITRATOR = address(0x100);
address constant _ARBITRUM_SEPOLIA_COUNCIL = address(0x101);

Expand Down
15 changes: 12 additions & 3 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ import {
IBondEscalationAccounting
} from '@defi-wonderland/prophet-modules/solidity/interfaces/extensions/IBondEscalationAccounting.sol';
import {IERC20} from '@openzeppelin/contracts/interfaces/IERC20.sol';
import {IEpochManager} from 'interfaces/external/IEpochManager.sol';
import {IHorizonStaking} from 'interfaces/external/IHorizonStaking.sol';

import {Arbitrable, IArbitrable} from 'contracts/Arbitrable.sol';
import {CouncilArbitrator, ICouncilArbitrator} from 'contracts/CouncilArbitrator.sol';
import {IEpochManager} from 'interfaces/external/IEpochManager.sol';
import {IHorizonStaking} from 'interfaces/external/IHorizonStaking.sol';

import {EBOAccessModule, IEBOAccessModule} from 'contracts/EBOAccessModule.sol';
import {EBOFinalityModule, IEBOFinalityModule} from 'contracts/EBOFinalityModule.sol';
import {EBORequestCreator, IEBORequestCreator} from 'contracts/EBORequestCreator.sol';
import {EBORequestModule, IEBORequestModule} from 'contracts/EBORequestModule.sol';
Expand All @@ -42,7 +44,7 @@ import {
import 'forge-std/Script.sol';

contract Deploy is Script {
uint256 public constant DEPLOYMENT_COUNT = 10;
uint256 public constant DEPLOYMENT_COUNT = 11;
uint256 public constant OFFSET_EBO_REQUEST_CREATOR = DEPLOYMENT_COUNT - 1;

// Oracle
Expand All @@ -54,6 +56,7 @@ contract Deploy is Script {
IBondEscalationModule public bondEscalationModule;
IArbitratorModule public arbitratorModule;
IEBOFinalityModule public eboFinalityModule;
IEBOAccessModule public eboAccessModule;

// Extensions
IHorizonAccountingExtension public horizonAccountingExtension;
Expand Down Expand Up @@ -155,6 +158,10 @@ contract Deploy is Script {
councilArbitrator = new CouncilArbitrator(arbitratorModule, arbitrable);
console.log('`CouncilArbitrator` deployed at:', address(councilArbitrator));

// Deploy `EBOAccessModule`
eboAccessModule = new EBOAccessModule(oracle, arbitrable, horizonAccountingExtension);
console.log('`EBOAccessModule` deployed at:', address(eboAccessModule));

// Deploy `EBORequestCreator`
IOracle.Request memory _requestData = _instantiateRequestData();
eboRequestCreator = new EBORequestCreator(oracle, epochManager, arbitrable, _requestData);
Expand All @@ -171,7 +178,9 @@ contract Deploy is Script {
_requestData.nonce = 0;

// Set requester and modules

_requestData.requester = address(eboRequestCreator);
_requestData.accessModule = address(eboAccessModule);
_requestData.requestModule = address(eboRequestModule);
_requestData.responseModule = address(bondedResponseModule);
_requestData.disputeModule = address(bondEscalationModule);
Expand Down
9 changes: 7 additions & 2 deletions src/contracts/CouncilArbitrator.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.26;

import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/access/IAccessController.sol';
import {ValidatorLib} from '@defi-wonderland/prophet-core/solidity/libraries/ValidatorLib.sol';
import {IArbitrator} from '@defi-wonderland/prophet-modules/solidity/interfaces/IArbitrator.sol';

Expand Down Expand Up @@ -68,16 +69,20 @@ contract CouncilArbitrator is ICouncilArbitrator {
if (getAnswer[_disputeId] != IOracle.DisputeStatus.None) revert CouncilArbitrator_DisputeAlreadyArbitrated();

getAnswer[_disputeId] = _award;
IAccessController.AccessControl memory _accessControl =
IAccessController.AccessControl({user: address(this), data: bytes('')});

ORACLE.resolveDispute(_resolutionParams.request, _resolutionParams.response, _resolutionParams.dispute);
ORACLE.resolveDispute(
_resolutionParams.request, _resolutionParams.response, _resolutionParams.dispute, _accessControl
);

// If the request was not finalized, finalize it
if (ORACLE.finalizedAt(_resolutionParams.dispute.requestId) == 0) {
// If the dispute was lost, finalize with response
if (_award != IOracle.DisputeStatus.Lost) {
_resolutionParams.response.requestId = 0;
}
ORACLE.finalize(_resolutionParams.request, _resolutionParams.response);
ORACLE.finalize(_resolutionParams.request, _resolutionParams.response, _accessControl);
}

emit DisputeArbitrated(_disputeId, _award);
Expand Down
79 changes: 79 additions & 0 deletions src/contracts/EBOAccessModule.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.26;

import {
IAccessModule,
IArbitrable,
IEBOAccessModule,
IHorizonAccountingExtension,
IHorizonStaking,
IOracle
} from 'interfaces/IEBOAccessModule.sol';

import {IModule, Module} from '@defi-wonderland/prophet-core/solidity/contracts/Module.sol';

contract EBOAccessModule is IEBOAccessModule, Module {
/// @inheritdoc IEBOAccessModule
IArbitrable public immutable ARBITRABLE;
/// @inheritdoc IEBOAccessModule
IHorizonStaking public horizonStaking;
/// @inheritdoc IEBOAccessModule
IHorizonAccountingExtension public horizonAccountingExtension;

/**
* @notice Constructor
* @param _oracle The address of the Oracle
* @param _arbitrable The address of the Arbitrable contract
* @param _horizonAccountingExtension The address of the Horizon Accounting Extension contract
*/
constructor(
IOracle _oracle,
IArbitrable _arbitrable,
IHorizonAccountingExtension _horizonAccountingExtension
) Module(_oracle) {
ARBITRABLE = _arbitrable;
_setHorizonAccountingExtension(_horizonAccountingExtension);
}

/// @inheritdoc IAccessModule
function decodeAccessControlParameters(bytes calldata _data)
public
pure
returns (IAccessModule.AccessControlParameters memory _params)
{
_params = abi.decode(_data, (IAccessModule.AccessControlParameters));
}

/// @inheritdoc IAccessModule
function hasAccess(bytes calldata _data) external view returns (bool _hasAccess) {
IAccessModule.AccessControlParameters memory _params = decodeAccessControlParameters(_data);
_hasAccess =
horizonStaking.isAuthorized(_params.accessControl.user, address(horizonAccountingExtension), _params.sender);
}

/// @inheritdoc IEBOAccessModule
function setHorizonAccountingExtension(IHorizonAccountingExtension _horizonAccountingExtension) external {
ARBITRABLE.validateArbitrator(msg.sender);

_setHorizonAccountingExtension(_horizonAccountingExtension);
}

/// @inheritdoc IModule
function moduleName() external pure returns (string memory _moduleName) {
_moduleName = 'EBOAccessModule';
}

/**
* @notice Internal function to set the horizon accounting extension contract.
* @dev It also updates the `horizonStaking` address.
* @param _horizonAccountingExtension The new horizon accounting extension contract.
*/
function _setHorizonAccountingExtension(IHorizonAccountingExtension _horizonAccountingExtension) internal {
horizonAccountingExtension = _horizonAccountingExtension;

// also update horizon staking address using the accounting extension view function
horizonStaking = _horizonAccountingExtension.HORIZON_STAKING();

emit HorizonAccountingExtensionSet(_horizonAccountingExtension);
}
}
6 changes: 4 additions & 2 deletions src/contracts/EBORequestCreator.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.26;

import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/access/IAccessController.sol';
import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';

import {
Expand Down Expand Up @@ -81,10 +82,11 @@ contract EBORequestCreator is IEBORequestCreator {
) revert EBORequestCreator_RequestAlreadyCreated();

_requestModuleData.chainId = _chainId;

_requestData.requestModuleData = abi.encode(_requestModuleData);

_requestId = ORACLE.createRequest(_requestData, bytes32(0));
IAccessController.AccessControl memory _accessControl =
IAccessController.AccessControl({user: address(this), data: bytes('')});
_requestId = ORACLE.createRequest(_requestData, bytes32(0), _accessControl);

requestIdPerChainAndEpoch[_chainId][_epoch] = _requestId;

Expand Down
1 change: 0 additions & 1 deletion src/contracts/EBORequestModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity 0.8.26;

import {IModule, Module} from '@defi-wonderland/prophet-core/solidity/contracts/Module.sol';

import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';

import {IArbitrable, IEBORequestCreator, IEBORequestModule, IOracle} from 'interfaces/IEBORequestModule.sol';
Expand Down
3 changes: 0 additions & 3 deletions src/contracts/HorizonAccountingExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {

// Check the balance in the contract
// If not enough balance, slash some users to get enough balance
// TODO: How many iterations should we do?
while (disputeBalance[_disputeId] < _rewardAmount) {
_slash(_disputeId, MAX_USERS_TO_SLASH, maxUsersToCheck, _result, _status);
}
Expand Down Expand Up @@ -407,8 +406,6 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
if (_slashAmount > 0) {
// Slash the user
HORIZON_STAKING.slash(_user, _slashAmount, _slashAmount, address(this));
// TODO: What if `MIN_THAWING_PERIOD` has passed, all provision tokens have been thawed
// and slashing is skipped or reverts (bricking `claimEscalationReward()`)?

_unbond(_user, _slashAmount);

Expand Down
55 changes: 55 additions & 0 deletions src/interfaces/IEBOAccessModule.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.26;

import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol';
import {IAccessModule} from '@defi-wonderland/prophet-core/solidity/interfaces/modules/access/IAccessModule.sol';

import {IHorizonAccountingExtension} from 'interfaces/IHorizonAccountingExtension.sol';

import {IHorizonStaking} from 'interfaces/external/IHorizonStaking.sol';

import {IArbitrable} from 'interfaces/IArbitrable.sol';

interface IEBOAccessModule is IAccessModule {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/

/**
* @notice Emitted when the Horizon Accounting Extension contract is set
* @param _horizonAccountingExtension The new Horizon Accounting Extension contract
*/
event HorizonAccountingExtensionSet(IHorizonAccountingExtension indexed _horizonAccountingExtension);

/*///////////////////////////////////////////////////////////////
VARIABLES
//////////////////////////////////////////////////////////////*/

/**
* @notice The Arbitrable contract
* @return _arbitrable The Arbitrable contract
*/
function ARBITRABLE() external view returns (IArbitrable _arbitrable);

/**
* @notice The Horizon Accounting Extension contract
* @return _horizonAccountingExtension The Horizon Accounting Extension contract
*/
function horizonAccountingExtension() external view returns (IHorizonAccountingExtension _horizonAccountingExtension);

/**
* @notice The Horizon Staking contract
* @return _horizonStaking The Horizon Staking contract
*/
function horizonStaking() external view returns (IHorizonStaking _horizonStaking);

/*///////////////////////////////////////////////////////////////
LOGIC
//////////////////////////////////////////////////////////////*/

/**
* @notice Sets the Horizon Accounting Extension contract
* @param _horizonAccountingExtension The new Horizon Accounting Extension contract
*/
function setHorizonAccountingExtension(IHorizonAccountingExtension _horizonAccountingExtension) external;
}
2 changes: 2 additions & 0 deletions src/interfaces/IEBORequestCreator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ interface IEBORequestCreator {
* @return _disputeModule The dispute module address
* @return _resolutionModule The resolution module address
* @return _finalityModule The finality module address
* @return _accessModule The address of the access module
* @return _requestModuleData The request module data
* @return _responseModuleData The response module data
* @return _disputeModuleData The dispute module data
Expand All @@ -170,6 +171,7 @@ interface IEBORequestCreator {
address _disputeModule,
address _resolutionModule,
address _finalityModule,
address _accessModule,
bytes memory _requestModuleData,
bytes memory _responseModuleData,
bytes memory _disputeModuleData,
Expand Down
9 changes: 9 additions & 0 deletions src/interfaces/external/IHorizonStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,13 @@ interface IHorizonStaking {
* @param verifierDestination The address to transfer the verifier cut to
*/
function slash(address serviceProvider, uint256 tokens, uint256 tokensVerifier, address verifierDestination) external;

/**
* @notice Check if an operator is authorized for the caller on a specific verifier / data service.
* @param serviceProvider The service provider on behalf of whom they're claiming to act
* @param verifier The verifier / data service on which they're claiming to act
* @param operator The address to check for auth
* @return Whether the operator is authorized or not
*/
function isAuthorized(address serviceProvider, address verifier, address operator) external view returns (bool);
}
Loading

0 comments on commit a3b8f1c

Please sign in to comment.