From 8765757a1d5b48d771349a39f25685f35a2ca2cc Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Mon, 23 Sep 2024 17:15:49 -0300 Subject: [PATCH 01/14] feat: deploy HorizonAccountingExtension --- script/Constants.sol | 15 +++- script/Deploy.s.sol | 40 +++++---- .../IHorizonAccountingExtension.sol | 6 +- test/integration/arbitrum/IntegrationBase.sol | 5 +- test/unit/Deploy.t.sol | 83 ++++++++++++------- test/unit/Deploy.tree | 7 +- 6 files changed, 100 insertions(+), 56 deletions(-) diff --git a/script/Constants.sol b/script/Constants.sol index 36b9698..159bc1d 100644 --- a/script/Constants.sol +++ b/script/Constants.sol @@ -1,10 +1,19 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.26; -// Contracts -address constant _GRAPH_TOKEN = 0x9623063377AD1B27544C965cCd7342f7EA7e88C7; -address constant _EPOCH_MANAGER = 0x5A843145c43d328B9bB7a4401d94918f131bB281; +// Arbitrum One +address constant _ARBITRUM_MAINNET_GRAPH_TOKEN = 0x9623063377AD1B27544C965cCd7342f7EA7e88C7; +address constant _ARBITRUM_MAINNET_HORIZON_STAKING = address(0x0); +address constant _ARBITRUM_MAINNET_EPOCH_MANAGER = 0x5A843145c43d328B9bB7a4401d94918f131bB281; + +// Arbitrum Sepolia +address constant _ARBITRUM_SEPOLIA_GRAPH_TOKEN = 0x1A1af8B44fD59dd2bbEb456D1b7604c7bd340702; +address constant _ARBITRUM_SEPOLIA_HORIZON_STAKING = 0x3F53F9f9a5d7F36dCC869f8D2F227499c411c0cf; +address constant _ARBITRUM_SEPOLIA_EPOCH_MANAGER = 0x7975475801BEf845f10Ce7784DC69aB1e0344f11; // TODO: EOAs address constant _ARBITRATOR = address(0x100); address constant _COUNCIL = address(0x101); + +// Data +uint256 constant _MIN_THAWING_PERIOD = 1 days; diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 7ec35e2..6004f3f 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -2,10 +2,6 @@ pragma solidity 0.8.26; import {IOracle, Oracle} from '@defi-wonderland/prophet-core/solidity/contracts/Oracle.sol'; -import { - BondEscalationAccounting, - IBondEscalationAccounting -} from '@defi-wonderland/prophet-modules/solidity/contracts/extensions/BondEscalationAccounting.sol'; import { BondEscalationModule, IBondEscalationModule @@ -18,16 +14,29 @@ import { BondedResponseModule, IBondedResponseModule } from '@defi-wonderland/prophet-modules/solidity/contracts/modules/response/BondedResponseModule.sol'; +import { + IAccountingExtension, + 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 {EBOFinalityModule, IEBOFinalityModule} from 'contracts/EBOFinalityModule.sol'; import {EBORequestCreator, IEBORequestCreator} from 'contracts/EBORequestCreator.sol'; import {EBORequestModule, IEBORequestModule} from 'contracts/EBORequestModule.sol'; +import {HorizonAccountingExtension, IHorizonAccountingExtension} from 'contracts/HorizonAccountingExtension.sol'; -import {_ARBITRATOR, _COUNCIL, _EPOCH_MANAGER, _GRAPH_TOKEN} from './Constants.sol'; +import { + _ARBITRATOR, + _ARBITRUM_SEPOLIA_EPOCH_MANAGER, + _ARBITRUM_SEPOLIA_GRAPH_TOKEN, + _ARBITRUM_SEPOLIA_HORIZON_STAKING, + _COUNCIL, + _MIN_THAWING_PERIOD +} from 'script/Constants.sol'; import 'forge-std/Script.sol'; @@ -50,6 +59,7 @@ contract Deploy is Script { // Extensions IBondEscalationAccounting public bondEscalationAccounting; + IHorizonAccountingExtension public horizonAccountingExtension; // Periphery IEBORequestCreator public eboRequestCreator; @@ -57,6 +67,7 @@ contract Deploy is Script { // The Graph IERC20 public graphToken; + IHorizonStaking public horizonStaking; IEpochManager public epochManager; address public arbitrator; address public council; @@ -76,8 +87,9 @@ contract Deploy is Script { function setUp() public virtual { // Define The Graph accounts - graphToken = IERC20(_GRAPH_TOKEN); - epochManager = IEpochManager(_EPOCH_MANAGER); + graphToken = IERC20(_ARBITRUM_SEPOLIA_GRAPH_TOKEN); + horizonStaking = IHorizonStaking(_ARBITRUM_SEPOLIA_HORIZON_STAKING); + epochManager = IEpochManager(_ARBITRUM_SEPOLIA_EPOCH_MANAGER); arbitrator = _ARBITRATOR; council = _COUNCIL; @@ -109,7 +121,7 @@ contract Deploy is Script { console.log('`Oracle` deployed at:', address(oracle)); // Deploy `Arbitrable` - arbitrable = new Arbitrable(_ARBITRATOR, _COUNCIL); + arbitrable = new Arbitrable(arbitrator, council); console.log('`Arbitrable` deployed at:', address(arbitrable)); // Deploy `EBORequestModule` @@ -132,9 +144,9 @@ contract Deploy is Script { eboFinalityModule = new EBOFinalityModule(oracle, _precomputedEBORequestCreator, arbitrable); console.log('`EBOFinalityModule` deployed at:', address(eboFinalityModule)); - // Deploy `BondEscalationAccounting` - bondEscalationAccounting = new BondEscalationAccounting(oracle); - console.log('`BondEscalationAccounting` deployed at:', address(bondEscalationAccounting)); + // Deploy `HorizonAccountingExtension` + horizonAccountingExtension = new HorizonAccountingExtension(horizonStaking, oracle, graphToken, _MIN_THAWING_PERIOD); + console.log('`HorizonAccountingExtension` deployed at:', address(horizonAccountingExtension)); // Deploy `CouncilArbitrator` councilArbitrator = new CouncilArbitrator(arbitratorModule, arbitrable); @@ -179,7 +191,7 @@ contract Deploy is Script { view returns (IEBORequestModule.RequestParameters memory _requestParams) { - _requestParams.accountingExtension = bondEscalationAccounting; + _requestParams.accountingExtension = IAccountingExtension(address(horizonAccountingExtension)); _requestParams.paymentAmount = paymentAmount; } @@ -188,7 +200,7 @@ contract Deploy is Script { view returns (IBondedResponseModule.RequestParameters memory _responseParams) { - _responseParams.accountingExtension = bondEscalationAccounting; + _responseParams.accountingExtension = IAccountingExtension(address(horizonAccountingExtension)); _responseParams.bondToken = graphToken; _responseParams.bondSize = responseBondSize; _responseParams.deadline = responseDeadline; @@ -200,7 +212,7 @@ contract Deploy is Script { view returns (IBondEscalationModule.RequestParameters memory _disputeParams) { - _disputeParams.accountingExtension = bondEscalationAccounting; + _disputeParams.accountingExtension = IBondEscalationAccounting(address(horizonAccountingExtension)); _disputeParams.bondToken = graphToken; _disputeParams.bondSize = disputeBondSize; _disputeParams.maxNumberOfEscalations = maxNumberOfEscalations; diff --git a/src/interfaces/IHorizonAccountingExtension.sol b/src/interfaces/IHorizonAccountingExtension.sol index 5de1ccd..b049545 100644 --- a/src/interfaces/IHorizonAccountingExtension.sol +++ b/src/interfaces/IHorizonAccountingExtension.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.26; -import {IHorizonStaking} from './external/IHorizonStaking.sol'; - import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; +import {IValidator} from '@defi-wonderland/prophet-core/solidity/interfaces/IValidator.sol'; import {IBondEscalationModule} from '@defi-wonderland/prophet-modules/solidity/interfaces/modules/dispute/IBondEscalationModule.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +import {IHorizonStaking} from 'interfaces/external/IHorizonStaking.sol'; -interface IHorizonAccountingExtension { +interface IHorizonAccountingExtension is IValidator { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ diff --git a/test/integration/arbitrum/IntegrationBase.sol b/test/integration/arbitrum/IntegrationBase.sol index 07396d3..bef9233 100644 --- a/test/integration/arbitrum/IntegrationBase.sol +++ b/test/integration/arbitrum/IntegrationBase.sol @@ -12,7 +12,8 @@ contract IntegrationBase is Deploy, Test { using ValidatorLib for IOracle.Response; using ValidatorLib for IOracle.Dispute; - uint256 internal constant _FORK_BLOCK = 240_000_000; + uint256 internal constant _ARBITRUM_MAINNET_FORK_BLOCK = 240_000_000; + uint256 internal constant _ARBITRUM_SEPOLIA_FORK_BLOCK = 83_000_000; // Users address internal _requester; @@ -27,7 +28,7 @@ contract IntegrationBase is Deploy, Test { uint256 internal _currentEpoch; function setUp() public virtual override { - vm.createSelectFork(vm.rpcUrl('arbitrum'), _FORK_BLOCK); + vm.createSelectFork(vm.rpcUrl('arbitrum'), _ARBITRUM_SEPOLIA_FORK_BLOCK); // Run deployment script super.setUp(); diff --git a/test/unit/Deploy.t.sol b/test/unit/Deploy.t.sol index 1f300ae..e7ce0df 100644 --- a/test/unit/Deploy.t.sol +++ b/test/unit/Deploy.t.sol @@ -2,8 +2,6 @@ pragma solidity 0.8.26; import {IOracle, Oracle} from '@defi-wonderland/prophet-core/solidity/contracts/Oracle.sol'; -import {BondEscalationAccounting} from - '@defi-wonderland/prophet-modules/solidity/contracts/extensions/BondEscalationAccounting.sol'; import { BondEscalationModule, IBondEscalationModule @@ -16,37 +14,32 @@ import { BondedResponseModule, IBondedResponseModule } from '@defi-wonderland/prophet-modules/solidity/contracts/modules/response/BondedResponseModule.sol'; +import { + IAccountingExtension, + IBondEscalationAccounting +} from '@defi-wonderland/prophet-modules/solidity/interfaces/extensions/IBondEscalationAccounting.sol'; import {IEpochManager} from 'interfaces/external/IEpochManager.sol'; +import {Arbitrable} from 'contracts/Arbitrable.sol'; import {CouncilArbitrator} from 'contracts/CouncilArbitrator.sol'; import {EBOFinalityModule} from 'contracts/EBOFinalityModule.sol'; import {EBORequestCreator} from 'contracts/EBORequestCreator.sol'; import {EBORequestModule, IEBORequestModule} from 'contracts/EBORequestModule.sol'; +import {HorizonAccountingExtension} from 'contracts/HorizonAccountingExtension.sol'; import {Deploy} from 'script/Deploy.s.sol'; -import {_ARBITRATOR, _COUNCIL, _EPOCH_MANAGER, _GRAPH_TOKEN} from 'script/Constants.sol'; +import { + _ARBITRATOR, + _ARBITRUM_SEPOLIA_EPOCH_MANAGER, + _ARBITRUM_SEPOLIA_GRAPH_TOKEN, + _ARBITRUM_SEPOLIA_HORIZON_STAKING, + _COUNCIL, + _MIN_THAWING_PERIOD +} from 'script/Constants.sol'; import 'forge-std/Test.sol'; -contract MockDeploy is Deploy { - address internal _ghost_precomputedAddress; - bool internal _ghost_mockPrecomputeCreateAddress; - - function mock_setPrecomputedAddress(address _precomputedAddress) external { - _ghost_precomputedAddress = _precomputedAddress; - _ghost_mockPrecomputeCreateAddress = true; - } - - function _precomputeCreateAddress(uint256 _deploymentOffset) internal view override returns (address _targetAddress) { - if (_ghost_mockPrecomputeCreateAddress) { - _targetAddress = _ghost_precomputedAddress; - } else { - _targetAddress = super._precomputeCreateAddress(_deploymentOffset); - } - } -} - contract UnitDeploy is Test { MockDeploy public deploy; @@ -62,8 +55,9 @@ contract UnitDeploy is Test { deploy.setUp(); // it should define The Graph accounts - assertEq(address(deploy.graphToken()).code, _GRAPH_TOKEN.code); - assertEq(address(deploy.epochManager()).code, _EPOCH_MANAGER.code); + assertEq(address(deploy.graphToken()).code, _ARBITRUM_SEPOLIA_GRAPH_TOKEN.code); + assertEq(address(deploy.horizonStaking()).code, _ARBITRUM_SEPOLIA_HORIZON_STAKING.code); + assertEq(address(deploy.epochManager()).code, _ARBITRUM_SEPOLIA_EPOCH_MANAGER.code); assertEq(address(deploy.arbitrator()), _ARBITRATOR); assertEq(address(deploy.council()), _COUNCIL); } @@ -75,7 +69,9 @@ contract UnitDeploy is Test { } modifier givenTheGraphAccountsAreSetUp() { - vm.mockCall(_EPOCH_MANAGER, abi.encodeCall(IEpochManager.currentEpoch, ()), abi.encode(_currentEpoch)); + vm.mockCall( + _ARBITRUM_SEPOLIA_EPOCH_MANAGER, abi.encodeCall(IEpochManager.currentEpoch, ()), abi.encode(_currentEpoch) + ); deploy.setUp(); _; @@ -107,6 +103,9 @@ contract UnitDeploy is Test { // it should deploy `Oracle` assertEq(address(deploy.oracle()).code, type(Oracle).runtimeCode); + // it should deploy `Arbitrable` + assertEq(address(deploy.arbitrable()).code, type(Arbitrable).runtimeCode); + // it should deploy `EBORequestModule` with correct args EBORequestModule _eboRequestModule = new EBORequestModule(deploy.oracle(), deploy.eboRequestCreator(), deploy.arbitrable()); @@ -138,10 +137,14 @@ contract UnitDeploy is Test { assertEq(address(deploy.eboFinalityModule().eboRequestCreator()), address(deploy.eboRequestCreator())); assertEq(address(deploy.eboFinalityModule().ARBITRABLE()), address(deploy.arbitrable())); - // it should deploy `BondEscalationAccounting` with correct args - BondEscalationAccounting _bondEscalationAccounting = new BondEscalationAccounting(deploy.oracle()); - assertEq(address(deploy.bondEscalationAccounting()).code, address(_bondEscalationAccounting).code); - assertEq(address(deploy.bondEscalationAccounting().ORACLE()), address(deploy.oracle())); + // it should deploy `HorizonAccountingExtension` with correct args + HorizonAccountingExtension _horizonAccountingExtension = + new HorizonAccountingExtension(deploy.horizonStaking(), deploy.oracle(), deploy.graphToken(), _MIN_THAWING_PERIOD); + assertEq(address(deploy.horizonAccountingExtension()).code, address(_horizonAccountingExtension).code); + assertEq(address(deploy.horizonAccountingExtension().HORIZON_STAKING()), address(deploy.horizonStaking())); + assertEq(address(deploy.horizonAccountingExtension().ORACLE()), address(deploy.oracle())); + assertEq(address(deploy.horizonAccountingExtension().GRT()), address(deploy.graphToken())); + assertEq(deploy.horizonAccountingExtension().MIN_THAWING_PERIOD(), _MIN_THAWING_PERIOD); // it should deploy `EBORequestCreator` with correct args IOracle.Request memory _requestData = _instantiateRequestData(); @@ -185,7 +188,7 @@ contract UnitDeploy is Test { view returns (IEBORequestModule.RequestParameters memory _requestParams) { - _requestParams.accountingExtension = deploy.bondEscalationAccounting(); + _requestParams.accountingExtension = IAccountingExtension(address(deploy.horizonAccountingExtension())); _requestParams.paymentAmount = deploy.paymentAmount(); } @@ -194,7 +197,7 @@ contract UnitDeploy is Test { view returns (IBondedResponseModule.RequestParameters memory _responseParams) { - _responseParams.accountingExtension = deploy.bondEscalationAccounting(); + _responseParams.accountingExtension = IAccountingExtension(address(deploy.horizonAccountingExtension())); _responseParams.bondToken = deploy.graphToken(); _responseParams.bondSize = deploy.responseBondSize(); _responseParams.deadline = deploy.responseDeadline(); @@ -206,7 +209,7 @@ contract UnitDeploy is Test { view returns (IBondEscalationModule.RequestParameters memory _disputeParams) { - _disputeParams.accountingExtension = deploy.bondEscalationAccounting(); + _disputeParams.accountingExtension = IBondEscalationAccounting(address(deploy.horizonAccountingExtension())); _disputeParams.bondToken = deploy.graphToken(); _disputeParams.bondSize = deploy.disputeBondSize(); _disputeParams.maxNumberOfEscalations = deploy.maxNumberOfEscalations(); @@ -223,3 +226,21 @@ contract UnitDeploy is Test { _resolutionParams.arbitrator = address(deploy.councilArbitrator()); } } + +contract MockDeploy is Deploy { + address internal _ghost_precomputedAddress; + bool internal _ghost_mockPrecomputeCreateAddress; + + function mock_setPrecomputedAddress(address _precomputedAddress) external { + _ghost_precomputedAddress = _precomputedAddress; + _ghost_mockPrecomputeCreateAddress = true; + } + + function _precomputeCreateAddress(uint256 _deploymentOffset) internal view override returns (address _targetAddress) { + if (_ghost_mockPrecomputeCreateAddress) { + _targetAddress = _ghost_precomputedAddress; + } else { + _targetAddress = super._precomputeCreateAddress(_deploymentOffset); + } + } +} diff --git a/test/unit/Deploy.tree b/test/unit/Deploy.tree index 3098c1b..a509289 100644 --- a/test/unit/Deploy.tree +++ b/test/unit/Deploy.tree @@ -1,7 +1,7 @@ -Deploy::setUp +UnitDeploy::setUp └── it should define The Graph accounts -Deploy::run +UnitDeploy::run ├── when The Graph accounts are not set up │ └── it should revert └── given The Graph accounts are set up @@ -10,11 +10,12 @@ Deploy::run └── when precomputed address is correct ├── it should deploy all contracts using a single EOA ├── it should deploy `Oracle` + ├── it should deploy `Arbitrable` ├── it should deploy `EBORequestModule` with correct args ├── it should deploy `BondedResponseModule` with correct args ├── it should deploy `BondEscalationModule` with correct args ├── it should deploy `ArbitratorModule` with correct args ├── it should deploy `EBOFinalityModule` with correct args - ├── it should deploy `BondEscalationAccounting` with correct args + ├── it should deploy `HorizonAccountingExtension` with correct args ├── it should deploy `EBORequestCreator` with correct args └── it should deploy `CouncilArbitrator` with correct args From e05ece56564b3736639a0b72e628d3c52a630699 Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Tue, 24 Sep 2024 01:38:03 -0300 Subject: [PATCH 02/14] refactor: revise max verifier cut and min thawing period --- src/contracts/HorizonAccountingExtension.sol | 8 ++++---- src/interfaces/IHorizonAccountingExtension.sol | 4 ++-- src/interfaces/external/IController.sol | 10 ++++++++++ test/unit/HorizonAccountingExtension.t.sol | 4 ++-- 4 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 src/interfaces/external/IController.sol diff --git a/src/contracts/HorizonAccountingExtension.sol b/src/contracts/HorizonAccountingExtension.sol index d1e4323..10a4bfb 100644 --- a/src/contracts/HorizonAccountingExtension.sol +++ b/src/contracts/HorizonAccountingExtension.sol @@ -25,10 +25,10 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { IERC20 public immutable GRT; /// @inheritdoc IHorizonAccountingExtension - uint256 public immutable MIN_THAWING_PERIOD; + uint64 public immutable MIN_THAWING_PERIOD; /// @inheritdoc IHorizonAccountingExtension - uint256 public constant MAX_VERIFIER_CUT = 1_000_000; + uint32 public constant MAX_VERIFIER_CUT = 1_000_000; // TODO: Validate what the correct magic numbers should be uint256 public constant MAX_SLASHING_USERS = 4; @@ -72,7 +72,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { IHorizonStaking _horizonStaking, IOracle _oracle, IERC20 _grt, - uint256 _minThawingPeriod + uint64 _minThawingPeriod ) Validator(_oracle) { HORIZON_STAKING = _horizonStaking; GRT = _grt; @@ -423,7 +423,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { function _bond(address _bonder, uint256 _amount) internal { IHorizonStaking.Provision memory _provisionData = HORIZON_STAKING.getProvision(_bonder, address(this)); - if (_provisionData.maxVerifierCut < MAX_VERIFIER_CUT) revert HorizonAccountingExtension_InvalidMaxVerifierCut(); + if (_provisionData.maxVerifierCut != MAX_VERIFIER_CUT) revert HorizonAccountingExtension_InvalidMaxVerifierCut(); if (_provisionData.thawingPeriod < MIN_THAWING_PERIOD) revert HorizonAccountingExtension_InvalidThawingPeriod(); if (_amount > _provisionData.tokens) revert HorizonAccountingExtension_InsufficientTokens(); diff --git a/src/interfaces/IHorizonAccountingExtension.sol b/src/interfaces/IHorizonAccountingExtension.sol index b049545..598fce7 100644 --- a/src/interfaces/IHorizonAccountingExtension.sol +++ b/src/interfaces/IHorizonAccountingExtension.sol @@ -204,13 +204,13 @@ interface IHorizonAccountingExtension is IValidator { * @notice The minimum thawing period * @return _MIN_THAWING_PERIOD The minimum thawing period */ - function MIN_THAWING_PERIOD() external view returns (uint256 _MIN_THAWING_PERIOD); + function MIN_THAWING_PERIOD() external view returns (uint64 _MIN_THAWING_PERIOD); /** * @notice The maximum verifier cut * @return _MAX_VERIFIER_CUT The maximum verifier cut */ - function MAX_VERIFIER_CUT() external view returns (uint256 _MAX_VERIFIER_CUT); + function MAX_VERIFIER_CUT() external view returns (uint32 _MAX_VERIFIER_CUT); /** * @notice The total bonded tokens for a user diff --git a/src/interfaces/external/IController.sol b/src/interfaces/external/IController.sol new file mode 100644 index 0000000..d0107c2 --- /dev/null +++ b/src/interfaces/external/IController.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.26; + +interface IController { + /*/////////////////////////////////////////////////////////////// + FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + function setPaused(bool _paused) external; +} diff --git a/test/unit/HorizonAccountingExtension.t.sol b/test/unit/HorizonAccountingExtension.t.sol index 6de5157..7b85601 100644 --- a/test/unit/HorizonAccountingExtension.t.sol +++ b/test/unit/HorizonAccountingExtension.t.sol @@ -25,7 +25,7 @@ contract HorizonAccountingExtensionForTest is HorizonAccountingExtension { IHorizonStaking _horizonStaking, IOracle _oracle, IERC20 _grt, - uint256 _minThawingPeriod + uint64 _minThawingPeriod ) HorizonAccountingExtension(_horizonStaking, _oracle, _grt, _minThawingPeriod) {} function approveModuleForTest(address _user, address _module) public { @@ -216,7 +216,7 @@ contract HorizonAccountingExtension_Unit_Pledge is HorizonAccountingExtension_Un function test_invalidVerfierCut(address _pledger, uint256 _amount, uint32 _invalidVerfierCut) public { vm.assume(_amount > 0); - vm.assume(_invalidVerfierCut < MAX_VERIFIER_CUT); + vm.assume(_invalidVerfierCut != MAX_VERIFIER_CUT); _provisionData.maxVerifierCut = _invalidVerfierCut; From 98752b6fe4d5f4b6a5f7f7a5e8114b7b894b12fa Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Wed, 25 Sep 2024 00:22:26 -0300 Subject: [PATCH 03/14] test: stake GRT and create provisions --- script/Constants.sol | 14 ++- script/Deploy.s.sol | 14 ++- .../arbitrum/ArbitrateDispute.t.sol | 11 ++- .../arbitrum/DisputeResponse.t.sol | 11 ++- .../arbitrum/EscalateDispute.t.sol | 11 ++- test/integration/arbitrum/IntegrationBase.sol | 93 ++++++++++++++----- .../arbitrum/ProposeResponse.t.sol | 11 ++- test/unit/Deploy.t.sol | 14 +-- test/unit/Deploy.tree | 4 +- 9 files changed, 121 insertions(+), 62 deletions(-) diff --git a/script/Constants.sol b/script/Constants.sol index 159bc1d..515c287 100644 --- a/script/Constants.sol +++ b/script/Constants.sol @@ -5,15 +5,19 @@ pragma solidity 0.8.26; address constant _ARBITRUM_MAINNET_GRAPH_TOKEN = 0x9623063377AD1B27544C965cCd7342f7EA7e88C7; address constant _ARBITRUM_MAINNET_HORIZON_STAKING = address(0x0); address constant _ARBITRUM_MAINNET_EPOCH_MANAGER = 0x5A843145c43d328B9bB7a4401d94918f131bB281; +address constant _ARBITRUM_MAINNET_CONTROLLER = address(0x0); +address constant _ARBITRUM_MAINNET_GOVERNOR = address(0x0); +address constant _ARBITRUM_MAINNET_ARBITRATOR = address(0x100); +address constant _ARBITRUM_MAINNET_COUNCIL = address(0x101); // Arbitrum Sepolia address constant _ARBITRUM_SEPOLIA_GRAPH_TOKEN = 0x1A1af8B44fD59dd2bbEb456D1b7604c7bd340702; address constant _ARBITRUM_SEPOLIA_HORIZON_STAKING = 0x3F53F9f9a5d7F36dCC869f8D2F227499c411c0cf; address constant _ARBITRUM_SEPOLIA_EPOCH_MANAGER = 0x7975475801BEf845f10Ce7784DC69aB1e0344f11; - -// TODO: EOAs -address constant _ARBITRATOR = address(0x100); -address constant _COUNCIL = address(0x101); +address constant _ARBITRUM_SEPOLIA_CONTROLLER = 0x4DbE1B10bc15D0F53fF508BE01942198262ddfCa; +address constant _ARBITRUM_SEPOLIA_GOVERNOR = 0xadE6B8EB69a49B56929C1d4F4b428d791861dB6f; +address constant _ARBITRUM_SEPOLIA_ARBITRATOR = address(0x100); +address constant _ARBITRUM_SEPOLIA_COUNCIL = address(0x101); // Data -uint256 constant _MIN_THAWING_PERIOD = 1 days; +uint64 constant _MIN_THAWING_PERIOD = 0 days; // TODO: Increase max thawing period via HorizonStaking::setMaxThawingPeriod diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 6004f3f..b0c4f34 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -30,11 +30,11 @@ import {EBORequestModule, IEBORequestModule} from 'contracts/EBORequestModule.so import {HorizonAccountingExtension, IHorizonAccountingExtension} from 'contracts/HorizonAccountingExtension.sol'; import { - _ARBITRATOR, + _ARBITRUM_SEPOLIA_ARBITRATOR, + _ARBITRUM_SEPOLIA_COUNCIL, _ARBITRUM_SEPOLIA_EPOCH_MANAGER, _ARBITRUM_SEPOLIA_GRAPH_TOKEN, _ARBITRUM_SEPOLIA_HORIZON_STAKING, - _COUNCIL, _MIN_THAWING_PERIOD } from 'script/Constants.sol'; @@ -47,9 +47,6 @@ contract Deploy is Script { // Oracle IOracle public oracle; - // Arbitrable - IArbitrable public arbitrable; - // Modules IEBORequestModule public eboRequestModule; IBondedResponseModule public bondedResponseModule; @@ -64,6 +61,7 @@ contract Deploy is Script { // Periphery IEBORequestCreator public eboRequestCreator; ICouncilArbitrator public councilArbitrator; + IArbitrable public arbitrable; // The Graph IERC20 public graphToken; @@ -90,11 +88,11 @@ contract Deploy is Script { graphToken = IERC20(_ARBITRUM_SEPOLIA_GRAPH_TOKEN); horizonStaking = IHorizonStaking(_ARBITRUM_SEPOLIA_HORIZON_STAKING); epochManager = IEpochManager(_ARBITRUM_SEPOLIA_EPOCH_MANAGER); - arbitrator = _ARBITRATOR; - council = _COUNCIL; + arbitrator = _ARBITRUM_SEPOLIA_ARBITRATOR; + council = _ARBITRUM_SEPOLIA_COUNCIL; // TODO: Set production request module params - paymentAmount = 0 ether; + paymentAmount = 0.1 ether; // TODO: Set production response module params responseBondSize = 0.5 ether; diff --git a/test/integration/arbitrum/ArbitrateDispute.t.sol b/test/integration/arbitrum/ArbitrateDispute.t.sol index f83e866..e6595c3 100644 --- a/test/integration/arbitrum/ArbitrateDispute.t.sol +++ b/test/integration/arbitrum/ArbitrateDispute.t.sol @@ -7,18 +7,21 @@ contract IntegrationArbitrateDispute is IntegrationBase { function setUp() public override { super.setUp(); + // Add chain IDs + _addChains(); + // Set modules data _setRequestModuleData(); _setResponseModuleData(); _setDisputeModuleData(); _setResolutionModuleData(); - // Deposit GRT and approve modules - _depositGRT(); + // Approve modules _approveModules(); - // Add chain IDs - _addChains(); + // Stake GRT and create provisions + _stakeGRT(); + _createProvisions(); } function test_ArbitrateDispute_Won() public { diff --git a/test/integration/arbitrum/DisputeResponse.t.sol b/test/integration/arbitrum/DisputeResponse.t.sol index fcecc31..26ff74f 100644 --- a/test/integration/arbitrum/DisputeResponse.t.sol +++ b/test/integration/arbitrum/DisputeResponse.t.sol @@ -7,18 +7,21 @@ contract IntegrationDisputeResponse is IntegrationBase { function setUp() public override { super.setUp(); + // Add chain IDs + _addChains(); + // Set modules data _setRequestModuleData(); _setResponseModuleData(); _setDisputeModuleData(); _setResolutionModuleData(); - // Deposit GRT and approve modules - _depositGRT(); + // Approve modules _approveModules(); - // Add chain IDs - _addChains(); + // Stake GRT and create provisions + _stakeGRT(); + _createProvisions(); } function test_DisputeResponse() public { diff --git a/test/integration/arbitrum/EscalateDispute.t.sol b/test/integration/arbitrum/EscalateDispute.t.sol index 935caff..9ac4e97 100644 --- a/test/integration/arbitrum/EscalateDispute.t.sol +++ b/test/integration/arbitrum/EscalateDispute.t.sol @@ -7,18 +7,21 @@ contract IntegrationEscalateDispute is IntegrationBase { function setUp() public override { super.setUp(); + // Add chain IDs + _addChains(); + // Set modules data _setRequestModuleData(); _setResponseModuleData(); _setDisputeModuleData(); _setResolutionModuleData(); - // Deposit GRT and approve modules - _depositGRT(); + // Approve modules _approveModules(); - // Add chain IDs - _addChains(); + // Stake GRT and create provisions + _stakeGRT(); + _createProvisions(); } function test_EscalateDispute() public { diff --git a/test/integration/arbitrum/IntegrationBase.sol b/test/integration/arbitrum/IntegrationBase.sol index bef9233..91d088f 100644 --- a/test/integration/arbitrum/IntegrationBase.sol +++ b/test/integration/arbitrum/IntegrationBase.sol @@ -2,6 +2,9 @@ pragma solidity 0.8.26; import {ValidatorLib} from '@defi-wonderland/prophet-core/solidity/libraries/ValidatorLib.sol'; +import {IController} from 'interfaces/external/IController.sol'; + +import {_ARBITRUM_SEPOLIA_CONTROLLER, _ARBITRUM_SEPOLIA_GOVERNOR} from 'script/Constants.sol'; import 'script/Deploy.s.sol'; @@ -15,6 +18,10 @@ contract IntegrationBase is Deploy, Test { uint256 internal constant _ARBITRUM_MAINNET_FORK_BLOCK = 240_000_000; uint256 internal constant _ARBITRUM_SEPOLIA_FORK_BLOCK = 83_000_000; + // The Graph + IController internal _controller; + address internal _governor; + // Users address internal _requester; address internal _proposer; @@ -34,6 +41,10 @@ contract IntegrationBase is Deploy, Test { super.setUp(); run(); + // Define The Graph accounts + _controller = IController(_ARBITRUM_SEPOLIA_CONTROLLER); + _governor = _ARBITRUM_SEPOLIA_GOVERNOR; + // Set user accounts _requester = makeAddr('requester'); _proposer = makeAddr('proposer'); @@ -44,6 +55,10 @@ contract IntegrationBase is Deploy, Test { // Fetch current epoch _currentEpoch = epochManager.currentEpoch(); + + // Unpause Graph Horizon + vm.prank(_governor); + _controller.setPaused(false); } function _createRequest() internal returns (bytes32 _requestId) { @@ -107,6 +122,16 @@ contract IntegrationBase is Deploy, Test { councilArbitrator.arbitrateDispute(_disputeId, _award); } + function _addChains() internal { + string[] memory _chainIds = _getChains(); + + vm.startPrank(arbitrator); + for (uint256 _i; _i < _chainIds.length; ++_i) { + eboRequestCreator.addChain(_chainIds[_i]); + } + vm.stopPrank(); + } + function _setRequestModuleData() internal { IEBORequestModule.RequestParameters memory _requestParams = _instantiateRequestParams(); @@ -135,42 +160,62 @@ contract IntegrationBase is Deploy, Test { eboRequestCreator.setResolutionModuleData(address(arbitratorModule), _resolutionParams); } - function _depositGRT() internal { + function _approveModules() internal { + vm.prank(_requester); + horizonAccountingExtension.approveModule(address(eboRequestModule)); + + vm.prank(_proposer); + horizonAccountingExtension.approveModule(address(bondedResponseModule)); + + vm.prank(_disputer); + horizonAccountingExtension.approveModule(address(bondEscalationModule)); + } + + function _stakeGRT() internal { vm.startPrank(_requester); deal(address(graphToken), _requester, paymentAmount, true); - graphToken.approve(address(bondEscalationAccounting), paymentAmount); - bondEscalationAccounting.deposit(graphToken, paymentAmount); + graphToken.approve(address(horizonStaking), paymentAmount); + horizonStaking.stake(paymentAmount); vm.startPrank(_proposer); deal(address(graphToken), _proposer, responseBondSize, true); - graphToken.approve(address(bondEscalationAccounting), responseBondSize); - bondEscalationAccounting.deposit(graphToken, responseBondSize); + graphToken.approve(address(horizonStaking), responseBondSize); + horizonStaking.stake(responseBondSize); vm.startPrank(_disputer); deal(address(graphToken), _disputer, disputeBondSize, true); - graphToken.approve(address(bondEscalationAccounting), disputeBondSize); - bondEscalationAccounting.deposit(graphToken, disputeBondSize); + graphToken.approve(address(horizonStaking), disputeBondSize); + horizonStaking.stake(disputeBondSize); vm.stopPrank(); } - function _approveModules() internal { - vm.prank(_requester); - bondEscalationAccounting.approveModule(address(eboRequestModule)); - - vm.prank(_proposer); - bondEscalationAccounting.approveModule(address(bondedResponseModule)); - - vm.prank(_disputer); - bondEscalationAccounting.approveModule(address(bondEscalationModule)); - } + function _createProvisions() internal { + vm.startPrank(_requester); + horizonStaking.provision( + _requester, + address(horizonAccountingExtension), + paymentAmount, + horizonAccountingExtension.MAX_VERIFIER_CUT(), + horizonAccountingExtension.MIN_THAWING_PERIOD() + ); - function _addChains() internal { - string[] memory _chainIds = _getChainIds(); + vm.startPrank(_proposer); + horizonStaking.provision( + _proposer, + address(horizonAccountingExtension), + responseBondSize, + horizonAccountingExtension.MAX_VERIFIER_CUT(), + horizonAccountingExtension.MIN_THAWING_PERIOD() + ); - vm.startPrank(arbitrator); - for (uint256 _i; _i < _chainIds.length; ++_i) { - eboRequestCreator.addChain(_chainIds[_i]); - } + vm.startPrank(_disputer); + horizonStaking.provision( + _disputer, + address(horizonAccountingExtension), + disputeBondSize, + horizonAccountingExtension.MAX_VERIFIER_CUT(), + horizonAccountingExtension.MIN_THAWING_PERIOD() + ); vm.stopPrank(); } @@ -190,7 +235,7 @@ contract IntegrationBase is Deploy, Test { _disputeData.requestId = _requestId; } - function _getChainIds() internal view returns (string[] memory _chainIds) { + function _getChains() internal view returns (string[] memory _chainIds) { _chainIds = new string[](1); _chainIds[0] = _chainId; } diff --git a/test/integration/arbitrum/ProposeResponse.t.sol b/test/integration/arbitrum/ProposeResponse.t.sol index 9a04dd9..92b3ea8 100644 --- a/test/integration/arbitrum/ProposeResponse.t.sol +++ b/test/integration/arbitrum/ProposeResponse.t.sol @@ -7,18 +7,21 @@ contract IntegrationProposeResponse is IntegrationBase { function setUp() public override { super.setUp(); + // Add chain IDs + _addChains(); + // Set modules data _setRequestModuleData(); _setResponseModuleData(); _setDisputeModuleData(); _setResolutionModuleData(); - // Deposit GRT and approve modules - _depositGRT(); + // Approve modules _approveModules(); - // Add chain IDs - _addChains(); + // Stake GRT and create provisions + _stakeGRT(); + _createProvisions(); } function test_ProposeResponse() public { diff --git a/test/unit/Deploy.t.sol b/test/unit/Deploy.t.sol index e7ce0df..7d0580d 100644 --- a/test/unit/Deploy.t.sol +++ b/test/unit/Deploy.t.sol @@ -30,11 +30,11 @@ import {HorizonAccountingExtension} from 'contracts/HorizonAccountingExtension.s import {Deploy} from 'script/Deploy.s.sol'; import { - _ARBITRATOR, + _ARBITRUM_SEPOLIA_ARBITRATOR, + _ARBITRUM_SEPOLIA_COUNCIL, _ARBITRUM_SEPOLIA_EPOCH_MANAGER, _ARBITRUM_SEPOLIA_GRAPH_TOKEN, _ARBITRUM_SEPOLIA_HORIZON_STAKING, - _COUNCIL, _MIN_THAWING_PERIOD } from 'script/Constants.sol'; @@ -58,8 +58,8 @@ contract UnitDeploy is Test { assertEq(address(deploy.graphToken()).code, _ARBITRUM_SEPOLIA_GRAPH_TOKEN.code); assertEq(address(deploy.horizonStaking()).code, _ARBITRUM_SEPOLIA_HORIZON_STAKING.code); assertEq(address(deploy.epochManager()).code, _ARBITRUM_SEPOLIA_EPOCH_MANAGER.code); - assertEq(address(deploy.arbitrator()), _ARBITRATOR); - assertEq(address(deploy.council()), _COUNCIL); + assertEq(address(deploy.arbitrator()), _ARBITRUM_SEPOLIA_ARBITRATOR); + assertEq(address(deploy.council()), _ARBITRUM_SEPOLIA_COUNCIL); } function test_RunRevertWhen_TheGraphAccountsAreNotSetUp() public { @@ -103,9 +103,6 @@ contract UnitDeploy is Test { // it should deploy `Oracle` assertEq(address(deploy.oracle()).code, type(Oracle).runtimeCode); - // it should deploy `Arbitrable` - assertEq(address(deploy.arbitrable()).code, type(Arbitrable).runtimeCode); - // it should deploy `EBORequestModule` with correct args EBORequestModule _eboRequestModule = new EBORequestModule(deploy.oracle(), deploy.eboRequestCreator(), deploy.arbitrable()); @@ -161,6 +158,9 @@ contract UnitDeploy is Test { assertEq(address(deploy.councilArbitrator()).code, address(_councilArbitrator).code); assertEq(address(deploy.councilArbitrator().ARBITRATOR_MODULE()), address(deploy.arbitratorModule())); assertEq(address(deploy.councilArbitrator().ARBITRABLE()), address(deploy.arbitrable())); + + // it should deploy `Arbitrable` + assertEq(address(deploy.arbitrable()).code, type(Arbitrable).runtimeCode); } function _instantiateRequestData() internal view returns (IOracle.Request memory _requestData) { diff --git a/test/unit/Deploy.tree b/test/unit/Deploy.tree index a509289..b80c1a8 100644 --- a/test/unit/Deploy.tree +++ b/test/unit/Deploy.tree @@ -10,7 +10,6 @@ UnitDeploy::run └── when precomputed address is correct ├── it should deploy all contracts using a single EOA ├── it should deploy `Oracle` - ├── it should deploy `Arbitrable` ├── it should deploy `EBORequestModule` with correct args ├── it should deploy `BondedResponseModule` with correct args ├── it should deploy `BondEscalationModule` with correct args @@ -18,4 +17,5 @@ UnitDeploy::run ├── it should deploy `EBOFinalityModule` with correct args ├── it should deploy `HorizonAccountingExtension` with correct args ├── it should deploy `EBORequestCreator` with correct args - └── it should deploy `CouncilArbitrator` with correct args + ├── it should deploy `CouncilArbitrator` with correct args + └── it should deploy `Arbitrable` From 59593a5285f1e454e2ca23c5892744bd3f8ec2b2 Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Wed, 25 Sep 2024 00:41:58 -0300 Subject: [PATCH 04/14] test: set max thawing period --- script/Constants.sol | 2 +- src/interfaces/external/IHorizonStaking.sol | 7 +++++++ test/integration/arbitrum/IntegrationBase.sol | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/script/Constants.sol b/script/Constants.sol index 515c287..f0a21ad 100644 --- a/script/Constants.sol +++ b/script/Constants.sol @@ -20,4 +20,4 @@ address constant _ARBITRUM_SEPOLIA_ARBITRATOR = address(0x100); address constant _ARBITRUM_SEPOLIA_COUNCIL = address(0x101); // Data -uint64 constant _MIN_THAWING_PERIOD = 0 days; // TODO: Increase max thawing period via HorizonStaking::setMaxThawingPeriod +uint64 constant _MIN_THAWING_PERIOD = 30 days; diff --git a/src/interfaces/external/IHorizonStaking.sol b/src/interfaces/external/IHorizonStaking.sol index e0565da..c0c51cf 100644 --- a/src/interfaces/external/IHorizonStaking.sol +++ b/src/interfaces/external/IHorizonStaking.sol @@ -9,6 +9,7 @@ interface IHorizonStaking { * @return The provision details. */ function getProvision(address serviceProvider, address verifier) external view returns (Provision memory); + /** * @notice Deposit tokens on the staking contract. * @dev Pulls tokens from the caller. @@ -114,4 +115,10 @@ interface IHorizonStaking { * @param verifierDestination The address to transfer the verifier cut to */ function slash(address serviceProvider, uint256 tokens, uint256 tokensVerifier, address verifierDestination) external; + + /** + * @notice Sets the global maximum thawing period allowed for provisions. + * @param maxThawingPeriod The new maximum thawing period, in seconds + */ + function setMaxThawingPeriod(uint64 maxThawingPeriod) external; } diff --git a/test/integration/arbitrum/IntegrationBase.sol b/test/integration/arbitrum/IntegrationBase.sol index 91d088f..0132aeb 100644 --- a/test/integration/arbitrum/IntegrationBase.sol +++ b/test/integration/arbitrum/IntegrationBase.sol @@ -56,9 +56,12 @@ contract IntegrationBase is Deploy, Test { // Fetch current epoch _currentEpoch = epochManager.currentEpoch(); + vm.startPrank(_governor); // Unpause Graph Horizon - vm.prank(_governor); _controller.setPaused(false); + // Set max thawing period + horizonStaking.setMaxThawingPeriod(_MIN_THAWING_PERIOD); + vm.stopPrank(); } function _createRequest() internal returns (bytes32 _requestId) { From 4cdbddcb15e2bbe5da79e95633ed33fc0520afca Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Wed, 25 Sep 2024 11:34:16 -0300 Subject: [PATCH 05/14] test: remove The Graph Controller --- script/Constants.sol | 4 +--- src/interfaces/external/IController.sol | 10 ---------- src/interfaces/external/IHorizonStaking.sol | 6 ------ test/integration/arbitrum/IntegrationBase.sol | 16 +++------------- 4 files changed, 4 insertions(+), 32 deletions(-) delete mode 100644 src/interfaces/external/IController.sol diff --git a/script/Constants.sol b/script/Constants.sol index f0a21ad..5ae311b 100644 --- a/script/Constants.sol +++ b/script/Constants.sol @@ -5,7 +5,6 @@ pragma solidity 0.8.26; address constant _ARBITRUM_MAINNET_GRAPH_TOKEN = 0x9623063377AD1B27544C965cCd7342f7EA7e88C7; address constant _ARBITRUM_MAINNET_HORIZON_STAKING = address(0x0); address constant _ARBITRUM_MAINNET_EPOCH_MANAGER = 0x5A843145c43d328B9bB7a4401d94918f131bB281; -address constant _ARBITRUM_MAINNET_CONTROLLER = address(0x0); address constant _ARBITRUM_MAINNET_GOVERNOR = address(0x0); address constant _ARBITRUM_MAINNET_ARBITRATOR = address(0x100); address constant _ARBITRUM_MAINNET_COUNCIL = address(0x101); @@ -14,10 +13,9 @@ 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_CONTROLLER = 0x4DbE1B10bc15D0F53fF508BE01942198262ddfCa; address constant _ARBITRUM_SEPOLIA_GOVERNOR = 0xadE6B8EB69a49B56929C1d4F4b428d791861dB6f; address constant _ARBITRUM_SEPOLIA_ARBITRATOR = address(0x100); address constant _ARBITRUM_SEPOLIA_COUNCIL = address(0x101); // Data -uint64 constant _MIN_THAWING_PERIOD = 30 days; +uint64 constant _MIN_THAWING_PERIOD = 3 days; diff --git a/src/interfaces/external/IController.sol b/src/interfaces/external/IController.sol deleted file mode 100644 index d0107c2..0000000 --- a/src/interfaces/external/IController.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.26; - -interface IController { - /*/////////////////////////////////////////////////////////////// - FUNCTIONS - //////////////////////////////////////////////////////////////*/ - - function setPaused(bool _paused) external; -} diff --git a/src/interfaces/external/IHorizonStaking.sol b/src/interfaces/external/IHorizonStaking.sol index c0c51cf..82af34f 100644 --- a/src/interfaces/external/IHorizonStaking.sol +++ b/src/interfaces/external/IHorizonStaking.sol @@ -115,10 +115,4 @@ interface IHorizonStaking { * @param verifierDestination The address to transfer the verifier cut to */ function slash(address serviceProvider, uint256 tokens, uint256 tokensVerifier, address verifierDestination) external; - - /** - * @notice Sets the global maximum thawing period allowed for provisions. - * @param maxThawingPeriod The new maximum thawing period, in seconds - */ - function setMaxThawingPeriod(uint64 maxThawingPeriod) external; } diff --git a/test/integration/arbitrum/IntegrationBase.sol b/test/integration/arbitrum/IntegrationBase.sol index 0132aeb..23cbdc4 100644 --- a/test/integration/arbitrum/IntegrationBase.sol +++ b/test/integration/arbitrum/IntegrationBase.sol @@ -2,9 +2,8 @@ pragma solidity 0.8.26; import {ValidatorLib} from '@defi-wonderland/prophet-core/solidity/libraries/ValidatorLib.sol'; -import {IController} from 'interfaces/external/IController.sol'; -import {_ARBITRUM_SEPOLIA_CONTROLLER, _ARBITRUM_SEPOLIA_GOVERNOR} from 'script/Constants.sol'; +import {_ARBITRUM_SEPOLIA_GOVERNOR} from 'script/Constants.sol'; import 'script/Deploy.s.sol'; @@ -16,11 +15,10 @@ contract IntegrationBase is Deploy, Test { using ValidatorLib for IOracle.Dispute; uint256 internal constant _ARBITRUM_MAINNET_FORK_BLOCK = 240_000_000; - uint256 internal constant _ARBITRUM_SEPOLIA_FORK_BLOCK = 83_000_000; + uint256 internal constant _ARBITRUM_SEPOLIA_FORK_BLOCK = 83_750_000; // The Graph - IController internal _controller; - address internal _governor; + address internal _governor; // TODO: Remove if unused // Users address internal _requester; @@ -42,7 +40,6 @@ contract IntegrationBase is Deploy, Test { run(); // Define The Graph accounts - _controller = IController(_ARBITRUM_SEPOLIA_CONTROLLER); _governor = _ARBITRUM_SEPOLIA_GOVERNOR; // Set user accounts @@ -55,13 +52,6 @@ contract IntegrationBase is Deploy, Test { // Fetch current epoch _currentEpoch = epochManager.currentEpoch(); - - vm.startPrank(_governor); - // Unpause Graph Horizon - _controller.setPaused(false); - // Set max thawing period - horizonStaking.setMaxThawingPeriod(_MIN_THAWING_PERIOD); - vm.stopPrank(); } function _createRequest() internal returns (bytes32 _requestId) { From af0a946b774843229758f3f8335671ee20305feb Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Wed, 25 Sep 2024 17:14:00 -0300 Subject: [PATCH 06/14] fix: conform with IAccountingExtension interface --- src/contracts/HorizonAccountingExtension.sol | 5 ++ .../IHorizonAccountingExtension.sol | 27 +++++++--- test/unit/HorizonAccountingExtension.t.sol | 50 +++++++++---------- 3 files changed, 50 insertions(+), 32 deletions(-) diff --git a/src/contracts/HorizonAccountingExtension.sol b/src/contracts/HorizonAccountingExtension.sol index 10a4bfb..6e547f0 100644 --- a/src/contracts/HorizonAccountingExtension.sol +++ b/src/contracts/HorizonAccountingExtension.sol @@ -264,6 +264,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { bytes32 _requestId, address _payer, address _receiver, + IERC20, /* _token */ uint256 _amount ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _payer) onlyParticipant(_requestId, _receiver) { // Discount the payer bondedForRequest @@ -283,6 +284,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { function bond( address _bonder, bytes32 _requestId, + IERC20, /* _token */ uint256 _amount ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _bonder) { if (!_approvals[_bonder].contains(msg.sender)) revert HorizonAccountingExtension_NotAllowed(); @@ -294,9 +296,11 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { emit Bonded(_requestId, _bonder, _amount); } + /// @inheritdoc IHorizonAccountingExtension function bond( address _bonder, bytes32 _requestId, + IERC20, /* _token */ uint256 _amount, address _sender ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _bonder) { @@ -318,6 +322,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { function release( address _bonder, bytes32 _requestId, + IERC20, /* _token */ uint256 _amount ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _bonder) { // TODO: Release is used to pay the user the rewards for proposing or returning the funds to the diff --git a/src/interfaces/IHorizonAccountingExtension.sol b/src/interfaces/IHorizonAccountingExtension.sol index 598fce7..e87de16 100644 --- a/src/interfaces/IHorizonAccountingExtension.sol +++ b/src/interfaces/IHorizonAccountingExtension.sol @@ -338,23 +338,36 @@ interface IHorizonAccountingExtension is IValidator { * @param _requestId The id of the request handling the user's tokens * @param _payer The address of the user paying the tokens * @param _receiver The address of the user receiving the tokens - * @param _amount The amount of GRT being transferred + * @param _token The address of the token being transferred + * @param _amount The amount of `_token` being transferred */ - function pay(bytes32 _requestId, address _payer, address _receiver, uint256 _amount) external; + function pay(bytes32 _requestId, address _payer, address _receiver, IERC20 _token, uint256 _amount) external; /** - * @notice Allows a allowed module to bond a user's tokens for a request + * @notice Allows an allowed module to bond a user's tokens for a request * @param _bonder The address of the user to bond tokens for * @param _requestId The id of the request the user is bonding for - * @param _amount The amount of GRT to bond + * @param _token The address of the token being bonded + * @param _amount The amount of `_token` to bond */ - function bond(address _bonder, bytes32 _requestId, uint256 _amount) external; + function bond(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount) external; + + /** + * @notice Allows a valid module to bond a user's tokens for a request + * @param _bonder The address of the user to bond tokens for + * @param _requestId The id of the request the user is bonding for + * @param _token The address of the token being bonded + * @param _amount The amount of `_token` to bond + * @param _sender The address starting the propose call on the Oracle + */ + function bond(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount, address _sender) external; /** * @notice Allows a valid module to release a user's tokens * @param _bonder The address of the user to release tokens for * @param _requestId The id of the request where the tokens were bonded - * @param _amount The amount of GRT to release + * @param _token The address of the token being released + * @param _amount The amount of `_token` to release */ - function release(address _bonder, bytes32 _requestId, uint256 _amount) external; + function release(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount) external; } diff --git a/test/unit/HorizonAccountingExtension.t.sol b/test/unit/HorizonAccountingExtension.t.sol index 7b85601..f5263b7 100644 --- a/test/unit/HorizonAccountingExtension.t.sol +++ b/test/unit/HorizonAccountingExtension.t.sol @@ -915,7 +915,7 @@ contract HorizonAccountingExtension_Unit_Pay is HorizonAccountingExtension_Unit_ // Check: does it revert if the module is not allowed? vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedModule.selector); - horizonAccountingExtension.pay(_requestId, _payer, _receiver, _amount); + horizonAccountingExtension.pay(_requestId, _payer, _receiver, grt, _amount); } function test_revertIfUnauthorizedUserPayer( @@ -934,7 +934,7 @@ contract HorizonAccountingExtension_Unit_Pay is HorizonAccountingExtension_Unit_ // Check: does it revert if the module is not allowed? vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedUser.selector); - horizonAccountingExtension.pay(_requestId, _payer, _receiver, _amount); + horizonAccountingExtension.pay(_requestId, _payer, _receiver, grt, _amount); } function test_revertIfUnauthorizedUserReceiver( @@ -956,7 +956,7 @@ contract HorizonAccountingExtension_Unit_Pay is HorizonAccountingExtension_Unit_ // Check: does it revert if the module is not allowed? vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedUser.selector); - horizonAccountingExtension.pay(_requestId, _payer, _receiver, _amount); + horizonAccountingExtension.pay(_requestId, _payer, _receiver, grt, _amount); } function test_successfulCall( @@ -988,7 +988,7 @@ contract HorizonAccountingExtension_Unit_Pay is HorizonAccountingExtension_Unit_ vm.expectEmit(); emit Paid(_requestId, _receiver, _payer, _amount); - horizonAccountingExtension.pay(_requestId, _payer, _receiver, _amount); + horizonAccountingExtension.pay(_requestId, _payer, _receiver, grt, _amount); uint256 _bondedAfter = horizonAccountingExtension.bondedForRequest(_payer, _requestId); uint256 _totalBondedAfter = horizonAccountingExtension.totalBonded(_payer); @@ -1028,7 +1028,7 @@ contract HorizonAccountingExtension_Unit_Bond is HorizonAccountingExtension_Unit // Check: does it revert if the module is not allowed? vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedModule.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount); } function test_revertIfUnauthorizedUser(address _bonder, bytes32 _requestId, uint256 _amount) public { @@ -1042,7 +1042,7 @@ contract HorizonAccountingExtension_Unit_Bond is HorizonAccountingExtension_Unit // Check: does it revert if the module is not allowed? vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedUser.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount); } function test_revertIfNotAllowed(address _bonder, bytes32 _requestId, uint256 _amount) public { @@ -1055,7 +1055,7 @@ contract HorizonAccountingExtension_Unit_Bond is HorizonAccountingExtension_Unit vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_NotAllowed.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount); } function test_revertIfInvalidMaxVerifierCut( @@ -1073,7 +1073,7 @@ contract HorizonAccountingExtension_Unit_Bond is HorizonAccountingExtension_Unit vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InvalidMaxVerifierCut.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount); } function test_revertIfInvalidThawingPeriod( @@ -1091,7 +1091,7 @@ contract HorizonAccountingExtension_Unit_Bond is HorizonAccountingExtension_Unit vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InvalidThawingPeriod.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount); } function test_revertIfInsufficientTokens( @@ -1108,7 +1108,7 @@ contract HorizonAccountingExtension_Unit_Bond is HorizonAccountingExtension_Unit ); vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientTokens.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount); } function test_revertIfInsufficientBondedTokens( @@ -1126,7 +1126,7 @@ contract HorizonAccountingExtension_Unit_Bond is HorizonAccountingExtension_Unit vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientBondedTokens.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount); } function test_successfulCall( @@ -1143,7 +1143,7 @@ contract HorizonAccountingExtension_Unit_Bond is HorizonAccountingExtension_Unit vm.expectEmit(); emit Bonded(_requestId, _bonder, _amount); - horizonAccountingExtension.bond(_bonder, _requestId, _amount); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount); uint256 _bondedForRequestAfter = horizonAccountingExtension.bondedForRequest(_bonder, _requestId); uint256 _totalBondedAfter = horizonAccountingExtension.totalBonded(_bonder); @@ -1184,7 +1184,7 @@ contract HorizonAccountingExtension_Unit_BondSender is HorizonAccountingExtensio // Check: does it revert if the module is not allowed? vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedModule.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount, _sender); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount, _sender); } function test_revertIfUnauthorizedUser(address _bonder, bytes32 _requestId, uint256 _amount, address _sender) public { @@ -1198,7 +1198,7 @@ contract HorizonAccountingExtension_Unit_BondSender is HorizonAccountingExtensio // Check: does it revert if the module is not allowed? vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedUser.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount, _sender); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount, _sender); } function test_revertIfNotAllowedModule(address _bonder, bytes32 _requestId, uint256 _amount, address _sender) public { @@ -1215,7 +1215,7 @@ contract HorizonAccountingExtension_Unit_BondSender is HorizonAccountingExtensio vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_NotAllowed.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount, _sender); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount, _sender); } function test_revertIfNotAllowedSender(address _bonder, bytes32 _requestId, uint256 _amount, address _sender) public { @@ -1232,7 +1232,7 @@ contract HorizonAccountingExtension_Unit_BondSender is HorizonAccountingExtensio vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_NotAllowed.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount, _sender); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount, _sender); } function test_revertIfInvalidMaxVerifierCut( @@ -1251,7 +1251,7 @@ contract HorizonAccountingExtension_Unit_BondSender is HorizonAccountingExtensio vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InvalidMaxVerifierCut.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount, _sender); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount, _sender); } function test_revertIfInvalidThawingPeriod( @@ -1270,7 +1270,7 @@ contract HorizonAccountingExtension_Unit_BondSender is HorizonAccountingExtensio vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InvalidThawingPeriod.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount, _sender); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount, _sender); } function test_revertIfInsufficientTokens( @@ -1288,7 +1288,7 @@ contract HorizonAccountingExtension_Unit_BondSender is HorizonAccountingExtensio ); vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientTokens.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount, _sender); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount, _sender); } function test_revertIfInsufficientBondedTokens( @@ -1307,7 +1307,7 @@ contract HorizonAccountingExtension_Unit_BondSender is HorizonAccountingExtensio vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientBondedTokens.selector); - horizonAccountingExtension.bond(_bonder, _requestId, _amount, _sender); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount, _sender); } function test_successfulCall( @@ -1325,7 +1325,7 @@ contract HorizonAccountingExtension_Unit_BondSender is HorizonAccountingExtensio vm.expectEmit(); emit Bonded(_requestId, _bonder, _amount); - horizonAccountingExtension.bond(_bonder, _requestId, _amount, _sender); + horizonAccountingExtension.bond(_bonder, _requestId, grt, _amount, _sender); uint256 _bondedForRequestAfter = horizonAccountingExtension.bondedForRequest(_bonder, _requestId); uint256 _totalBondedAfter = horizonAccountingExtension.totalBonded(_bonder); @@ -1358,7 +1358,7 @@ contract HorizonAccountingExtension_Unit_Release is HorizonAccountingExtension_U // Check: does it revert if the module is not allowed? vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedModule.selector); - horizonAccountingExtension.release(_bonder, _requestId, _amount); + horizonAccountingExtension.release(_bonder, _requestId, grt, _amount); } function test_revertIfUnauthorizedUser(address _bonder, bytes32 _requestId, uint256 _amount) public { @@ -1372,7 +1372,7 @@ contract HorizonAccountingExtension_Unit_Release is HorizonAccountingExtension_U // Check: does it revert if the module is not allowed? vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedUser.selector); - horizonAccountingExtension.release(_bonder, _requestId, _amount); + horizonAccountingExtension.release(_bonder, _requestId, grt, _amount); } function test_revertIfInsufficientBondedTokens( @@ -1384,7 +1384,7 @@ contract HorizonAccountingExtension_Unit_Release is HorizonAccountingExtension_U vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientBondedTokens.selector); - horizonAccountingExtension.release(_bonder, _requestId, _amount); + horizonAccountingExtension.release(_bonder, _requestId, grt, _amount); } function test_successfulCall( @@ -1397,7 +1397,7 @@ contract HorizonAccountingExtension_Unit_Release is HorizonAccountingExtension_U vm.expectEmit(); emit Released(_requestId, _bonder, _amount); - horizonAccountingExtension.release(_bonder, _requestId, _amount); + horizonAccountingExtension.release(_bonder, _requestId, grt, _amount); uint256 _bondedForRequestAfter = horizonAccountingExtension.bondedForRequest(_bonder, _requestId); uint256 _totalBondedAfter = horizonAccountingExtension.totalBonded(_bonder); From 845f0a36c03e3707f69ffd9691446a8d30c07a74 Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Wed, 25 Sep 2024 18:19:57 -0300 Subject: [PATCH 07/14] test: integrate HorizonAccountingExtension --- script/Deploy.s.sol | 5 +-- .../arbitrum/ArbitrateDispute.t.sol | 45 ++++++++++++------- .../arbitrum/DisputeResponse.t.sol | 6 +-- .../arbitrum/ProposeResponse.t.sol | 6 +-- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index b0c4f34..9ea22f7 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -55,7 +55,6 @@ contract Deploy is Script { IEBOFinalityModule public eboFinalityModule; // Extensions - IBondEscalationAccounting public bondEscalationAccounting; IHorizonAccountingExtension public horizonAccountingExtension; // Periphery @@ -94,12 +93,12 @@ contract Deploy is Script { // TODO: Set production request module params paymentAmount = 0.1 ether; - // TODO: Set production response module params + // TODO: Set production response module params (responseBondSize == disputeBondSize) responseBondSize = 0.5 ether; responseDeadline = block.timestamp + 5 days; responseDisputeWindow = block.timestamp + 1 weeks; - // TODO: Set production dispute module params + // TODO: Set production dispute module params (disputeBondSize == responseBondSize) disputeBondSize = 0.3 ether; maxNumberOfEscalations = 1; disputeDeadline = block.timestamp + 10 days; diff --git a/test/integration/arbitrum/ArbitrateDispute.t.sol b/test/integration/arbitrum/ArbitrateDispute.t.sol index e6595c3..be472fb 100644 --- a/test/integration/arbitrum/ArbitrateDispute.t.sol +++ b/test/integration/arbitrum/ArbitrateDispute.t.sol @@ -74,14 +74,18 @@ contract IntegrationArbitrateDispute is IntegrationBase { IBondEscalationModule.BondEscalation memory _escalation = bondEscalationModule.getEscalation(_requestId); assertEq(_escalation.disputeId, _disputeId); assertEq(uint8(_escalation.status), uint8(IBondEscalationModule.BondEscalationStatus.DisputerWon)); - // Assert BondEscalationAccounting::pay - assertEq( - bondEscalationAccounting.bondedAmountOf(_proposer, graphToken, _requestId), responseBondSize - disputeBondSize - ); - assertEq(bondEscalationAccounting.balanceOf(_proposer, graphToken), 0); - // Assert BondEscalationAccounting::release - assertEq(bondEscalationAccounting.bondedAmountOf(_disputer, graphToken, _requestId), 0); - assertEq(bondEscalationAccounting.balanceOf(_disputer, graphToken), disputeBondSize * 2); + // Assert HorizonAccountingExtension::pay + assertEq(horizonAccountingExtension.bondedForRequest(_proposer, _requestId), responseBondSize - disputeBondSize); + assertEq(horizonAccountingExtension.totalBonded(_proposer), responseBondSize - disputeBondSize); + // Assert HorizonStaking::slash + IHorizonStaking.Provision memory _provision = + horizonStaking.getProvision(_proposer, address(horizonAccountingExtension)); + assertEq(_provision.tokens, responseBondSize - disputeBondSize); + // Assert GraphToken::transfer + assertEq(graphToken.balanceOf(_disputer), disputeBondSize); + // Assert HorizonAccountingExtension::release + assertEq(horizonAccountingExtension.bondedForRequest(_disputer, _requestId), 0); + assertEq(horizonAccountingExtension.totalBonded(_disputer), 0); // Assert Oracle::finalize assertEq(oracle.finalizedAt(_requestId), block.number); assertEq(oracle.finalizedResponseId(_requestId), 0); @@ -152,15 +156,21 @@ contract IntegrationArbitrateDispute is IntegrationBase { IBondEscalationModule.BondEscalation memory _escalation = bondEscalationModule.getEscalation(_requestId); assertEq(_escalation.disputeId, _disputeId); assertEq(uint8(_escalation.status), uint8(IBondEscalationModule.BondEscalationStatus.DisputerLost)); - // Assert BondEscalationAccounting::pay - assertEq(bondEscalationAccounting.bondedAmountOf(_disputer, graphToken, _requestId), 0); - assertEq(bondEscalationAccounting.balanceOf(_disputer, graphToken), 0); + // Assert HorizonAccountingExtension::pay + assertEq(horizonAccountingExtension.bondedForRequest(_disputer, _requestId), 0); + assertEq(horizonAccountingExtension.totalBonded(_disputer), 0); + // Assert HorizonStaking::slash + IHorizonStaking.Provision memory _provision = + horizonStaking.getProvision(_disputer, address(horizonAccountingExtension)); + assertEq(_provision.tokens, 0); + // Assert GraphToken::transfer + assertEq(graphToken.balanceOf(_proposer), disputeBondSize); // Assert Oracle::finalize assertEq(oracle.finalizedAt(_requestId), block.number); assertEq(oracle.finalizedResponseId(_requestId), _responseId); - // Assert BondEscalationAccounting::release - assertEq(bondEscalationAccounting.bondedAmountOf(_proposer, graphToken, _requestId), 0); - assertEq(bondEscalationAccounting.balanceOf(_proposer, graphToken), responseBondSize + disputeBondSize); + // Assert HorizonAccountingExtension::release + assertEq(horizonAccountingExtension.bondedForRequest(_proposer, _requestId), 0); + assertEq(horizonAccountingExtension.totalBonded(_proposer), 0); // Revert if the dispute has already been arbitrated vm.expectRevert(ICouncilArbitrator.CouncilArbitrator_DisputeAlreadyArbitrated.selector); @@ -221,9 +231,10 @@ contract IntegrationArbitrateDispute is IntegrationBase { IBondEscalationModule.BondEscalation memory _escalation = bondEscalationModule.getEscalation(_requestId); assertEq(_escalation.disputeId, _disputeId); assertEq(uint8(_escalation.status), uint8(IBondEscalationModule.BondEscalationStatus.Escalated)); - // Assert BondEscalationAccounting::release - assertEq(bondEscalationAccounting.bondedAmountOf(_disputer, graphToken, _requestId), 0); - assertEq(bondEscalationAccounting.balanceOf(_disputer, graphToken), disputeBondSize); + // Assert HorizonAccountingExtension::release + assertEq(horizonAccountingExtension.bondedForRequest(_disputer, _requestId), 0); + assertEq(horizonAccountingExtension.totalBonded(_disputer), 0); + // TODO: Why isn't proposer's bond released? // Assert Oracle::finalize assertEq(oracle.finalizedAt(_requestId), block.number); assertEq(oracle.finalizedResponseId(_requestId), 0); diff --git a/test/integration/arbitrum/DisputeResponse.t.sol b/test/integration/arbitrum/DisputeResponse.t.sol index 26ff74f..e8eb4f9 100644 --- a/test/integration/arbitrum/DisputeResponse.t.sol +++ b/test/integration/arbitrum/DisputeResponse.t.sol @@ -61,9 +61,9 @@ contract IntegrationDisputeResponse is IntegrationBase { IBondEscalationModule.BondEscalation memory _escalation = bondEscalationModule.getEscalation(_requestId); assertEq(_escalation.disputeId, _disputeId); assertEq(uint8(_escalation.status), uint8(IBondEscalationModule.BondEscalationStatus.Active)); - // Assert BondEscalationAccounting::bond - assertEq(bondEscalationAccounting.bondedAmountOf(_disputer, graphToken, _requestId), disputeBondSize); - assertEq(bondEscalationAccounting.balanceOf(_disputer, graphToken), 0); + // Assert HorizonAccountingExtension::bond + assertEq(horizonAccountingExtension.bondedForRequest(_disputer, _requestId), disputeBondSize); + assertEq(horizonAccountingExtension.totalBonded(_disputer), disputeBondSize); // Revert if the response has already been disputed vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_ResponseAlreadyDisputed.selector, _responseId)); diff --git a/test/integration/arbitrum/ProposeResponse.t.sol b/test/integration/arbitrum/ProposeResponse.t.sol index 92b3ea8..948cd9b 100644 --- a/test/integration/arbitrum/ProposeResponse.t.sol +++ b/test/integration/arbitrum/ProposeResponse.t.sol @@ -43,9 +43,9 @@ contract IntegrationProposeResponse is IntegrationBase { // Assert Oracle::proposeResponse assertEq(oracle.responseCreatedAt(_responseId), block.number); - // Assert BondEscalationAccounting::bond - assertEq(bondEscalationAccounting.bondedAmountOf(_proposer, graphToken, _requestId), responseBondSize); - assertEq(bondEscalationAccounting.balanceOf(_proposer, graphToken), 0); + // Assert HorizonAccountingExtension::bond + assertEq(horizonAccountingExtension.bondedForRequest(_proposer, _requestId), responseBondSize); + assertEq(horizonAccountingExtension.totalBonded(_proposer), responseBondSize); // Revert if the response has already been proposed vm.expectRevert(IOracle.Oracle_InvalidResponseBody.selector); From cec6226ca37bbecb36c5aa1e503b426803e62a95 Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Thu, 3 Oct 2024 15:26:00 -0300 Subject: [PATCH 08/14] feat: instantiate authorized callers in deployment script --- package.json | 2 +- script/Deploy.s.sol | 9 ++++++++- test/unit/Deploy.t.sol | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index e9a8f7f..4b6a1ac 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "build": "forge build", "build:optimized": "FOUNDRY_PROFILE=optimized forge build", "coverage": "forge coverage --report summary --report lcov --match-path 'test/unit/*'", - "deploy:arbitrum": "bash -c 'source .env && forge script Deploy --rpc-url $ARBITRUM_RPC --account $ARBITRUM_DEPLOYER_NAME --broadcast --verify --chain arbitrum -vvvvv'", + "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", "lint:natspec": "npx @defi-wonderland/natspec-smells --config natspec-smells.config.js", diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 9a5b23d..cfd03e8 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -142,7 +142,9 @@ contract Deploy is Script { console.log('`EBOFinalityModule` deployed at:', address(eboFinalityModule)); // Deploy `HorizonAccountingExtension` - horizonAccountingExtension = new HorizonAccountingExtension(horizonStaking, oracle, graphToken, _MIN_THAWING_PERIOD); + address[] memory _authorizedCallers = _instantiateAuthorizedCallers(); + horizonAccountingExtension = + new HorizonAccountingExtension(horizonStaking, oracle, graphToken, _MIN_THAWING_PERIOD, _authorizedCallers); console.log('`HorizonAccountingExtension` deployed at:', address(horizonAccountingExtension)); // Deploy `CouncilArbitrator` @@ -226,6 +228,11 @@ contract Deploy is Script { _resolutionParams.arbitrator = address(councilArbitrator); } + function _instantiateAuthorizedCallers() internal view returns (address[] memory _authorizedCallers) { + _authorizedCallers = new address[](1); + _authorizedCallers[0] = address(bondEscalationModule); + } + function _precomputeCreateAddress(uint256 _deploymentOffset) internal view virtual returns (address _targetAddress) { // Get nonce for the target deployment uint256 _targetNonce = vm.getNonce(tx.origin) + _deploymentOffset; diff --git a/test/unit/Deploy.t.sol b/test/unit/Deploy.t.sol index 641e508..aca28f2 100644 --- a/test/unit/Deploy.t.sol +++ b/test/unit/Deploy.t.sol @@ -135,13 +135,18 @@ contract UnitDeploy is Test { assertEq(address(deploy.eboFinalityModule().ARBITRABLE()), address(deploy.arbitrable())); // it should deploy `HorizonAccountingExtension` with correct args - HorizonAccountingExtension _horizonAccountingExtension = - new HorizonAccountingExtension(deploy.horizonStaking(), deploy.oracle(), deploy.graphToken(), _MIN_THAWING_PERIOD); + address[] memory _authorizedCallers = _instantiateAuthorizedCallers(); + HorizonAccountingExtension _horizonAccountingExtension = new HorizonAccountingExtension( + deploy.horizonStaking(), deploy.oracle(), deploy.graphToken(), _MIN_THAWING_PERIOD, _authorizedCallers + ); assertEq(address(deploy.horizonAccountingExtension()).code, address(_horizonAccountingExtension).code); assertEq(address(deploy.horizonAccountingExtension().HORIZON_STAKING()), address(deploy.horizonStaking())); assertEq(address(deploy.horizonAccountingExtension().ORACLE()), address(deploy.oracle())); assertEq(address(deploy.horizonAccountingExtension().GRT()), address(deploy.graphToken())); assertEq(deploy.horizonAccountingExtension().MIN_THAWING_PERIOD(), _MIN_THAWING_PERIOD); + for (uint256 _i; _i < _authorizedCallers.length; ++_i) { + assertTrue(deploy.horizonAccountingExtension().authorizedCallers(_authorizedCallers[_i])); + } // it should deploy `EBORequestCreator` with correct args IOracle.Request memory _requestData = _instantiateRequestData(); @@ -225,6 +230,11 @@ contract UnitDeploy is Test { { _resolutionParams.arbitrator = address(deploy.councilArbitrator()); } + + function _instantiateAuthorizedCallers() internal view returns (address[] memory _authorizedCallers) { + _authorizedCallers = new address[](1); + _authorizedCallers[0] = address(deploy.bondEscalationModule()); + } } contract MockDeploy is Deploy { From a79426ecc485ba3cab51b0c84c2791ad1dc103fd Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Thu, 3 Oct 2024 16:57:10 -0300 Subject: [PATCH 09/14] test: integrate HorizonAccountingExtension with bond escalation --- src/contracts/HorizonAccountingExtension.sol | 46 ++-- .../IHorizonAccountingExtension.sol | 62 ++++-- .../arbitrum/ArbitrateDispute.t.sol | 65 +++--- .../integration/arbitrum/BondEscalation.t.sol | 199 +++++++++++------- test/integration/arbitrum/IntegrationBase.sol | 26 ++- test/unit/HorizonAccountingExtension.t.sol | 78 ++----- 6 files changed, 274 insertions(+), 202 deletions(-) diff --git a/src/contracts/HorizonAccountingExtension.sol b/src/contracts/HorizonAccountingExtension.sol index f8957a0..3b59df8 100644 --- a/src/contracts/HorizonAccountingExtension.sol +++ b/src/contracts/HorizonAccountingExtension.sol @@ -115,11 +115,6 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { _; } - /// @inheritdoc IHorizonAccountingExtension - function approvedModules(address _user) external view returns (address[] memory _approvedModules) { - _approvedModules = _approvals[_user].values(); - } - /// @inheritdoc IHorizonAccountingExtension function approveModule(address _module) external { _approvals[msg.sender].add(_module); @@ -135,6 +130,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { address _pledger, IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, + IERC20, /* _token */ uint256 _amount ) external onlyAuthorizedCaller { bytes32 _requestId = _getId(_request); @@ -155,6 +151,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { function onSettleBondEscalation( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, + IERC20, /* _token */ uint256 _amountPerPledger, uint256 _winningPledgersLength ) external onlyAuthorizedCaller { @@ -176,7 +173,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { escalationResults[_disputeId] = EscalationResult({ requestId: _requestId, amountPerPledger: _amountPerPledger, - bondSize: _bondEscalationModule.decodeRequestData(_request.requestModuleData).bondSize, + bondSize: _bondEscalationModule.decodeRequestData(_request.disputeModuleData).bondSize, bondEscalationModule: _bondEscalationModule }); @@ -218,32 +215,32 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { ? _result.bondEscalationModule.pledgesForDispute(_requestId, _pledger) : _result.bondEscalationModule.pledgesAgainstDispute(_requestId, _pledger); - // Release the winning pledges to the user _pledgeAmount = _result.bondSize * _numberOfPledges; - _claimAmount = _amountPerPledger * _numberOfPledges; + _rewardAmount = _claimAmount - _pledgeAmount; // Check the balance in the contract // If not enough balance, slash some users to get enough balance - uint256 _balance = GRT.balanceOf(address(this)); + uint256 _balance = GRT.balanceOf(address(this)); // TODO: What if the balance is enough by means other than slashing? // TODO: How many iterations should we do? - while (_balance < _claimAmount) { + while (_balance < _rewardAmount) { _balance += _slash(_disputeId, 1, MAX_USERS_TO_CHECK, _result, _status); } - _rewardAmount = _claimAmount - _pledgeAmount; - // Send the user the amount they won by participating in the dispute GRT.safeTransfer(_pledger, _rewardAmount); } + // Release the winning pledges to the user _unbond(_pledger, _pledgeAmount); pledgerClaimed[_requestId][_pledger] = true; pledges[_disputeId] -= _claimAmount; + // TODO: Delete _pledgers[_disputeId] if pledges[_disputeId] == 0 + emit EscalationRewardClaimed({ _requestId: _requestId, _disputeId: _disputeId, @@ -253,11 +250,13 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { }); } + // TODO: Remove /// @inheritdoc IHorizonAccountingExtension function releasePledge( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, address _pledger, + IERC20, /* _token */ uint256 _amount ) external onlyAuthorizedCaller { bytes32 _requestId = _getId(_request); @@ -368,6 +367,22 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { _slash(_disputeId, _usersToSlash, _maxUsersToCheck, _result, _status); } + /// @inheritdoc IHorizonAccountingExtension + function getEscalationResult(bytes32 _disputeId) external view returns (EscalationResult memory _escalationResult) { + _escalationResult = escalationResults[_disputeId]; + } + + /// @inheritdoc IHorizonAccountingExtension + function approvedModules(address _user) external view returns (address[] memory _approvedModules) { + _approvedModules = _approvals[_user].values(); + } + + // TODO: Remove if unwanted + /// @inheritdoc IHorizonAccountingExtension + function getPledgers(bytes32 _disputeId) external view returns (address[] memory __pledgers) { + __pledgers = _pledgers[_disputeId].values(); + } + /** * @notice Slash the users that have pledged for a dispute. * @param _disputeId The dispute id. @@ -393,7 +408,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { _maxUsersToCheck = _maxUsersToCheck > _length ? _length : _maxUsersToCheck; - for (uint256 _i; _i < _maxUsersToCheck && _slashedUsers < _usersToSlash; _i++) { + for (uint256 _i; _i < _maxUsersToCheck && _slashedUsers < _usersToSlash; ++_i) { _user = _users.at(0); // Check if the user is actually slashable @@ -401,10 +416,13 @@ 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()`)? + + // TODO: Unbond slashed pledgers _slashedAmount += _slashAmount; - _slashedUsers++; + ++_slashedUsers; } // Remove the user from the list of users diff --git a/src/interfaces/IHorizonAccountingExtension.sol b/src/interfaces/IHorizonAccountingExtension.sol index 780929e..aa8caa6 100644 --- a/src/interfaces/IHorizonAccountingExtension.sol +++ b/src/interfaces/IHorizonAccountingExtension.sol @@ -227,22 +227,22 @@ interface IHorizonAccountingExtension is IValidator { /** * @notice The bound amount of tokens for a user in a request * @param _user The user address - * @param _requestId The request Id + * @param _requestId The ID of the request * @return _amount The amount of tokens bonded */ function bondedForRequest(address _user, bytes32 _requestId) external view returns (uint256 _amount); /** * @notice The total pledged tokens for a user - * @param _disputeId The dispute Id + * @param _disputeId The ID of the dispute * @return _amount The total pledged tokens for a user */ function pledges(bytes32 _disputeId) external view returns (uint256 _amount); /** - * @notice The escalation result of a request - * @param _disputeId The dispute Id - * @return _requestId The request Id + * @notice The escalation result of a dispute + * @param _disputeId The ID of the dispute + * @return _requestId The ID of the request * @return _amountPerPledger The amount of token paid to each of the winning pledgers * @return _bondSize The size of the bond required for bond escalation * @return _bondEscalationModule The address of the bond escalation module that was used @@ -257,14 +257,29 @@ interface IHorizonAccountingExtension is IValidator { IBondEscalationModule _bondEscalationModule ); + /** + * @notice The escalation result of a dispute + * @param _disputeId The ID of the dispute + * @return _escalationResult The escalation result + */ + function getEscalationResult(bytes32 _disputeId) external view returns (EscalationResult memory _escalationResult); + /** * @notice The claim status of a user for a pledge - * @param _requestId The request Id + * @param _requestId The ID of the request * @param _pledger The user address * @return _claimed True if the user claimed their pledge */ function pledgerClaimed(bytes32 _requestId, address _pledger) external view returns (bool _claimed); + /** + * @notice Checks whether an address is an authorized caller + * + * @param _caller The address to check + * @return _authorized True if the address is authorized, false otherwise + */ + function authorizedCallers(address _caller) external returns (bool _authorized); + /** * @notice Returns the approved modules for bonding tokens * @param _user The address of the user @@ -273,12 +288,11 @@ interface IHorizonAccountingExtension is IValidator { function approvedModules(address _user) external view returns (address[] memory _approvedModules); /** - * @notice Checks whether an address is an authorized caller. - * - * @param _caller The address to check - * @return _authorized True if the address is authorized, false otherwise + * @notice Returns the pledgers for a dispute + * @param _disputeId The ID of the dispute + * @return _pledgers The pledgers for the dispute */ - function authorizedCallers(address _caller) external returns (bool _authorized); + function getPledgers(bytes32 _disputeId) external view returns (address[] memory _pledgers); /*/////////////////////////////////////////////////////////////// LOGIC @@ -297,16 +311,18 @@ interface IHorizonAccountingExtension is IValidator { function revokeModule(address _module) external; /** - * @notice Pledges the given amount of token to the provided dispute id of the provided request id + * @notice Pledges the given amount of token to the provided dispute ID of the provided request ID * @param _pledger Address of the pledger * @param _request The bond-escalated request * @param _dispute The bond-escalated dispute - * @param _amount Amount of token to pledge + * @param _token Address of the token being paid as a reward for winning the bond escalation + * @param _amount Amount of GRT to pledge */ function pledge( address _pledger, IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, + IERC20 _token, uint256 _amount ) external; @@ -315,12 +331,14 @@ interface IHorizonAccountingExtension is IValidator { * @notice Updates the accounting of the given dispute to reflect the result of the bond escalation * @param _request The bond-escalated request * @param _dispute The bond-escalated dispute + * @param _token Address of the token being paid as a reward for winning the bond escalation * @param _amountPerPledger Amount of GRT to be rewarded to each of the winning pledgers * @param _winningPledgersLength Amount of pledges that won the dispute */ function onSettleBondEscalation( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, + IERC20 _token, uint256 _amountPerPledger, uint256 _winningPledgersLength ) external; @@ -337,40 +355,42 @@ interface IHorizonAccountingExtension is IValidator { * @param _request The bond-escalated request * @param _dispute The bond-escalated dispute * @param _pledger Address of the pledger + * @param _token Address of the token to be released * @param _amount Amount of GRT to be released to the pledger */ function releasePledge( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, address _pledger, + IERC20 _token, uint256 _amount ) external; /** * @notice Allows a allowed module to transfer bonded tokens from one user to another - * @param _requestId The id of the request handling the user's tokens + * @param _requestId The ID of the request handling the user's tokens * @param _payer The address of the user paying the tokens * @param _receiver The address of the user receiving the tokens * @param _token The address of the token being transferred - * @param _amount The amount of `_token` being transferred + * @param _amount The amount of GRT being transferred */ function pay(bytes32 _requestId, address _payer, address _receiver, IERC20 _token, uint256 _amount) external; /** * @notice Allows an allowed module to bond a user's tokens for a request * @param _bonder The address of the user to bond tokens for - * @param _requestId The id of the request the user is bonding for + * @param _requestId The ID of the request the user is bonding for * @param _token The address of the token being bonded - * @param _amount The amount of `_token` to bond + * @param _amount The amount of GRT to bond */ function bond(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount) external; /** * @notice Allows a valid module to bond a user's tokens for a request * @param _bonder The address of the user to bond tokens for - * @param _requestId The id of the request the user is bonding for + * @param _requestId The ID of the request the user is bonding for * @param _token The address of the token being bonded - * @param _amount The amount of `_token` to bond + * @param _amount The amount of GRT to bond * @param _sender The address starting the propose call on the Oracle */ function bond(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount, address _sender) external; @@ -378,9 +398,9 @@ interface IHorizonAccountingExtension is IValidator { /** * @notice Allows a valid module to release a user's tokens * @param _bonder The address of the user to release tokens for - * @param _requestId The id of the request where the tokens were bonded + * @param _requestId The ID of the request where the tokens were bonded * @param _token The address of the token being released - * @param _amount The amount of `_token` to release + * @param _amount The amount of GRT to release */ function release(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount) external; } diff --git a/test/integration/arbitrum/ArbitrateDispute.t.sol b/test/integration/arbitrum/ArbitrateDispute.t.sol index 46426be..124ad79 100644 --- a/test/integration/arbitrum/ArbitrateDispute.t.sol +++ b/test/integration/arbitrum/ArbitrateDispute.t.sol @@ -79,23 +79,26 @@ contract IntegrationArbitrateDispute is IntegrationBase { IBondEscalationModule.BondEscalation memory _escalation = bondEscalationModule.getEscalation(_requestId); assertEq(_escalation.disputeId, _disputeId); assertEq(uint8(_escalation.status), uint8(IBondEscalationModule.BondEscalationStatus.DisputerWon)); - // Assert BondEscalationAccounting::onSettleBondEscalation - // IBondEscalationAccounting.EscalationResult memory _escalationResult = bondEscalationAccounting.getEscalationResult(_disputeId); - (bytes32 __requestId, IERC20 __token, uint256 __amountPerPledger, IBondEscalationModule __bondEscalationModule) = - bondEscalationAccounting.escalationResults(_disputeId); - assertEq(__requestId, _requestId); - assertEq(__amountPerPledger, disputeBondSize * 2); - assertEq(address(__token), address(graphToken)); - assertEq(address(__bondEscalationModule), address(bondEscalationModule)); + // Assert HorizonAccountingExtension::onSettleBondEscalation + IHorizonAccountingExtension.EscalationResult memory _escalationResult = + horizonAccountingExtension.getEscalationResult(_disputeId); + assertEq(_escalationResult.requestId, _requestId); + assertEq(_escalationResult.amountPerPledger, disputeBondSize * 2); + assertEq(_escalationResult.bondSize, disputeBondSize); + assertEq(address(_escalationResult.bondEscalationModule), address(bondEscalationModule)); // Assert HorizonAccountingExtension::pay assertEq(horizonAccountingExtension.bondedForRequest(_proposer, _requestId), responseBondSize - disputeBondSize); assertEq(horizonAccountingExtension.totalBonded(_proposer), responseBondSize - disputeBondSize); // Assert HorizonStaking::slash - IHorizonStaking.Provision memory _provision = + IHorizonStaking.Provision memory _proposerProvision = horizonStaking.getProvision(_proposer, address(horizonAccountingExtension)); - assertEq(_provision.tokens, responseBondSize - disputeBondSize); + IHorizonStaking.Provision memory _disputerProvision = + horizonStaking.getProvision(_disputer, address(horizonAccountingExtension)); + assertEq(_proposerProvision.tokens, responseBondSize - disputeBondSize); + assertEq(_disputerProvision.tokens, disputeBondSize); // Assert GraphToken::transfer assertEq(graphToken.balanceOf(_disputer), disputeBondSize); + assertEq(graphToken.balanceOf(_proposer), 0); // Assert HorizonAccountingExtension::release assertEq(horizonAccountingExtension.bondedForRequest(_disputer, _requestId), 0); assertEq(horizonAccountingExtension.totalBonded(_disputer), 0); @@ -174,23 +177,26 @@ contract IntegrationArbitrateDispute is IntegrationBase { IBondEscalationModule.BondEscalation memory _escalation = bondEscalationModule.getEscalation(_requestId); assertEq(_escalation.disputeId, _disputeId); assertEq(uint8(_escalation.status), uint8(IBondEscalationModule.BondEscalationStatus.DisputerLost)); - // Assert BondEscalationAccounting::onSettleBondEscalation - // IBondEscalationAccounting.EscalationResult memory _escalationResult = bondEscalationAccounting.getEscalationResult(_disputeId); - (bytes32 __requestId, IERC20 __token, uint256 __amountPerPledger, IBondEscalationModule __bondEscalationModule) = - bondEscalationAccounting.escalationResults(_disputeId); - assertEq(__requestId, _requestId); - assertEq(__amountPerPledger, disputeBondSize * 2); - assertEq(address(__token), address(graphToken)); - assertEq(address(__bondEscalationModule), address(bondEscalationModule)); + // Assert HorizonAccountingExtension::onSettleBondEscalation + IHorizonAccountingExtension.EscalationResult memory _escalationResult = + horizonAccountingExtension.getEscalationResult(_disputeId); + assertEq(_escalationResult.requestId, _requestId); + assertEq(_escalationResult.amountPerPledger, disputeBondSize * 2); + assertEq(_escalationResult.bondSize, disputeBondSize); + assertEq(address(_escalationResult.bondEscalationModule), address(bondEscalationModule)); // Assert HorizonAccountingExtension::pay assertEq(horizonAccountingExtension.bondedForRequest(_disputer, _requestId), 0); assertEq(horizonAccountingExtension.totalBonded(_disputer), 0); // Assert HorizonStaking::slash - IHorizonStaking.Provision memory _provision = + IHorizonStaking.Provision memory _disputerProvision = horizonStaking.getProvision(_disputer, address(horizonAccountingExtension)); - assertEq(_provision.tokens, 0); + IHorizonStaking.Provision memory _proposerProvision = + horizonStaking.getProvision(_proposer, address(horizonAccountingExtension)); + assertEq(_disputerProvision.tokens, 0); + assertEq(_proposerProvision.tokens, responseBondSize); // Assert GraphToken::transfer assertEq(graphToken.balanceOf(_proposer), disputeBondSize); + assertEq(graphToken.balanceOf(_disputer), 0); // Assert Oracle::finalize assertEq(oracle.finalizedAt(_requestId), block.number); assertEq(oracle.finalizedResponseId(_requestId), _responseId); @@ -262,19 +268,18 @@ contract IntegrationArbitrateDispute is IntegrationBase { IBondEscalationModule.BondEscalation memory _escalation = bondEscalationModule.getEscalation(_requestId); assertEq(_escalation.disputeId, _disputeId); assertEq(uint8(_escalation.status), uint8(IBondEscalationModule.BondEscalationStatus.Escalated)); - // Assert BondEscalationAccounting::onSettleBondEscalation - // IBondEscalationAccounting.EscalationResult memory _escalationResult = bondEscalationAccounting.getEscalationResult(_disputeId); - (bytes32 __requestId, IERC20 __token, uint256 __amountPerPledger, IBondEscalationModule __bondEscalationModule) = - bondEscalationAccounting.escalationResults(_disputeId); - assertEq(__requestId, _requestId); - assertEq(__amountPerPledger, disputeBondSize); - assertEq(address(__token), address(graphToken)); - assertEq(address(__bondEscalationModule), address(bondEscalationModule)); + // Assert HorizonAccountingExtension::onSettleBondEscalation + IHorizonAccountingExtension.EscalationResult memory _escalationResult = + horizonAccountingExtension.getEscalationResult(_disputeId); + assertEq(_escalationResult.requestId, _requestId); + assertEq(_escalationResult.amountPerPledger, disputeBondSize); + assertEq(_escalationResult.bondSize, disputeBondSize); + assertEq(address(_escalationResult.bondEscalationModule), address(bondEscalationModule)); // Assert HorizonAccountingExtension::release assertEq(horizonAccountingExtension.bondedForRequest(_disputer, _requestId), 0); assertEq(horizonAccountingExtension.totalBonded(_disputer), 0); - assertEq(bondEscalationAccounting.bondedAmountOf(_proposer, graphToken, _requestId), responseBondSize); - assertEq(bondEscalationAccounting.balanceOf(_proposer, graphToken), 0); + assertEq(horizonAccountingExtension.bondedForRequest(_proposer, _requestId), responseBondSize); + assertEq(horizonAccountingExtension.totalBonded(_proposer), responseBondSize); // Assert Oracle::finalize assertEq(oracle.finalizedAt(_requestId), block.number); assertEq(oracle.finalizedResponseId(_requestId), 0); diff --git a/test/integration/arbitrum/BondEscalation.t.sol b/test/integration/arbitrum/BondEscalation.t.sol index 75e93ac..7584c81 100644 --- a/test/integration/arbitrum/BondEscalation.t.sol +++ b/test/integration/arbitrum/BondEscalation.t.sol @@ -7,18 +7,21 @@ contract IntegrationBondEscalation is IntegrationBase { function setUp() public override { super.setUp(); + // Add chain IDs + _addChains(); + // Set modules data _setRequestModuleData(); _setResponseModuleData(); _setDisputeModuleData(); _setResolutionModuleData(); - // Deposit GRT and approve modules - _depositGRT(); + // Approve modules _approveModules(); - // Add chain IDs - _addChains(); + // Stake GRT and create provisions + _stakeGRT(); + _createProvisions(); } function test_PledgeForDispute() public { @@ -54,12 +57,12 @@ contract IntegrationBondEscalation is IntegrationBase { assertEq(_escalation.disputeId, _disputeId); assertEq(_escalation.amountOfPledgesForDispute, 1); assertEq(bondEscalationModule.pledgesForDispute(_requestId, _pledgerFor), 1); - // Assert BondEscalationAccounting::pledge - assertEq(bondEscalationAccounting.pledges(_disputeId, graphToken), disputeBondSize); - assertEq( - bondEscalationAccounting.balanceOf(_pledgerFor, graphToken), - disputeBondSize * maxNumberOfEscalations - disputeBondSize - ); + // Assert HorizonAccountingExtension::pledge + assertEq(horizonAccountingExtension.pledges(_disputeId), disputeBondSize); + assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), disputeBondSize); + address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); + assertEq(_pledgers[0], _pledgerFor); + assertEq(_pledgers.length, 1); // Revert if the dispute has already been pledged for, but not pledged against vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); @@ -99,12 +102,12 @@ contract IntegrationBondEscalation is IntegrationBase { assertEq(_escalation.disputeId, _disputeId); assertEq(_escalation.amountOfPledgesAgainstDispute, 1); assertEq(bondEscalationModule.pledgesAgainstDispute(_requestId, _pledgerAgainst), 1); - // Assert BondEscalationAccounting::pledge - assertEq(bondEscalationAccounting.pledges(_disputeId, graphToken), disputeBondSize); - assertEq( - bondEscalationAccounting.balanceOf(_pledgerAgainst, graphToken), - disputeBondSize * maxNumberOfEscalations - disputeBondSize - ); + // Assert HorizonAccountingExtension::pledge + assertEq(horizonAccountingExtension.pledges(_disputeId), disputeBondSize); + assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), disputeBondSize); + address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); + assertEq(_pledgers[0], _pledgerAgainst); + assertEq(_pledgers.length, 1); // Revert if the dispute has already been pledged against, but not pledged for vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); @@ -139,10 +142,14 @@ contract IntegrationBondEscalation is IntegrationBase { assertEq(_escalation.amountOfPledgesAgainstDispute, maxNumberOfEscalations); assertEq(bondEscalationModule.pledgesForDispute(_requestId, _pledgerFor), maxNumberOfEscalations); assertEq(bondEscalationModule.pledgesAgainstDispute(_requestId, _pledgerAgainst), maxNumberOfEscalations); - // Assert BondEscalationAccounting::pledge - assertEq(bondEscalationAccounting.pledges(_disputeId, graphToken), disputeBondSize * maxNumberOfEscalations * 2); - assertEq(bondEscalationAccounting.balanceOf(_pledgerFor, graphToken), 0); - assertEq(bondEscalationAccounting.balanceOf(_pledgerAgainst, graphToken), 0); + // Assert HorizonAccountingExtension::pledge + assertEq(horizonAccountingExtension.pledges(_disputeId), disputeBondSize * maxNumberOfEscalations * 2); + assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), disputeBondSize * maxNumberOfEscalations); + assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), disputeBondSize * maxNumberOfEscalations); + address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); + assertEq(_pledgers[0], _pledgerFor); + assertEq(_pledgers[1], _pledgerAgainst); + assertEq(_pledgers.length, 2); // Revert if the max number of escalations has been reached vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); @@ -192,22 +199,29 @@ contract IntegrationBondEscalation is IntegrationBase { assertEq(uint8(_escalation.status), uint8(IBondEscalationModule.BondEscalationStatus.DisputerWon)); // Assert Oracle::updateDisputeStatus assertEq(uint8(oracle.disputeStatus(_disputeId)), uint8(IOracle.DisputeStatus.Won)); - // Assert BondEscalationAccounting::onSettleBondEscalation - // IBondEscalationAccounting.EscalationResult memory _escalationResult = bondEscalationAccounting.getEscalationResult(_disputeId); - (bytes32 __requestId, IERC20 __token, uint256 __amountPerPledger, IBondEscalationModule __bondEscalationModule) = - bondEscalationAccounting.escalationResults(_disputeId); - assertEq(__requestId, _requestId); - assertEq(__amountPerPledger, disputeBondSize + disputeBondSize / 2); - assertEq(address(__token), address(graphToken)); - assertEq(address(__bondEscalationModule), address(bondEscalationModule)); - // Assert BondEscalationAccounting::pay - assertEq( - bondEscalationAccounting.bondedAmountOf(_proposer, graphToken, _requestId), responseBondSize - disputeBondSize - ); - assertEq(bondEscalationAccounting.balanceOf(_proposer, graphToken), 0); - // Assert BondEscalationAccounting::release - assertEq(bondEscalationAccounting.bondedAmountOf(_disputer, graphToken, _requestId), 0); - assertEq(bondEscalationAccounting.balanceOf(_disputer, graphToken), disputeBondSize * 2); + // Assert HorizonAccountingExtension::onSettleBondEscalation + IHorizonAccountingExtension.EscalationResult memory _escalationResult = + horizonAccountingExtension.getEscalationResult(_disputeId); + assertEq(_escalationResult.requestId, _requestId); + assertEq(_escalationResult.amountPerPledger, disputeBondSize + disputeBondSize / 2); + assertEq(_escalationResult.bondSize, disputeBondSize); + assertEq(address(_escalationResult.bondEscalationModule), address(bondEscalationModule)); + // Assert HorizonAccountingExtension::pay + assertEq(horizonAccountingExtension.bondedForRequest(_proposer, _requestId), responseBondSize - disputeBondSize); + assertEq(horizonAccountingExtension.totalBonded(_proposer), responseBondSize - disputeBondSize); + // Assert HorizonStaking::slash + IHorizonStaking.Provision memory _proposerProvision = + horizonStaking.getProvision(_proposer, address(horizonAccountingExtension)); + IHorizonStaking.Provision memory _disputerProvision = + horizonStaking.getProvision(_disputer, address(horizonAccountingExtension)); + assertEq(_proposerProvision.tokens, responseBondSize - disputeBondSize); + assertEq(_disputerProvision.tokens, disputeBondSize); + // Assert GraphToken::transfer + assertEq(graphToken.balanceOf(_disputer), disputeBondSize); + assertEq(graphToken.balanceOf(_proposer), 0); + // Assert HorizonAccountingExtension::release + assertEq(horizonAccountingExtension.bondedForRequest(_disputer, _requestId), 0); + assertEq(horizonAccountingExtension.totalBonded(_disputer), 0); // Revert if the bond escalation has already been settled vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationCantBeSettled.selector); @@ -259,19 +273,28 @@ contract IntegrationBondEscalation is IntegrationBase { assertEq(uint8(_escalation.status), uint8(IBondEscalationModule.BondEscalationStatus.DisputerLost)); // Assert Oracle::updateDisputeStatus assertEq(uint8(oracle.disputeStatus(_disputeId)), uint8(IOracle.DisputeStatus.Lost)); - // Assert BondEscalationAccounting::onSettleBondEscalation - // IBondEscalationAccounting.EscalationResult memory _escalationResult = bondEscalationAccounting.getEscalationResult(_disputeId); - (bytes32 __requestId, IERC20 __token, uint256 __amountPerPledger, IBondEscalationModule __bondEscalationModule) = - bondEscalationAccounting.escalationResults(_disputeId); - assertEq(__requestId, _requestId); - assertEq(__amountPerPledger, disputeBondSize + disputeBondSize / 2); - assertEq(address(__token), address(graphToken)); - assertEq(address(__bondEscalationModule), address(bondEscalationModule)); - // Assert BondEscalationAccounting::pay - assertEq(bondEscalationAccounting.bondedAmountOf(_disputer, graphToken, _requestId), 0); - assertEq(bondEscalationAccounting.balanceOf(_disputer, graphToken), 0); - assertEq(bondEscalationAccounting.bondedAmountOf(_proposer, graphToken, _requestId), responseBondSize); - assertEq(bondEscalationAccounting.balanceOf(_proposer, graphToken), disputeBondSize); + // Assert HorizonAccountingExtension::onSettleBondEscalation + IHorizonAccountingExtension.EscalationResult memory _escalationResult = + horizonAccountingExtension.getEscalationResult(_disputeId); + assertEq(_escalationResult.requestId, _requestId); + assertEq(_escalationResult.amountPerPledger, disputeBondSize + disputeBondSize / 2); + assertEq(_escalationResult.bondSize, disputeBondSize); + assertEq(address(_escalationResult.bondEscalationModule), address(bondEscalationModule)); + // Assert HorizonAccountingExtension::pay + assertEq(horizonAccountingExtension.bondedForRequest(_disputer, _requestId), 0); + assertEq(horizonAccountingExtension.totalBonded(_disputer), 0); + assertEq(horizonAccountingExtension.bondedForRequest(_proposer, _requestId), responseBondSize); + assertEq(horizonAccountingExtension.totalBonded(_proposer), responseBondSize); + // Assert HorizonStaking::slash + IHorizonStaking.Provision memory _disputerProvision = + horizonStaking.getProvision(_disputer, address(horizonAccountingExtension)); + IHorizonStaking.Provision memory _proposerProvision = + horizonStaking.getProvision(_proposer, address(horizonAccountingExtension)); + assertEq(_disputerProvision.tokens, 0); + assertEq(_proposerProvision.tokens, responseBondSize); + // Assert GraphToken::transfer + assertEq(graphToken.balanceOf(_proposer), disputeBondSize); + assertEq(graphToken.balanceOf(_disputer), 0); // Revert if the bond escalation has already been settled vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationCantBeSettled.selector); @@ -291,8 +314,8 @@ contract IntegrationBondEscalation is IntegrationBase { bytes32 _disputeId = _disputeResponse(_requestId, _responseId); // Revert if the bond escalation has not been settled - vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_NoEscalationResult.selector); - bondEscalationAccounting.claimEscalationReward(_disputeId, _pledgerFor); + vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_NoEscalationResult.selector); + horizonAccountingExtension.claimEscalationReward(_disputeId, _pledgerFor); // Pledge against the dispute _pledgeAgainstDispute(_requestId, _disputeId); @@ -308,19 +331,32 @@ contract IntegrationBondEscalation is IntegrationBase { _settleBondEscalation(_requestId, _responseId, _disputeId); // Claim the escalation rewards - bondEscalationAccounting.claimEscalationReward(_disputeId, _pledgerFor); - bondEscalationAccounting.claimEscalationReward(_disputeId, _pledgerAgainst); - - // Assert BondEscalationAccounting::claimEscalationReward - assertTrue(bondEscalationAccounting.pledgerClaimed(_requestId, _pledgerFor)); - assertTrue(bondEscalationAccounting.pledgerClaimed(_requestId, _pledgerAgainst)); - assertEq(bondEscalationAccounting.balanceOf(_pledgerFor, graphToken), disputeBondSize * 3); - assertEq(bondEscalationAccounting.balanceOf(_pledgerAgainst, graphToken), disputeBondSize); - assertEq(bondEscalationAccounting.pledges(_disputeId, graphToken), 0); + horizonAccountingExtension.claimEscalationReward(_disputeId, _pledgerFor); + horizonAccountingExtension.claimEscalationReward(_disputeId, _pledgerAgainst); + + // Assert HorizonAccountingExtension::claimEscalationReward + assertTrue(horizonAccountingExtension.pledgerClaimed(_requestId, _pledgerFor)); + assertTrue(horizonAccountingExtension.pledgerClaimed(_requestId, _pledgerAgainst)); + assertEq(horizonAccountingExtension.pledges(_disputeId), 0); + assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), 0); + assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), disputeBondSize); // TODO: `disputeBondSize` remains bonded + address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); + assertEq(_pledgers[0], _pledgerFor); // TODO: `_pledgerFor` remains in the pledgers list + assertEq(_pledgers.length, 1); + // Assert HorizonStaking::slash + IHorizonStaking.Provision memory _pledgerForProvision = + horizonStaking.getProvision(_pledgerFor, address(horizonAccountingExtension)); + IHorizonStaking.Provision memory _pledgerAgainstProvision = + horizonStaking.getProvision(_pledgerAgainst, address(horizonAccountingExtension)); + assertEq(_pledgerForProvision.tokens, disputeBondSize * maxNumberOfEscalations); + assertEq(_pledgerAgainstProvision.tokens, disputeBondSize * maxNumberOfEscalations - disputeBondSize); + // Assert GraphToken::transfer + assertEq(graphToken.balanceOf(_pledgerFor), disputeBondSize); + assertEq(graphToken.balanceOf(_pledgerAgainst), 0); // Revert if the escalation reward has already been claimed - vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_AlreadyClaimed.selector); - bondEscalationAccounting.claimEscalationReward(_disputeId, _pledgerFor); + vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_AlreadyClaimed.selector); + horizonAccountingExtension.claimEscalationReward(_disputeId, _pledgerFor); } function test_ClaimEscalationReward_DisputerLost() public { @@ -332,8 +368,8 @@ contract IntegrationBondEscalation is IntegrationBase { bytes32 _disputeId = _disputeResponse(_requestId, _responseId); // Revert if the bond escalation has not been settled - vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_NoEscalationResult.selector); - bondEscalationAccounting.claimEscalationReward(_disputeId, _pledgerAgainst); + vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_NoEscalationResult.selector); + horizonAccountingExtension.claimEscalationReward(_disputeId, _pledgerAgainst); // Pledge for the dispute _pledgeForDispute(_requestId, _disputeId); @@ -349,18 +385,31 @@ contract IntegrationBondEscalation is IntegrationBase { _settleBondEscalation(_requestId, _responseId, _disputeId); // Claim the escalation rewards - bondEscalationAccounting.claimEscalationReward(_disputeId, _pledgerFor); - bondEscalationAccounting.claimEscalationReward(_disputeId, _pledgerAgainst); - - // Assert BondEscalationAccounting::claimEscalationReward - assertTrue(bondEscalationAccounting.pledgerClaimed(_requestId, _pledgerFor)); - assertTrue(bondEscalationAccounting.pledgerClaimed(_requestId, _pledgerAgainst)); - assertEq(bondEscalationAccounting.balanceOf(_pledgerFor, graphToken), disputeBondSize); - assertEq(bondEscalationAccounting.balanceOf(_pledgerAgainst, graphToken), disputeBondSize * 3); - assertEq(bondEscalationAccounting.pledges(_disputeId, graphToken), 0); + horizonAccountingExtension.claimEscalationReward(_disputeId, _pledgerFor); + horizonAccountingExtension.claimEscalationReward(_disputeId, _pledgerAgainst); + + // Assert HorizonAccountingExtension::claimEscalationReward + assertTrue(horizonAccountingExtension.pledgerClaimed(_requestId, _pledgerFor)); + assertTrue(horizonAccountingExtension.pledgerClaimed(_requestId, _pledgerAgainst)); + assertEq(horizonAccountingExtension.pledges(_disputeId), 0); + assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), disputeBondSize); // TODO: `disputeBondSize` remains bonded + assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), 0); + address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); + assertEq(_pledgers[0], _pledgerAgainst); // TODO: `_pledgerAgainst` remains in the pledgers list + assertEq(_pledgers.length, 1); + // Assert HorizonStaking::slash + IHorizonStaking.Provision memory _pledgerForProvision = + horizonStaking.getProvision(_pledgerFor, address(horizonAccountingExtension)); + IHorizonStaking.Provision memory _pledgerAgainstProvision = + horizonStaking.getProvision(_pledgerAgainst, address(horizonAccountingExtension)); + assertEq(_pledgerForProvision.tokens, disputeBondSize * maxNumberOfEscalations - disputeBondSize); + assertEq(_pledgerAgainstProvision.tokens, disputeBondSize * maxNumberOfEscalations); + // Assert GraphToken::transfer + assertEq(graphToken.balanceOf(_pledgerFor), 0); + assertEq(graphToken.balanceOf(_pledgerAgainst), disputeBondSize); // Revert if the escalation reward has already been claimed - vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_AlreadyClaimed.selector); - bondEscalationAccounting.claimEscalationReward(_disputeId, _pledgerAgainst); + vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_AlreadyClaimed.selector); + horizonAccountingExtension.claimEscalationReward(_disputeId, _pledgerAgainst); } } diff --git a/test/integration/arbitrum/IntegrationBase.sol b/test/integration/arbitrum/IntegrationBase.sol index 72a3429..e854d46 100644 --- a/test/integration/arbitrum/IntegrationBase.sol +++ b/test/integration/arbitrum/IntegrationBase.sol @@ -214,13 +214,13 @@ contract IntegrationBase is Deploy, Test { vm.startPrank(_pledgerFor); deal(address(graphToken), _pledgerFor, disputeBondSize * maxNumberOfEscalations, true); - graphToken.approve(address(bondEscalationAccounting), disputeBondSize * maxNumberOfEscalations); - bondEscalationAccounting.deposit(graphToken, disputeBondSize * maxNumberOfEscalations); + graphToken.approve(address(horizonStaking), disputeBondSize * maxNumberOfEscalations); + horizonStaking.stake(disputeBondSize * maxNumberOfEscalations); vm.startPrank(_pledgerAgainst); deal(address(graphToken), _pledgerAgainst, disputeBondSize * maxNumberOfEscalations, true); - graphToken.approve(address(bondEscalationAccounting), disputeBondSize * maxNumberOfEscalations); - bondEscalationAccounting.deposit(graphToken, disputeBondSize * maxNumberOfEscalations); + graphToken.approve(address(horizonStaking), disputeBondSize * maxNumberOfEscalations); + horizonStaking.stake(disputeBondSize * maxNumberOfEscalations); vm.stopPrank(); } @@ -251,6 +251,24 @@ contract IntegrationBase is Deploy, Test { horizonAccountingExtension.MAX_VERIFIER_CUT(), horizonAccountingExtension.MIN_THAWING_PERIOD() ); + + vm.startPrank(_pledgerFor); + horizonStaking.provision( + _pledgerFor, + address(horizonAccountingExtension), + disputeBondSize * maxNumberOfEscalations, + horizonAccountingExtension.MAX_VERIFIER_CUT(), + horizonAccountingExtension.MIN_THAWING_PERIOD() + ); + + vm.startPrank(_pledgerAgainst); + horizonStaking.provision( + _pledgerAgainst, + address(horizonAccountingExtension), + disputeBondSize * maxNumberOfEscalations, + horizonAccountingExtension.MAX_VERIFIER_CUT(), + horizonAccountingExtension.MIN_THAWING_PERIOD() + ); vm.stopPrank(); } diff --git a/test/unit/HorizonAccountingExtension.t.sol b/test/unit/HorizonAccountingExtension.t.sol index a954271..18e58cc 100644 --- a/test/unit/HorizonAccountingExtension.t.sol +++ b/test/unit/HorizonAccountingExtension.t.sol @@ -215,12 +215,7 @@ contract HorizonAccountingExtension_Unit_Pledge is HorizonAccountingExtension_Un function test_revertIfUnauthorizedCaller(address _pledger, uint256 _amount) public { vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedCaller.selector); - horizonAccountingExtension.pledge({ - _pledger: _pledger, - _request: mockRequest, - _dispute: mockDispute, - _amount: _amount - }); + horizonAccountingExtension.pledge(_pledger, mockRequest, mockDispute, grt, _amount); } function test_revertIfDisallowedModule(address _pledger, uint256 _amount) public { @@ -235,12 +230,7 @@ contract HorizonAccountingExtension_Unit_Pledge is HorizonAccountingExtension_Un vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedModule.selector); vm.prank(authorizedCaller); - horizonAccountingExtension.pledge({ - _pledger: _pledger, - _request: mockRequest, - _dispute: mockDispute, - _amount: _amount - }); + horizonAccountingExtension.pledge(_pledger, mockRequest, mockDispute, grt, _amount); } function test_invalidVerfierCut(address _pledger, uint256 _amount, uint32 _invalidVerfierCut) public { @@ -266,12 +256,7 @@ contract HorizonAccountingExtension_Unit_Pledge is HorizonAccountingExtension_Un ); vm.prank(authorizedCaller); - horizonAccountingExtension.pledge({ - _pledger: _pledger, - _request: mockRequest, - _dispute: mockDispute, - _amount: _amount - }); + horizonAccountingExtension.pledge(_pledger, mockRequest, mockDispute, grt, _amount); } function test_invalidThawingPeriod(address _pledger, uint256 _amount) public { @@ -296,12 +281,7 @@ contract HorizonAccountingExtension_Unit_Pledge is HorizonAccountingExtension_Un ); vm.prank(authorizedCaller); - horizonAccountingExtension.pledge({ - _pledger: _pledger, - _request: mockRequest, - _dispute: mockDispute, - _amount: _amount - }); + horizonAccountingExtension.pledge(_pledger, mockRequest, mockDispute, grt, _amount); } function test_insufficientTokens(address _pledger, uint256 _amount) public { @@ -327,12 +307,7 @@ contract HorizonAccountingExtension_Unit_Pledge is HorizonAccountingExtension_Un ); vm.prank(authorizedCaller); - horizonAccountingExtension.pledge({ - _pledger: _pledger, - _request: mockRequest, - _dispute: mockDispute, - _amount: _amount - }); + horizonAccountingExtension.pledge(_pledger, mockRequest, mockDispute, grt, _amount); } function test_insufficientBondedTokens( @@ -367,12 +342,7 @@ contract HorizonAccountingExtension_Unit_Pledge is HorizonAccountingExtension_Un ); vm.prank(authorizedCaller); - horizonAccountingExtension.pledge({ - _pledger: _pledger, - _request: mockRequest, - _dispute: mockDispute, - _amount: _amount - }); + horizonAccountingExtension.pledge(_pledger, mockRequest, mockDispute, grt, _amount); } function test_successfulCall( @@ -387,12 +357,7 @@ contract HorizonAccountingExtension_Unit_Pledge is HorizonAccountingExtension_Un uint256 _balanceBeforePledge = horizonAccountingExtension.totalBonded(_pledger); uint256 _pledgesBeforePledge = horizonAccountingExtension.pledges(_mockDisputeId); - horizonAccountingExtension.pledge({ - _pledger: _pledger, - _request: mockRequest, - _dispute: mockDispute, - _amount: _amount - }); + horizonAccountingExtension.pledge(_pledger, mockRequest, mockDispute, grt, _amount); uint256 _balanceAfterPledge = horizonAccountingExtension.totalBonded(_pledger); uint256 _pledgesAfterPledge = horizonAccountingExtension.pledges(_mockDisputeId); @@ -423,7 +388,7 @@ contract HorizonAccountingExtension_Unit_OnSettleBondEscalation is HorizonAccoun vm.mockCall( address(bondEscalationModule), - abi.encodeWithSelector(IBondEscalationModule.decodeRequestData.selector, mockRequest.requestModuleData), + abi.encodeWithSelector(IBondEscalationModule.decodeRequestData.selector, mockRequest.disputeModuleData), abi.encode(_requestParameters) ); @@ -451,7 +416,7 @@ contract HorizonAccountingExtension_Unit_OnSettleBondEscalation is HorizonAccoun vm.prank(address(bondEscalationModule)); horizonAccountingExtension.onSettleBondEscalation( - mockRequest, mockDispute, _amountPerPledger, _winningPledgersLength + mockRequest, mockDispute, grt, _amountPerPledger, _winningPledgersLength ); } @@ -474,7 +439,7 @@ contract HorizonAccountingExtension_Unit_OnSettleBondEscalation is HorizonAccoun vm.prank(address(bondEscalationModule)); horizonAccountingExtension.onSettleBondEscalation( - mockRequest, mockDispute, _amountPerPledger, _winningPledgersLength + mockRequest, mockDispute, grt, _amountPerPledger, _winningPledgersLength ); } @@ -505,7 +470,7 @@ contract HorizonAccountingExtension_Unit_OnSettleBondEscalation is HorizonAccoun vm.prank(address(bondEscalationModule)); horizonAccountingExtension.onSettleBondEscalation( - mockRequest, mockDispute, _amountPerPledger, _winningPledgersLength + mockRequest, mockDispute, grt, _amountPerPledger, _winningPledgersLength ); } @@ -527,7 +492,7 @@ contract HorizonAccountingExtension_Unit_OnSettleBondEscalation is HorizonAccoun vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_AlreadySettled.selector); horizonAccountingExtension.onSettleBondEscalation( - mockRequest, mockDispute, _amountPerPledger, _winningPledgersLength + mockRequest, mockDispute, grt, _amountPerPledger, _winningPledgersLength ); } @@ -542,12 +507,9 @@ contract HorizonAccountingExtension_Unit_OnSettleBondEscalation is HorizonAccoun vm.expectEmit(); emit BondEscalationSettled(_mockRequestId, _mockDisputeId, _amountPerPledger, _winningPledgersLength); - horizonAccountingExtension.onSettleBondEscalation({ - _request: mockRequest, - _dispute: mockDispute, - _amountPerPledger: _amountPerPledger, - _winningPledgersLength: _winningPledgersLength - }); + horizonAccountingExtension.onSettleBondEscalation( + mockRequest, mockDispute, grt, _amountPerPledger, _winningPledgersLength + ); ( bytes32 _requestIdSaved, @@ -904,7 +866,7 @@ contract HorizonAccountingExtension_Unit_ReleasePledge is HorizonAccountingExten vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedCaller.selector); vm.prank(address(bondEscalationModule)); - horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, _amount); + horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, grt, _amount); } function test_revertIfDisallowedModule(address _pledger, uint256 _amount) public { @@ -921,7 +883,7 @@ contract HorizonAccountingExtension_Unit_ReleasePledge is HorizonAccountingExten vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedModule.selector); vm.prank(authorizedCaller); - horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, _amount); + horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, grt, _amount); } function test_revertIfInsufficientFunds( @@ -932,7 +894,7 @@ contract HorizonAccountingExtension_Unit_ReleasePledge is HorizonAccountingExten horizonAccountingExtension.setPledgedForTest(_mockDisputeId, 0); vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientFunds.selector); - horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, _amount); + horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, grt, _amount); } function test_revertIfInsufficientBondedTokens( @@ -943,7 +905,7 @@ contract HorizonAccountingExtension_Unit_ReleasePledge is HorizonAccountingExten horizonAccountingExtension.setBondedTokensForTest(_pledger, 0); vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientBondedTokens.selector); - horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, _amount); + horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, grt, _amount); } function test_successfulCall( @@ -954,7 +916,7 @@ contract HorizonAccountingExtension_Unit_ReleasePledge is HorizonAccountingExten vm.expectEmit(); emit PledgeReleased(_mockRequestId, _mockDisputeId, _pledger, _amount); - horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, _amount); + horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, grt, _amount); uint256 _pledgesAfter = horizonAccountingExtension.pledges(_mockDisputeId); uint256 _totalBondedAfter = horizonAccountingExtension.totalBonded(_pledger); From 850c1c7d7a17a958d28348f23bf2bef9190b08f9 Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Thu, 3 Oct 2024 17:52:08 -0300 Subject: [PATCH 10/14] feat: null payment amount --- script/Deploy.s.sol | 10 ++++++---- test/integration/arbitrum/IntegrationBase.sol | 17 ----------------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index cfd03e8..670497a 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -90,15 +90,17 @@ contract Deploy is Script { arbitrator = _ARBITRUM_SEPOLIA_ARBITRATOR; council = _ARBITRUM_SEPOLIA_COUNCIL; - // TODO: Set production request module params - paymentAmount = 0.1 ether; + // Set request module params + paymentAmount = 0 ether; - // TODO: Set production response module params (responseBondSize == disputeBondSize) + // Set response module params + // TODO: Review production params (responseBondSize == disputeBondSize) responseBondSize = 0.5 ether; responseDeadline = block.timestamp + 5 days; responseDisputeWindow = block.timestamp + 1 weeks; - // TODO: Set production dispute module params (disputeBondSize == responseBondSize) + // Set dispute module params + // TODO: Review production params (disputeBondSize == responseBondSize) disputeBondSize = 0.3 ether; maxNumberOfEscalations = 2; disputeDeadline = block.timestamp + 10 days; diff --git a/test/integration/arbitrum/IntegrationBase.sol b/test/integration/arbitrum/IntegrationBase.sol index e854d46..e173394 100644 --- a/test/integration/arbitrum/IntegrationBase.sol +++ b/test/integration/arbitrum/IntegrationBase.sol @@ -186,9 +186,6 @@ contract IntegrationBase is Deploy, Test { } function _approveModules() internal { - vm.prank(_requester); - horizonAccountingExtension.approveModule(address(eboRequestModule)); - vm.prank(_proposer); horizonAccountingExtension.approveModule(address(bondedResponseModule)); @@ -197,11 +194,6 @@ contract IntegrationBase is Deploy, Test { } function _stakeGRT() internal { - vm.startPrank(_requester); - deal(address(graphToken), _requester, paymentAmount, true); - graphToken.approve(address(horizonStaking), paymentAmount); - horizonStaking.stake(paymentAmount); - vm.startPrank(_proposer); deal(address(graphToken), _proposer, responseBondSize, true); graphToken.approve(address(horizonStaking), responseBondSize); @@ -225,15 +217,6 @@ contract IntegrationBase is Deploy, Test { } function _createProvisions() internal { - vm.startPrank(_requester); - horizonStaking.provision( - _requester, - address(horizonAccountingExtension), - paymentAmount, - horizonAccountingExtension.MAX_VERIFIER_CUT(), - horizonAccountingExtension.MIN_THAWING_PERIOD() - ); - vm.startPrank(_proposer); horizonStaking.provision( _proposer, From b7cd5fdc26e0a693c636f8a4b10ce70d30e88d99 Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Mon, 7 Oct 2024 02:24:43 -0300 Subject: [PATCH 11/14] fix: unbond slashed pledgers --- src/contracts/HorizonAccountingExtension.sol | 10 +- .../integration/arbitrum/BondEscalation.t.sol | 4 +- test/unit/HorizonAccountingExtension.t.sol | 116 ++++++++++++++++-- 3 files changed, 116 insertions(+), 14 deletions(-) diff --git a/src/contracts/HorizonAccountingExtension.sol b/src/contracts/HorizonAccountingExtension.sol index 3b59df8..16a161c 100644 --- a/src/contracts/HorizonAccountingExtension.sol +++ b/src/contracts/HorizonAccountingExtension.sol @@ -250,7 +250,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { }); } - // TODO: Remove + // TODO: Remove? /// @inheritdoc IHorizonAccountingExtension function releasePledge( IOracle.Request calldata _request, @@ -270,6 +270,8 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { pledges[_disputeId] -= _amount; } + // TODO: _pledgers[_disputeId].remove(_pledger); + _unbond(_pledger, _amount); emit PledgeReleased({_requestId: _requestId, _disputeId: _disputeId, _pledger: _pledger, _amount: _amount}); @@ -416,9 +418,10 @@ 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()`)? + // TODO: What if `MIN_THAWING_PERIOD` has passed, all provision tokens have been thawed + // and slashing is skipped or reverts (bricking `claimEscalationReward()`)? - // TODO: Unbond slashed pledgers + _unbond(_user, _slashAmount); _slashedAmount += _slashAmount; @@ -466,6 +469,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { if (_provisionData.maxVerifierCut != MAX_VERIFIER_CUT) revert HorizonAccountingExtension_InvalidMaxVerifierCut(); if (_provisionData.thawingPeriod < MIN_THAWING_PERIOD) revert HorizonAccountingExtension_InvalidThawingPeriod(); if (_amount > _provisionData.tokens) revert HorizonAccountingExtension_InsufficientTokens(); + // TODO: `thaw()` does not subtract from provision `tokens` but adds to `tokensThawing` totalBonded[_bonder] += _amount; diff --git a/test/integration/arbitrum/BondEscalation.t.sol b/test/integration/arbitrum/BondEscalation.t.sol index 7584c81..713106d 100644 --- a/test/integration/arbitrum/BondEscalation.t.sol +++ b/test/integration/arbitrum/BondEscalation.t.sol @@ -339,7 +339,7 @@ contract IntegrationBondEscalation is IntegrationBase { assertTrue(horizonAccountingExtension.pledgerClaimed(_requestId, _pledgerAgainst)); assertEq(horizonAccountingExtension.pledges(_disputeId), 0); assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), 0); - assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), disputeBondSize); // TODO: `disputeBondSize` remains bonded + assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), 0); address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); assertEq(_pledgers[0], _pledgerFor); // TODO: `_pledgerFor` remains in the pledgers list assertEq(_pledgers.length, 1); @@ -392,7 +392,7 @@ contract IntegrationBondEscalation is IntegrationBase { assertTrue(horizonAccountingExtension.pledgerClaimed(_requestId, _pledgerFor)); assertTrue(horizonAccountingExtension.pledgerClaimed(_requestId, _pledgerAgainst)); assertEq(horizonAccountingExtension.pledges(_disputeId), 0); - assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), disputeBondSize); // TODO: `disputeBondSize` remains bonded + assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), 0); assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), 0); address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); assertEq(_pledgers[0], _pledgerAgainst); // TODO: `_pledgerAgainst` remains in the pledgers list diff --git a/test/unit/HorizonAccountingExtension.t.sol b/test/unit/HorizonAccountingExtension.t.sol index 18e58cc..1faa23c 100644 --- a/test/unit/HorizonAccountingExtension.t.sol +++ b/test/unit/HorizonAccountingExtension.t.sol @@ -557,6 +557,36 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount horizonAccountingExtension.claimEscalationReward(_mockDisputeId, _pledger); } + function test_revertIfInsufficientBondedTokens( + address _pledger, + uint256 _pledgesForDispute, + uint256 _pledgesAgainstDispute, + uint256 _bondSize, + uint256 _amount + ) public happyPath(_pledgesForDispute, _pledgesAgainstDispute, _bondSize, _amount) { + // Mock and expect the call to oracle checking the dispute status + _mockAndExpect( + address(oracle), + abi.encodeWithSelector(IOracle.disputeStatus.selector, _mockDisputeId), + abi.encode(IOracle.DisputeStatus.NoResolution) + ); + + _mockAndExpect( + address(bondEscalationModule), + abi.encodeWithSelector(IBondEscalationModule.pledgesForDispute.selector, _mockRequestId, _pledger), + abi.encode(_pledgesForDispute) + ); + + _mockAndExpect( + address(bondEscalationModule), + abi.encodeWithSelector(IBondEscalationModule.pledgesAgainstDispute.selector, _mockRequestId, _pledger), + abi.encode(_pledgesAgainstDispute) + ); + + vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientBondedTokens.selector); + horizonAccountingExtension.claimEscalationReward(_mockDisputeId, _pledger); + } + function test_successfulCallNoResolution( address _pledger, uint256 _pledgesForDispute, @@ -709,6 +739,9 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount ) public happyPath(_pledgesForDispute, _pledgesAgainstDispute, _bondSize, _amount) { vm.assume(_pledger != _slashedUser); vm.assume(_slashedUser != _notSlashedUser); + + _pledgesAgainstDispute = _pledgesForDispute * _amount / _bondSize + 1; + // Mock and expect the call to oracle checking the dispute status _mockAndExpect( address(oracle), @@ -731,7 +764,7 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount _mockAndExpect( address(bondEscalationModule), abi.encodeWithSelector(IBondEscalationModule.pledgesAgainstDispute.selector, _mockRequestId, _slashedUser), - abi.encode(_pledgesForDispute * _amount / _bondSize + 1) + abi.encode(_pledgesAgainstDispute) ); _mockAndExpect( @@ -752,6 +785,7 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount ); horizonAccountingExtension.setBondedTokensForTest(_pledger, _bondSize * _pledgesForDispute); + horizonAccountingExtension.setBondedTokensForTest(_slashedUser, _bondSize * _pledgesAgainstDispute); horizonAccountingExtension.setPledgersForTest(_mockDisputeId, _notSlashedUser); horizonAccountingExtension.setPledgersForTest(_mockDisputeId, _slashedUser); @@ -767,6 +801,12 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount ); horizonAccountingExtension.claimEscalationReward(_mockDisputeId, _pledger); + + uint256 _pledgerTotalBondedAfter = horizonAccountingExtension.totalBonded(_pledger); + uint256 _slashedUserTotalBondedAfter = horizonAccountingExtension.totalBonded(_slashedUser); + + assertEq(_pledgerTotalBondedAfter, 0); + assertEq(_slashedUserTotalBondedAfter, 0); } function test_successfulCallLostAgainstDisputeSlashing( @@ -780,6 +820,9 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount ) public happyPath(_pledgesForDispute, _pledgesAgainstDispute, _bondSize, _amount) { vm.assume(_pledger != _slashedUser); vm.assume(_slashedUser != _notSlashedUser); + + _pledgesForDispute = _pledgesAgainstDispute * _amount / _bondSize + 1; + // Mock and expect the call to oracle checking the dispute status _mockAndExpect( address(oracle), @@ -802,7 +845,7 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount _mockAndExpect( address(bondEscalationModule), abi.encodeWithSelector(IBondEscalationModule.pledgesForDispute.selector, _mockRequestId, _slashedUser), - abi.encode(_pledgesAgainstDispute * _amount / _bondSize + 1) + abi.encode(_pledgesForDispute) ); _mockAndExpect( @@ -823,6 +866,7 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount ); horizonAccountingExtension.setBondedTokensForTest(_pledger, _bondSize * _pledgesAgainstDispute); + horizonAccountingExtension.setBondedTokensForTest(_slashedUser, _bondSize * _pledgesForDispute); horizonAccountingExtension.setPledgersForTest(_mockDisputeId, _notSlashedUser); horizonAccountingExtension.setPledgersForTest(_mockDisputeId, _slashedUser); @@ -838,6 +882,12 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount ); horizonAccountingExtension.claimEscalationReward(_mockDisputeId, _pledger); + + uint256 _pledgerTotalBondedAfter = horizonAccountingExtension.totalBonded(_pledger); + uint256 _slashedUserTotalBondedAfter = horizonAccountingExtension.totalBonded(_slashedUser); + + assertEq(_pledgerTotalBondedAfter, 0); + assertEq(_slashedUserTotalBondedAfter, 0); } } @@ -1446,6 +1496,8 @@ contract HorizonAccountingExtension_Unit_Slash is HorizonAccountingExtension_Uni vm.assume(_pledgesForDispute > 0 && _pledgesForDispute < type(uint16).max); vm.assume(_bondSize > 0 && _bondSize < type(uint16).max); + uint256 _slashAmount = _pledgesForDispute * _bondSize; + for (uint256 _i; _i < _users.length; _i++) { horizonAccountingExtension.setPledgersForTest(_mockDisputeId, _users[_i]); _cleanPledgers.add(_users[_i]); @@ -1453,6 +1505,7 @@ contract HorizonAccountingExtension_Unit_Slash is HorizonAccountingExtension_Uni for (uint256 _i; _i < _cleanPledgers.length(); _i++) { assertEq(horizonAccountingExtension.getPledgerForTest(_mockDisputeId, _i), _cleanPledgers.at(_i)); + horizonAccountingExtension.setBondedTokensForTest(_cleanPledgers.at(_i), _slashAmount); } horizonAccountingExtension.setEscalationResultForTest( @@ -1466,9 +1519,44 @@ contract HorizonAccountingExtension_Unit_Slash is HorizonAccountingExtension_Uni vm.assume(_maxUsersToCheck > 0 && _maxUsersToCheck < type(uint16).max); horizonAccountingExtension.setPledgersForTest(_mockDisputeId, _pledger); - // Check: does it revert if the module is not allowed? + vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_NoEscalationResult.selector); + horizonAccountingExtension.slash(_mockDisputeId, _usersToSlash, _maxUsersToCheck); + } + + function test_revertIfInsufficientBondedTokens( + uint256 _usersToSlash, + uint256 _maxUsersToCheck, + address[] memory _users, + uint256 _pledgesAgainstDispute, + uint256 _bondSize + ) public happyPath(_usersToSlash, _maxUsersToCheck, _users, _pledgesAgainstDispute, _bondSize) { + horizonAccountingExtension.setBondedTokensForTest(_cleanPledgers.at(0), 0); + // Mock and expect the call to oracle checking the dispute status + _mockAndExpect( + address(oracle), + abi.encodeWithSelector(IOracle.disputeStatus.selector, _mockDisputeId), + abi.encode(IOracle.DisputeStatus.Won) + ); + + uint256 _slashAmount = _pledgesAgainstDispute * _bondSize; + + _mockAndExpect( + address(bondEscalationModule), + abi.encodeCall(IBondEscalationModule.pledgesAgainstDispute, (_mockRequestId, _cleanPledgers.at(0))), + abi.encode(_pledgesAgainstDispute) + ); + + _mockAndExpect( + address(horizonStaking), + abi.encodeCall( + IHorizonStaking.slash, (_cleanPledgers.at(0), _slashAmount, _slashAmount, address(horizonAccountingExtension)) + ), + abi.encode(true) + ); + + vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientBondedTokens.selector); horizonAccountingExtension.slash(_mockDisputeId, _usersToSlash, _maxUsersToCheck); } @@ -1487,8 +1575,8 @@ contract HorizonAccountingExtension_Unit_Slash is HorizonAccountingExtension_Uni ); uint256 _length = _cleanPledgers.length(); + uint256 _slashAmount = _pledgesAgainstDispute * _bondSize; - uint256 _slashAmount; for (uint256 _i; _i < _length; _i++) { _mockAndExpect( address(bondEscalationModule), @@ -1496,8 +1584,6 @@ contract HorizonAccountingExtension_Unit_Slash is HorizonAccountingExtension_Uni abi.encode(_pledgesAgainstDispute) ); - _slashAmount = _pledgesAgainstDispute * _bondSize; - _mockAndExpect( address(horizonStaking), abi.encodeCall( @@ -1509,6 +1595,13 @@ contract HorizonAccountingExtension_Unit_Slash is HorizonAccountingExtension_Uni } horizonAccountingExtension.slash(_mockDisputeId, _length, _length); + + uint256 _totalBondedAfter; + for (uint256 _i; _i < _length; _i++) { + _totalBondedAfter = horizonAccountingExtension.totalBonded(_cleanPledgers.at(_i)); + + assertEq(_totalBondedAfter, 0); + } } function test_successfulCallResultionLost( @@ -1526,8 +1619,8 @@ contract HorizonAccountingExtension_Unit_Slash is HorizonAccountingExtension_Uni ); uint256 _length = _cleanPledgers.length(); + uint256 _slashAmount = _pledgesForDispute * _bondSize; - uint256 _slashAmount; for (uint256 _i; _i < _length; _i++) { _mockAndExpect( address(bondEscalationModule), @@ -1535,8 +1628,6 @@ contract HorizonAccountingExtension_Unit_Slash is HorizonAccountingExtension_Uni abi.encode(_pledgesForDispute) ); - _slashAmount = _pledgesForDispute * _bondSize; - _mockAndExpect( address(horizonStaking), abi.encodeCall( @@ -1548,6 +1639,13 @@ contract HorizonAccountingExtension_Unit_Slash is HorizonAccountingExtension_Uni } horizonAccountingExtension.slash(_mockDisputeId, _length, _length); + + uint256 _totalBondedAfter; + for (uint256 _i; _i < _length; _i++) { + _totalBondedAfter = horizonAccountingExtension.totalBonded(_cleanPledgers.at(_i)); + + assertEq(_totalBondedAfter, 0); + } } function test_successfulCallNoResultion( From c9b283ef6dd564216f5850301d3b9c1bcfab7cdb Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Mon, 7 Oct 2024 03:20:05 -0300 Subject: [PATCH 12/14] perf: wipe pledgers list after last escalation reward claim --- src/contracts/HorizonAccountingExtension.sol | 4 +- .../integration/arbitrum/BondEscalation.t.sol | 6 +-- test/unit/HorizonAccountingExtension.t.sol | 50 ++++++++++++++++++- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/contracts/HorizonAccountingExtension.sol b/src/contracts/HorizonAccountingExtension.sol index 16a161c..6a6fd3f 100644 --- a/src/contracts/HorizonAccountingExtension.sol +++ b/src/contracts/HorizonAccountingExtension.sol @@ -239,7 +239,9 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { pledges[_disputeId] -= _claimAmount; - // TODO: Delete _pledgers[_disputeId] if pledges[_disputeId] == 0 + if (pledges[_disputeId] == 0) { + delete _pledgers[_disputeId]; + } emit EscalationRewardClaimed({ _requestId: _requestId, diff --git a/test/integration/arbitrum/BondEscalation.t.sol b/test/integration/arbitrum/BondEscalation.t.sol index 713106d..11259f9 100644 --- a/test/integration/arbitrum/BondEscalation.t.sol +++ b/test/integration/arbitrum/BondEscalation.t.sol @@ -341,8 +341,7 @@ contract IntegrationBondEscalation is IntegrationBase { assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), 0); assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), 0); address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); - assertEq(_pledgers[0], _pledgerFor); // TODO: `_pledgerFor` remains in the pledgers list - assertEq(_pledgers.length, 1); + assertEq(_pledgers.length, 0); // Assert HorizonStaking::slash IHorizonStaking.Provision memory _pledgerForProvision = horizonStaking.getProvision(_pledgerFor, address(horizonAccountingExtension)); @@ -395,8 +394,7 @@ contract IntegrationBondEscalation is IntegrationBase { assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), 0); assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), 0); address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); - assertEq(_pledgers[0], _pledgerAgainst); // TODO: `_pledgerAgainst` remains in the pledgers list - assertEq(_pledgers.length, 1); + assertEq(_pledgers.length, 0); // Assert HorizonStaking::slash IHorizonStaking.Provision memory _pledgerForProvision = horizonStaking.getProvision(_pledgerFor, address(horizonAccountingExtension)); diff --git a/test/unit/HorizonAccountingExtension.t.sol b/test/unit/HorizonAccountingExtension.t.sol index 1faa23c..6867059 100644 --- a/test/unit/HorizonAccountingExtension.t.sol +++ b/test/unit/HorizonAccountingExtension.t.sol @@ -626,6 +626,16 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount ); horizonAccountingExtension.claimEscalationReward(_mockDisputeId, _pledger); + + bool _pledgerClaimedAfter = horizonAccountingExtension.pledgerClaimed(_mockRequestId, _pledger); + uint256 _pledgerTotalBondedAfter = horizonAccountingExtension.totalBonded(_pledger); + uint256 _pledgesAfter = horizonAccountingExtension.pledges(_mockDisputeId); + uint256 _pledgersLengthAfter = horizonAccountingExtension.getPledgersLengthForTest(_mockDisputeId); + + assertTrue(_pledgerClaimedAfter); + assertEq(_pledgerTotalBondedAfter, 0); + assertEq(_pledgesAfter, 0); + assertEq(_pledgersLengthAfter, 0); } function test_successfulCallWonForDispute( @@ -676,6 +686,16 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount ); horizonAccountingExtension.claimEscalationReward(_mockDisputeId, _pledger); + + bool _pledgerClaimedAfter = horizonAccountingExtension.pledgerClaimed(_mockRequestId, _pledger); + uint256 _pledgerTotalBondedAfter = horizonAccountingExtension.totalBonded(_pledger); + uint256 _pledgesAfter = horizonAccountingExtension.pledges(_mockDisputeId); + uint256 _pledgersLengthAfter = horizonAccountingExtension.getPledgersLengthForTest(_mockDisputeId); + + assertTrue(_pledgerClaimedAfter); + assertEq(_pledgerTotalBondedAfter, 0); + assertEq(_pledgesAfter, 0); + assertEq(_pledgersLengthAfter, 0); } function test_successfulCallLostAgainstDispute( @@ -726,6 +746,16 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount ); horizonAccountingExtension.claimEscalationReward(_mockDisputeId, _pledger); + + bool _pledgerClaimedAfter = horizonAccountingExtension.pledgerClaimed(_mockRequestId, _pledger); + uint256 _pledgerTotalBondedAfter = horizonAccountingExtension.totalBonded(_pledger); + uint256 _pledgesAfter = horizonAccountingExtension.pledges(_mockDisputeId); + uint256 _pledgersLengthAfter = horizonAccountingExtension.getPledgersLengthForTest(_mockDisputeId); + + assertTrue(_pledgerClaimedAfter); + assertEq(_pledgerTotalBondedAfter, 0); + assertEq(_pledgesAfter, 0); + assertEq(_pledgersLengthAfter, 0); } function test_successfulCallWinForDisputeSlashing( @@ -789,7 +819,7 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount horizonAccountingExtension.setPledgersForTest(_mockDisputeId, _notSlashedUser); horizonAccountingExtension.setPledgersForTest(_mockDisputeId, _slashedUser); - horizonAccountingExtension.setPledgedForTest(_mockDisputeId, _pledgesForDispute * _amount * _bondSize); + horizonAccountingExtension.setPledgedForTest(_mockDisputeId, _pledgesForDispute * _amount); vm.expectEmit(); emit EscalationRewardClaimed( @@ -802,11 +832,19 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount horizonAccountingExtension.claimEscalationReward(_mockDisputeId, _pledger); + bool _pledgerClaimedAfter = horizonAccountingExtension.pledgerClaimed(_mockRequestId, _pledger); + bool _slashedUserClaimedAfter = horizonAccountingExtension.pledgerClaimed(_mockRequestId, _slashedUser); uint256 _pledgerTotalBondedAfter = horizonAccountingExtension.totalBonded(_pledger); uint256 _slashedUserTotalBondedAfter = horizonAccountingExtension.totalBonded(_slashedUser); + uint256 _pledgesAfter = horizonAccountingExtension.pledges(_mockDisputeId); + uint256 _pledgersLengthAfter = horizonAccountingExtension.getPledgersLengthForTest(_mockDisputeId); + assertTrue(_pledgerClaimedAfter); + assertFalse(_slashedUserClaimedAfter); assertEq(_pledgerTotalBondedAfter, 0); assertEq(_slashedUserTotalBondedAfter, 0); + assertEq(_pledgesAfter, 0); + assertEq(_pledgersLengthAfter, 0); } function test_successfulCallLostAgainstDisputeSlashing( @@ -870,7 +908,7 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount horizonAccountingExtension.setPledgersForTest(_mockDisputeId, _notSlashedUser); horizonAccountingExtension.setPledgersForTest(_mockDisputeId, _slashedUser); - horizonAccountingExtension.setPledgedForTest(_mockDisputeId, _pledgesAgainstDispute * _amount * _bondSize); + horizonAccountingExtension.setPledgedForTest(_mockDisputeId, _pledgesAgainstDispute * _amount); vm.expectEmit(); emit EscalationRewardClaimed( @@ -883,11 +921,19 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount horizonAccountingExtension.claimEscalationReward(_mockDisputeId, _pledger); + bool _pledgerClaimedAfter = horizonAccountingExtension.pledgerClaimed(_mockRequestId, _pledger); + bool _slashedUserClaimedAfter = horizonAccountingExtension.pledgerClaimed(_mockRequestId, _slashedUser); uint256 _pledgerTotalBondedAfter = horizonAccountingExtension.totalBonded(_pledger); uint256 _slashedUserTotalBondedAfter = horizonAccountingExtension.totalBonded(_slashedUser); + uint256 _pledgesAfter = horizonAccountingExtension.pledges(_mockDisputeId); + uint256 _pledgersLengthAfter = horizonAccountingExtension.getPledgersLengthForTest(_mockDisputeId); + assertTrue(_pledgerClaimedAfter); + assertFalse(_slashedUserClaimedAfter); assertEq(_pledgerTotalBondedAfter, 0); assertEq(_slashedUserTotalBondedAfter, 0); + assertEq(_pledgesAfter, 0); + assertEq(_pledgersLengthAfter, 0); } } From 544f7ace06ab943f4e241aaf2ed264caea8c7f1c Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Mon, 7 Oct 2024 03:24:46 -0300 Subject: [PATCH 13/14] feat: remove releasePledge() --- src/contracts/HorizonAccountingExtension.sol | 27 ------ .../IHorizonAccountingExtension.sol | 28 ------ test/unit/HorizonAccountingExtension.t.sol | 88 ------------------- 3 files changed, 143 deletions(-) diff --git a/src/contracts/HorizonAccountingExtension.sol b/src/contracts/HorizonAccountingExtension.sol index 6a6fd3f..73511cf 100644 --- a/src/contracts/HorizonAccountingExtension.sol +++ b/src/contracts/HorizonAccountingExtension.sol @@ -252,33 +252,6 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { }); } - // TODO: Remove? - /// @inheritdoc IHorizonAccountingExtension - function releasePledge( - IOracle.Request calldata _request, - IOracle.Dispute calldata _dispute, - address _pledger, - IERC20, /* _token */ - uint256 _amount - ) external onlyAuthorizedCaller { - bytes32 _requestId = _getId(_request); - bytes32 _disputeId = _validateDispute(_request, _dispute); - - if (!ORACLE.allowedModule(_requestId, msg.sender)) revert HorizonAccountingExtension_UnauthorizedModule(); - - if (_amount > pledges[_disputeId]) revert HorizonAccountingExtension_InsufficientFunds(); - - unchecked { - pledges[_disputeId] -= _amount; - } - - // TODO: _pledgers[_disputeId].remove(_pledger); - - _unbond(_pledger, _amount); - - emit PledgeReleased({_requestId: _requestId, _disputeId: _disputeId, _pledger: _pledger, _amount: _amount}); - } - /// @inheritdoc IHorizonAccountingExtension function pay( bytes32 _requestId, diff --git a/src/interfaces/IHorizonAccountingExtension.sol b/src/interfaces/IHorizonAccountingExtension.sol index aa8caa6..d2b9c95 100644 --- a/src/interfaces/IHorizonAccountingExtension.sol +++ b/src/interfaces/IHorizonAccountingExtension.sol @@ -75,18 +75,6 @@ interface IHorizonAccountingExtension is IValidator { bytes32 _requestId, bytes32 _disputeId, uint256 _amountPerPledger, uint256 _winningPledgersLength ); - /** - * @notice A pledge has been released back to the user - * - * @param _requestId The ID of the bond-escalated request - * @param _disputeId The ID of the bond-escalated dispute - * @param _pledger The user who is getting their tokens released - * @param _amount The amount of GRT released - */ - event PledgeReleased( - bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, uint256 _amount - ); - /** * @notice A user claimed their reward for pledging for the winning side of a dispute * @@ -350,22 +338,6 @@ interface IHorizonAccountingExtension is IValidator { */ function claimEscalationReward(bytes32 _disputeId, address _pledger) external; - /** - * @notice Releases a given amount of funds to the pledger - * @param _request The bond-escalated request - * @param _dispute The bond-escalated dispute - * @param _pledger Address of the pledger - * @param _token Address of the token to be released - * @param _amount Amount of GRT to be released to the pledger - */ - function releasePledge( - IOracle.Request calldata _request, - IOracle.Dispute calldata _dispute, - address _pledger, - IERC20 _token, - uint256 _amount - ) external; - /** * @notice Allows a allowed module to transfer bonded tokens from one user to another * @param _requestId The ID of the request handling the user's tokens diff --git a/test/unit/HorizonAccountingExtension.t.sol b/test/unit/HorizonAccountingExtension.t.sol index 6867059..9083254 100644 --- a/test/unit/HorizonAccountingExtension.t.sol +++ b/test/unit/HorizonAccountingExtension.t.sol @@ -115,9 +115,6 @@ contract HorizonAccountingExtension_Unit_BaseTest is Test, Helpers { event BondEscalationSettled( bytes32 _requestId, bytes32 _disputeId, uint256 _amountPerPledger, uint256 _winningPledgersLength ); - event PledgeReleased( - bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, uint256 _amount - ); event EscalationRewardClaimed( bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, uint256 _reward, uint256 _released ); @@ -937,91 +934,6 @@ contract HorizonAccountingExtension_Unit_ClaimEscalationReward is HorizonAccount } } -contract HorizonAccountingExtension_Unit_ReleasePledge is HorizonAccountingExtension_Unit_BaseTest { - modifier happyPath(address _pledger, uint256 _amount, uint256 _amountPledge) { - vm.assume(_amount > 0); - vm.assume(_amountPledge > _amount); - - horizonAccountingExtension.setPledgedForTest(_mockDisputeId, _amountPledge); - horizonAccountingExtension.setBondedTokensForTest(_pledger, _amount); - - vm.mockCall( - address(oracle), abi.encodeWithSelector(IOracle.disputeCreatedAt.selector, _mockDisputeId), abi.encode(1) - ); - - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_mockRequestId, authorizedCaller)), abi.encode(true) - ); - - vm.startPrank(authorizedCaller); - _; - } - - function test_revertIfUnauthorizedCaller(address _pledger, uint256 _amount) public { - vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedCaller.selector); - - vm.prank(address(bondEscalationModule)); - horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, grt, _amount); - } - - function test_revertIfDisallowedModule(address _pledger, uint256 _amount) public { - vm.mockCall( - address(oracle), abi.encodeWithSelector(IOracle.disputeCreatedAt.selector, _mockDisputeId), abi.encode(1) - ); - - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_mockRequestId, authorizedCaller)), abi.encode(false) - ); - - // Check: does it revert if the module is not allowed? - vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_UnauthorizedModule.selector); - - vm.prank(authorizedCaller); - horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, grt, _amount); - } - - function test_revertIfInsufficientFunds( - address _pledger, - uint256 _amount, - uint256 _amountPledge - ) public happyPath(_pledger, _amount, _amountPledge) { - horizonAccountingExtension.setPledgedForTest(_mockDisputeId, 0); - - vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientFunds.selector); - horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, grt, _amount); - } - - function test_revertIfInsufficientBondedTokens( - address _pledger, - uint256 _amount, - uint256 _amountPledge - ) public happyPath(_pledger, _amount, _amountPledge) { - horizonAccountingExtension.setBondedTokensForTest(_pledger, 0); - - vm.expectRevert(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientBondedTokens.selector); - horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, grt, _amount); - } - - function test_successfulCall( - address _pledger, - uint256 _amount, - uint256 _amountPledge - ) public happyPath(_pledger, _amount, _amountPledge) { - vm.expectEmit(); - emit PledgeReleased(_mockRequestId, _mockDisputeId, _pledger, _amount); - - horizonAccountingExtension.releasePledge(mockRequest, mockDispute, _pledger, grt, _amount); - - uint256 _pledgesAfter = horizonAccountingExtension.pledges(_mockDisputeId); - uint256 _totalBondedAfter = horizonAccountingExtension.totalBonded(_pledger); - - assertEq(_pledgesAfter, _amountPledge - _amount); - assertEq(_totalBondedAfter, _amount - _amount); - } -} - contract HorizonAccountingExtension_Unit_Pay is HorizonAccountingExtension_Unit_BaseTest { function test_revertIfDisallowedModule(bytes32 _requestId, address _payer, address _receiver, uint256 _amount) public { // Mock and expect the call to oracle checking if the module is allowed From 665c7555d4e9e7347ddbbc2908bb68c4192638b5 Mon Sep 17 00:00:00 2001 From: 0xJabberwock <0xjabberwock@defi.sucks> Date: Mon, 7 Oct 2024 03:36:14 -0300 Subject: [PATCH 14/14] feat: remove getPledgers() --- src/contracts/HorizonAccountingExtension.sol | 6 ------ src/interfaces/IHorizonAccountingExtension.sol | 7 ------- test/integration/arbitrum/BondEscalation.t.sol | 14 -------------- 3 files changed, 27 deletions(-) diff --git a/src/contracts/HorizonAccountingExtension.sol b/src/contracts/HorizonAccountingExtension.sol index 73511cf..215a530 100644 --- a/src/contracts/HorizonAccountingExtension.sol +++ b/src/contracts/HorizonAccountingExtension.sol @@ -354,12 +354,6 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension { _approvedModules = _approvals[_user].values(); } - // TODO: Remove if unwanted - /// @inheritdoc IHorizonAccountingExtension - function getPledgers(bytes32 _disputeId) external view returns (address[] memory __pledgers) { - __pledgers = _pledgers[_disputeId].values(); - } - /** * @notice Slash the users that have pledged for a dispute. * @param _disputeId The dispute id. diff --git a/src/interfaces/IHorizonAccountingExtension.sol b/src/interfaces/IHorizonAccountingExtension.sol index d2b9c95..ee6341b 100644 --- a/src/interfaces/IHorizonAccountingExtension.sol +++ b/src/interfaces/IHorizonAccountingExtension.sol @@ -275,13 +275,6 @@ interface IHorizonAccountingExtension is IValidator { */ function approvedModules(address _user) external view returns (address[] memory _approvedModules); - /** - * @notice Returns the pledgers for a dispute - * @param _disputeId The ID of the dispute - * @return _pledgers The pledgers for the dispute - */ - function getPledgers(bytes32 _disputeId) external view returns (address[] memory _pledgers); - /*/////////////////////////////////////////////////////////////// LOGIC //////////////////////////////////////////////////////////////*/ diff --git a/test/integration/arbitrum/BondEscalation.t.sol b/test/integration/arbitrum/BondEscalation.t.sol index 11259f9..1f54776 100644 --- a/test/integration/arbitrum/BondEscalation.t.sol +++ b/test/integration/arbitrum/BondEscalation.t.sol @@ -60,9 +60,6 @@ contract IntegrationBondEscalation is IntegrationBase { // Assert HorizonAccountingExtension::pledge assertEq(horizonAccountingExtension.pledges(_disputeId), disputeBondSize); assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), disputeBondSize); - address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); - assertEq(_pledgers[0], _pledgerFor); - assertEq(_pledgers.length, 1); // Revert if the dispute has already been pledged for, but not pledged against vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); @@ -105,9 +102,6 @@ contract IntegrationBondEscalation is IntegrationBase { // Assert HorizonAccountingExtension::pledge assertEq(horizonAccountingExtension.pledges(_disputeId), disputeBondSize); assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), disputeBondSize); - address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); - assertEq(_pledgers[0], _pledgerAgainst); - assertEq(_pledgers.length, 1); // Revert if the dispute has already been pledged against, but not pledged for vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); @@ -146,10 +140,6 @@ contract IntegrationBondEscalation is IntegrationBase { assertEq(horizonAccountingExtension.pledges(_disputeId), disputeBondSize * maxNumberOfEscalations * 2); assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), disputeBondSize * maxNumberOfEscalations); assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), disputeBondSize * maxNumberOfEscalations); - address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); - assertEq(_pledgers[0], _pledgerFor); - assertEq(_pledgers[1], _pledgerAgainst); - assertEq(_pledgers.length, 2); // Revert if the max number of escalations has been reached vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); @@ -340,8 +330,6 @@ contract IntegrationBondEscalation is IntegrationBase { assertEq(horizonAccountingExtension.pledges(_disputeId), 0); assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), 0); assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), 0); - address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); - assertEq(_pledgers.length, 0); // Assert HorizonStaking::slash IHorizonStaking.Provision memory _pledgerForProvision = horizonStaking.getProvision(_pledgerFor, address(horizonAccountingExtension)); @@ -393,8 +381,6 @@ contract IntegrationBondEscalation is IntegrationBase { assertEq(horizonAccountingExtension.pledges(_disputeId), 0); assertEq(horizonAccountingExtension.totalBonded(_pledgerFor), 0); assertEq(horizonAccountingExtension.totalBonded(_pledgerAgainst), 0); - address[] memory _pledgers = horizonAccountingExtension.getPledgers(_disputeId); - assertEq(_pledgers.length, 0); // Assert HorizonStaking::slash IHorizonStaking.Provision memory _pledgerForProvision = horizonStaking.getProvision(_pledgerFor, address(horizonAccountingExtension));