From f559e53591b0a577bcb01b047717e4cee6ac1d27 Mon Sep 17 00:00:00 2001 From: Gas One Cent <86567384+gas1cent@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:39:30 +0400 Subject: [PATCH] feat: comment out modules --- .../extensions/AccountingExtension.sol | 326 +- .../extensions/BondEscalationAccounting.sol | 268 +- .../modules/dispute/BondEscalationModule.sol | 628 ++-- .../modules/dispute/BondedDisputeModule.sol | 204 +- .../modules/dispute/CircuitResolverModule.sol | 182 +- .../dispute/RootVerificationModule.sol | 188 +- .../modules/finality/CallbackModule.sol | 70 +- .../finality/MultipleCallbacksModule.sol | 116 +- .../request/ContractCallRequestModule.sol | 114 +- .../modules/request/HttpRequestModule.sol | 112 +- .../request/SparseMerkleTreeRequestModule.sol | 114 +- .../modules/resolution/ArbitratorModule.sol | 92 +- .../BondEscalationResolutionModule.sol | 578 ++-- .../resolution/ERC20ResolutionModule.sol | 222 +- .../PrivateERC20ResolutionModule.sol | 286 +- .../resolution/SequentialResolutionModule.sol | 574 ++-- .../modules/response/BondedResponseModule.sol | 236 +- .../extensions/IAccountingExtension.sol | 380 +-- .../extensions/IBondEscalationAccounting.sol | 480 +-- .../modules/dispute/IBondEscalationModule.sol | 500 ++-- .../modules/dispute/IBondedDisputeModule.sol | 132 +- .../dispute/ICircuitResolverModule.sol | 118 +- .../dispute/IRootVerificationModule.sol | 152 +- .../modules/finality/ICallbackModule.sol | 110 +- .../finality/IMultipleCallbacksModule.sol | 118 +- .../request/IContractCallRequestModule.sol | 80 +- .../modules/request/IHttpRequestModule.sol | 114 +- .../ISparseMerkleTreeRequestModule.sol | 100 +- .../modules/resolution/IArbitratorModule.sol | 142 +- .../IBondEscalationResolutionModule.sol | 600 ++-- .../resolution/IERC20ResolutionModule.sol | 284 +- .../IPrivateERC20ResolutionModule.sol | 400 +-- .../ISequentialResolutionModule.sol | 232 +- .../response/IBondedResponseModule.sol | 204 +- solidity/scripts/Deploy.sol | 270 +- .../integration/AccountingExtension.t.sol | 242 +- solidity/test/integration/Arbitration.t.sol | 392 +-- .../test/integration/BondEscalation.t.sol | 918 +++--- .../test/integration/EscalateDispute.t.sol | 256 +- solidity/test/integration/Finalization.t.sol | 570 ++-- solidity/test/integration/IntegrationBase.sol | 270 +- solidity/test/integration/Payments.t.sol | 534 ++-- .../test/integration/RequestCreation.t.sol | 562 ++-- .../test/integration/ResponseDispute.t.sol | 342 +-- .../test/integration/ResponseProposal.t.sol | 366 +-- .../test/integration/RootVerification.t.sol | 390 +-- solidity/test/invariant/InvariantsTest.t.sol | 330 +- solidity/test/mocks/MockAtomicArbitrator.sol | 44 +- solidity/test/unit/AccountingExtension.t.sol | 481 --- .../unit/extensions/AccountingExtension.t.sol | 481 +++ .../dispute/BondEscalationAccounting.t.sol | 1084 +++---- .../dispute/BondEscalationModule.t.sol | 2648 ++++++++--------- .../modules/dispute/BondedDisputeModule.t.sol | 814 ++--- .../dispute/CircuitResolverModule.t.sol | 954 +++--- .../dispute/RootVerificationModule.t.sol | 712 ++--- .../modules/finality/CallbackModule.t.sol | 294 +- .../finality/MultipleCallbacksModule.t.sol | 312 +- .../request/ContractCallRequestModule.t.sol | 620 ++-- .../modules/request/HttpRequestModule.t.sol | 598 ++-- .../SparseMerkleTreeRequestModule.t.sol | 720 ++--- .../modules/resolution/ArbitratorModule.t.sol | 656 ++-- .../BondEscalationResolutionModule.t.sol | 2346 +++++++-------- .../resolution/ERC20ResolutionModule.t.sol | 788 ++--- .../PrivateERC20ResolutionModule.t.sol | 1190 ++++---- .../SequentialResolutionModule.t.sol | 1494 +++++----- .../response/BondedResponseModule.t.sol | 922 +++--- solidity/test/utils/Helpers.sol | 98 +- 67 files changed, 15577 insertions(+), 15577 deletions(-) delete mode 100644 solidity/test/unit/AccountingExtension.t.sol create mode 100644 solidity/test/unit/extensions/AccountingExtension.t.sol diff --git a/solidity/contracts/extensions/AccountingExtension.sol b/solidity/contracts/extensions/AccountingExtension.sol index 214251b0..abfec376 100644 --- a/solidity/contracts/extensions/AccountingExtension.sol +++ b/solidity/contracts/extensions/AccountingExtension.sol @@ -1,163 +1,163 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; -import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; - -import {IAccountingExtension} from '../../interfaces/extensions/IAccountingExtension.sol'; - -contract AccountingExtension is IAccountingExtension { - using SafeERC20 for IERC20; - using EnumerableSet for EnumerableSet.AddressSet; - - /// @inheritdoc IAccountingExtension - IOracle public immutable ORACLE; - - /// @inheritdoc IAccountingExtension - mapping(address _bonder => mapping(IERC20 _token => uint256 _balance)) public balanceOf; - - /// @inheritdoc IAccountingExtension - mapping(address _bonder => mapping(IERC20 _token => mapping(bytes32 _requestId => uint256 _amount))) public - bondedAmountOf; - - /** - * @notice Storing which modules have the users approved to bond their tokens. - */ - mapping(address _bonder => EnumerableSet.AddressSet _modules) internal _approvals; - - constructor(IOracle _oracle) { - ORACLE = _oracle; - } - - /** - * @notice Checks that the caller is an allowed module used in the request. - */ - modifier onlyAllowedModule(bytes32 _requestId) { - if (!ORACLE.allowedModule(_requestId, msg.sender)) revert AccountingExtension_UnauthorizedModule(); - _; - } - - modifier onlyParticipant(bytes32 _requestId, address _user) { - if (!ORACLE.isParticipant(_requestId, _user)) revert AccountingExtension_UnauthorizedUser(); - _; - } - - /// @inheritdoc IAccountingExtension - function deposit(IERC20 _token, uint256 _amount) external { - _token.safeTransferFrom(msg.sender, address(this), _amount); - balanceOf[msg.sender][_token] += _amount; - emit Deposited(msg.sender, _token, _amount); - } - - /// @inheritdoc IAccountingExtension - function withdraw(IERC20 _token, uint256 _amount) external { - uint256 _balance = balanceOf[msg.sender][_token]; - - if (_balance < _amount) revert AccountingExtension_InsufficientFunds(); - - unchecked { - balanceOf[msg.sender][_token] -= _amount; - } - - _token.safeTransfer(msg.sender, _amount); - - emit Withdrew(msg.sender, _token, _amount); - } - - /// @inheritdoc IAccountingExtension - function pay( - bytes32 _requestId, - address _payer, - address _receiver, - IERC20 _token, - uint256 _amount - ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _payer) onlyParticipant(_requestId, _receiver) { - if (bondedAmountOf[_payer][_token][_requestId] < _amount) { - revert AccountingExtension_InsufficientFunds(); - } - - balanceOf[_receiver][_token] += _amount; - - unchecked { - bondedAmountOf[_payer][_token][_requestId] -= _amount; - } - - emit Paid({_requestId: _requestId, _beneficiary: _receiver, _payer: _payer, _token: _token, _amount: _amount}); - } - - /// @inheritdoc IAccountingExtension - function bond( - address _bonder, - bytes32 _requestId, - IERC20 _token, - uint256 _amount - ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _bonder) { - if (!_approvals[_bonder].contains(msg.sender)) revert AccountingExtension_InsufficientAllowance(); - if (balanceOf[_bonder][_token] < _amount) revert AccountingExtension_InsufficientFunds(); - - bondedAmountOf[_bonder][_token][_requestId] += _amount; - - unchecked { - balanceOf[_bonder][_token] -= _amount; - } - - emit Bonded(_requestId, _bonder, _token, _amount); - } - - /// @inheritdoc IAccountingExtension - function bond( - address _bonder, - bytes32 _requestId, - IERC20 _token, - uint256 _amount, - address _sender - ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _bonder) { - if (!(_approvals[_bonder].contains(msg.sender) || _approvals[_bonder].contains(_sender))) { - revert AccountingExtension_InsufficientAllowance(); - } - if (balanceOf[_bonder][_token] < _amount) revert AccountingExtension_InsufficientFunds(); - - bondedAmountOf[_bonder][_token][_requestId] += _amount; - - unchecked { - balanceOf[_bonder][_token] -= _amount; - } - - emit Bonded(_requestId, _bonder, _token, _amount); - } - - /// @inheritdoc IAccountingExtension - function release( - address _bonder, - bytes32 _requestId, - IERC20 _token, - uint256 _amount - ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _bonder) { - if (bondedAmountOf[_bonder][_token][_requestId] < _amount) revert AccountingExtension_InsufficientFunds(); - - balanceOf[_bonder][_token] += _amount; - - unchecked { - bondedAmountOf[_bonder][_token][_requestId] -= _amount; - } - - emit Released(_requestId, _bonder, _token, _amount); - } - - /// @inheritdoc IAccountingExtension - function approveModule(address _module) external { - _approvals[msg.sender].add(_module); - } - - /// @inheritdoc IAccountingExtension - function revokeModule(address _module) external { - _approvals[msg.sender].remove(_module); - } - - /// @inheritdoc IAccountingExtension - function approvedModules(address _user) external view returns (address[] memory _approvedModules) { - _approvedModules = _approvals[_user].values(); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +// import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; + +// import {IAccountingExtension} from '../../interfaces/extensions/IAccountingExtension.sol'; + +// contract AccountingExtension is IAccountingExtension { +// using SafeERC20 for IERC20; +// using EnumerableSet for EnumerableSet.AddressSet; + +// /// @inheritdoc IAccountingExtension +// IOracle public immutable ORACLE; + +// /// @inheritdoc IAccountingExtension +// mapping(address _bonder => mapping(IERC20 _token => uint256 _balance)) public balanceOf; + +// /// @inheritdoc IAccountingExtension +// mapping(address _bonder => mapping(IERC20 _token => mapping(bytes32 _requestId => uint256 _amount))) public +// bondedAmountOf; + +// /** +// * @notice Storing which modules have the users approved to bond their tokens. +// */ +// mapping(address _bonder => EnumerableSet.AddressSet _modules) internal _approvals; + +// constructor(IOracle _oracle) { +// ORACLE = _oracle; +// } + +// /** +// * @notice Checks that the caller is an allowed module used in the request. +// */ +// modifier onlyAllowedModule(bytes32 _requestId) { +// if (!ORACLE.allowedModule(_requestId, msg.sender)) revert AccountingExtension_UnauthorizedModule(); +// _; +// } + +// modifier onlyParticipant(bytes32 _requestId, address _user) { +// if (!ORACLE.isParticipant(_requestId, _user)) revert AccountingExtension_UnauthorizedUser(); +// _; +// } + +// /// @inheritdoc IAccountingExtension +// function deposit(IERC20 _token, uint256 _amount) external { +// _token.safeTransferFrom(msg.sender, address(this), _amount); +// balanceOf[msg.sender][_token] += _amount; +// emit Deposited(msg.sender, _token, _amount); +// } + +// /// @inheritdoc IAccountingExtension +// function withdraw(IERC20 _token, uint256 _amount) external { +// uint256 _balance = balanceOf[msg.sender][_token]; + +// if (_balance < _amount) revert AccountingExtension_InsufficientFunds(); + +// unchecked { +// balanceOf[msg.sender][_token] -= _amount; +// } + +// _token.safeTransfer(msg.sender, _amount); + +// emit Withdrew(msg.sender, _token, _amount); +// } + +// /// @inheritdoc IAccountingExtension +// function pay( +// bytes32 _requestId, +// address _payer, +// address _receiver, +// IERC20 _token, +// uint256 _amount +// ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _payer) onlyParticipant(_requestId, _receiver) { +// if (bondedAmountOf[_payer][_token][_requestId] < _amount) { +// revert AccountingExtension_InsufficientFunds(); +// } + +// balanceOf[_receiver][_token] += _amount; + +// unchecked { +// bondedAmountOf[_payer][_token][_requestId] -= _amount; +// } + +// emit Paid({_requestId: _requestId, _beneficiary: _receiver, _payer: _payer, _token: _token, _amount: _amount}); +// } + +// /// @inheritdoc IAccountingExtension +// function bond( +// address _bonder, +// bytes32 _requestId, +// IERC20 _token, +// uint256 _amount +// ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _bonder) { +// if (!_approvals[_bonder].contains(msg.sender)) revert AccountingExtension_InsufficientAllowance(); +// if (balanceOf[_bonder][_token] < _amount) revert AccountingExtension_InsufficientFunds(); + +// bondedAmountOf[_bonder][_token][_requestId] += _amount; + +// unchecked { +// balanceOf[_bonder][_token] -= _amount; +// } + +// emit Bonded(_requestId, _bonder, _token, _amount); +// } + +// /// @inheritdoc IAccountingExtension +// function bond( +// address _bonder, +// bytes32 _requestId, +// IERC20 _token, +// uint256 _amount, +// address _sender +// ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _bonder) { +// if (!(_approvals[_bonder].contains(msg.sender) || _approvals[_bonder].contains(_sender))) { +// revert AccountingExtension_InsufficientAllowance(); +// } +// if (balanceOf[_bonder][_token] < _amount) revert AccountingExtension_InsufficientFunds(); + +// bondedAmountOf[_bonder][_token][_requestId] += _amount; + +// unchecked { +// balanceOf[_bonder][_token] -= _amount; +// } + +// emit Bonded(_requestId, _bonder, _token, _amount); +// } + +// /// @inheritdoc IAccountingExtension +// function release( +// address _bonder, +// bytes32 _requestId, +// IERC20 _token, +// uint256 _amount +// ) external onlyAllowedModule(_requestId) onlyParticipant(_requestId, _bonder) { +// if (bondedAmountOf[_bonder][_token][_requestId] < _amount) revert AccountingExtension_InsufficientFunds(); + +// balanceOf[_bonder][_token] += _amount; + +// unchecked { +// bondedAmountOf[_bonder][_token][_requestId] -= _amount; +// } + +// emit Released(_requestId, _bonder, _token, _amount); +// } + +// /// @inheritdoc IAccountingExtension +// function approveModule(address _module) external { +// _approvals[msg.sender].add(_module); +// } + +// /// @inheritdoc IAccountingExtension +// function revokeModule(address _module) external { +// _approvals[msg.sender].remove(_module); +// } + +// /// @inheritdoc IAccountingExtension +// function approvedModules(address _user) external view returns (address[] memory _approvedModules) { +// _approvedModules = _approvals[_user].values(); +// } +// } diff --git a/solidity/contracts/extensions/BondEscalationAccounting.sol b/solidity/contracts/extensions/BondEscalationAccounting.sol index 3efe1e2a..3c75595d 100644 --- a/solidity/contracts/extensions/BondEscalationAccounting.sol +++ b/solidity/contracts/extensions/BondEscalationAccounting.sol @@ -1,134 +1,134 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; - -import {AccountingExtension} from './AccountingExtension.sol'; - -import {IBondEscalationAccounting} from '../../interfaces/extensions/IBondEscalationAccounting.sol'; -import {IBondEscalationModule} from '../../interfaces/modules/dispute/IBondEscalationModule.sol'; - -contract BondEscalationAccounting is AccountingExtension, IBondEscalationAccounting { - /// @inheritdoc IBondEscalationAccounting - mapping(bytes32 _disputeId => mapping(IERC20 _token => uint256 _amount)) public pledges; - - /// @inheritdoc IBondEscalationAccounting - mapping(bytes32 _disputeId => EscalationResult _result) public escalationResults; - - /// @inheritdoc IBondEscalationAccounting - mapping(bytes32 _requestId => mapping(address _pledger => bool)) public pledgerClaimed; - - constructor(IOracle _oracle) AccountingExtension(_oracle) {} - - /// @inheritdoc IBondEscalationAccounting - function pledge( - address _pledger, - bytes32 _requestId, - bytes32 _disputeId, - IERC20 _token, - uint256 _amount - ) external onlyAllowedModule(_requestId) { - if (balanceOf[_pledger][_token] < _amount) revert BondEscalationAccounting_InsufficientFunds(); - - pledges[_disputeId][_token] += _amount; - - unchecked { - balanceOf[_pledger][_token] -= _amount; - } - - emit Pledged({_pledger: _pledger, _requestId: _requestId, _disputeId: _disputeId, _token: _token, _amount: _amount}); - } - - /// @inheritdoc IBondEscalationAccounting - function onSettleBondEscalation( - bytes32 _requestId, - bytes32 _disputeId, - bool _forVotesWon, - IERC20 _token, - uint256 _amountPerPledger, - uint256 _winningPledgersLength - ) external onlyAllowedModule(_requestId) { - // TODO: check that flooring at _amountPerPledger calculation doesn't mess with this check - if (pledges[_disputeId][_token] < _amountPerPledger * _winningPledgersLength) { - revert BondEscalationAccounting_InsufficientFunds(); - } - - if (escalationResults[_disputeId].requestId != bytes32(0)) { - revert BondEscalationAccounting_AlreadySettled(); - } - - escalationResults[_disputeId] = EscalationResult({ - requestId: _requestId, - forVotesWon: _forVotesWon, - token: _token, - amountPerPledger: _amountPerPledger, - bondEscalationModule: IBondEscalationModule(msg.sender) - }); - - emit BondEscalationSettled({ - _requestId: _requestId, - _disputeId: _disputeId, - _forVotesWon: _forVotesWon, - _token: _token, - _amountPerPledger: _amountPerPledger, - _winningPledgersLength: _winningPledgersLength - }); - } - - /// @inheritdoc IBondEscalationAccounting - function claimEscalationReward(bytes32 _disputeId, address _pledger) external { - EscalationResult memory _result = escalationResults[_disputeId]; - if (_result.token == IERC20(address(0))) revert BondEscalationAccounting_NoEscalationResult(); - bytes32 _requestId = _result.requestId; - if (pledgerClaimed[_requestId][_pledger]) revert BondEscalationAccounting_AlreadyClaimed(); - - uint256 _amountPerPledger = _result.amountPerPledger; - uint256 _numberOfPledges = _result.forVotesWon - ? _result.bondEscalationModule.pledgesForDispute(_requestId, _pledger) - : _result.bondEscalationModule.pledgesAgainstDispute(_requestId, _pledger); - - IERC20 _token = _result.token; - uint256 _claimAmount = _amountPerPledger * _numberOfPledges; - - pledgerClaimed[_requestId][_pledger] = true; - balanceOf[_pledger][_token] += _claimAmount; - - unchecked { - pledges[_disputeId][_token] -= _claimAmount; - } - - emit EscalationRewardClaimed({ - _requestId: _requestId, - _disputeId: _disputeId, - _pledger: _pledger, - _token: _result.token, - _amount: _claimAmount - }); - } - - /// @inheritdoc IBondEscalationAccounting - function releasePledge( - bytes32 _requestId, - bytes32 _disputeId, - address _pledger, - IERC20 _token, - uint256 _amount - ) external onlyAllowedModule(_requestId) { - if (pledges[_disputeId][_token] < _amount) revert BondEscalationAccounting_InsufficientFunds(); - - balanceOf[_pledger][_token] += _amount; - - unchecked { - pledges[_disputeId][_token] -= _amount; - } - - emit PledgeReleased({ - _requestId: _requestId, - _disputeId: _disputeId, - _pledger: _pledger, - _token: _token, - _amount: _amount - }); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; + +// import {AccountingExtension} from './AccountingExtension.sol'; + +// import {IBondEscalationAccounting} from '../../interfaces/extensions/IBondEscalationAccounting.sol'; +// import {IBondEscalationModule} from '../../interfaces/modules/dispute/IBondEscalationModule.sol'; + +// contract BondEscalationAccounting is AccountingExtension, IBondEscalationAccounting { +// /// @inheritdoc IBondEscalationAccounting +// mapping(bytes32 _disputeId => mapping(IERC20 _token => uint256 _amount)) public pledges; + +// /// @inheritdoc IBondEscalationAccounting +// mapping(bytes32 _disputeId => EscalationResult _result) public escalationResults; + +// /// @inheritdoc IBondEscalationAccounting +// mapping(bytes32 _requestId => mapping(address _pledger => bool)) public pledgerClaimed; + +// constructor(IOracle _oracle) AccountingExtension(_oracle) {} + +// /// @inheritdoc IBondEscalationAccounting +// function pledge( +// address _pledger, +// bytes32 _requestId, +// bytes32 _disputeId, +// IERC20 _token, +// uint256 _amount +// ) external onlyAllowedModule(_requestId) { +// if (balanceOf[_pledger][_token] < _amount) revert BondEscalationAccounting_InsufficientFunds(); + +// pledges[_disputeId][_token] += _amount; + +// unchecked { +// balanceOf[_pledger][_token] -= _amount; +// } + +// emit Pledged({_pledger: _pledger, _requestId: _requestId, _disputeId: _disputeId, _token: _token, _amount: _amount}); +// } + +// /// @inheritdoc IBondEscalationAccounting +// function onSettleBondEscalation( +// bytes32 _requestId, +// bytes32 _disputeId, +// bool _forVotesWon, +// IERC20 _token, +// uint256 _amountPerPledger, +// uint256 _winningPledgersLength +// ) external onlyAllowedModule(_requestId) { +// // TODO: check that flooring at _amountPerPledger calculation doesn't mess with this check +// if (pledges[_disputeId][_token] < _amountPerPledger * _winningPledgersLength) { +// revert BondEscalationAccounting_InsufficientFunds(); +// } + +// if (escalationResults[_disputeId].requestId != bytes32(0)) { +// revert BondEscalationAccounting_AlreadySettled(); +// } + +// escalationResults[_disputeId] = EscalationResult({ +// requestId: _requestId, +// forVotesWon: _forVotesWon, +// token: _token, +// amountPerPledger: _amountPerPledger, +// bondEscalationModule: IBondEscalationModule(msg.sender) +// }); + +// emit BondEscalationSettled({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _forVotesWon: _forVotesWon, +// _token: _token, +// _amountPerPledger: _amountPerPledger, +// _winningPledgersLength: _winningPledgersLength +// }); +// } + +// /// @inheritdoc IBondEscalationAccounting +// function claimEscalationReward(bytes32 _disputeId, address _pledger) external { +// EscalationResult memory _result = escalationResults[_disputeId]; +// if (_result.token == IERC20(address(0))) revert BondEscalationAccounting_NoEscalationResult(); +// bytes32 _requestId = _result.requestId; +// if (pledgerClaimed[_requestId][_pledger]) revert BondEscalationAccounting_AlreadyClaimed(); + +// uint256 _amountPerPledger = _result.amountPerPledger; +// uint256 _numberOfPledges = _result.forVotesWon +// ? _result.bondEscalationModule.pledgesForDispute(_requestId, _pledger) +// : _result.bondEscalationModule.pledgesAgainstDispute(_requestId, _pledger); + +// IERC20 _token = _result.token; +// uint256 _claimAmount = _amountPerPledger * _numberOfPledges; + +// pledgerClaimed[_requestId][_pledger] = true; +// balanceOf[_pledger][_token] += _claimAmount; + +// unchecked { +// pledges[_disputeId][_token] -= _claimAmount; +// } + +// emit EscalationRewardClaimed({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _pledger: _pledger, +// _token: _result.token, +// _amount: _claimAmount +// }); +// } + +// /// @inheritdoc IBondEscalationAccounting +// function releasePledge( +// bytes32 _requestId, +// bytes32 _disputeId, +// address _pledger, +// IERC20 _token, +// uint256 _amount +// ) external onlyAllowedModule(_requestId) { +// if (pledges[_disputeId][_token] < _amount) revert BondEscalationAccounting_InsufficientFunds(); + +// balanceOf[_pledger][_token] += _amount; + +// unchecked { +// pledges[_disputeId][_token] -= _amount; +// } + +// emit PledgeReleased({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _pledger: _pledger, +// _token: _token, +// _amount: _amount +// }); +// } +// } diff --git a/solidity/contracts/modules/dispute/BondEscalationModule.sol b/solidity/contracts/modules/dispute/BondEscalationModule.sol index e0785b51..ce44ec97 100644 --- a/solidity/contracts/modules/dispute/BondEscalationModule.sol +++ b/solidity/contracts/modules/dispute/BondEscalationModule.sol @@ -1,314 +1,314 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {FixedPointMathLib} from 'solmate/utils/FixedPointMathLib.sol'; - -import {IBondEscalationModule} from '../../../interfaces/modules/dispute/IBondEscalationModule.sol'; - -contract BondEscalationModule is Module, IBondEscalationModule { - /// @inheritdoc IBondEscalationModule - mapping(bytes32 _requestId => mapping(address _pledger => uint256 pledges)) public pledgesForDispute; - - /// @inheritdoc IBondEscalationModule - mapping(bytes32 _requestId => mapping(address _pledger => uint256 pledges)) public pledgesAgainstDispute; - - /** - * @notice Struct containing all the data for a given escalation. - */ - mapping(bytes32 _requestId => BondEscalation) internal _escalations; - - constructor(IOracle _oracle) Module(_oracle) {} - - /// @inheritdoc IModule - function moduleName() external pure returns (string memory _moduleName) { - return 'BondEscalationModule'; - } - - /** - * @notice Checks if the escalation parameters are valid - * @param _data The encoded data for the request - */ - function _afterSetupRequest(bytes32, bytes calldata _data) internal pure override { - RequestParameters memory _params = abi.decode(_data, (RequestParameters)); - if (_params.maxNumberOfEscalations == 0 || _params.bondSize == 0) { - revert BondEscalationModule_InvalidEscalationParameters(); - } - } - - /// @inheritdoc IBondEscalationModule - function disputeEscalated(bytes32 _disputeId) external onlyOracle { - IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); - bytes32 _requestId = _dispute.requestId; - BondEscalation storage _escalation = _escalations[_requestId]; - - if (_requestId == bytes32(0)) revert BondEscalationModule_DisputeDoesNotExist(); - - if (_disputeId == _escalation.disputeId) { - RequestParameters memory _params = decodeRequestData(_requestId); - if (block.timestamp <= _params.bondEscalationDeadline) revert BondEscalationModule_BondEscalationNotOver(); - - if ( - _escalation.status != BondEscalationStatus.Active - || _escalation.amountOfPledgesForDispute != _escalation.amountOfPledgesAgainstDispute - ) { - revert BondEscalationModule_NotEscalatable(); - } - - _escalation.status = BondEscalationStatus.Escalated; - emit BondEscalationStatusUpdated(_requestId, _disputeId, BondEscalationStatus.Escalated); - } - } - - /// @inheritdoc IBondEscalationModule - function disputeResponse( - bytes32 _requestId, - bytes32 _responseId, - address _disputer, - address _proposer - ) external onlyOracle returns (IOracle.Dispute memory _dispute) { - RequestParameters memory _params = decodeRequestData(_requestId); - IOracle.Response memory _response = ORACLE.getResponse(_responseId); - - if (block.timestamp > _response.createdAt + _params.disputeWindow) { - revert BondEscalationModule_DisputeWindowOver(); - } - - BondEscalation storage _escalation = _escalations[_requestId]; - - // Only the first dispute of a request should go through the bond escalation - // Consecutive disputes should be handled by the resolution module - if (_escalation.status == BondEscalationStatus.None) { - if (block.timestamp > _params.bondEscalationDeadline) revert BondEscalationModule_BondEscalationOver(); - - // Note: this imitates the way _disputeId is calculated on the Oracle, it must always match - bytes32 _disputeId = keccak256(abi.encodePacked(_disputer, _requestId, _responseId)); - _escalation.status = BondEscalationStatus.Active; - _escalation.disputeId = _disputeId; - emit BondEscalationStatusUpdated(_requestId, _disputeId, BondEscalationStatus.Active); - } - - _dispute = IOracle.Dispute({ - disputer: _disputer, - responseId: _responseId, - proposer: _proposer, - requestId: _requestId, - status: IOracle.DisputeStatus.Active, - createdAt: block.timestamp - }); - - _params.accountingExtension.bond({ - _bonder: _disputer, - _requestId: _requestId, - _token: _params.bondToken, - _amount: _params.bondSize - }); - - emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); - } - - /// @inheritdoc IBondEscalationModule - function onDisputeStatusChange(bytes32 _disputeId, IOracle.Dispute memory _dispute) external onlyOracle { - RequestParameters memory _params = decodeRequestData(_dispute.requestId); - - bool _won = _dispute.status == IOracle.DisputeStatus.Won; - - _params.accountingExtension.pay({ - _requestId: _dispute.requestId, - _payer: _won ? _dispute.proposer : _dispute.disputer, - _receiver: _won ? _dispute.disputer : _dispute.proposer, - _token: _params.bondToken, - _amount: _params.bondSize - }); - - if (_won) { - _params.accountingExtension.release({ - _requestId: _dispute.requestId, - _bonder: _dispute.disputer, - _token: _params.bondToken, - _amount: _params.bondSize - }); - } - - BondEscalation storage _escalation = _escalations[_dispute.requestId]; - - if (_disputeId == _escalation.disputeId) { - // The dispute has been escalated to the Resolution module - if (_escalation.status == BondEscalationStatus.Escalated) { - if (_escalation.amountOfPledgesAgainstDispute == 0) { - return; - } - - BondEscalationStatus _newStatus = _won ? BondEscalationStatus.DisputerWon : BondEscalationStatus.DisputerLost; - _escalation.status = _newStatus; - - emit BondEscalationStatusUpdated(_dispute.requestId, _disputeId, _newStatus); - - _params.accountingExtension.onSettleBondEscalation({ - _requestId: _dispute.requestId, - _disputeId: _disputeId, - _forVotesWon: _won, - _token: _params.bondToken, - _amountPerPledger: _params.bondSize << 1, - _winningPledgersLength: _won ? _escalation.amountOfPledgesForDispute : _escalation.amountOfPledgesAgainstDispute - }); - } else { - // The status has changed to Won or Lost - uint256 _pledgesForDispute = _escalation.amountOfPledgesForDispute; - uint256 _pledgesAgainstDispute = _escalation.amountOfPledgesAgainstDispute; - bool _disputersWon = _pledgesForDispute > _pledgesAgainstDispute; - - uint256 _amountToPay = _disputersWon - ? _params.bondSize + FixedPointMathLib.mulDivDown(_pledgesAgainstDispute, _params.bondSize, _pledgesForDispute) - : _params.bondSize + FixedPointMathLib.mulDivDown(_pledgesForDispute, _params.bondSize, _pledgesAgainstDispute); - - _params.accountingExtension.onSettleBondEscalation({ - _requestId: _dispute.requestId, - _disputeId: _escalation.disputeId, - _forVotesWon: _disputersWon, - _token: _params.bondToken, - _amountPerPledger: _amountToPay, - _winningPledgersLength: _disputersWon ? _pledgesForDispute : _pledgesAgainstDispute - }); - } - } - - emit DisputeStatusChanged({ - _requestId: _dispute.requestId, - _responseId: _dispute.responseId, - _disputer: _dispute.disputer, - _proposer: _dispute.proposer, - _status: _dispute.status - }); - } - - //////////////////////////////////////////////////////////////////// - // Bond Escalation Exclusive Functions - //////////////////////////////////////////////////////////////////// - - /// @inheritdoc IBondEscalationModule - function pledgeForDispute(bytes32 _disputeId) external { - (bytes32 _requestId, RequestParameters memory _params) = _pledgeChecks(_disputeId, true); - - _escalations[_requestId].amountOfPledgesForDispute += 1; - pledgesForDispute[_requestId][msg.sender] += 1; - _params.accountingExtension.pledge({ - _pledger: msg.sender, - _requestId: _requestId, - _disputeId: _disputeId, - _token: _params.bondToken, - _amount: _params.bondSize - }); - - emit PledgedForDispute(_disputeId, msg.sender, _params.bondSize); - } - - /// @inheritdoc IBondEscalationModule - function pledgeAgainstDispute(bytes32 _disputeId) external { - (bytes32 _requestId, RequestParameters memory _params) = _pledgeChecks(_disputeId, false); - - _escalations[_requestId].amountOfPledgesAgainstDispute += 1; - pledgesAgainstDispute[_requestId][msg.sender] += 1; - _params.accountingExtension.pledge({ - _pledger: msg.sender, - _requestId: _requestId, - _disputeId: _disputeId, - _token: _params.bondToken, - _amount: _params.bondSize - }); - - emit PledgedAgainstDispute(_disputeId, msg.sender, _params.bondSize); - } - - /// @inheritdoc IBondEscalationModule - function settleBondEscalation(bytes32 _requestId) external { - RequestParameters memory _params = decodeRequestData(_requestId); - BondEscalation storage _escalation = _escalations[_requestId]; - - if (block.timestamp <= _params.bondEscalationDeadline + _params.tyingBuffer) { - revert BondEscalationModule_BondEscalationNotOver(); - } - - if (_escalation.status != BondEscalationStatus.Active) { - revert BondEscalationModule_BondEscalationCantBeSettled(); - } - - uint256 _pledgesForDispute = _escalation.amountOfPledgesForDispute; - uint256 _pledgesAgainstDispute = _escalation.amountOfPledgesAgainstDispute; - - if (_pledgesForDispute == _pledgesAgainstDispute) { - revert BondEscalationModule_ShouldBeEscalated(); - } - - bool _disputersWon = _pledgesForDispute > _pledgesAgainstDispute; - _escalation.status = _disputersWon ? BondEscalationStatus.DisputerWon : BondEscalationStatus.DisputerLost; - - emit BondEscalationStatusUpdated(_requestId, _escalation.disputeId, _escalation.status); - - ORACLE.updateDisputeStatus( - _escalation.disputeId, _disputersWon ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost - ); - } - - /** - * @notice Checks the necessary conditions for pledging - * @param _disputeId The encoded data for the request - * @return _requestId The ID of the request being disputed on - * @return _params The decoded parameters for the request - */ - function _pledgeChecks( - bytes32 _disputeId, - bool _forDispute - ) internal view returns (bytes32 _requestId, RequestParameters memory _params) { - if (_disputeId == 0) revert BondEscalationModule_DisputeDoesNotExist(); - - IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); - _requestId = _dispute.requestId; - BondEscalation memory _escalation = _escalations[_requestId]; - - if (_disputeId != _escalation.disputeId) { - revert BondEscalationModule_InvalidDispute(); - } - - _params = decodeRequestData(_requestId); - - if (block.timestamp > _params.bondEscalationDeadline + _params.tyingBuffer) { - revert BondEscalationModule_BondEscalationOver(); - } - - uint256 _numPledgersForDispute = _escalation.amountOfPledgesForDispute; - uint256 _numPledgersAgainstDispute = _escalation.amountOfPledgesAgainstDispute; - - if (_forDispute) { - if (_numPledgersForDispute == _params.maxNumberOfEscalations) { - revert BondEscalationModule_MaxNumberOfEscalationsReached(); - } - if (_numPledgersForDispute > _numPledgersAgainstDispute) revert BondEscalationModule_CanOnlySurpassByOnePledge(); - } else { - if (_numPledgersAgainstDispute == _params.maxNumberOfEscalations) { - revert BondEscalationModule_MaxNumberOfEscalationsReached(); - } - if (_numPledgersAgainstDispute > _numPledgersForDispute) revert BondEscalationModule_CanOnlySurpassByOnePledge(); - } - - if (block.timestamp > _params.bondEscalationDeadline && _numPledgersForDispute == _numPledgersAgainstDispute) { - revert BondEscalationModule_CannotBreakTieDuringTyingBuffer(); - } - } - - //////////////////////////////////////////////////////////////////// - // View Functions - //////////////////////////////////////////////////////////////////// - - /// @inheritdoc IBondEscalationModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } - - /// @inheritdoc IBondEscalationModule - function getEscalation(bytes32 _requestId) public view returns (BondEscalation memory _escalation) { - _escalation = _escalations[_requestId]; - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {FixedPointMathLib} from 'solmate/utils/FixedPointMathLib.sol'; + +// import {IBondEscalationModule} from '../../../interfaces/modules/dispute/IBondEscalationModule.sol'; + +// contract BondEscalationModule is Module, IBondEscalationModule { +// /// @inheritdoc IBondEscalationModule +// mapping(bytes32 _requestId => mapping(address _pledger => uint256 pledges)) public pledgesForDispute; + +// /// @inheritdoc IBondEscalationModule +// mapping(bytes32 _requestId => mapping(address _pledger => uint256 pledges)) public pledgesAgainstDispute; + +// /** +// * @notice Struct containing all the data for a given escalation. +// */ +// mapping(bytes32 _requestId => BondEscalation) internal _escalations; + +// constructor(IOracle _oracle) Module(_oracle) {} + +// /// @inheritdoc IModule +// function moduleName() external pure returns (string memory _moduleName) { +// return 'BondEscalationModule'; +// } + +// /** +// * @notice Checks if the escalation parameters are valid +// * @param _data The encoded data for the request +// */ +// function _afterSetupRequest(bytes32, bytes calldata _data) internal pure override { +// RequestParameters memory _params = abi.decode(_data, (RequestParameters)); +// if (_params.maxNumberOfEscalations == 0 || _params.bondSize == 0) { +// revert BondEscalationModule_InvalidEscalationParameters(); +// } +// } + +// /// @inheritdoc IBondEscalationModule +// function disputeEscalated(bytes32 _disputeId) external onlyOracle { +// IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); +// bytes32 _requestId = _dispute.requestId; +// BondEscalation storage _escalation = _escalations[_requestId]; + +// if (_requestId == bytes32(0)) revert BondEscalationModule_DisputeDoesNotExist(); + +// if (_disputeId == _escalation.disputeId) { +// RequestParameters memory _params = decodeRequestData(_requestId); +// if (block.timestamp <= _params.bondEscalationDeadline) revert BondEscalationModule_BondEscalationNotOver(); + +// if ( +// _escalation.status != BondEscalationStatus.Active +// || _escalation.amountOfPledgesForDispute != _escalation.amountOfPledgesAgainstDispute +// ) { +// revert BondEscalationModule_NotEscalatable(); +// } + +// _escalation.status = BondEscalationStatus.Escalated; +// emit BondEscalationStatusUpdated(_requestId, _disputeId, BondEscalationStatus.Escalated); +// } +// } + +// /// @inheritdoc IBondEscalationModule +// function disputeResponse( +// bytes32 _requestId, +// bytes32 _responseId, +// address _disputer, +// address _proposer +// ) external onlyOracle returns (IOracle.Dispute memory _dispute) { +// RequestParameters memory _params = decodeRequestData(_requestId); +// IOracle.Response memory _response = ORACLE.getResponse(_responseId); + +// if (block.timestamp > _response.createdAt + _params.disputeWindow) { +// revert BondEscalationModule_DisputeWindowOver(); +// } + +// BondEscalation storage _escalation = _escalations[_requestId]; + +// // Only the first dispute of a request should go through the bond escalation +// // Consecutive disputes should be handled by the resolution module +// if (_escalation.status == BondEscalationStatus.None) { +// if (block.timestamp > _params.bondEscalationDeadline) revert BondEscalationModule_BondEscalationOver(); + +// // Note: this imitates the way _disputeId is calculated on the Oracle, it must always match +// bytes32 _disputeId = keccak256(abi.encodePacked(_disputer, _requestId, _responseId)); +// _escalation.status = BondEscalationStatus.Active; +// _escalation.disputeId = _disputeId; +// emit BondEscalationStatusUpdated(_requestId, _disputeId, BondEscalationStatus.Active); +// } + +// _dispute = IOracle.Dispute({ +// disputer: _disputer, +// responseId: _responseId, +// proposer: _proposer, +// requestId: _requestId, +// status: IOracle.DisputeStatus.Active, +// createdAt: block.timestamp +// }); + +// _params.accountingExtension.bond({ +// _bonder: _disputer, +// _requestId: _requestId, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); + +// emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); +// } + +// /// @inheritdoc IBondEscalationModule +// function onDisputeStatusChange(bytes32 _disputeId, IOracle.Dispute memory _dispute) external onlyOracle { +// RequestParameters memory _params = decodeRequestData(_dispute.requestId); + +// bool _won = _dispute.status == IOracle.DisputeStatus.Won; + +// _params.accountingExtension.pay({ +// _requestId: _dispute.requestId, +// _payer: _won ? _dispute.proposer : _dispute.disputer, +// _receiver: _won ? _dispute.disputer : _dispute.proposer, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); + +// if (_won) { +// _params.accountingExtension.release({ +// _requestId: _dispute.requestId, +// _bonder: _dispute.disputer, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); +// } + +// BondEscalation storage _escalation = _escalations[_dispute.requestId]; + +// if (_disputeId == _escalation.disputeId) { +// // The dispute has been escalated to the Resolution module +// if (_escalation.status == BondEscalationStatus.Escalated) { +// if (_escalation.amountOfPledgesAgainstDispute == 0) { +// return; +// } + +// BondEscalationStatus _newStatus = _won ? BondEscalationStatus.DisputerWon : BondEscalationStatus.DisputerLost; +// _escalation.status = _newStatus; + +// emit BondEscalationStatusUpdated(_dispute.requestId, _disputeId, _newStatus); + +// _params.accountingExtension.onSettleBondEscalation({ +// _requestId: _dispute.requestId, +// _disputeId: _disputeId, +// _forVotesWon: _won, +// _token: _params.bondToken, +// _amountPerPledger: _params.bondSize << 1, +// _winningPledgersLength: _won ? _escalation.amountOfPledgesForDispute : _escalation.amountOfPledgesAgainstDispute +// }); +// } else { +// // The status has changed to Won or Lost +// uint256 _pledgesForDispute = _escalation.amountOfPledgesForDispute; +// uint256 _pledgesAgainstDispute = _escalation.amountOfPledgesAgainstDispute; +// bool _disputersWon = _pledgesForDispute > _pledgesAgainstDispute; + +// uint256 _amountToPay = _disputersWon +// ? _params.bondSize + FixedPointMathLib.mulDivDown(_pledgesAgainstDispute, _params.bondSize, _pledgesForDispute) +// : _params.bondSize + FixedPointMathLib.mulDivDown(_pledgesForDispute, _params.bondSize, _pledgesAgainstDispute); + +// _params.accountingExtension.onSettleBondEscalation({ +// _requestId: _dispute.requestId, +// _disputeId: _escalation.disputeId, +// _forVotesWon: _disputersWon, +// _token: _params.bondToken, +// _amountPerPledger: _amountToPay, +// _winningPledgersLength: _disputersWon ? _pledgesForDispute : _pledgesAgainstDispute +// }); +// } +// } + +// emit DisputeStatusChanged({ +// _requestId: _dispute.requestId, +// _responseId: _dispute.responseId, +// _disputer: _dispute.disputer, +// _proposer: _dispute.proposer, +// _status: _dispute.status +// }); +// } + +// //////////////////////////////////////////////////////////////////// +// // Bond Escalation Exclusive Functions +// //////////////////////////////////////////////////////////////////// + +// /// @inheritdoc IBondEscalationModule +// function pledgeForDispute(bytes32 _disputeId) external { +// (bytes32 _requestId, RequestParameters memory _params) = _pledgeChecks(_disputeId, true); + +// _escalations[_requestId].amountOfPledgesForDispute += 1; +// pledgesForDispute[_requestId][msg.sender] += 1; +// _params.accountingExtension.pledge({ +// _pledger: msg.sender, +// _requestId: _requestId, +// _disputeId: _disputeId, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); + +// emit PledgedForDispute(_disputeId, msg.sender, _params.bondSize); +// } + +// /// @inheritdoc IBondEscalationModule +// function pledgeAgainstDispute(bytes32 _disputeId) external { +// (bytes32 _requestId, RequestParameters memory _params) = _pledgeChecks(_disputeId, false); + +// _escalations[_requestId].amountOfPledgesAgainstDispute += 1; +// pledgesAgainstDispute[_requestId][msg.sender] += 1; +// _params.accountingExtension.pledge({ +// _pledger: msg.sender, +// _requestId: _requestId, +// _disputeId: _disputeId, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); + +// emit PledgedAgainstDispute(_disputeId, msg.sender, _params.bondSize); +// } + +// /// @inheritdoc IBondEscalationModule +// function settleBondEscalation(bytes32 _requestId) external { +// RequestParameters memory _params = decodeRequestData(_requestId); +// BondEscalation storage _escalation = _escalations[_requestId]; + +// if (block.timestamp <= _params.bondEscalationDeadline + _params.tyingBuffer) { +// revert BondEscalationModule_BondEscalationNotOver(); +// } + +// if (_escalation.status != BondEscalationStatus.Active) { +// revert BondEscalationModule_BondEscalationCantBeSettled(); +// } + +// uint256 _pledgesForDispute = _escalation.amountOfPledgesForDispute; +// uint256 _pledgesAgainstDispute = _escalation.amountOfPledgesAgainstDispute; + +// if (_pledgesForDispute == _pledgesAgainstDispute) { +// revert BondEscalationModule_ShouldBeEscalated(); +// } + +// bool _disputersWon = _pledgesForDispute > _pledgesAgainstDispute; +// _escalation.status = _disputersWon ? BondEscalationStatus.DisputerWon : BondEscalationStatus.DisputerLost; + +// emit BondEscalationStatusUpdated(_requestId, _escalation.disputeId, _escalation.status); + +// ORACLE.updateDisputeStatus( +// _escalation.disputeId, _disputersWon ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost +// ); +// } + +// /** +// * @notice Checks the necessary conditions for pledging +// * @param _disputeId The encoded data for the request +// * @return _requestId The ID of the request being disputed on +// * @return _params The decoded parameters for the request +// */ +// function _pledgeChecks( +// bytes32 _disputeId, +// bool _forDispute +// ) internal view returns (bytes32 _requestId, RequestParameters memory _params) { +// if (_disputeId == 0) revert BondEscalationModule_DisputeDoesNotExist(); + +// IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); +// _requestId = _dispute.requestId; +// BondEscalation memory _escalation = _escalations[_requestId]; + +// if (_disputeId != _escalation.disputeId) { +// revert BondEscalationModule_InvalidDispute(); +// } + +// _params = decodeRequestData(_requestId); + +// if (block.timestamp > _params.bondEscalationDeadline + _params.tyingBuffer) { +// revert BondEscalationModule_BondEscalationOver(); +// } + +// uint256 _numPledgersForDispute = _escalation.amountOfPledgesForDispute; +// uint256 _numPledgersAgainstDispute = _escalation.amountOfPledgesAgainstDispute; + +// if (_forDispute) { +// if (_numPledgersForDispute == _params.maxNumberOfEscalations) { +// revert BondEscalationModule_MaxNumberOfEscalationsReached(); +// } +// if (_numPledgersForDispute > _numPledgersAgainstDispute) revert BondEscalationModule_CanOnlySurpassByOnePledge(); +// } else { +// if (_numPledgersAgainstDispute == _params.maxNumberOfEscalations) { +// revert BondEscalationModule_MaxNumberOfEscalationsReached(); +// } +// if (_numPledgersAgainstDispute > _numPledgersForDispute) revert BondEscalationModule_CanOnlySurpassByOnePledge(); +// } + +// if (block.timestamp > _params.bondEscalationDeadline && _numPledgersForDispute == _numPledgersAgainstDispute) { +// revert BondEscalationModule_CannotBreakTieDuringTyingBuffer(); +// } +// } + +// //////////////////////////////////////////////////////////////////// +// // View Functions +// //////////////////////////////////////////////////////////////////// + +// /// @inheritdoc IBondEscalationModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } + +// /// @inheritdoc IBondEscalationModule +// function getEscalation(bytes32 _requestId) public view returns (BondEscalation memory _escalation) { +// _escalation = _escalations[_requestId]; +// } +// } diff --git a/solidity/contracts/modules/dispute/BondedDisputeModule.sol b/solidity/contracts/modules/dispute/BondedDisputeModule.sol index bd533433..8fb44575 100644 --- a/solidity/contracts/modules/dispute/BondedDisputeModule.sol +++ b/solidity/contracts/modules/dispute/BondedDisputeModule.sol @@ -1,115 +1,115 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IBondedDisputeModule} from '../../../interfaces/modules/dispute/IBondedDisputeModule.sol'; +// import {IBondedDisputeModule} from '../../../interfaces/modules/dispute/IBondedDisputeModule.sol'; -contract BondedDisputeModule is Module, IBondedDisputeModule { - constructor(IOracle _oracle) Module(_oracle) {} +// contract BondedDisputeModule is Module, IBondedDisputeModule { +// constructor(IOracle _oracle) Module(_oracle) {} - /// @inheritdoc IModule - function moduleName() external pure returns (string memory _moduleName) { - return 'BondedDisputeModule'; - } +// /// @inheritdoc IModule +// function moduleName() external pure returns (string memory _moduleName) { +// return 'BondedDisputeModule'; +// } - /// @inheritdoc IBondedDisputeModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } +// /// @inheritdoc IBondedDisputeModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } - /// @inheritdoc IBondedDisputeModule - function disputeEscalated(bytes32 _disputeId) external onlyOracle {} +// /// @inheritdoc IBondedDisputeModule +// function disputeEscalated(bytes32 _disputeId) external onlyOracle {} - /// @inheritdoc IBondedDisputeModule - function disputeResponse( - bytes32 _requestId, - bytes32 _responseId, - address _disputer, - address _proposer - ) external onlyOracle returns (IOracle.Dispute memory _dispute) { - _dispute = IOracle.Dispute({ - disputer: _disputer, - responseId: _responseId, - proposer: _proposer, - requestId: _requestId, - status: IOracle.DisputeStatus.Active, - createdAt: block.timestamp - }); +// /// @inheritdoc IBondedDisputeModule +// function disputeResponse( +// bytes32 _requestId, +// bytes32 _responseId, +// address _disputer, +// address _proposer +// ) external onlyOracle returns (IOracle.Dispute memory _dispute) { +// _dispute = IOracle.Dispute({ +// disputer: _disputer, +// responseId: _responseId, +// proposer: _proposer, +// requestId: _requestId, +// status: IOracle.DisputeStatus.Active, +// createdAt: block.timestamp +// }); - RequestParameters memory _params = decodeRequestData(_requestId); - _params.accountingExtension.bond({ - _bonder: _disputer, - _requestId: _requestId, - _token: _params.bondToken, - _amount: _params.bondSize - }); +// RequestParameters memory _params = decodeRequestData(_requestId); +// _params.accountingExtension.bond({ +// _bonder: _disputer, +// _requestId: _requestId, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); - emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); - } +// emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); +// } - /// @inheritdoc IBondedDisputeModule - function onDisputeStatusChange(bytes32, /* _disputeId */ IOracle.Dispute memory _dispute) external onlyOracle { - RequestParameters memory _params = decodeRequestData(_dispute.requestId); - IOracle.DisputeStatus _status = _dispute.status; - address _proposer = _dispute.proposer; - address _disputer = _dispute.disputer; +// /// @inheritdoc IBondedDisputeModule +// function onDisputeStatusChange(bytes32, /* _disputeId */ IOracle.Dispute memory _dispute) external onlyOracle { +// RequestParameters memory _params = decodeRequestData(_dispute.requestId); +// IOracle.DisputeStatus _status = _dispute.status; +// address _proposer = _dispute.proposer; +// address _disputer = _dispute.disputer; - if (_status == IOracle.DisputeStatus.NoResolution) { - // No resolution, we release both bonds - _params.accountingExtension.release({ - _bonder: _disputer, - _requestId: _dispute.requestId, - _token: _params.bondToken, - _amount: _params.bondSize - }); +// if (_status == IOracle.DisputeStatus.NoResolution) { +// // No resolution, we release both bonds +// _params.accountingExtension.release({ +// _bonder: _disputer, +// _requestId: _dispute.requestId, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); - _params.accountingExtension.release({ - _bonder: _proposer, - _requestId: _dispute.requestId, - _token: _params.bondToken, - _amount: _params.bondSize - }); - } else if (_status == IOracle.DisputeStatus.Won) { - // Disputer won, we pay the disputer and release their bond - _params.accountingExtension.pay({ - _requestId: _dispute.requestId, - _payer: _proposer, - _receiver: _disputer, - _token: _params.bondToken, - _amount: _params.bondSize - }); - _params.accountingExtension.release({ - _bonder: _disputer, - _requestId: _dispute.requestId, - _token: _params.bondToken, - _amount: _params.bondSize - }); - } else if (_status == IOracle.DisputeStatus.Lost) { - // Disputer lost, we pay the proposer and release their bond - _params.accountingExtension.pay({ - _requestId: _dispute.requestId, - _payer: _disputer, - _receiver: _proposer, - _token: _params.bondToken, - _amount: _params.bondSize - }); - _params.accountingExtension.release({ - _bonder: _proposer, - _requestId: _dispute.requestId, - _token: _params.bondToken, - _amount: _params.bondSize - }); - } +// _params.accountingExtension.release({ +// _bonder: _proposer, +// _requestId: _dispute.requestId, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); +// } else if (_status == IOracle.DisputeStatus.Won) { +// // Disputer won, we pay the disputer and release their bond +// _params.accountingExtension.pay({ +// _requestId: _dispute.requestId, +// _payer: _proposer, +// _receiver: _disputer, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); +// _params.accountingExtension.release({ +// _bonder: _disputer, +// _requestId: _dispute.requestId, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); +// } else if (_status == IOracle.DisputeStatus.Lost) { +// // Disputer lost, we pay the proposer and release their bond +// _params.accountingExtension.pay({ +// _requestId: _dispute.requestId, +// _payer: _disputer, +// _receiver: _proposer, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); +// _params.accountingExtension.release({ +// _bonder: _proposer, +// _requestId: _dispute.requestId, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); +// } - emit DisputeStatusChanged({ - _requestId: _dispute.requestId, - _responseId: _dispute.responseId, - _disputer: _disputer, - _proposer: _proposer, - _status: _status - }); - } -} +// emit DisputeStatusChanged({ +// _requestId: _dispute.requestId, +// _responseId: _dispute.responseId, +// _disputer: _disputer, +// _proposer: _proposer, +// _status: _status +// }); +// } +// } diff --git a/solidity/contracts/modules/dispute/CircuitResolverModule.sol b/solidity/contracts/modules/dispute/CircuitResolverModule.sol index 46e9fb74..015d8a76 100644 --- a/solidity/contracts/modules/dispute/CircuitResolverModule.sol +++ b/solidity/contracts/modules/dispute/CircuitResolverModule.sol @@ -1,91 +1,91 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; - -import {ICircuitResolverModule} from '../../../interfaces/modules/dispute/ICircuitResolverModule.sol'; - -contract CircuitResolverModule is Module, ICircuitResolverModule { - constructor(IOracle _oracle) Module(_oracle) {} - - mapping(bytes32 _requestId => bytes _correctResponse) internal _correctResponses; - - /// @inheritdoc IModule - function moduleName() external pure returns (string memory _moduleName) { - return 'CircuitResolverModule'; - } - - /// @inheritdoc ICircuitResolverModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } - - /// @inheritdoc ICircuitResolverModule - function disputeEscalated(bytes32 _disputeId) external onlyOracle {} - - /// @inheritdoc ICircuitResolverModule - function onDisputeStatusChange(bytes32, /* _disputeId */ IOracle.Dispute memory _dispute) external onlyOracle { - RequestParameters memory _params = decodeRequestData(_dispute.requestId); - - IOracle.Response memory _response = ORACLE.getResponse(_dispute.responseId); - - bytes memory _correctResponse = _correctResponses[_dispute.requestId]; - bool _won = _response.response.length != _correctResponse.length - || keccak256(_response.response) != keccak256(_correctResponse); - - if (_won) { - _params.accountingExtension.pay({ - _requestId: _dispute.requestId, - _payer: _dispute.proposer, - _receiver: _dispute.disputer, - _token: _params.bondToken, - _amount: _params.bondSize - }); - bytes32 _correctResponseId = - ORACLE.proposeResponse(_dispute.disputer, _dispute.requestId, abi.encode(_correctResponses[_dispute.requestId])); - ORACLE.finalize(_dispute.requestId, _correctResponseId); - } else { - ORACLE.finalize(_dispute.requestId, _dispute.responseId); - } - - delete _correctResponses[_dispute.requestId]; - - emit DisputeStatusChanged({ - _requestId: _dispute.requestId, - _responseId: _dispute.responseId, - _disputer: _dispute.disputer, - _proposer: _dispute.proposer, - _status: _dispute.status - }); - } - - /// @inheritdoc ICircuitResolverModule - function disputeResponse( - bytes32 _requestId, - bytes32 _responseId, - address _disputer, - address _proposer - ) external onlyOracle returns (IOracle.Dispute memory _dispute) { - IOracle.Response memory _response = ORACLE.getResponse(_responseId); - RequestParameters memory _params = decodeRequestData(_requestId); - - (, bytes memory _correctResponse) = _params.verifier.call(_params.callData); - _correctResponses[_requestId] = _correctResponse; - - bool _won = _response.response.length != _correctResponse.length - || keccak256(_response.response) != keccak256(_correctResponse); - - _dispute = IOracle.Dispute({ - disputer: _disputer, - responseId: _responseId, - proposer: _proposer, - requestId: _requestId, - status: _won ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost, - createdAt: block.timestamp - }); - - emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; + +// import {ICircuitResolverModule} from '../../../interfaces/modules/dispute/ICircuitResolverModule.sol'; + +// contract CircuitResolverModule is Module, ICircuitResolverModule { +// constructor(IOracle _oracle) Module(_oracle) {} + +// mapping(bytes32 _requestId => bytes _correctResponse) internal _correctResponses; + +// /// @inheritdoc IModule +// function moduleName() external pure returns (string memory _moduleName) { +// return 'CircuitResolverModule'; +// } + +// /// @inheritdoc ICircuitResolverModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } + +// /// @inheritdoc ICircuitResolverModule +// function disputeEscalated(bytes32 _disputeId) external onlyOracle {} + +// /// @inheritdoc ICircuitResolverModule +// function onDisputeStatusChange(bytes32, /* _disputeId */ IOracle.Dispute memory _dispute) external onlyOracle { +// RequestParameters memory _params = decodeRequestData(_dispute.requestId); + +// IOracle.Response memory _response = ORACLE.getResponse(_dispute.responseId); + +// bytes memory _correctResponse = _correctResponses[_dispute.requestId]; +// bool _won = _response.response.length != _correctResponse.length +// || keccak256(_response.response) != keccak256(_correctResponse); + +// if (_won) { +// _params.accountingExtension.pay({ +// _requestId: _dispute.requestId, +// _payer: _dispute.proposer, +// _receiver: _dispute.disputer, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); +// bytes32 _correctResponseId = +// ORACLE.proposeResponse(_dispute.disputer, _dispute.requestId, abi.encode(_correctResponses[_dispute.requestId])); +// ORACLE.finalize(_dispute.requestId, _correctResponseId); +// } else { +// ORACLE.finalize(_dispute.requestId, _dispute.responseId); +// } + +// delete _correctResponses[_dispute.requestId]; + +// emit DisputeStatusChanged({ +// _requestId: _dispute.requestId, +// _responseId: _dispute.responseId, +// _disputer: _dispute.disputer, +// _proposer: _dispute.proposer, +// _status: _dispute.status +// }); +// } + +// /// @inheritdoc ICircuitResolverModule +// function disputeResponse( +// bytes32 _requestId, +// bytes32 _responseId, +// address _disputer, +// address _proposer +// ) external onlyOracle returns (IOracle.Dispute memory _dispute) { +// IOracle.Response memory _response = ORACLE.getResponse(_responseId); +// RequestParameters memory _params = decodeRequestData(_requestId); + +// (, bytes memory _correctResponse) = _params.verifier.call(_params.callData); +// _correctResponses[_requestId] = _correctResponse; + +// bool _won = _response.response.length != _correctResponse.length +// || keccak256(_response.response) != keccak256(_correctResponse); + +// _dispute = IOracle.Dispute({ +// disputer: _disputer, +// responseId: _responseId, +// proposer: _proposer, +// requestId: _requestId, +// status: _won ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost, +// createdAt: block.timestamp +// }); + +// emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); +// } +// } diff --git a/solidity/contracts/modules/dispute/RootVerificationModule.sol b/solidity/contracts/modules/dispute/RootVerificationModule.sol index 911f460e..e19f1cf0 100644 --- a/solidity/contracts/modules/dispute/RootVerificationModule.sol +++ b/solidity/contracts/modules/dispute/RootVerificationModule.sol @@ -1,94 +1,94 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; - -import {IRootVerificationModule} from '../../../interfaces/modules/dispute/IRootVerificationModule.sol'; -import {MerkleLib} from '../../libraries/MerkleLib.sol'; - -contract RootVerificationModule is Module, IRootVerificationModule { - using MerkleLib for MerkleLib.Tree; - - /** - * @notice The calculated correct root for a given request - */ - mapping(bytes32 _requestId => bytes32 _correctRoot) internal _correctRoots; - - constructor(IOracle _oracle) Module(_oracle) {} - - /// @inheritdoc IModule - function moduleName() external pure returns (string memory _moduleName) { - return 'RootVerificationModule'; - } - - /// @inheritdoc IRootVerificationModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } - - /// @inheritdoc IRootVerificationModule - function disputeEscalated(bytes32 _disputeId) external onlyOracle {} - - /// @inheritdoc IRootVerificationModule - function onDisputeStatusChange(bytes32, IOracle.Dispute memory _dispute) external onlyOracle { - RequestParameters memory _params = decodeRequestData(_dispute.requestId); - - IOracle.Response memory _response = ORACLE.getResponse(_dispute.responseId); - - bool _won = abi.decode(_response.response, (bytes32)) != _correctRoots[_dispute.requestId]; - - if (_won) { - _params.accountingExtension.pay({ - _requestId: _dispute.requestId, - _payer: _dispute.proposer, - _receiver: _dispute.disputer, - _token: _params.bondToken, - _amount: _params.bondSize - }); - bytes32 _correctResponseId = - ORACLE.proposeResponse(_dispute.disputer, _dispute.requestId, abi.encode(_correctRoots[_dispute.requestId])); - ORACLE.finalize(_dispute.requestId, _correctResponseId); - } else { - ORACLE.finalize(_dispute.requestId, _dispute.responseId); - } - - delete _correctRoots[_dispute.requestId]; - - emit DisputeStatusChanged({ - _requestId: _dispute.requestId, - _responseId: _dispute.responseId, - _disputer: _dispute.disputer, - _proposer: _dispute.proposer, - _status: _dispute.status - }); - } - - /// @inheritdoc IRootVerificationModule - function disputeResponse( - bytes32 _requestId, - bytes32 _responseId, - address _disputer, - address _proposer - ) external onlyOracle returns (IOracle.Dispute memory _dispute) { - IOracle.Response memory _response = ORACLE.getResponse(_responseId); - RequestParameters memory _params = decodeRequestData(_requestId); - - bytes32 _correctRoot = _params.treeVerifier.calculateRoot(_params.treeData, _params.leavesToInsert); - _correctRoots[_requestId] = _correctRoot; - - bool _won = abi.decode(_response.response, (bytes32)) != _correctRoot; - - _dispute = IOracle.Dispute({ - disputer: _disputer, - responseId: _responseId, - proposer: _proposer, - requestId: _requestId, - status: _won ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost, - createdAt: block.timestamp - }); - - emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; + +// import {IRootVerificationModule} from '../../../interfaces/modules/dispute/IRootVerificationModule.sol'; +// import {MerkleLib} from '../../libraries/MerkleLib.sol'; + +// contract RootVerificationModule is Module, IRootVerificationModule { +// using MerkleLib for MerkleLib.Tree; + +// /** +// * @notice The calculated correct root for a given request +// */ +// mapping(bytes32 _requestId => bytes32 _correctRoot) internal _correctRoots; + +// constructor(IOracle _oracle) Module(_oracle) {} + +// /// @inheritdoc IModule +// function moduleName() external pure returns (string memory _moduleName) { +// return 'RootVerificationModule'; +// } + +// /// @inheritdoc IRootVerificationModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } + +// /// @inheritdoc IRootVerificationModule +// function disputeEscalated(bytes32 _disputeId) external onlyOracle {} + +// /// @inheritdoc IRootVerificationModule +// function onDisputeStatusChange(bytes32, IOracle.Dispute memory _dispute) external onlyOracle { +// RequestParameters memory _params = decodeRequestData(_dispute.requestId); + +// IOracle.Response memory _response = ORACLE.getResponse(_dispute.responseId); + +// bool _won = abi.decode(_response.response, (bytes32)) != _correctRoots[_dispute.requestId]; + +// if (_won) { +// _params.accountingExtension.pay({ +// _requestId: _dispute.requestId, +// _payer: _dispute.proposer, +// _receiver: _dispute.disputer, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); +// bytes32 _correctResponseId = +// ORACLE.proposeResponse(_dispute.disputer, _dispute.requestId, abi.encode(_correctRoots[_dispute.requestId])); +// ORACLE.finalize(_dispute.requestId, _correctResponseId); +// } else { +// ORACLE.finalize(_dispute.requestId, _dispute.responseId); +// } + +// delete _correctRoots[_dispute.requestId]; + +// emit DisputeStatusChanged({ +// _requestId: _dispute.requestId, +// _responseId: _dispute.responseId, +// _disputer: _dispute.disputer, +// _proposer: _dispute.proposer, +// _status: _dispute.status +// }); +// } + +// /// @inheritdoc IRootVerificationModule +// function disputeResponse( +// bytes32 _requestId, +// bytes32 _responseId, +// address _disputer, +// address _proposer +// ) external onlyOracle returns (IOracle.Dispute memory _dispute) { +// IOracle.Response memory _response = ORACLE.getResponse(_responseId); +// RequestParameters memory _params = decodeRequestData(_requestId); + +// bytes32 _correctRoot = _params.treeVerifier.calculateRoot(_params.treeData, _params.leavesToInsert); +// _correctRoots[_requestId] = _correctRoot; + +// bool _won = abi.decode(_response.response, (bytes32)) != _correctRoot; + +// _dispute = IOracle.Dispute({ +// disputer: _disputer, +// responseId: _responseId, +// proposer: _proposer, +// requestId: _requestId, +// status: _won ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost, +// createdAt: block.timestamp +// }); + +// emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); +// } +// } diff --git a/solidity/contracts/modules/finality/CallbackModule.sol b/solidity/contracts/modules/finality/CallbackModule.sol index b1f77c9c..3f3faf9d 100644 --- a/solidity/contracts/modules/finality/CallbackModule.sol +++ b/solidity/contracts/modules/finality/CallbackModule.sol @@ -1,42 +1,42 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {ICallbackModule} from '../../../interfaces/modules/finality/ICallbackModule.sol'; +// import {ICallbackModule} from '../../../interfaces/modules/finality/ICallbackModule.sol'; -contract CallbackModule is Module, ICallbackModule { - constructor(IOracle _oracle) Module(_oracle) {} +// contract CallbackModule is Module, ICallbackModule { +// constructor(IOracle _oracle) Module(_oracle) {} - /// @inheritdoc IModule - function moduleName() public pure returns (string memory _moduleName) { - _moduleName = 'CallbackModule'; - } +// /// @inheritdoc IModule +// function moduleName() public pure returns (string memory _moduleName) { +// _moduleName = 'CallbackModule'; +// } - /// @inheritdoc ICallbackModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } +// /// @inheritdoc ICallbackModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } - /** - * @notice Checks if the target address has code (i.e. is a contract) - * @param _data The encoded data for the request - */ - function _afterSetupRequest(bytes32, bytes calldata _data) internal view override { - RequestParameters memory _params = abi.decode(_data, (RequestParameters)); - if (_params.target.code.length == 0) revert CallbackModule_TargetHasNoCode(); - } +// /** +// * @notice Checks if the target address has code (i.e. is a contract) +// * @param _data The encoded data for the request +// */ +// function _afterSetupRequest(bytes32, bytes calldata _data) internal view override { +// RequestParameters memory _params = abi.decode(_data, (RequestParameters)); +// if (_params.target.code.length == 0) revert CallbackModule_TargetHasNoCode(); +// } - /// @inheritdoc ICallbackModule - function finalizeRequest( - bytes32 _requestId, - address _finalizer - ) external override(Module, ICallbackModule) onlyOracle { - RequestParameters memory _params = decodeRequestData(_requestId); - _params.target.call(_params.data); - emit Callback(_requestId, _params.target, _params.data); - emit RequestFinalized(_requestId, _finalizer); - } -} +// /// @inheritdoc ICallbackModule +// function finalizeRequest( +// bytes32 _requestId, +// address _finalizer +// ) external override(Module, ICallbackModule) onlyOracle { +// RequestParameters memory _params = decodeRequestData(_requestId); +// _params.target.call(_params.data); +// emit Callback(_requestId, _params.target, _params.data); +// emit RequestFinalized(_requestId, _finalizer); +// } +// } diff --git a/solidity/contracts/modules/finality/MultipleCallbacksModule.sol b/solidity/contracts/modules/finality/MultipleCallbacksModule.sol index c216e19a..77d8a311 100644 --- a/solidity/contracts/modules/finality/MultipleCallbacksModule.sol +++ b/solidity/contracts/modules/finality/MultipleCallbacksModule.sol @@ -1,58 +1,58 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; - -import {IMultipleCallbacksModule} from '../../../interfaces/modules/finality/IMultipleCallbacksModule.sol'; - -contract MultipleCallbacksModule is Module, IMultipleCallbacksModule { - constructor(IOracle _oracle) Module(_oracle) {} - - /// @inheritdoc IMultipleCallbacksModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } - - /// @inheritdoc IModule - function moduleName() public pure returns (string memory _moduleName) { - _moduleName = 'MultipleCallbacksModule'; - } - - /** - * @notice Checks if the target addresses have code and the calldata amount matches the targets amount - * @param _data The ABI encoded address of the target contracts and the calldata to be executed - */ - function _afterSetupRequest(bytes32, bytes calldata _data) internal view override { - RequestParameters memory _params = abi.decode(_data, (RequestParameters)); - uint256 _length = _params.targets.length; - if (_length != _params.data.length) revert MultipleCallbackModule_InvalidParameters(); - - for (uint256 _i; _i < _length;) { - if (_params.targets[_i].code.length == 0) revert MultipleCallbackModule_TargetHasNoCode(); - unchecked { - ++_i; - } - } - } - - /// @inheritdoc IMultipleCallbacksModule - function finalizeRequest( - bytes32 _requestId, - address _finalizer - ) external override(IMultipleCallbacksModule, Module) onlyOracle { - RequestParameters memory _params = decodeRequestData(_requestId); - uint256 _length = _params.targets.length; - - for (uint256 _i; _i < _length;) { - _params.targets[_i].call(_params.data[_i]); - emit Callback(_requestId, _params.targets[_i], _params.data[_i]); - unchecked { - ++_i; - } - } - - emit RequestFinalized(_requestId, _finalizer); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; + +// import {IMultipleCallbacksModule} from '../../../interfaces/modules/finality/IMultipleCallbacksModule.sol'; + +// contract MultipleCallbacksModule is Module, IMultipleCallbacksModule { +// constructor(IOracle _oracle) Module(_oracle) {} + +// /// @inheritdoc IMultipleCallbacksModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } + +// /// @inheritdoc IModule +// function moduleName() public pure returns (string memory _moduleName) { +// _moduleName = 'MultipleCallbacksModule'; +// } + +// /** +// * @notice Checks if the target addresses have code and the calldata amount matches the targets amount +// * @param _data The ABI encoded address of the target contracts and the calldata to be executed +// */ +// function _afterSetupRequest(bytes32, bytes calldata _data) internal view override { +// RequestParameters memory _params = abi.decode(_data, (RequestParameters)); +// uint256 _length = _params.targets.length; +// if (_length != _params.data.length) revert MultipleCallbackModule_InvalidParameters(); + +// for (uint256 _i; _i < _length;) { +// if (_params.targets[_i].code.length == 0) revert MultipleCallbackModule_TargetHasNoCode(); +// unchecked { +// ++_i; +// } +// } +// } + +// /// @inheritdoc IMultipleCallbacksModule +// function finalizeRequest( +// bytes32 _requestId, +// address _finalizer +// ) external override(IMultipleCallbacksModule, Module) onlyOracle { +// RequestParameters memory _params = decodeRequestData(_requestId); +// uint256 _length = _params.targets.length; + +// for (uint256 _i; _i < _length;) { +// _params.targets[_i].call(_params.data[_i]); +// emit Callback(_requestId, _params.targets[_i], _params.data[_i]); +// unchecked { +// ++_i; +// } +// } + +// emit RequestFinalized(_requestId, _finalizer); +// } +// } diff --git a/solidity/contracts/modules/request/ContractCallRequestModule.sol b/solidity/contracts/modules/request/ContractCallRequestModule.sol index 29b7ed11..afd6b55b 100644 --- a/solidity/contracts/modules/request/ContractCallRequestModule.sol +++ b/solidity/contracts/modules/request/ContractCallRequestModule.sol @@ -1,64 +1,64 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IContractCallRequestModule} from '../../../interfaces/modules/request/IContractCallRequestModule.sol'; +// import {IContractCallRequestModule} from '../../../interfaces/modules/request/IContractCallRequestModule.sol'; -contract ContractCallRequestModule is Module, IContractCallRequestModule { - constructor(IOracle _oracle) Module(_oracle) {} +// contract ContractCallRequestModule is Module, IContractCallRequestModule { +// constructor(IOracle _oracle) Module(_oracle) {} - /// @inheritdoc IModule - function moduleName() public pure returns (string memory _moduleName) { - _moduleName = 'ContractCallRequestModule'; - } +// /// @inheritdoc IModule +// function moduleName() public pure returns (string memory _moduleName) { +// _moduleName = 'ContractCallRequestModule'; +// } - /// @inheritdoc IContractCallRequestModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } +// /// @inheritdoc IContractCallRequestModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } - /** - * @notice Bonds the requester's funds through the accounting extension - * @param _requestId The id of the request being set up - */ - function _afterSetupRequest(bytes32 _requestId, bytes calldata) internal override { - RequestParameters memory _params = decodeRequestData(_requestId); - IOracle.Request memory _request = ORACLE.getRequest(_requestId); - _params.accountingExtension.bond({ - _bonder: _request.requester, - _requestId: _requestId, - _token: _params.paymentToken, - _amount: _params.paymentAmount - }); - } +// /** +// * @notice Bonds the requester's funds through the accounting extension +// * @param _requestId The id of the request being set up +// */ +// function _afterSetupRequest(bytes32 _requestId, bytes calldata) internal override { +// RequestParameters memory _params = decodeRequestData(_requestId); +// IOracle.Request memory _request = ORACLE.getRequest(_requestId); +// _params.accountingExtension.bond({ +// _bonder: _request.requester, +// _requestId: _requestId, +// _token: _params.paymentToken, +// _amount: _params.paymentAmount +// }); +// } - /// @inheritdoc IContractCallRequestModule - function finalizeRequest( - bytes32 _requestId, - address _finalizer - ) external override(IContractCallRequestModule, Module) onlyOracle { - IOracle.Request memory _request = ORACLE.getRequest(_requestId); - IOracle.Response memory _response = ORACLE.getFinalizedResponse(_requestId); - RequestParameters memory _params = decodeRequestData(_requestId); - if (_response.createdAt != 0) { - _params.accountingExtension.pay({ - _requestId: _requestId, - _payer: _request.requester, - _receiver: _response.proposer, - _token: _params.paymentToken, - _amount: _params.paymentAmount - }); - } else { - _params.accountingExtension.release({ - _bonder: _request.requester, - _requestId: _requestId, - _token: _params.paymentToken, - _amount: _params.paymentAmount - }); - } - emit RequestFinalized(_requestId, _finalizer); - } -} +// /// @inheritdoc IContractCallRequestModule +// function finalizeRequest( +// bytes32 _requestId, +// address _finalizer +// ) external override(IContractCallRequestModule, Module) onlyOracle { +// IOracle.Request memory _request = ORACLE.getRequest(_requestId); +// IOracle.Response memory _response = ORACLE.getFinalizedResponse(_requestId); +// RequestParameters memory _params = decodeRequestData(_requestId); +// if (_response.createdAt != 0) { +// _params.accountingExtension.pay({ +// _requestId: _requestId, +// _payer: _request.requester, +// _receiver: _response.proposer, +// _token: _params.paymentToken, +// _amount: _params.paymentAmount +// }); +// } else { +// _params.accountingExtension.release({ +// _bonder: _request.requester, +// _requestId: _requestId, +// _token: _params.paymentToken, +// _amount: _params.paymentAmount +// }); +// } +// emit RequestFinalized(_requestId, _finalizer); +// } +// } diff --git a/solidity/contracts/modules/request/HttpRequestModule.sol b/solidity/contracts/modules/request/HttpRequestModule.sol index a7d43919..ef8890fa 100644 --- a/solidity/contracts/modules/request/HttpRequestModule.sol +++ b/solidity/contracts/modules/request/HttpRequestModule.sol @@ -1,63 +1,63 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IHttpRequestModule} from '../../../interfaces/modules/request/IHttpRequestModule.sol'; +// import {IHttpRequestModule} from '../../../interfaces/modules/request/IHttpRequestModule.sol'; -contract HttpRequestModule is Module, IHttpRequestModule { - constructor(IOracle _oracle) Module(_oracle) {} +// contract HttpRequestModule is Module, IHttpRequestModule { +// constructor(IOracle _oracle) Module(_oracle) {} - /// @inheritdoc IModule - function moduleName() public pure returns (string memory _moduleName) { - _moduleName = 'HttpRequestModule'; - } +// /// @inheritdoc IModule +// function moduleName() public pure returns (string memory _moduleName) { +// _moduleName = 'HttpRequestModule'; +// } - /// @inheritdoc IHttpRequestModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } +// /// @inheritdoc IHttpRequestModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } - /** - * @notice Bonds the requester tokens to use as payment for the response proposer. - */ - function _afterSetupRequest(bytes32 _requestId, bytes calldata) internal override { - RequestParameters memory _params = decodeRequestData(_requestId); - IOracle.Request memory _request = ORACLE.getRequest(_requestId); - _params.accountingExtension.bond({ - _bonder: _request.requester, - _requestId: _requestId, - _token: _params.paymentToken, - _amount: _params.paymentAmount - }); - } +// /** +// * @notice Bonds the requester tokens to use as payment for the response proposer. +// */ +// function _afterSetupRequest(bytes32 _requestId, bytes calldata) internal override { +// RequestParameters memory _params = decodeRequestData(_requestId); +// IOracle.Request memory _request = ORACLE.getRequest(_requestId); +// _params.accountingExtension.bond({ +// _bonder: _request.requester, +// _requestId: _requestId, +// _token: _params.paymentToken, +// _amount: _params.paymentAmount +// }); +// } - /// @inheritdoc IHttpRequestModule - function finalizeRequest( - bytes32 _requestId, - address _finalizer - ) external override(IHttpRequestModule, Module) onlyOracle { - IOracle.Request memory _request = ORACLE.getRequest(_requestId); - IOracle.Response memory _response = ORACLE.getFinalizedResponse(_requestId); - RequestParameters memory _params = decodeRequestData(_requestId); - if (_response.createdAt != 0) { - _params.accountingExtension.pay({ - _requestId: _requestId, - _payer: _request.requester, - _receiver: _response.proposer, - _token: _params.paymentToken, - _amount: _params.paymentAmount - }); - } else { - _params.accountingExtension.release({ - _bonder: _request.requester, - _requestId: _requestId, - _token: _params.paymentToken, - _amount: _params.paymentAmount - }); - } - emit RequestFinalized(_requestId, _finalizer); - } -} +// /// @inheritdoc IHttpRequestModule +// function finalizeRequest( +// bytes32 _requestId, +// address _finalizer +// ) external override(IHttpRequestModule, Module) onlyOracle { +// IOracle.Request memory _request = ORACLE.getRequest(_requestId); +// IOracle.Response memory _response = ORACLE.getFinalizedResponse(_requestId); +// RequestParameters memory _params = decodeRequestData(_requestId); +// if (_response.createdAt != 0) { +// _params.accountingExtension.pay({ +// _requestId: _requestId, +// _payer: _request.requester, +// _receiver: _response.proposer, +// _token: _params.paymentToken, +// _amount: _params.paymentAmount +// }); +// } else { +// _params.accountingExtension.release({ +// _bonder: _request.requester, +// _requestId: _requestId, +// _token: _params.paymentToken, +// _amount: _params.paymentAmount +// }); +// } +// emit RequestFinalized(_requestId, _finalizer); +// } +// } diff --git a/solidity/contracts/modules/request/SparseMerkleTreeRequestModule.sol b/solidity/contracts/modules/request/SparseMerkleTreeRequestModule.sol index bc2d4492..f72f07a1 100644 --- a/solidity/contracts/modules/request/SparseMerkleTreeRequestModule.sol +++ b/solidity/contracts/modules/request/SparseMerkleTreeRequestModule.sol @@ -1,64 +1,64 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {ISparseMerkleTreeRequestModule} from '../../../interfaces/modules/request/ISparseMerkleTreeRequestModule.sol'; +// import {ISparseMerkleTreeRequestModule} from '../../../interfaces/modules/request/ISparseMerkleTreeRequestModule.sol'; -contract SparseMerkleTreeRequestModule is Module, ISparseMerkleTreeRequestModule { - constructor(IOracle _oracle) Module(_oracle) {} +// contract SparseMerkleTreeRequestModule is Module, ISparseMerkleTreeRequestModule { +// constructor(IOracle _oracle) Module(_oracle) {} - /// @inheritdoc IModule - function moduleName() public pure returns (string memory _moduleName) { - _moduleName = 'SparseMerkleTreeRequestModule'; - } +// /// @inheritdoc IModule +// function moduleName() public pure returns (string memory _moduleName) { +// _moduleName = 'SparseMerkleTreeRequestModule'; +// } - /// @inheritdoc ISparseMerkleTreeRequestModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } +// /// @inheritdoc ISparseMerkleTreeRequestModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } - /** - * @notice Hook triggered after setting up a request. Bonds the requester's payment amount - * @param _requestId The ID of the request being setup - */ - function _afterSetupRequest(bytes32 _requestId, bytes calldata) internal override { - RequestParameters memory _params = decodeRequestData(_requestId); - IOracle.Request memory _request = ORACLE.getRequest(_requestId); - _params.accountingExtension.bond({ - _bonder: _request.requester, - _requestId: _requestId, - _token: _params.paymentToken, - _amount: _params.paymentAmount - }); - } +// /** +// * @notice Hook triggered after setting up a request. Bonds the requester's payment amount +// * @param _requestId The ID of the request being setup +// */ +// function _afterSetupRequest(bytes32 _requestId, bytes calldata) internal override { +// RequestParameters memory _params = decodeRequestData(_requestId); +// IOracle.Request memory _request = ORACLE.getRequest(_requestId); +// _params.accountingExtension.bond({ +// _bonder: _request.requester, +// _requestId: _requestId, +// _token: _params.paymentToken, +// _amount: _params.paymentAmount +// }); +// } - /// @inheritdoc ISparseMerkleTreeRequestModule - function finalizeRequest( - bytes32 _requestId, - address _finalizer - ) external override(ISparseMerkleTreeRequestModule, Module) onlyOracle { - IOracle.Request memory _request = ORACLE.getRequest(_requestId); - IOracle.Response memory _response = ORACLE.getFinalizedResponse(_requestId); - RequestParameters memory _params = decodeRequestData(_requestId); - if (_response.createdAt != 0) { - _params.accountingExtension.pay({ - _requestId: _requestId, - _payer: _request.requester, - _receiver: _response.proposer, - _token: _params.paymentToken, - _amount: _params.paymentAmount - }); - } else { - _params.accountingExtension.release({ - _bonder: _request.requester, - _requestId: _requestId, - _token: _params.paymentToken, - _amount: _params.paymentAmount - }); - } - emit RequestFinalized(_requestId, _finalizer); - } -} +// /// @inheritdoc ISparseMerkleTreeRequestModule +// function finalizeRequest( +// bytes32 _requestId, +// address _finalizer +// ) external override(ISparseMerkleTreeRequestModule, Module) onlyOracle { +// IOracle.Request memory _request = ORACLE.getRequest(_requestId); +// IOracle.Response memory _response = ORACLE.getFinalizedResponse(_requestId); +// RequestParameters memory _params = decodeRequestData(_requestId); +// if (_response.createdAt != 0) { +// _params.accountingExtension.pay({ +// _requestId: _requestId, +// _payer: _request.requester, +// _receiver: _response.proposer, +// _token: _params.paymentToken, +// _amount: _params.paymentAmount +// }); +// } else { +// _params.accountingExtension.release({ +// _bonder: _request.requester, +// _requestId: _requestId, +// _token: _params.paymentToken, +// _amount: _params.paymentAmount +// }); +// } +// emit RequestFinalized(_requestId, _finalizer); +// } +// } diff --git a/solidity/contracts/modules/resolution/ArbitratorModule.sol b/solidity/contracts/modules/resolution/ArbitratorModule.sol index add450d1..daf419fc 100644 --- a/solidity/contracts/modules/resolution/ArbitratorModule.sol +++ b/solidity/contracts/modules/resolution/ArbitratorModule.sol @@ -1,62 +1,62 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IArbitratorModule} from '../../../interfaces/modules/resolution/IArbitratorModule.sol'; -import {IArbitrator} from '../../../interfaces/IArbitrator.sol'; +// import {IArbitratorModule} from '../../../interfaces/modules/resolution/IArbitratorModule.sol'; +// import {IArbitrator} from '../../../interfaces/IArbitrator.sol'; -contract ArbitratorModule is Module, IArbitratorModule { - /** - * @notice The status of all disputes - */ - mapping(bytes32 _disputeId => ArbitrationStatus _status) internal _disputeData; +// contract ArbitratorModule is Module, IArbitratorModule { +// /** +// * @notice The status of all disputes +// */ +// mapping(bytes32 _disputeId => ArbitrationStatus _status) internal _disputeData; - constructor(IOracle _oracle) Module(_oracle) {} +// constructor(IOracle _oracle) Module(_oracle) {} - /// @inheritdoc IModule - function moduleName() external pure returns (string memory _moduleName) { - return 'ArbitratorModule'; - } +// /// @inheritdoc IModule +// function moduleName() external pure returns (string memory _moduleName) { +// return 'ArbitratorModule'; +// } - /// @inheritdoc IArbitratorModule - function decodeRequestData(bytes32 _requestId) public view returns (address _arbitrator) { - _arbitrator = abi.decode(requestData[_requestId], (address)); - } +// /// @inheritdoc IArbitratorModule +// function decodeRequestData(bytes32 _requestId) public view returns (address _arbitrator) { +// _arbitrator = abi.decode(requestData[_requestId], (address)); +// } - /// @inheritdoc IArbitratorModule - function getStatus(bytes32 _disputeId) external view returns (ArbitrationStatus _disputeStatus) { - _disputeStatus = _disputeData[_disputeId]; - } +// /// @inheritdoc IArbitratorModule +// function getStatus(bytes32 _disputeId) external view returns (ArbitrationStatus _disputeStatus) { +// _disputeStatus = _disputeData[_disputeId]; +// } - /// @inheritdoc IArbitratorModule - function startResolution(bytes32 _disputeId) external onlyOracle { - IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); +// /// @inheritdoc IArbitratorModule +// function startResolution(bytes32 _disputeId) external onlyOracle { +// IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); - address _arbitrator = abi.decode(requestData[_dispute.requestId], (address)); - if (_arbitrator == address(0)) revert ArbitratorModule_InvalidArbitrator(); +// address _arbitrator = abi.decode(requestData[_dispute.requestId], (address)); +// if (_arbitrator == address(0)) revert ArbitratorModule_InvalidArbitrator(); - _disputeData[_disputeId] = ArbitrationStatus.Active; - IArbitrator(_arbitrator).resolve(_disputeId); +// _disputeData[_disputeId] = ArbitrationStatus.Active; +// IArbitrator(_arbitrator).resolve(_disputeId); - emit ResolutionStarted(_dispute.requestId, _disputeId); - } +// emit ResolutionStarted(_dispute.requestId, _disputeId); +// } - /// @inheritdoc IArbitratorModule - function resolveDispute(bytes32 _disputeId) external onlyOracle { - IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); - if (_dispute.status != IOracle.DisputeStatus.Escalated) revert ArbitratorModule_InvalidDisputeId(); +// /// @inheritdoc IArbitratorModule +// function resolveDispute(bytes32 _disputeId) external onlyOracle { +// IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); +// if (_dispute.status != IOracle.DisputeStatus.Escalated) revert ArbitratorModule_InvalidDisputeId(); - address _arbitrator = abi.decode(requestData[_dispute.requestId], (address)); - IOracle.DisputeStatus _status = IArbitrator(_arbitrator).getAnswer(_disputeId); +// address _arbitrator = abi.decode(requestData[_dispute.requestId], (address)); +// IOracle.DisputeStatus _status = IArbitrator(_arbitrator).getAnswer(_disputeId); - if (_status <= IOracle.DisputeStatus.Escalated) revert ArbitratorModule_InvalidResolutionStatus(); - _disputeData[_disputeId] = ArbitrationStatus.Resolved; +// if (_status <= IOracle.DisputeStatus.Escalated) revert ArbitratorModule_InvalidResolutionStatus(); +// _disputeData[_disputeId] = ArbitrationStatus.Resolved; - ORACLE.updateDisputeStatus(_disputeId, _status); +// ORACLE.updateDisputeStatus(_disputeId, _status); - emit DisputeResolved(_dispute.requestId, _disputeId, _status); - } -} +// emit DisputeResolved(_dispute.requestId, _disputeId, _status); +// } +// } diff --git a/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol b/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol index ded1829f..b0e85fb4 100644 --- a/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol +++ b/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol @@ -1,292 +1,292 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -// solhint-disable-next-line no-unused-import -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; -import {FixedPointMathLib} from 'solmate/utils/FixedPointMathLib.sol'; - -// solhint-disable-next-line no-unused-import -import {IResolutionModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// // solhint-disable-next-line no-unused-import +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +// import {FixedPointMathLib} from 'solmate/utils/FixedPointMathLib.sol'; + +// // solhint-disable-next-line no-unused-import +// import {IResolutionModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IBondEscalationResolutionModule} from - '../../../interfaces/modules/resolution/IBondEscalationResolutionModule.sol'; +// import {IBondEscalationResolutionModule} from +// '../../../interfaces/modules/resolution/IBondEscalationResolutionModule.sol'; -contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModule { - using SafeERC20 for IERC20; - - /// @inheritdoc IBondEscalationResolutionModule - uint256 public constant BASE = 1e18; - - /// @inheritdoc IBondEscalationResolutionModule - mapping(bytes32 _disputeId => Escalation _escalation) public escalations; - - /// @inheritdoc IBondEscalationResolutionModule - mapping(bytes32 _disputeId => InequalityData _inequalityData) public inequalityData; - - /// @inheritdoc IBondEscalationResolutionModule - mapping(bytes32 _disputeId => mapping(address _pledger => uint256 pledges)) public pledgesForDispute; - - /// @inheritdoc IBondEscalationResolutionModule - mapping(bytes32 _disputeId => mapping(address _pledger => uint256 pledges)) public pledgesAgainstDispute; - - constructor(IOracle _oracle) Module(_oracle) {} - - /// @inheritdoc IModule - function moduleName() external pure returns (string memory _moduleName) { - return 'BondEscalationResolutionModule'; - } - - /// @inheritdoc IBondEscalationResolutionModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } - - /// @inheritdoc IResolutionModule - function startResolution(bytes32 _disputeId) external onlyOracle { - bytes32 _requestId = ORACLE.getDispute(_disputeId).requestId; - escalations[_disputeId].startTime = uint128(block.timestamp); - emit ResolutionStarted(_requestId, _disputeId); - } - - /// @inheritdoc IBondEscalationResolutionModule - function pledgeForDispute(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) external { - _pledge(_requestId, _disputeId, _pledgeAmount, true); - } - - /// @inheritdoc IBondEscalationResolutionModule - function pledgeAgainstDispute(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) external { - _pledge(_requestId, _disputeId, _pledgeAmount, false); - } - - /// @inheritdoc IResolutionModule - function resolveDispute(bytes32 _disputeId) external onlyOracle { - Escalation storage _escalation = escalations[_disputeId]; - - if (_escalation.resolution != Resolution.Unresolved) revert BondEscalationResolutionModule_AlreadyResolved(); - if (_escalation.startTime == 0) revert BondEscalationResolutionModule_NotEscalated(); - - bytes32 _requestId = ORACLE.getDispute(_disputeId).requestId; - - RequestParameters memory _params = decodeRequestData(_requestId); - InequalityData storage _inequalityData = inequalityData[_disputeId]; - - uint256 _inequalityTimerDeadline = _inequalityData.time + _params.timeToBreakInequality; - uint256 _pledgingDeadline = _escalation.startTime + _params.timeUntilDeadline; - - // Revert if we have not yet reached the deadline and the timer has not passed - if (block.timestamp < _pledgingDeadline && block.timestamp < _inequalityTimerDeadline) { - revert BondEscalationResolutionModule_PledgingPhaseNotOver(); - } - - uint256 _pledgesFor = _escalation.pledgesFor; - uint256 _pledgesAgainst = _escalation.pledgesAgainst; - uint256 _totalPledges = _pledgesFor + _pledgesAgainst; - - IOracle.DisputeStatus _disputeStatus; - - if (_totalPledges < _params.pledgeThreshold || _pledgesFor == _pledgesAgainst) { - _escalation.resolution = Resolution.NoResolution; - _disputeStatus = IOracle.DisputeStatus.NoResolution; - } else if (_pledgesFor > _pledgesAgainst) { - _escalation.resolution = Resolution.DisputerWon; - _disputeStatus = IOracle.DisputeStatus.Won; - } else if (_pledgesAgainst > _pledgesFor) { - _escalation.resolution = Resolution.DisputerLost; - _disputeStatus = IOracle.DisputeStatus.Lost; - } - - ORACLE.updateDisputeStatus(_disputeId, _disputeStatus); - emit DisputeResolved(_requestId, _disputeId, _disputeStatus); - } - - /// @inheritdoc IBondEscalationResolutionModule - function claimPledge(bytes32 _requestId, bytes32 _disputeId) external { - Escalation storage _escalation = escalations[_disputeId]; - - if (_escalation.resolution == Resolution.Unresolved) revert BondEscalationResolutionModule_NotResolved(); - - uint256 _pledgerBalanceBefore; - uint256 _pledgerProportion; - uint256 _amountToRelease; - uint256 _reward; - - if (_escalation.resolution == Resolution.DisputerWon) { - _pledgerBalanceBefore = pledgesForDispute[_disputeId][msg.sender]; - pledgesForDispute[_disputeId][msg.sender] -= _pledgerBalanceBefore; - _pledgerProportion = FixedPointMathLib.mulDivDown(_pledgerBalanceBefore, BASE, _escalation.pledgesFor); - _reward = FixedPointMathLib.mulDivDown(_escalation.pledgesAgainst, _pledgerProportion, BASE); - _amountToRelease = _reward + _pledgerBalanceBefore; - _claimPledge(_requestId, _disputeId, _amountToRelease, _escalation.resolution); - } else if (_escalation.resolution == Resolution.DisputerLost) { - _pledgerBalanceBefore = pledgesAgainstDispute[_disputeId][msg.sender]; - pledgesAgainstDispute[_disputeId][msg.sender] -= _pledgerBalanceBefore; - _pledgerProportion = FixedPointMathLib.mulDivDown(_pledgerBalanceBefore, BASE, _escalation.pledgesAgainst); - _reward = FixedPointMathLib.mulDivDown(_escalation.pledgesFor, _pledgerProportion, BASE); - _amountToRelease = _reward + _pledgerBalanceBefore; - _claimPledge(_requestId, _disputeId, _amountToRelease, _escalation.resolution); - } else if (_escalation.resolution == Resolution.NoResolution) { - uint256 _pledgerBalanceFor = pledgesForDispute[_disputeId][msg.sender]; - uint256 _pledgerBalanceAgainst = pledgesAgainstDispute[_disputeId][msg.sender]; - - if (_pledgerBalanceFor > 0) { - pledgesForDispute[_disputeId][msg.sender] -= _pledgerBalanceFor; - _claimPledge(_requestId, _disputeId, _pledgerBalanceFor, _escalation.resolution); - } - - if (_pledgerBalanceAgainst > 0) { - pledgesAgainstDispute[_disputeId][msg.sender] -= _pledgerBalanceAgainst; - _claimPledge(_requestId, _disputeId, _pledgerBalanceAgainst, _escalation.resolution); - } - } - } - - /** - * @notice Pledges for or against a dispute - * - * @param _requestId The ID of the request - * @param _disputeId The ID of the dispute - * @param _pledgeAmount The amount to pledge - * @param _pledgingFor Whether the pledger is pledging for or against the dispute - */ - function _pledge(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount, bool _pledgingFor) internal { - Escalation storage _escalation = escalations[_disputeId]; - - if (_escalation.startTime == 0) revert BondEscalationResolutionModule_NotEscalated(); - - InequalityData storage _inequalityData = inequalityData[_disputeId]; - RequestParameters memory _params = decodeRequestData(_requestId); - - uint256 _pledgingDeadline = _escalation.startTime + _params.timeUntilDeadline; - - if (block.timestamp >= _pledgingDeadline) revert BondEscalationResolutionModule_PledgingPhaseOver(); - - // Revert if the inequality timer has passed - if (_inequalityData.time != 0 && block.timestamp >= _inequalityData.time + _params.timeToBreakInequality) { - revert BondEscalationResolutionModule_MustBeResolved(); - } - - _params.accountingExtension.pledge({ - _pledger: msg.sender, - _requestId: _requestId, - _disputeId: _disputeId, - _token: _params.bondToken, - _amount: _pledgeAmount - }); - - if (_pledgingFor) { - if (_inequalityData.inequalityStatus == InequalityStatus.AgainstTurnToEqualize) { - revert BondEscalationResolutionModule_AgainstTurnToEqualize(); - } - - _escalation.pledgesFor += _pledgeAmount; - pledgesForDispute[_disputeId][msg.sender] += _pledgeAmount; - emit PledgedForDispute(msg.sender, _requestId, _disputeId, _pledgeAmount); - } else { - if (_inequalityData.inequalityStatus == InequalityStatus.ForTurnToEqualize) { - revert BondEscalationResolutionModule_ForTurnToEqualize(); - } - - _escalation.pledgesAgainst += _pledgeAmount; - pledgesAgainstDispute[_disputeId][msg.sender] += _pledgeAmount; - emit PledgedAgainstDispute(msg.sender, _requestId, _disputeId, _pledgeAmount); - } - - if (_escalation.pledgesFor + _escalation.pledgesAgainst >= _params.pledgeThreshold) { - _updateInequalityStatus({ - _inequalityData: _inequalityData, - _pledgesFor: _escalation.pledgesFor, - _pledgesAgainst: _escalation.pledgesAgainst, - _percentageDiff: _params.percentageDiff, - _pledgingFor: _pledgingFor - }); - } - } - - /** - * @notice Updates the inequality status of the dispute, switching it from one side to the other if the percentage difference is reached - * - * @param _inequalityData The inequality data for the dispute - * @param _pledgesFor The total amount of pledges for the dispute - * @param _pledgesAgainst The total amount of pledges against the dispute - * @param _percentageDiff The percentage difference between the two sides - * @param _pledgingFor Whether the pledger is pledging for or against the dispute - */ - function _updateInequalityStatus( - InequalityData storage _inequalityData, - uint256 _pledgesFor, - uint256 _pledgesAgainst, - uint256 _percentageDiff, - bool _pledgingFor - ) internal { - uint256 _totalPledges = _pledgesFor + _pledgesAgainst; - uint256 _pledgesForPercentage = FixedPointMathLib.mulDivDown(_pledgesFor, BASE, _totalPledges); - uint256 _pledgesAgainstPercentage = FixedPointMathLib.mulDivDown(_pledgesAgainst, BASE, _totalPledges); - - int256 _forPercentageDifference = int256(_pledgesForPercentage) - int256(_pledgesAgainstPercentage); - int256 _againstPercentageDifference = int256(_pledgesAgainstPercentage) - int256(_pledgesForPercentage); - - int256 _scaledPercentageDiffAsInt = int256(_percentageDiff * BASE / 100); - - if (_pledgingFor) { - if (_againstPercentageDifference >= _scaledPercentageDiffAsInt) return; - - if (_forPercentageDifference >= _scaledPercentageDiffAsInt) { - _inequalityData.inequalityStatus = InequalityStatus.AgainstTurnToEqualize; - _inequalityData.time = block.timestamp; - } else if (_inequalityData.inequalityStatus == InequalityStatus.ForTurnToEqualize) { - // At this point, both _forPercentageDiff and _againstPercentageDiff are < _percentageDiff - _inequalityData.inequalityStatus = InequalityStatus.Equalized; - _inequalityData.time = 0; - } - } else { - if (_forPercentageDifference >= _scaledPercentageDiffAsInt) return; - - if (_againstPercentageDifference >= _scaledPercentageDiffAsInt) { - _inequalityData.inequalityStatus = InequalityStatus.ForTurnToEqualize; - _inequalityData.time = block.timestamp; - } else if (_inequalityData.inequalityStatus == InequalityStatus.AgainstTurnToEqualize) { - // At this point, both _forPercentageDiff and _againstPercentageDiff are < _percentageDiff - _inequalityData.inequalityStatus = InequalityStatus.Equalized; - _inequalityData.time = 0; - } - } - } - - /** - * @notice Releases the pledged funds to the pledger - * - * @param _requestId The ID of the request - * @param _disputeId The ID of the dispute - * @param _amountToRelease The amount to release - * @param _resolution The resolution of the dispute - */ - function _claimPledge( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amountToRelease, - Resolution _resolution - ) internal { - RequestParameters memory _params = decodeRequestData(_requestId); - - _params.accountingExtension.releasePledge({ - _requestId: _requestId, - _disputeId: _disputeId, - _pledger: msg.sender, - _token: _params.bondToken, - _amount: _amountToRelease - }); - - emit PledgeClaimed({ - _requestId: _requestId, - _disputeId: _disputeId, - _pledger: msg.sender, - _token: _params.bondToken, - _pledgeReleased: _amountToRelease, - _resolution: _resolution - }); - } -} +// contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModule { +// using SafeERC20 for IERC20; + +// /// @inheritdoc IBondEscalationResolutionModule +// uint256 public constant BASE = 1e18; + +// /// @inheritdoc IBondEscalationResolutionModule +// mapping(bytes32 _disputeId => Escalation _escalation) public escalations; + +// /// @inheritdoc IBondEscalationResolutionModule +// mapping(bytes32 _disputeId => InequalityData _inequalityData) public inequalityData; + +// /// @inheritdoc IBondEscalationResolutionModule +// mapping(bytes32 _disputeId => mapping(address _pledger => uint256 pledges)) public pledgesForDispute; + +// /// @inheritdoc IBondEscalationResolutionModule +// mapping(bytes32 _disputeId => mapping(address _pledger => uint256 pledges)) public pledgesAgainstDispute; + +// constructor(IOracle _oracle) Module(_oracle) {} + +// /// @inheritdoc IModule +// function moduleName() external pure returns (string memory _moduleName) { +// return 'BondEscalationResolutionModule'; +// } + +// /// @inheritdoc IBondEscalationResolutionModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } + +// /// @inheritdoc IResolutionModule +// function startResolution(bytes32 _disputeId) external onlyOracle { +// bytes32 _requestId = ORACLE.getDispute(_disputeId).requestId; +// escalations[_disputeId].startTime = uint128(block.timestamp); +// emit ResolutionStarted(_requestId, _disputeId); +// } + +// /// @inheritdoc IBondEscalationResolutionModule +// function pledgeForDispute(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) external { +// _pledge(_requestId, _disputeId, _pledgeAmount, true); +// } + +// /// @inheritdoc IBondEscalationResolutionModule +// function pledgeAgainstDispute(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) external { +// _pledge(_requestId, _disputeId, _pledgeAmount, false); +// } + +// /// @inheritdoc IResolutionModule +// function resolveDispute(bytes32 _disputeId) external onlyOracle { +// Escalation storage _escalation = escalations[_disputeId]; + +// if (_escalation.resolution != Resolution.Unresolved) revert BondEscalationResolutionModule_AlreadyResolved(); +// if (_escalation.startTime == 0) revert BondEscalationResolutionModule_NotEscalated(); + +// bytes32 _requestId = ORACLE.getDispute(_disputeId).requestId; + +// RequestParameters memory _params = decodeRequestData(_requestId); +// InequalityData storage _inequalityData = inequalityData[_disputeId]; + +// uint256 _inequalityTimerDeadline = _inequalityData.time + _params.timeToBreakInequality; +// uint256 _pledgingDeadline = _escalation.startTime + _params.timeUntilDeadline; + +// // Revert if we have not yet reached the deadline and the timer has not passed +// if (block.timestamp < _pledgingDeadline && block.timestamp < _inequalityTimerDeadline) { +// revert BondEscalationResolutionModule_PledgingPhaseNotOver(); +// } + +// uint256 _pledgesFor = _escalation.pledgesFor; +// uint256 _pledgesAgainst = _escalation.pledgesAgainst; +// uint256 _totalPledges = _pledgesFor + _pledgesAgainst; + +// IOracle.DisputeStatus _disputeStatus; + +// if (_totalPledges < _params.pledgeThreshold || _pledgesFor == _pledgesAgainst) { +// _escalation.resolution = Resolution.NoResolution; +// _disputeStatus = IOracle.DisputeStatus.NoResolution; +// } else if (_pledgesFor > _pledgesAgainst) { +// _escalation.resolution = Resolution.DisputerWon; +// _disputeStatus = IOracle.DisputeStatus.Won; +// } else if (_pledgesAgainst > _pledgesFor) { +// _escalation.resolution = Resolution.DisputerLost; +// _disputeStatus = IOracle.DisputeStatus.Lost; +// } + +// ORACLE.updateDisputeStatus(_disputeId, _disputeStatus); +// emit DisputeResolved(_requestId, _disputeId, _disputeStatus); +// } + +// /// @inheritdoc IBondEscalationResolutionModule +// function claimPledge(bytes32 _requestId, bytes32 _disputeId) external { +// Escalation storage _escalation = escalations[_disputeId]; + +// if (_escalation.resolution == Resolution.Unresolved) revert BondEscalationResolutionModule_NotResolved(); + +// uint256 _pledgerBalanceBefore; +// uint256 _pledgerProportion; +// uint256 _amountToRelease; +// uint256 _reward; + +// if (_escalation.resolution == Resolution.DisputerWon) { +// _pledgerBalanceBefore = pledgesForDispute[_disputeId][msg.sender]; +// pledgesForDispute[_disputeId][msg.sender] -= _pledgerBalanceBefore; +// _pledgerProportion = FixedPointMathLib.mulDivDown(_pledgerBalanceBefore, BASE, _escalation.pledgesFor); +// _reward = FixedPointMathLib.mulDivDown(_escalation.pledgesAgainst, _pledgerProportion, BASE); +// _amountToRelease = _reward + _pledgerBalanceBefore; +// _claimPledge(_requestId, _disputeId, _amountToRelease, _escalation.resolution); +// } else if (_escalation.resolution == Resolution.DisputerLost) { +// _pledgerBalanceBefore = pledgesAgainstDispute[_disputeId][msg.sender]; +// pledgesAgainstDispute[_disputeId][msg.sender] -= _pledgerBalanceBefore; +// _pledgerProportion = FixedPointMathLib.mulDivDown(_pledgerBalanceBefore, BASE, _escalation.pledgesAgainst); +// _reward = FixedPointMathLib.mulDivDown(_escalation.pledgesFor, _pledgerProportion, BASE); +// _amountToRelease = _reward + _pledgerBalanceBefore; +// _claimPledge(_requestId, _disputeId, _amountToRelease, _escalation.resolution); +// } else if (_escalation.resolution == Resolution.NoResolution) { +// uint256 _pledgerBalanceFor = pledgesForDispute[_disputeId][msg.sender]; +// uint256 _pledgerBalanceAgainst = pledgesAgainstDispute[_disputeId][msg.sender]; + +// if (_pledgerBalanceFor > 0) { +// pledgesForDispute[_disputeId][msg.sender] -= _pledgerBalanceFor; +// _claimPledge(_requestId, _disputeId, _pledgerBalanceFor, _escalation.resolution); +// } + +// if (_pledgerBalanceAgainst > 0) { +// pledgesAgainstDispute[_disputeId][msg.sender] -= _pledgerBalanceAgainst; +// _claimPledge(_requestId, _disputeId, _pledgerBalanceAgainst, _escalation.resolution); +// } +// } +// } + +// /** +// * @notice Pledges for or against a dispute +// * +// * @param _requestId The ID of the request +// * @param _disputeId The ID of the dispute +// * @param _pledgeAmount The amount to pledge +// * @param _pledgingFor Whether the pledger is pledging for or against the dispute +// */ +// function _pledge(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount, bool _pledgingFor) internal { +// Escalation storage _escalation = escalations[_disputeId]; + +// if (_escalation.startTime == 0) revert BondEscalationResolutionModule_NotEscalated(); + +// InequalityData storage _inequalityData = inequalityData[_disputeId]; +// RequestParameters memory _params = decodeRequestData(_requestId); + +// uint256 _pledgingDeadline = _escalation.startTime + _params.timeUntilDeadline; + +// if (block.timestamp >= _pledgingDeadline) revert BondEscalationResolutionModule_PledgingPhaseOver(); + +// // Revert if the inequality timer has passed +// if (_inequalityData.time != 0 && block.timestamp >= _inequalityData.time + _params.timeToBreakInequality) { +// revert BondEscalationResolutionModule_MustBeResolved(); +// } + +// _params.accountingExtension.pledge({ +// _pledger: msg.sender, +// _requestId: _requestId, +// _disputeId: _disputeId, +// _token: _params.bondToken, +// _amount: _pledgeAmount +// }); + +// if (_pledgingFor) { +// if (_inequalityData.inequalityStatus == InequalityStatus.AgainstTurnToEqualize) { +// revert BondEscalationResolutionModule_AgainstTurnToEqualize(); +// } + +// _escalation.pledgesFor += _pledgeAmount; +// pledgesForDispute[_disputeId][msg.sender] += _pledgeAmount; +// emit PledgedForDispute(msg.sender, _requestId, _disputeId, _pledgeAmount); +// } else { +// if (_inequalityData.inequalityStatus == InequalityStatus.ForTurnToEqualize) { +// revert BondEscalationResolutionModule_ForTurnToEqualize(); +// } + +// _escalation.pledgesAgainst += _pledgeAmount; +// pledgesAgainstDispute[_disputeId][msg.sender] += _pledgeAmount; +// emit PledgedAgainstDispute(msg.sender, _requestId, _disputeId, _pledgeAmount); +// } + +// if (_escalation.pledgesFor + _escalation.pledgesAgainst >= _params.pledgeThreshold) { +// _updateInequalityStatus({ +// _inequalityData: _inequalityData, +// _pledgesFor: _escalation.pledgesFor, +// _pledgesAgainst: _escalation.pledgesAgainst, +// _percentageDiff: _params.percentageDiff, +// _pledgingFor: _pledgingFor +// }); +// } +// } + +// /** +// * @notice Updates the inequality status of the dispute, switching it from one side to the other if the percentage difference is reached +// * +// * @param _inequalityData The inequality data for the dispute +// * @param _pledgesFor The total amount of pledges for the dispute +// * @param _pledgesAgainst The total amount of pledges against the dispute +// * @param _percentageDiff The percentage difference between the two sides +// * @param _pledgingFor Whether the pledger is pledging for or against the dispute +// */ +// function _updateInequalityStatus( +// InequalityData storage _inequalityData, +// uint256 _pledgesFor, +// uint256 _pledgesAgainst, +// uint256 _percentageDiff, +// bool _pledgingFor +// ) internal { +// uint256 _totalPledges = _pledgesFor + _pledgesAgainst; +// uint256 _pledgesForPercentage = FixedPointMathLib.mulDivDown(_pledgesFor, BASE, _totalPledges); +// uint256 _pledgesAgainstPercentage = FixedPointMathLib.mulDivDown(_pledgesAgainst, BASE, _totalPledges); + +// int256 _forPercentageDifference = int256(_pledgesForPercentage) - int256(_pledgesAgainstPercentage); +// int256 _againstPercentageDifference = int256(_pledgesAgainstPercentage) - int256(_pledgesForPercentage); + +// int256 _scaledPercentageDiffAsInt = int256(_percentageDiff * BASE / 100); + +// if (_pledgingFor) { +// if (_againstPercentageDifference >= _scaledPercentageDiffAsInt) return; + +// if (_forPercentageDifference >= _scaledPercentageDiffAsInt) { +// _inequalityData.inequalityStatus = InequalityStatus.AgainstTurnToEqualize; +// _inequalityData.time = block.timestamp; +// } else if (_inequalityData.inequalityStatus == InequalityStatus.ForTurnToEqualize) { +// // At this point, both _forPercentageDiff and _againstPercentageDiff are < _percentageDiff +// _inequalityData.inequalityStatus = InequalityStatus.Equalized; +// _inequalityData.time = 0; +// } +// } else { +// if (_forPercentageDifference >= _scaledPercentageDiffAsInt) return; + +// if (_againstPercentageDifference >= _scaledPercentageDiffAsInt) { +// _inequalityData.inequalityStatus = InequalityStatus.ForTurnToEqualize; +// _inequalityData.time = block.timestamp; +// } else if (_inequalityData.inequalityStatus == InequalityStatus.AgainstTurnToEqualize) { +// // At this point, both _forPercentageDiff and _againstPercentageDiff are < _percentageDiff +// _inequalityData.inequalityStatus = InequalityStatus.Equalized; +// _inequalityData.time = 0; +// } +// } +// } + +// /** +// * @notice Releases the pledged funds to the pledger +// * +// * @param _requestId The ID of the request +// * @param _disputeId The ID of the dispute +// * @param _amountToRelease The amount to release +// * @param _resolution The resolution of the dispute +// */ +// function _claimPledge( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _amountToRelease, +// Resolution _resolution +// ) internal { +// RequestParameters memory _params = decodeRequestData(_requestId); + +// _params.accountingExtension.releasePledge({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _pledger: msg.sender, +// _token: _params.bondToken, +// _amount: _amountToRelease +// }); + +// emit PledgeClaimed({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _pledger: msg.sender, +// _token: _params.bondToken, +// _pledgeReleased: _amountToRelease, +// _resolution: _resolution +// }); +// } +// } diff --git a/solidity/contracts/modules/resolution/ERC20ResolutionModule.sol b/solidity/contracts/modules/resolution/ERC20ResolutionModule.sol index c741f66c..78b0ce2c 100644 --- a/solidity/contracts/modules/resolution/ERC20ResolutionModule.sol +++ b/solidity/contracts/modules/resolution/ERC20ResolutionModule.sol @@ -1,112 +1,112 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -// solhint-disable-next-line no-unused-import -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; -import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; - -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; - -import {IERC20ResolutionModule} from '../../../interfaces/modules/resolution/IERC20ResolutionModule.sol'; - -contract ERC20ResolutionModule is Module, IERC20ResolutionModule { - using SafeERC20 for IERC20; - using EnumerableSet for EnumerableSet.AddressSet; - - /// @inheritdoc IERC20ResolutionModule - mapping(bytes32 _disputeId => Escalation _escalation) public escalations; - - /// @inheritdoc IERC20ResolutionModule - mapping(bytes32 _disputeId => mapping(address _voter => uint256 _numOfVotes)) public votes; - - mapping(bytes32 _disputeId => EnumerableSet.AddressSet _votersSet) private _voters; - - constructor(IOracle _oracle) Module(_oracle) {} - - /// @inheritdoc IModule - function moduleName() external pure returns (string memory _moduleName) { - return 'ERC20ResolutionModule'; - } - - /// @inheritdoc IERC20ResolutionModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } - - /// @inheritdoc IERC20ResolutionModule - function startResolution(bytes32 _disputeId) external onlyOracle { - escalations[_disputeId].startTime = block.timestamp; - emit VotingPhaseStarted(block.timestamp, _disputeId); - } - - /// @inheritdoc IERC20ResolutionModule - function castVote(bytes32 _requestId, bytes32 _disputeId, uint256 _numberOfVotes) public { - IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); - if (_dispute.createdAt == 0) revert ERC20ResolutionModule_NonExistentDispute(); - if (_dispute.status != IOracle.DisputeStatus.None) revert ERC20ResolutionModule_AlreadyResolved(); - - Escalation memory _escalation = escalations[_disputeId]; - if (_escalation.startTime == 0) revert ERC20ResolutionModule_DisputeNotEscalated(); - - RequestParameters memory _params = decodeRequestData(_requestId); - uint256 _deadline = _escalation.startTime + _params.timeUntilDeadline; - if (block.timestamp >= _deadline) revert ERC20ResolutionModule_VotingPhaseOver(); - - votes[_disputeId][msg.sender] += _numberOfVotes; - - _voters[_disputeId].add(msg.sender); - escalations[_disputeId].totalVotes += _numberOfVotes; - - _params.votingToken.safeTransferFrom(msg.sender, address(this), _numberOfVotes); - emit VoteCast(msg.sender, _disputeId, _numberOfVotes); - } - - /// @inheritdoc IERC20ResolutionModule - function resolveDispute(bytes32 _disputeId) external onlyOracle { - // 0. Check disputeId actually exists and that it isn't resolved already - IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); - if (_dispute.createdAt == 0) revert ERC20ResolutionModule_NonExistentDispute(); - if (_dispute.status != IOracle.DisputeStatus.None) revert ERC20ResolutionModule_AlreadyResolved(); - - Escalation memory _escalation = escalations[_disputeId]; - // 1. Check that the dispute is actually escalated - if (_escalation.startTime == 0) revert ERC20ResolutionModule_DisputeNotEscalated(); - - // 2. Check that voting deadline is over - RequestParameters memory _params = decodeRequestData(_dispute.requestId); - uint256 _deadline = _escalation.startTime + _params.timeUntilDeadline; - if (block.timestamp < _deadline) revert ERC20ResolutionModule_OnGoingVotingPhase(); - - uint256 _quorumReached = _escalation.totalVotes >= _params.minVotesForQuorum ? 1 : 0; - - address[] memory __voters = _voters[_disputeId].values(); - - // 5. Update status - if (_quorumReached == 1) { - ORACLE.updateDisputeStatus(_disputeId, IOracle.DisputeStatus.Won); - emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Won); - } else { - ORACLE.updateDisputeStatus(_disputeId, IOracle.DisputeStatus.Lost); - emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Lost); - } - - uint256 _votersLength = __voters.length; - - // 6. Return tokens - for (uint256 _i; _i < _votersLength;) { - address _voter = __voters[_i]; - _params.votingToken.safeTransfer(_voter, votes[_disputeId][_voter]); - unchecked { - ++_i; - } - } - } - - /// @inheritdoc IERC20ResolutionModule - function getVoters(bytes32 _disputeId) external view returns (address[] memory __voters) { - __voters = _voters[_disputeId].values(); - } -} +// // solhint-disable-next-line no-unused-import +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +// import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; + +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; + +// import {IERC20ResolutionModule} from '../../../interfaces/modules/resolution/IERC20ResolutionModule.sol'; + +// contract ERC20ResolutionModule is Module, IERC20ResolutionModule { +// using SafeERC20 for IERC20; +// using EnumerableSet for EnumerableSet.AddressSet; + +// /// @inheritdoc IERC20ResolutionModule +// mapping(bytes32 _disputeId => Escalation _escalation) public escalations; + +// /// @inheritdoc IERC20ResolutionModule +// mapping(bytes32 _disputeId => mapping(address _voter => uint256 _numOfVotes)) public votes; + +// mapping(bytes32 _disputeId => EnumerableSet.AddressSet _votersSet) private _voters; + +// constructor(IOracle _oracle) Module(_oracle) {} + +// /// @inheritdoc IModule +// function moduleName() external pure returns (string memory _moduleName) { +// return 'ERC20ResolutionModule'; +// } + +// /// @inheritdoc IERC20ResolutionModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } + +// /// @inheritdoc IERC20ResolutionModule +// function startResolution(bytes32 _disputeId) external onlyOracle { +// escalations[_disputeId].startTime = block.timestamp; +// emit VotingPhaseStarted(block.timestamp, _disputeId); +// } + +// /// @inheritdoc IERC20ResolutionModule +// function castVote(bytes32 _requestId, bytes32 _disputeId, uint256 _numberOfVotes) public { +// IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); +// if (_dispute.createdAt == 0) revert ERC20ResolutionModule_NonExistentDispute(); +// if (_dispute.status != IOracle.DisputeStatus.None) revert ERC20ResolutionModule_AlreadyResolved(); + +// Escalation memory _escalation = escalations[_disputeId]; +// if (_escalation.startTime == 0) revert ERC20ResolutionModule_DisputeNotEscalated(); + +// RequestParameters memory _params = decodeRequestData(_requestId); +// uint256 _deadline = _escalation.startTime + _params.timeUntilDeadline; +// if (block.timestamp >= _deadline) revert ERC20ResolutionModule_VotingPhaseOver(); + +// votes[_disputeId][msg.sender] += _numberOfVotes; + +// _voters[_disputeId].add(msg.sender); +// escalations[_disputeId].totalVotes += _numberOfVotes; + +// _params.votingToken.safeTransferFrom(msg.sender, address(this), _numberOfVotes); +// emit VoteCast(msg.sender, _disputeId, _numberOfVotes); +// } + +// /// @inheritdoc IERC20ResolutionModule +// function resolveDispute(bytes32 _disputeId) external onlyOracle { +// // 0. Check disputeId actually exists and that it isn't resolved already +// IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); +// if (_dispute.createdAt == 0) revert ERC20ResolutionModule_NonExistentDispute(); +// if (_dispute.status != IOracle.DisputeStatus.None) revert ERC20ResolutionModule_AlreadyResolved(); + +// Escalation memory _escalation = escalations[_disputeId]; +// // 1. Check that the dispute is actually escalated +// if (_escalation.startTime == 0) revert ERC20ResolutionModule_DisputeNotEscalated(); + +// // 2. Check that voting deadline is over +// RequestParameters memory _params = decodeRequestData(_dispute.requestId); +// uint256 _deadline = _escalation.startTime + _params.timeUntilDeadline; +// if (block.timestamp < _deadline) revert ERC20ResolutionModule_OnGoingVotingPhase(); + +// uint256 _quorumReached = _escalation.totalVotes >= _params.minVotesForQuorum ? 1 : 0; + +// address[] memory __voters = _voters[_disputeId].values(); + +// // 5. Update status +// if (_quorumReached == 1) { +// ORACLE.updateDisputeStatus(_disputeId, IOracle.DisputeStatus.Won); +// emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Won); +// } else { +// ORACLE.updateDisputeStatus(_disputeId, IOracle.DisputeStatus.Lost); +// emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Lost); +// } + +// uint256 _votersLength = __voters.length; + +// // 6. Return tokens +// for (uint256 _i; _i < _votersLength;) { +// address _voter = __voters[_i]; +// _params.votingToken.safeTransfer(_voter, votes[_disputeId][_voter]); +// unchecked { +// ++_i; +// } +// } +// } + +// /// @inheritdoc IERC20ResolutionModule +// function getVoters(bytes32 _disputeId) external view returns (address[] memory __voters) { +// __voters = _voters[_disputeId].values(); +// } +// } diff --git a/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol b/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol index ec115938..079326fd 100644 --- a/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol +++ b/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol @@ -1,143 +1,143 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -// solhint-disable-next-line no-unused-import -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; -import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; - -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; - -import {IPrivateERC20ResolutionModule} from '../../../interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol'; - -contract PrivateERC20ResolutionModule is Module, IPrivateERC20ResolutionModule { - using SafeERC20 for IERC20; - using EnumerableSet for EnumerableSet.AddressSet; - - /// @inheritdoc IPrivateERC20ResolutionModule - mapping(bytes32 _disputeId => Escalation _escalation) public escalations; - /** - * @notice The data of the voters for a given dispute - */ - mapping(bytes32 _disputeId => mapping(address _voter => VoterData)) internal _votersData; - /** - * @notice The voters addresses for a given dispute - */ - mapping(bytes32 _disputeId => EnumerableSet.AddressSet _votersSet) internal _voters; - - constructor(IOracle _oracle) Module(_oracle) {} - - /// @inheritdoc IModule - function moduleName() external pure returns (string memory _moduleName) { - return 'PrivateERC20ResolutionModule'; - } - - /// @inheritdoc IPrivateERC20ResolutionModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } - - /// @inheritdoc IPrivateERC20ResolutionModule - function startResolution(bytes32 _disputeId) external onlyOracle { - escalations[_disputeId].startTime = block.timestamp; - emit CommittingPhaseStarted(block.timestamp, _disputeId); - } - - /// @inheritdoc IPrivateERC20ResolutionModule - function commitVote(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) public { - IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); - if (_dispute.createdAt == 0) revert PrivateERC20ResolutionModule_NonExistentDispute(); - if (_dispute.status != IOracle.DisputeStatus.None) revert PrivateERC20ResolutionModule_AlreadyResolved(); - - uint256 _startTime = escalations[_disputeId].startTime; - if (_startTime == 0) revert PrivateERC20ResolutionModule_DisputeNotEscalated(); - - RequestParameters memory _params = decodeRequestData(_requestId); - uint256 _committingDeadline = _startTime + _params.committingTimeWindow; - if (block.timestamp >= _committingDeadline) revert PrivateERC20ResolutionModule_CommittingPhaseOver(); - - if (_commitment == bytes32('')) revert PrivateERC20ResolutionModule_EmptyCommitment(); - _votersData[_disputeId][msg.sender] = VoterData({numOfVotes: 0, commitment: _commitment}); - - emit VoteCommitted(msg.sender, _disputeId, _commitment); - } - - /// @inheritdoc IPrivateERC20ResolutionModule - function revealVote(bytes32 _requestId, bytes32 _disputeId, uint256 _numberOfVotes, bytes32 _salt) public { - Escalation memory _escalation = escalations[_disputeId]; - if (_escalation.startTime == 0) revert PrivateERC20ResolutionModule_DisputeNotEscalated(); - - RequestParameters memory _params = decodeRequestData(_requestId); - (uint256 _revealStartTime, uint256 _revealEndTime) = ( - _escalation.startTime + _params.committingTimeWindow, - _escalation.startTime + _params.committingTimeWindow + _params.revealingTimeWindow - ); - if (block.timestamp <= _revealStartTime) revert PrivateERC20ResolutionModule_OnGoingCommittingPhase(); - if (block.timestamp > _revealEndTime) revert PrivateERC20ResolutionModule_RevealingPhaseOver(); - - VoterData storage _voterData = _votersData[_disputeId][msg.sender]; - - if (_voterData.commitment != keccak256(abi.encode(msg.sender, _disputeId, _numberOfVotes, _salt))) { - revert PrivateERC20ResolutionModule_WrongRevealData(); - } - - _voterData.numOfVotes = _numberOfVotes; - _voterData.commitment = bytes32(''); - _voters[_disputeId].add(msg.sender); - escalations[_disputeId].totalVotes += _numberOfVotes; - - _params.votingToken.safeTransferFrom(msg.sender, address(this), _numberOfVotes); - - emit VoteRevealed(msg.sender, _disputeId, _numberOfVotes); - } - - /// @inheritdoc IPrivateERC20ResolutionModule - function resolveDispute(bytes32 _disputeId) external onlyOracle { - IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); - if (_dispute.createdAt == 0) revert PrivateERC20ResolutionModule_NonExistentDispute(); - if (_dispute.status != IOracle.DisputeStatus.None) revert PrivateERC20ResolutionModule_AlreadyResolved(); - - Escalation memory _escalation = escalations[_disputeId]; - if (_escalation.startTime == 0) revert PrivateERC20ResolutionModule_DisputeNotEscalated(); - - RequestParameters memory _params = decodeRequestData(_dispute.requestId); - - if (block.timestamp < _escalation.startTime + _params.committingTimeWindow) { - revert PrivateERC20ResolutionModule_OnGoingCommittingPhase(); - } - if (block.timestamp < _escalation.startTime + _params.committingTimeWindow + _params.revealingTimeWindow) { - revert PrivateERC20ResolutionModule_OnGoingRevealingPhase(); - } - - uint256 _quorumReached = _escalation.totalVotes >= _params.minVotesForQuorum ? 1 : 0; - - address[] memory __voters = _voters[_disputeId].values(); - - if (_quorumReached == 1) { - ORACLE.updateDisputeStatus(_disputeId, IOracle.DisputeStatus.Won); - emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Won); - } else { - ORACLE.updateDisputeStatus(_disputeId, IOracle.DisputeStatus.Lost); - emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Lost); - } - - uint256 _length = __voters.length; - for (uint256 _i; _i < _length;) { - _params.votingToken.safeTransfer(__voters[_i], _votersData[_disputeId][__voters[_i]].numOfVotes); - unchecked { - ++_i; - } - } - } - - /// @inheritdoc IPrivateERC20ResolutionModule - function computeCommitment( - bytes32 _disputeId, - uint256 _numberOfVotes, - bytes32 _salt - ) external view returns (bytes32 _commitment) { - _commitment = keccak256(abi.encode(msg.sender, _disputeId, _numberOfVotes, _salt)); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// // solhint-disable-next-line no-unused-import +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; +// import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; + +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; + +// import {IPrivateERC20ResolutionModule} from '../../../interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol'; + +// contract PrivateERC20ResolutionModule is Module, IPrivateERC20ResolutionModule { +// using SafeERC20 for IERC20; +// using EnumerableSet for EnumerableSet.AddressSet; + +// /// @inheritdoc IPrivateERC20ResolutionModule +// mapping(bytes32 _disputeId => Escalation _escalation) public escalations; +// /** +// * @notice The data of the voters for a given dispute +// */ +// mapping(bytes32 _disputeId => mapping(address _voter => VoterData)) internal _votersData; +// /** +// * @notice The voters addresses for a given dispute +// */ +// mapping(bytes32 _disputeId => EnumerableSet.AddressSet _votersSet) internal _voters; + +// constructor(IOracle _oracle) Module(_oracle) {} + +// /// @inheritdoc IModule +// function moduleName() external pure returns (string memory _moduleName) { +// return 'PrivateERC20ResolutionModule'; +// } + +// /// @inheritdoc IPrivateERC20ResolutionModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } + +// /// @inheritdoc IPrivateERC20ResolutionModule +// function startResolution(bytes32 _disputeId) external onlyOracle { +// escalations[_disputeId].startTime = block.timestamp; +// emit CommittingPhaseStarted(block.timestamp, _disputeId); +// } + +// /// @inheritdoc IPrivateERC20ResolutionModule +// function commitVote(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) public { +// IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); +// if (_dispute.createdAt == 0) revert PrivateERC20ResolutionModule_NonExistentDispute(); +// if (_dispute.status != IOracle.DisputeStatus.None) revert PrivateERC20ResolutionModule_AlreadyResolved(); + +// uint256 _startTime = escalations[_disputeId].startTime; +// if (_startTime == 0) revert PrivateERC20ResolutionModule_DisputeNotEscalated(); + +// RequestParameters memory _params = decodeRequestData(_requestId); +// uint256 _committingDeadline = _startTime + _params.committingTimeWindow; +// if (block.timestamp >= _committingDeadline) revert PrivateERC20ResolutionModule_CommittingPhaseOver(); + +// if (_commitment == bytes32('')) revert PrivateERC20ResolutionModule_EmptyCommitment(); +// _votersData[_disputeId][msg.sender] = VoterData({numOfVotes: 0, commitment: _commitment}); + +// emit VoteCommitted(msg.sender, _disputeId, _commitment); +// } + +// /// @inheritdoc IPrivateERC20ResolutionModule +// function revealVote(bytes32 _requestId, bytes32 _disputeId, uint256 _numberOfVotes, bytes32 _salt) public { +// Escalation memory _escalation = escalations[_disputeId]; +// if (_escalation.startTime == 0) revert PrivateERC20ResolutionModule_DisputeNotEscalated(); + +// RequestParameters memory _params = decodeRequestData(_requestId); +// (uint256 _revealStartTime, uint256 _revealEndTime) = ( +// _escalation.startTime + _params.committingTimeWindow, +// _escalation.startTime + _params.committingTimeWindow + _params.revealingTimeWindow +// ); +// if (block.timestamp <= _revealStartTime) revert PrivateERC20ResolutionModule_OnGoingCommittingPhase(); +// if (block.timestamp > _revealEndTime) revert PrivateERC20ResolutionModule_RevealingPhaseOver(); + +// VoterData storage _voterData = _votersData[_disputeId][msg.sender]; + +// if (_voterData.commitment != keccak256(abi.encode(msg.sender, _disputeId, _numberOfVotes, _salt))) { +// revert PrivateERC20ResolutionModule_WrongRevealData(); +// } + +// _voterData.numOfVotes = _numberOfVotes; +// _voterData.commitment = bytes32(''); +// _voters[_disputeId].add(msg.sender); +// escalations[_disputeId].totalVotes += _numberOfVotes; + +// _params.votingToken.safeTransferFrom(msg.sender, address(this), _numberOfVotes); + +// emit VoteRevealed(msg.sender, _disputeId, _numberOfVotes); +// } + +// /// @inheritdoc IPrivateERC20ResolutionModule +// function resolveDispute(bytes32 _disputeId) external onlyOracle { +// IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); +// if (_dispute.createdAt == 0) revert PrivateERC20ResolutionModule_NonExistentDispute(); +// if (_dispute.status != IOracle.DisputeStatus.None) revert PrivateERC20ResolutionModule_AlreadyResolved(); + +// Escalation memory _escalation = escalations[_disputeId]; +// if (_escalation.startTime == 0) revert PrivateERC20ResolutionModule_DisputeNotEscalated(); + +// RequestParameters memory _params = decodeRequestData(_dispute.requestId); + +// if (block.timestamp < _escalation.startTime + _params.committingTimeWindow) { +// revert PrivateERC20ResolutionModule_OnGoingCommittingPhase(); +// } +// if (block.timestamp < _escalation.startTime + _params.committingTimeWindow + _params.revealingTimeWindow) { +// revert PrivateERC20ResolutionModule_OnGoingRevealingPhase(); +// } + +// uint256 _quorumReached = _escalation.totalVotes >= _params.minVotesForQuorum ? 1 : 0; + +// address[] memory __voters = _voters[_disputeId].values(); + +// if (_quorumReached == 1) { +// ORACLE.updateDisputeStatus(_disputeId, IOracle.DisputeStatus.Won); +// emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Won); +// } else { +// ORACLE.updateDisputeStatus(_disputeId, IOracle.DisputeStatus.Lost); +// emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Lost); +// } + +// uint256 _length = __voters.length; +// for (uint256 _i; _i < _length;) { +// _params.votingToken.safeTransfer(__voters[_i], _votersData[_disputeId][__voters[_i]].numOfVotes); +// unchecked { +// ++_i; +// } +// } +// } + +// /// @inheritdoc IPrivateERC20ResolutionModule +// function computeCommitment( +// bytes32 _disputeId, +// uint256 _numberOfVotes, +// bytes32 _salt +// ) external view returns (bytes32 _commitment) { +// _commitment = keccak256(abi.encode(msg.sender, _disputeId, _numberOfVotes, _salt)); +// } +// } diff --git a/solidity/contracts/modules/resolution/SequentialResolutionModule.sol b/solidity/contracts/modules/resolution/SequentialResolutionModule.sol index a0f63bb0..e918c5df 100644 --- a/solidity/contracts/modules/resolution/SequentialResolutionModule.sol +++ b/solidity/contracts/modules/resolution/SequentialResolutionModule.sol @@ -1,287 +1,287 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; - -import { - ISequentialResolutionModule, - IResolutionModule -} from '../../../interfaces/modules/resolution/ISequentialResolutionModule.sol'; - -/** - * @notice Module that leverages multiple resolution modules to obtain an answer - * @dev The next resolution is started if the current resolution module returns no answer - */ -contract SequentialResolutionModule is Module, ISequentialResolutionModule { - using EnumerableSet for EnumerableSet.AddressSet; - - /// @inheritdoc ISequentialResolutionModule - mapping(bytes32 _disputeId => uint256 _moduleIndex) public currentModuleIndex; - - /// @inheritdoc ISequentialResolutionModule - mapping(bytes32 _disputeId => bytes32 _requestId) public requestIdForDispute; - - /// @inheritdoc ISequentialResolutionModule - uint256 public currentSequenceId; - - /** - * @notice Maps the sequenceId to the array of modules to use - */ - mapping(uint256 _sequenceId => EnumerableSet.AddressSet _modules) internal _resolutionModules; - - constructor(IOracle _oracle) Module(_oracle) {} - - /** - * @notice Checks that the caller is a valid sub-module - */ - modifier onlySubmodule(bytes32 _requestId) { - if (!_resolutionModules[_getSequenceId(_requestId)].contains(msg.sender)) { - revert SequentialResolutionModule_OnlySubmodule(); - } - _; - } - - /// @inheritdoc ISequentialResolutionModule - function addResolutionModuleSequence(IResolutionModule[] memory _modules) external returns (uint256 _sequenceId) { - _sequenceId = ++currentSequenceId; - EnumerableSet.AddressSet storage _setModules = _resolutionModules[_sequenceId]; - for (uint256 _i; _i < _modules.length; ++_i) { - _setModules.add(address(_modules[_i])); - } - emit ResolutionSequenceAdded(_sequenceId, _modules); - } - - /// @inheritdoc ISequentialResolutionModule - function getCurrentResolutionModule(bytes32 _disputeId) public view returns (IResolutionModule _module) { - uint256 _currentIndex = currentModuleIndex[_disputeId]; - EnumerableSet.AddressSet storage _modules = _resolutionModules[_getSequenceId(requestIdForDispute[_disputeId])]; - _module = IResolutionModule(_modules.at(_currentIndex)); - } - - /// @inheritdoc ISequentialResolutionModule - function listSubmodules( - uint256 _startFrom, - uint256 _batchSize, - uint256 _sequenceId - ) external view returns (IResolutionModule[] memory _list) { - EnumerableSet.AddressSet storage _modules = _resolutionModules[_sequenceId]; - uint256 _length = _modules.length(); - uint256 _count = (_batchSize > _length - _startFrom) ? _length - _startFrom : _batchSize; - _list = new IResolutionModule[](_count); - for (uint256 _i; _i < _count; ++_i) { - _list[_i] = IResolutionModule(_modules.at(_startFrom + _i)); - } - } - - /// @inheritdoc IModule - function moduleName() external pure returns (string memory _moduleName) { - return 'SequentialResolutionModule'; - } - - /// @inheritdoc ISequentialResolutionModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } - - /// @inheritdoc IModule - function finalizeRequest( - bytes32 _requestId, - address _finalizer - ) external virtual override(Module, IModule) onlyOracle { - EnumerableSet.AddressSet storage _modules = _resolutionModules[_getSequenceId(_requestId)]; - for (uint256 _i; _i < _modules.length(); ++_i) { - IResolutionModule(_modules.at(_i)).finalizeRequest(_requestId, _finalizer); - } - } - - /// @inheritdoc IOracle - function updateDisputeStatus( - bytes32 _disputeId, - DisputeStatus _status - ) external onlySubmodule(requestIdForDispute[_disputeId]) { - bytes32 _requestId = requestIdForDispute[_disputeId]; - uint256 _nextModuleIndex = currentModuleIndex[_disputeId] + 1; - EnumerableSet.AddressSet storage _modules = _resolutionModules[_getSequenceId(_requestId)]; - if (_status == DisputeStatus.NoResolution && _nextModuleIndex < _modules.length()) { - currentModuleIndex[_disputeId] = _nextModuleIndex; - IResolutionModule(_modules.at(_nextModuleIndex)).startResolution(_disputeId); - } else { - ORACLE.updateDisputeStatus(_disputeId, _status); - } - } - - /// @inheritdoc IResolutionModule - function startResolution(bytes32 _disputeId) external onlyOracle { - bytes32 _requestIdForDispute = ORACLE.getDispute(_disputeId).requestId; - requestIdForDispute[_disputeId] = _requestIdForDispute; - - EnumerableSet.AddressSet storage _modules = _resolutionModules[_getSequenceId(_requestIdForDispute)]; - IResolutionModule(_modules.at(0)).startResolution(_disputeId); - } - - /// @inheritdoc IResolutionModule - function resolveDispute(bytes32 _disputeId) external onlyOracle { - getCurrentResolutionModule(_disputeId).resolveDispute(_disputeId); - } - - /// @inheritdoc Module - function _afterSetupRequest(bytes32 _requestId, bytes calldata _data) internal override { - RequestParameters memory _params = _decodeData(_data); - EnumerableSet.AddressSet storage _modules = _resolutionModules[_params.sequenceId]; - for (uint256 _i; _i < _modules.length(); ++_i) { - IResolutionModule(_modules.at(_i)).setupRequest(_requestId, _params.submoduleData[_i]); - } - } - - /** - * @notice Decodes the data received - * @param _data The data received - * @return _params The parameters of the request - */ - function _decodeData(bytes memory _data) internal pure returns (RequestParameters memory _params) { - _params = abi.decode(_data, (RequestParameters)); - } - - /** - * @notice Returns the sequenceId for a particular requestId - * @param _requestId The requestId to the sequenceId - * @return _sequenceId The sequenceId - */ - function _getSequenceId(bytes32 _requestId) internal view returns (uint256 _sequenceId) { - bytes memory _data = requestData[_requestId]; - RequestParameters memory _params = _decodeData(_data); - _sequenceId = _params.sequenceId; - } - - // ============ ORACLE Proxy ============= - - /// @inheritdoc IOracle - function allowedModule(bytes32 _requestId, address _module) external view returns (bool _allowedModule) { - _allowedModule = ORACLE.allowedModule(_requestId, _module); - } - - /// @inheritdoc IOracle - function isParticipant(bytes32 _requestId, address _user) external view returns (bool _isParticipant) { - _isParticipant = ORACLE.isParticipant(_requestId, _user); - } - - /// @inheritdoc IOracle - function getDispute(bytes32 _disputeId) external view returns (IOracle.Dispute memory _dispute) { - _dispute = ORACLE.getDispute(_disputeId); - } - - /// @inheritdoc IOracle - function getResponse(bytes32 _responseId) external view returns (IOracle.Response memory _response) { - _response = ORACLE.getResponse(_responseId); - } - - /// @inheritdoc IOracle - function getRequestId(uint256 _nonce) external view returns (bytes32 _requestId) { - _requestId = ORACLE.getRequestId(_nonce); - } - - /// @inheritdoc IOracle - function getRequestByNonce(uint256 _nonce) external view returns (Request memory _request) { - _request = ORACLE.getRequestByNonce(_nonce); - } - - /// @inheritdoc IOracle - function getRequest(bytes32 _requestId) external view returns (IOracle.Request memory _request) { - _request = ORACLE.getRequest(_requestId); - } - - /// @inheritdoc IOracle - function getFullRequest(bytes32 _requestId) external view returns (IOracle.FullRequest memory _request) { - _request = ORACLE.getFullRequest(_requestId); - } - - /// @inheritdoc IOracle - function disputeOf(bytes32 _requestId) external view returns (bytes32 _disputeId) { - _disputeId = ORACLE.disputeOf(_requestId); - } - - /// @inheritdoc IOracle - function getFinalizedResponseId(bytes32 _requestId) external view returns (bytes32 _finalizedResponseId) { - _finalizedResponseId = ORACLE.getFinalizedResponseId(_requestId); - } - - /// @inheritdoc IOracle - function getFinalizedResponse(bytes32 _requestId) external view returns (IOracle.Response memory _response) { - _response = ORACLE.getFinalizedResponse(_requestId); - } - - /// @inheritdoc IOracle - function getResponseIds(bytes32 _requestId) external view returns (bytes32[] memory _ids) { - _ids = ORACLE.getResponseIds(_requestId); - } - - /// @inheritdoc IOracle - function listRequests(uint256 _startFrom, uint256 _amount) external view returns (IOracle.FullRequest[] memory _list) { - _list = ORACLE.listRequests(_startFrom, _amount); - } - - /// @inheritdoc IOracle - function listRequestIds(uint256 _startFrom, uint256 _batchSize) external view returns (bytes32[] memory _list) { - _list = ORACLE.listRequestIds(_startFrom, _batchSize); - } - - /// @inheritdoc IOracle - function finalize(bytes32 _requestId, bytes32 _finalizedResponseId) external onlySubmodule(_requestId) { - ORACLE.finalize(_requestId, _finalizedResponseId); - } - - /// @inheritdoc IOracle - function finalize(bytes32 _requestId) external onlySubmodule(_requestId) { - ORACLE.finalize(_requestId); - } - - /// @inheritdoc IOracle - function escalateDispute(bytes32 _disputeId) external onlySubmodule(requestIdForDispute[_disputeId]) { - ORACLE.escalateDispute(_disputeId); - } - - /// @inheritdoc IOracle - function totalRequestCount() external view returns (uint256 _count) { - _count = ORACLE.totalRequestCount(); - } - - // ============ ORACLE Proxy not implemented ============= - - // solhint-disable defi-wonderland/named-return-values - - // This functions use msg.sender in the oracle implementation and cannot be called from a the sequential resolution module - /// @inheritdoc IOracle - function createRequest(IOracle.NewRequest memory) external pure returns (bytes32) { - revert SequentialResolutionModule_NotImplemented(); - } - - /// @inheritdoc IOracle - function createRequests(IOracle.NewRequest[] calldata) external pure returns (bytes32[] memory) { - revert SequentialResolutionModule_NotImplemented(); - } - - /// @inheritdoc IOracle - function disputeResponse(bytes32, bytes32) external pure returns (bytes32) { - revert SequentialResolutionModule_NotImplemented(); - } - - /// @inheritdoc IOracle - function proposeResponse(bytes32, bytes calldata) external pure returns (bytes32) { - revert SequentialResolutionModule_NotImplemented(); - } - - /// @inheritdoc IOracle - function proposeResponse(address, bytes32, bytes calldata) external pure returns (bytes32) { - revert SequentialResolutionModule_NotImplemented(); - } - - /// @inheritdoc IOracle - function deleteResponse(bytes32) external pure { - revert SequentialResolutionModule_NotImplemented(); - } - - // solhint-enable defi-wonderland/named-return-values -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; + +// import { +// ISequentialResolutionModule, +// IResolutionModule +// } from '../../../interfaces/modules/resolution/ISequentialResolutionModule.sol'; + +// /** +// * @notice Module that leverages multiple resolution modules to obtain an answer +// * @dev The next resolution is started if the current resolution module returns no answer +// */ +// contract SequentialResolutionModule is Module, ISequentialResolutionModule { +// using EnumerableSet for EnumerableSet.AddressSet; + +// /// @inheritdoc ISequentialResolutionModule +// mapping(bytes32 _disputeId => uint256 _moduleIndex) public currentModuleIndex; + +// /// @inheritdoc ISequentialResolutionModule +// mapping(bytes32 _disputeId => bytes32 _requestId) public requestIdForDispute; + +// /// @inheritdoc ISequentialResolutionModule +// uint256 public currentSequenceId; + +// /** +// * @notice Maps the sequenceId to the array of modules to use +// */ +// mapping(uint256 _sequenceId => EnumerableSet.AddressSet _modules) internal _resolutionModules; + +// constructor(IOracle _oracle) Module(_oracle) {} + +// /** +// * @notice Checks that the caller is a valid sub-module +// */ +// modifier onlySubmodule(bytes32 _requestId) { +// if (!_resolutionModules[_getSequenceId(_requestId)].contains(msg.sender)) { +// revert SequentialResolutionModule_OnlySubmodule(); +// } +// _; +// } + +// /// @inheritdoc ISequentialResolutionModule +// function addResolutionModuleSequence(IResolutionModule[] memory _modules) external returns (uint256 _sequenceId) { +// _sequenceId = ++currentSequenceId; +// EnumerableSet.AddressSet storage _setModules = _resolutionModules[_sequenceId]; +// for (uint256 _i; _i < _modules.length; ++_i) { +// _setModules.add(address(_modules[_i])); +// } +// emit ResolutionSequenceAdded(_sequenceId, _modules); +// } + +// /// @inheritdoc ISequentialResolutionModule +// function getCurrentResolutionModule(bytes32 _disputeId) public view returns (IResolutionModule _module) { +// uint256 _currentIndex = currentModuleIndex[_disputeId]; +// EnumerableSet.AddressSet storage _modules = _resolutionModules[_getSequenceId(requestIdForDispute[_disputeId])]; +// _module = IResolutionModule(_modules.at(_currentIndex)); +// } + +// /// @inheritdoc ISequentialResolutionModule +// function listSubmodules( +// uint256 _startFrom, +// uint256 _batchSize, +// uint256 _sequenceId +// ) external view returns (IResolutionModule[] memory _list) { +// EnumerableSet.AddressSet storage _modules = _resolutionModules[_sequenceId]; +// uint256 _length = _modules.length(); +// uint256 _count = (_batchSize > _length - _startFrom) ? _length - _startFrom : _batchSize; +// _list = new IResolutionModule[](_count); +// for (uint256 _i; _i < _count; ++_i) { +// _list[_i] = IResolutionModule(_modules.at(_startFrom + _i)); +// } +// } + +// /// @inheritdoc IModule +// function moduleName() external pure returns (string memory _moduleName) { +// return 'SequentialResolutionModule'; +// } + +// /// @inheritdoc ISequentialResolutionModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } + +// /// @inheritdoc IModule +// function finalizeRequest( +// bytes32 _requestId, +// address _finalizer +// ) external virtual override(Module, IModule) onlyOracle { +// EnumerableSet.AddressSet storage _modules = _resolutionModules[_getSequenceId(_requestId)]; +// for (uint256 _i; _i < _modules.length(); ++_i) { +// IResolutionModule(_modules.at(_i)).finalizeRequest(_requestId, _finalizer); +// } +// } + +// /// @inheritdoc IOracle +// function updateDisputeStatus( +// bytes32 _disputeId, +// DisputeStatus _status +// ) external onlySubmodule(requestIdForDispute[_disputeId]) { +// bytes32 _requestId = requestIdForDispute[_disputeId]; +// uint256 _nextModuleIndex = currentModuleIndex[_disputeId] + 1; +// EnumerableSet.AddressSet storage _modules = _resolutionModules[_getSequenceId(_requestId)]; +// if (_status == DisputeStatus.NoResolution && _nextModuleIndex < _modules.length()) { +// currentModuleIndex[_disputeId] = _nextModuleIndex; +// IResolutionModule(_modules.at(_nextModuleIndex)).startResolution(_disputeId); +// } else { +// ORACLE.updateDisputeStatus(_disputeId, _status); +// } +// } + +// /// @inheritdoc IResolutionModule +// function startResolution(bytes32 _disputeId) external onlyOracle { +// bytes32 _requestIdForDispute = ORACLE.getDispute(_disputeId).requestId; +// requestIdForDispute[_disputeId] = _requestIdForDispute; + +// EnumerableSet.AddressSet storage _modules = _resolutionModules[_getSequenceId(_requestIdForDispute)]; +// IResolutionModule(_modules.at(0)).startResolution(_disputeId); +// } + +// /// @inheritdoc IResolutionModule +// function resolveDispute(bytes32 _disputeId) external onlyOracle { +// getCurrentResolutionModule(_disputeId).resolveDispute(_disputeId); +// } + +// /// @inheritdoc Module +// function _afterSetupRequest(bytes32 _requestId, bytes calldata _data) internal override { +// RequestParameters memory _params = _decodeData(_data); +// EnumerableSet.AddressSet storage _modules = _resolutionModules[_params.sequenceId]; +// for (uint256 _i; _i < _modules.length(); ++_i) { +// IResolutionModule(_modules.at(_i)).setupRequest(_requestId, _params.submoduleData[_i]); +// } +// } + +// /** +// * @notice Decodes the data received +// * @param _data The data received +// * @return _params The parameters of the request +// */ +// function _decodeData(bytes memory _data) internal pure returns (RequestParameters memory _params) { +// _params = abi.decode(_data, (RequestParameters)); +// } + +// /** +// * @notice Returns the sequenceId for a particular requestId +// * @param _requestId The requestId to the sequenceId +// * @return _sequenceId The sequenceId +// */ +// function _getSequenceId(bytes32 _requestId) internal view returns (uint256 _sequenceId) { +// bytes memory _data = requestData[_requestId]; +// RequestParameters memory _params = _decodeData(_data); +// _sequenceId = _params.sequenceId; +// } + +// // ============ ORACLE Proxy ============= + +// /// @inheritdoc IOracle +// function allowedModule(bytes32 _requestId, address _module) external view returns (bool _allowedModule) { +// _allowedModule = ORACLE.allowedModule(_requestId, _module); +// } + +// /// @inheritdoc IOracle +// function isParticipant(bytes32 _requestId, address _user) external view returns (bool _isParticipant) { +// _isParticipant = ORACLE.isParticipant(_requestId, _user); +// } + +// /// @inheritdoc IOracle +// function getDispute(bytes32 _disputeId) external view returns (IOracle.Dispute memory _dispute) { +// _dispute = ORACLE.getDispute(_disputeId); +// } + +// /// @inheritdoc IOracle +// function getResponse(bytes32 _responseId) external view returns (IOracle.Response memory _response) { +// _response = ORACLE.getResponse(_responseId); +// } + +// /// @inheritdoc IOracle +// function getRequestId(uint256 _nonce) external view returns (bytes32 _requestId) { +// _requestId = ORACLE.getRequestId(_nonce); +// } + +// /// @inheritdoc IOracle +// function getRequestByNonce(uint256 _nonce) external view returns (Request memory _request) { +// _request = ORACLE.getRequestByNonce(_nonce); +// } + +// /// @inheritdoc IOracle +// function getRequest(bytes32 _requestId) external view returns (IOracle.Request memory _request) { +// _request = ORACLE.getRequest(_requestId); +// } + +// /// @inheritdoc IOracle +// function getFullRequest(bytes32 _requestId) external view returns (IOracle.FullRequest memory _request) { +// _request = ORACLE.getFullRequest(_requestId); +// } + +// /// @inheritdoc IOracle +// function disputeOf(bytes32 _requestId) external view returns (bytes32 _disputeId) { +// _disputeId = ORACLE.disputeOf(_requestId); +// } + +// /// @inheritdoc IOracle +// function getFinalizedResponseId(bytes32 _requestId) external view returns (bytes32 _finalizedResponseId) { +// _finalizedResponseId = ORACLE.getFinalizedResponseId(_requestId); +// } + +// /// @inheritdoc IOracle +// function getFinalizedResponse(bytes32 _requestId) external view returns (IOracle.Response memory _response) { +// _response = ORACLE.getFinalizedResponse(_requestId); +// } + +// /// @inheritdoc IOracle +// function getResponseIds(bytes32 _requestId) external view returns (bytes32[] memory _ids) { +// _ids = ORACLE.getResponseIds(_requestId); +// } + +// /// @inheritdoc IOracle +// function listRequests(uint256 _startFrom, uint256 _amount) external view returns (IOracle.FullRequest[] memory _list) { +// _list = ORACLE.listRequests(_startFrom, _amount); +// } + +// /// @inheritdoc IOracle +// function listRequestIds(uint256 _startFrom, uint256 _batchSize) external view returns (bytes32[] memory _list) { +// _list = ORACLE.listRequestIds(_startFrom, _batchSize); +// } + +// /// @inheritdoc IOracle +// function finalize(bytes32 _requestId, bytes32 _finalizedResponseId) external onlySubmodule(_requestId) { +// ORACLE.finalize(_requestId, _finalizedResponseId); +// } + +// /// @inheritdoc IOracle +// function finalize(bytes32 _requestId) external onlySubmodule(_requestId) { +// ORACLE.finalize(_requestId); +// } + +// /// @inheritdoc IOracle +// function escalateDispute(bytes32 _disputeId) external onlySubmodule(requestIdForDispute[_disputeId]) { +// ORACLE.escalateDispute(_disputeId); +// } + +// /// @inheritdoc IOracle +// function totalRequestCount() external view returns (uint256 _count) { +// _count = ORACLE.totalRequestCount(); +// } + +// // ============ ORACLE Proxy not implemented ============= + +// // solhint-disable defi-wonderland/named-return-values + +// // This functions use msg.sender in the oracle implementation and cannot be called from a the sequential resolution module +// /// @inheritdoc IOracle +// function createRequest(IOracle.NewRequest memory) external pure returns (bytes32) { +// revert SequentialResolutionModule_NotImplemented(); +// } + +// /// @inheritdoc IOracle +// function createRequests(IOracle.NewRequest[] calldata) external pure returns (bytes32[] memory) { +// revert SequentialResolutionModule_NotImplemented(); +// } + +// /// @inheritdoc IOracle +// function disputeResponse(bytes32, bytes32) external pure returns (bytes32) { +// revert SequentialResolutionModule_NotImplemented(); +// } + +// /// @inheritdoc IOracle +// function proposeResponse(bytes32, bytes calldata) external pure returns (bytes32) { +// revert SequentialResolutionModule_NotImplemented(); +// } + +// /// @inheritdoc IOracle +// function proposeResponse(address, bytes32, bytes calldata) external pure returns (bytes32) { +// revert SequentialResolutionModule_NotImplemented(); +// } + +// /// @inheritdoc IOracle +// function deleteResponse(bytes32) external pure { +// revert SequentialResolutionModule_NotImplemented(); +// } + +// // solhint-enable defi-wonderland/named-return-values +// } diff --git a/solidity/contracts/modules/response/BondedResponseModule.sol b/solidity/contracts/modules/response/BondedResponseModule.sol index b8567c96..3dffd2fb 100644 --- a/solidity/contracts/modules/response/BondedResponseModule.sol +++ b/solidity/contracts/modules/response/BondedResponseModule.sol @@ -1,118 +1,118 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -// solhint-disable-next-line no-unused-import -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IBondedResponseModule} from '../../../interfaces/modules/response/IBondedResponseModule.sol'; - -contract BondedResponseModule is Module, IBondedResponseModule { - constructor(IOracle _oracle) Module(_oracle) {} - - /// @inheritdoc IModule - function moduleName() public pure returns (string memory _moduleName) { - _moduleName = 'BondedResponseModule'; - } - - /// @inheritdoc IBondedResponseModule - function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { - _params = abi.decode(requestData[_requestId], (RequestParameters)); - } - - /// @inheritdoc IBondedResponseModule - function propose( - bytes32 _requestId, - address _proposer, - bytes calldata _responseData, - address _sender - ) external onlyOracle returns (IOracle.Response memory _response) { - RequestParameters memory _params = decodeRequestData(_requestId); - - // Cannot propose after the deadline - if (block.timestamp >= _params.deadline) revert BondedResponseModule_TooLateToPropose(); - - // Cannot propose to a request with a response, unless the response is being disputed - bytes32[] memory _responseIds = ORACLE.getResponseIds(_requestId); - uint256 _responsesLength = _responseIds.length; - - if (_responsesLength != 0) { - bytes32 _disputeId = ORACLE.getResponse(_responseIds[_responsesLength - 1]).disputeId; - - // Allowing one undisputed response at a time - if (_disputeId == bytes32(0)) revert BondedResponseModule_AlreadyResponded(); - IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); - // TODO: leaving a note here to re-check this check if a new status is added - // If the dispute was lost, we assume the proposed answer was correct. DisputeStatus.None should not be reachable due to the previous check. - if (_dispute.status == IOracle.DisputeStatus.Lost) revert BondedResponseModule_AlreadyResponded(); - } - - _response = IOracle.Response({ - requestId: _requestId, - disputeId: bytes32(0), - proposer: _proposer, - response: _responseData, - createdAt: block.timestamp - }); - - _params.accountingExtension.bond({ - _bonder: _response.proposer, - _requestId: _requestId, - _token: _params.bondToken, - _amount: _params.bondSize, - _sender: _sender - }); - - emit ProposeResponse(_requestId, _proposer, _responseData); - } - - /// @inheritdoc IBondedResponseModule - function deleteResponse(bytes32 _requestId, bytes32, address _proposer) external onlyOracle { - RequestParameters memory _params = decodeRequestData(_requestId); - - if (block.timestamp > _params.deadline) revert BondedResponseModule_TooLateToDelete(); - - _params.accountingExtension.release({ - _bonder: _proposer, - _requestId: _requestId, - _token: _params.bondToken, - _amount: _params.bondSize - }); - } - - /// @inheritdoc IBondedResponseModule - function finalizeRequest( - bytes32 _requestId, - address _finalizer - ) external override(IBondedResponseModule, Module) onlyOracle { - RequestParameters memory _params = decodeRequestData(_requestId); - - bool _isModule = ORACLE.allowedModule(_requestId, _finalizer); - - if (!_isModule && block.timestamp < _params.deadline) { - revert BondedResponseModule_TooEarlyToFinalize(); - } - - IOracle.Response memory _response = ORACLE.getFinalizedResponse(_requestId); - if (_response.createdAt != 0) { - if (!_isModule && block.timestamp < _response.createdAt + _params.disputeWindow) { - revert BondedResponseModule_TooEarlyToFinalize(); - } - - _params.accountingExtension.release({ - _bonder: _response.proposer, - _requestId: _requestId, - _token: _params.bondToken, - _amount: _params.bondSize - }); - } - emit RequestFinalized(_requestId, _finalizer); - } - - /// @inheritdoc Module - function _afterSetupRequest(bytes32, bytes calldata _data) internal view override { - RequestParameters memory _params = abi.decode(_data, (RequestParameters)); - if (_params.deadline <= block.timestamp) { - revert BondedResponseModule_InvalidRequest(); - } - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// // solhint-disable-next-line no-unused-import +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IBondedResponseModule} from '../../../interfaces/modules/response/IBondedResponseModule.sol'; + +// contract BondedResponseModule is Module, IBondedResponseModule { +// constructor(IOracle _oracle) Module(_oracle) {} + +// /// @inheritdoc IModule +// function moduleName() public pure returns (string memory _moduleName) { +// _moduleName = 'BondedResponseModule'; +// } + +// /// @inheritdoc IBondedResponseModule +// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { +// _params = abi.decode(requestData[_requestId], (RequestParameters)); +// } + +// /// @inheritdoc IBondedResponseModule +// function propose( +// bytes32 _requestId, +// address _proposer, +// bytes calldata _responseData, +// address _sender +// ) external onlyOracle returns (IOracle.Response memory _response) { +// RequestParameters memory _params = decodeRequestData(_requestId); + +// // Cannot propose after the deadline +// if (block.timestamp >= _params.deadline) revert BondedResponseModule_TooLateToPropose(); + +// // Cannot propose to a request with a response, unless the response is being disputed +// bytes32[] memory _responseIds = ORACLE.getResponseIds(_requestId); +// uint256 _responsesLength = _responseIds.length; + +// if (_responsesLength != 0) { +// bytes32 _disputeId = ORACLE.getResponse(_responseIds[_responsesLength - 1]).disputeId; + +// // Allowing one undisputed response at a time +// if (_disputeId == bytes32(0)) revert BondedResponseModule_AlreadyResponded(); +// IOracle.Dispute memory _dispute = ORACLE.getDispute(_disputeId); +// // TODO: leaving a note here to re-check this check if a new status is added +// // If the dispute was lost, we assume the proposed answer was correct. DisputeStatus.None should not be reachable due to the previous check. +// if (_dispute.status == IOracle.DisputeStatus.Lost) revert BondedResponseModule_AlreadyResponded(); +// } + +// _response = IOracle.Response({ +// requestId: _requestId, +// disputeId: bytes32(0), +// proposer: _proposer, +// response: _responseData, +// createdAt: block.timestamp +// }); + +// _params.accountingExtension.bond({ +// _bonder: _response.proposer, +// _requestId: _requestId, +// _token: _params.bondToken, +// _amount: _params.bondSize, +// _sender: _sender +// }); + +// emit ProposeResponse(_requestId, _proposer, _responseData); +// } + +// /// @inheritdoc IBondedResponseModule +// function deleteResponse(bytes32 _requestId, bytes32, address _proposer) external onlyOracle { +// RequestParameters memory _params = decodeRequestData(_requestId); + +// if (block.timestamp > _params.deadline) revert BondedResponseModule_TooLateToDelete(); + +// _params.accountingExtension.release({ +// _bonder: _proposer, +// _requestId: _requestId, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); +// } + +// /// @inheritdoc IBondedResponseModule +// function finalizeRequest( +// bytes32 _requestId, +// address _finalizer +// ) external override(IBondedResponseModule, Module) onlyOracle { +// RequestParameters memory _params = decodeRequestData(_requestId); + +// bool _isModule = ORACLE.allowedModule(_requestId, _finalizer); + +// if (!_isModule && block.timestamp < _params.deadline) { +// revert BondedResponseModule_TooEarlyToFinalize(); +// } + +// IOracle.Response memory _response = ORACLE.getFinalizedResponse(_requestId); +// if (_response.createdAt != 0) { +// if (!_isModule && block.timestamp < _response.createdAt + _params.disputeWindow) { +// revert BondedResponseModule_TooEarlyToFinalize(); +// } + +// _params.accountingExtension.release({ +// _bonder: _response.proposer, +// _requestId: _requestId, +// _token: _params.bondToken, +// _amount: _params.bondSize +// }); +// } +// emit RequestFinalized(_requestId, _finalizer); +// } + +// /// @inheritdoc Module +// function _afterSetupRequest(bytes32, bytes calldata _data) internal view override { +// RequestParameters memory _params = abi.decode(_data, (RequestParameters)); +// if (_params.deadline <= block.timestamp) { +// revert BondedResponseModule_InvalidRequest(); +// } +// } +// } diff --git a/solidity/interfaces/extensions/IAccountingExtension.sol b/solidity/interfaces/extensions/IAccountingExtension.sol index 74c9c9cd..5a42243e 100644 --- a/solidity/interfaces/extensions/IAccountingExtension.sol +++ b/solidity/interfaces/extensions/IAccountingExtension.sol @@ -1,190 +1,190 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; - -/* - * @title AccountingExtension - * @notice Extension allowing users to deposit and bond funds - * to be used for payments and disputes. - */ -interface IAccountingExtension { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice A user deposited tokens into the accounting extension - * @param _depositor The user who deposited the tokens - * @param _token The address of the token deposited by the user - * @param _amount The amount of `_token` deposited - */ - event Deposited(address indexed _depositor, IERC20 indexed _token, uint256 _amount); - - /** - * @notice A user withdrew tokens from the accounting extension - * @param _withdrawer The user who withdrew the tokens - * @param _token The address of the token withdrawn by the user - * @param _amount The amount of `_token` withdrawn - */ - event Withdrew(address indexed _withdrawer, IERC20 indexed _token, uint256 _amount); - - /** - * @notice A payment between users has been made - * @param _beneficiary The user receiving the tokens - * @param _payer The user who is getting its tokens transferred - * @param _token The address of the token being transferred - * @param _amount The amount of `_token` transferred - */ - event Paid( - bytes32 indexed _requestId, address indexed _beneficiary, address indexed _payer, IERC20 _token, uint256 _amount - ); - - /** - * @notice User's funds have been bonded - * @param _bonder The user who is getting its tokens bonded - * @param _token The address of the token being bonded - * @param _amount The amount of `_token` bonded - */ - event Bonded(bytes32 indexed _requestId, address indexed _bonder, IERC20 indexed _token, uint256 _amount); - - /** - * @notice User's funds have been released - * @param _beneficiary The user who is getting its tokens released - * @param _token The address of the token being released - * @param _amount The amount of `_token` released - */ - event Released(bytes32 indexed _requestId, address indexed _beneficiary, IERC20 indexed _token, uint256 _amount); - - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Thrown when the account doesn't have enough balance to bond/withdraw - * or not enough bonded to release/pay - */ - error AccountingExtension_InsufficientFunds(); - - /** - * @notice Thrown when the module bonding user tokens hasn't been approved by the user. - */ - error AccountingExtension_InsufficientAllowance(); - - /** - * @notice Thrown when an `onlyAllowedModule` function is called by something - * else than a module being used in the corresponding request - */ - error AccountingExtension_UnauthorizedModule(); - - /** - * @notice Thrown when an `onlyParticipant` function is called with an address - * that is not part of the request. - */ - error AccountingExtension_UnauthorizedUser(); - - /*/////////////////////////////////////////////////////////////// - VARIABLES - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Returns the interface for the Oracle contract - */ - function ORACLE() external view returns (IOracle _oracle); - - /** - * @notice Returns the amount of a token a user has bonded - * @param _user The address of the user with bonded tokens - * @param _bondToken The token bonded - * @param _requestId The id of the request the user bonded for - * @return _amount The amount of `_bondToken` bonded - */ - function bondedAmountOf(address _user, IERC20 _bondToken, bytes32 _requestId) external returns (uint256 _amount); - - /** - * @notice Returns the amount of a token a user has deposited - * @param _user The address of the user with deposited tokens - * @param _token The token deposited - * @return _amount The amount of `_token` deposited - */ - function balanceOf(address _user, IERC20 _token) external view returns (uint256 _amount); - - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Transfers tokens from a user and updates his virtual balance - * @dev The user must have approved the accounting extension to transfer the tokens. - * @param _token The address of the token being deposited - * @param _amount The amount of `_token` to deposit - */ - function deposit(IERC20 _token, uint256 _amount) external; - - /** - * @notice Allows an user to withdraw deposited tokens - * @param _token The address of the token being withdrawn - * @param _amount The amount of `_token` to withdraw - */ - function withdraw(IERC20 _token, uint256 _amount) external; - - /** - * @notice Allows a allowed module to transfer bonded tokens from one user to another - * @dev Only the virtual balances in the accounting extension are modified. The token contract - * is not called nor its balances modified. - * @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 - */ - 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 - * @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 - */ - 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 _token The address of the token being released - * @param _amount The amount of `_token` to release - */ - function release(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount) external; - - /** - * @notice Allows a user to approve a module for bonding tokens - * @param _module The address of the module to be approved - */ - function approveModule(address _module) external; - - /** - * @notice Allows a user to revoke a module's approval for bonding tokens - * @param _module The address of the module to be revoked - */ - function revokeModule(address _module) external; - - /** - * @notice Returns a list of all modules a user has approved - * @param _user The address of the user - * @return _approvedModules The array of all modules approved by the user - */ - function approvedModules(address _user) external view returns (address[] memory _approvedModules); -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; + +// /* +// * @title AccountingExtension +// * @notice Extension allowing users to deposit and bond funds +// * to be used for payments and disputes. +// */ +// interface IAccountingExtension { +// /*/////////////////////////////////////////////////////////////// +// EVENTS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice A user deposited tokens into the accounting extension +// * @param _depositor The user who deposited the tokens +// * @param _token The address of the token deposited by the user +// * @param _amount The amount of `_token` deposited +// */ +// event Deposited(address indexed _depositor, IERC20 indexed _token, uint256 _amount); + +// /** +// * @notice A user withdrew tokens from the accounting extension +// * @param _withdrawer The user who withdrew the tokens +// * @param _token The address of the token withdrawn by the user +// * @param _amount The amount of `_token` withdrawn +// */ +// event Withdrew(address indexed _withdrawer, IERC20 indexed _token, uint256 _amount); + +// /** +// * @notice A payment between users has been made +// * @param _beneficiary The user receiving the tokens +// * @param _payer The user who is getting its tokens transferred +// * @param _token The address of the token being transferred +// * @param _amount The amount of `_token` transferred +// */ +// event Paid( +// bytes32 indexed _requestId, address indexed _beneficiary, address indexed _payer, IERC20 _token, uint256 _amount +// ); + +// /** +// * @notice User's funds have been bonded +// * @param _bonder The user who is getting its tokens bonded +// * @param _token The address of the token being bonded +// * @param _amount The amount of `_token` bonded +// */ +// event Bonded(bytes32 indexed _requestId, address indexed _bonder, IERC20 indexed _token, uint256 _amount); + +// /** +// * @notice User's funds have been released +// * @param _beneficiary The user who is getting its tokens released +// * @param _token The address of the token being released +// * @param _amount The amount of `_token` released +// */ +// event Released(bytes32 indexed _requestId, address indexed _beneficiary, IERC20 indexed _token, uint256 _amount); + +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Thrown when the account doesn't have enough balance to bond/withdraw +// * or not enough bonded to release/pay +// */ +// error AccountingExtension_InsufficientFunds(); + +// /** +// * @notice Thrown when the module bonding user tokens hasn't been approved by the user. +// */ +// error AccountingExtension_InsufficientAllowance(); + +// /** +// * @notice Thrown when an `onlyAllowedModule` function is called by something +// * else than a module being used in the corresponding request +// */ +// error AccountingExtension_UnauthorizedModule(); + +// /** +// * @notice Thrown when an `onlyParticipant` function is called with an address +// * that is not part of the request. +// */ +// error AccountingExtension_UnauthorizedUser(); + +// /*/////////////////////////////////////////////////////////////// +// VARIABLES +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Returns the interface for the Oracle contract +// */ +// function ORACLE() external view returns (IOracle _oracle); + +// /** +// * @notice Returns the amount of a token a user has bonded +// * @param _user The address of the user with bonded tokens +// * @param _bondToken The token bonded +// * @param _requestId The id of the request the user bonded for +// * @return _amount The amount of `_bondToken` bonded +// */ +// function bondedAmountOf(address _user, IERC20 _bondToken, bytes32 _requestId) external returns (uint256 _amount); + +// /** +// * @notice Returns the amount of a token a user has deposited +// * @param _user The address of the user with deposited tokens +// * @param _token The token deposited +// * @return _amount The amount of `_token` deposited +// */ +// function balanceOf(address _user, IERC20 _token) external view returns (uint256 _amount); + +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Transfers tokens from a user and updates his virtual balance +// * @dev The user must have approved the accounting extension to transfer the tokens. +// * @param _token The address of the token being deposited +// * @param _amount The amount of `_token` to deposit +// */ +// function deposit(IERC20 _token, uint256 _amount) external; + +// /** +// * @notice Allows an user to withdraw deposited tokens +// * @param _token The address of the token being withdrawn +// * @param _amount The amount of `_token` to withdraw +// */ +// function withdraw(IERC20 _token, uint256 _amount) external; + +// /** +// * @notice Allows a allowed module to transfer bonded tokens from one user to another +// * @dev Only the virtual balances in the accounting extension are modified. The token contract +// * is not called nor its balances modified. +// * @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 +// */ +// 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 +// * @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 +// */ +// 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 _token The address of the token being released +// * @param _amount The amount of `_token` to release +// */ +// function release(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount) external; + +// /** +// * @notice Allows a user to approve a module for bonding tokens +// * @param _module The address of the module to be approved +// */ +// function approveModule(address _module) external; + +// /** +// * @notice Allows a user to revoke a module's approval for bonding tokens +// * @param _module The address of the module to be revoked +// */ +// function revokeModule(address _module) external; + +// /** +// * @notice Returns a list of all modules a user has approved +// * @param _user The address of the user +// * @return _approvedModules The array of all modules approved by the user +// */ +// function approvedModules(address _user) external view returns (address[] memory _approvedModules); +// } diff --git a/solidity/interfaces/extensions/IBondEscalationAccounting.sol b/solidity/interfaces/extensions/IBondEscalationAccounting.sol index ce7728c9..6dbec948 100644 --- a/solidity/interfaces/extensions/IBondEscalationAccounting.sol +++ b/solidity/interfaces/extensions/IBondEscalationAccounting.sol @@ -1,240 +1,240 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import {IAccountingExtension} from './IAccountingExtension.sol'; -import {IBondEscalationModule} from '../modules/dispute/IBondEscalationModule.sol'; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -/** - * @title BondEscalationAccounting - * @notice Extension allowing users to deposit and pledge funds to be used for bond escalation - */ -interface IBondEscalationAccounting is IAccountingExtension { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice A user pledged tokens for one of the sides of a dispute - * - * @param _pledger The user who pledged the tokens - * @param _requestId The ID of the bond-escalated request - * @param _disputeId The ID of the bond-escalated dispute - * @param _token The address of the token being pledged - * @param _amount The amount of `_token` pledged by the user - */ - event Pledged( - address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, IERC20 _token, uint256 _amount - ); - - /** - * @notice The pledgers of the winning side of a dispute have been paid - * - * @param _requestId The ID of the bond-escalated request - * @param _disputeId The ID of the bond-escalated dispute - * @param _winningPledgers The users who got paid for pledging for the winning side - * @param _token The address of the token being paid out - * @param _amountPerPledger The amount of `_token` paid to each of the winning pledgers - */ - event WinningPledgersPaid( - bytes32 indexed _requestId, - bytes32 indexed _disputeId, - address[] indexed _winningPledgers, - IERC20 _token, - uint256 _amountPerPledger - ); - - /** - * @notice A bond escalation has been settled - * - * @param _requestId The ID of the bond-escalated request - * @param _disputeId The ID of the bond-escalated dispute - * @param _forVotesWon True if the winning side were the for votes - * @param _token The address of the token being paid out - * @param _amountPerPledger The amount of `_token` to be paid for each winning pledgers - * @param _winningPledgersLength The number of winning pledgers - */ - event BondEscalationSettled( - bytes32 _requestId, - bytes32 _disputeId, - bool _forVotesWon, - IERC20 _token, - 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 _token The address of the token being released - * @param _amount The amount of `_token` released - */ - event PledgeReleased( - bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, IERC20 _token, uint256 _amount - ); - - /** - * @notice A user claimed their reward for pledging for the winning side of a dispute - * - * @param _requestId The ID of the bond-escalated request - * @param _disputeId The ID of the bond-escalated dispute - * @param _pledger The user who claimed their reward - * @param _token The address of the token being paid out - * @param _amount The amount of `_token` paid to the pledger - */ - event EscalationRewardClaimed( - bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, IERC20 _token, uint256 _amount - ); - - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Contains the data of the result of an escalation. Is used by users to claim their pledges - * @param requestId The ID of the bond-escalated request - * @param forVotesWon Whether the for votes won the dispute - * @param token The address of the token being paid out - * @param amountPerPledger The amount of token paid to each of the winning pledgers - * @param bondEscalationModule The address of the bond escalation module that was used - */ - struct EscalationResult { - bytes32 requestId; - bool forVotesWon; - IERC20 token; - uint256 amountPerPledger; - IBondEscalationModule bondEscalationModule; - } - - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Thrown when the user tries to claim their pledge for an escalation that was already claimed - */ - error BondEscalationAccounting_AlreadyClaimed(); - - /** - * @notice Thrown when the user tries to claim their pledge for an escalation that wasn't finished yet - */ - error BondEscalationAccounting_NoEscalationResult(); - - /** - * @notice Thrown when the user doesn't have enough funds to pledge - */ - error BondEscalationAccounting_InsufficientFunds(); - - /** - * @notice Thrown when trying to settle an already settled escalation - */ - error BondEscalationAccounting_AlreadySettled(); - - /*/////////////////////////////////////////////////////////////// - VARIABLES - //////////////////////////////////////////////////////////////*/ - - /** - * @notice The amount pledged by the given pledger in the given dispute of the given request - * - * @param _disputeId The ID of the bond-escalated dispute - * @param _token Address of the token being pledged - * @return _amountPledged The amount of pledged tokens - */ - function pledges(bytes32 _disputeId, IERC20 _token) external returns (uint256 _amountPledged); - - /** - * @notice The result of the given dispute - * - * @param _disputeId The ID of the bond-escalated dispute - * @return _requestId The ID of the bond-escalated request - * @return _forVotesWon True if the for votes won the dispute - * @return _token Address of the token being paid as a reward for winning the bond escalation - * @return _amountPerPledger Amount of `_token` to be rewarded to each of the winning pledgers - * @return _bondEscalationModule The address of the bond escalation module that was used - */ - function escalationResults(bytes32 _disputeId) - external - returns ( - bytes32 _requestId, - bool _forVotesWon, - IERC20 _token, - uint256 _amountPerPledger, - IBondEscalationModule _bondEscalationModule - ); - - /** - * @notice True if the given pledger has claimed their reward for the given dispute - * - * @param _requestId The ID of the bond-escalated request - * @param _pledger Address of the pledger - * @return _claimed True if the pledger has claimed their reward - */ - function pledgerClaimed(bytes32 _requestId, address _pledger) external returns (bool _claimed); - - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Pledges the given amount of token to the provided dispute id of the provided request id - * - * @dev This function must be called by an allowed module - * - * @param _pledger Address of the pledger - * @param _requestId The ID of the bond-escalated request - * @param _disputeId The ID of the bond-escalated dispute - * @param _token Address of the token being paid as a reward for winning the bond escalation - * @param _amount Amount of token to pledge - */ - function pledge(address _pledger, bytes32 _requestId, bytes32 _disputeId, IERC20 _token, uint256 _amount) external; - - /** - * @notice Updates the accounting of the given dispute to reflect the result of the bond escalation - * @dev This function must be called by an allowed module - * - * @param _requestId The ID of the bond-escalated request - * @param _disputeId The ID of the bond-escalated dispute - * @param _forVotesWon True if the for votes won the dispute - * @param _token Address of the token being paid as a reward for winning the bond escalation - * @param _amountPerPledger Amount of `_token` to be rewarded to each of the winning pledgers - * @param _winningPledgersLength Amount of pledges that won the dispute - */ - function onSettleBondEscalation( - bytes32 _requestId, - bytes32 _disputeId, - bool _forVotesWon, - IERC20 _token, - uint256 _amountPerPledger, - uint256 _winningPledgersLength - ) external; - - /** - * @notice Releases a given amount of funds to the pledger - * - * @dev This function must be called by an allowed module - * - * @param _requestId The ID of the bond-escalated request - * @param _disputeId The ID of the bond-escalated dispute - * @param _pledger Address of the pledger - * @param _token Address of the token to be released - * @param _amount Amount of `_token` to be released to the pledger - */ - function releasePledge( - bytes32 _requestId, - bytes32 _disputeId, - address _pledger, - IERC20 _token, - uint256 _amount - ) external; - - /** - * @notice Claims the reward for the pledger the given dispute - * @param _disputeId The ID of the bond-escalated dispute - * @param _pledger Address of the pledger to claim the rewards - */ - function claimEscalationReward(bytes32 _disputeId, address _pledger) external; -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import {IAccountingExtension} from './IAccountingExtension.sol'; +// import {IBondEscalationModule} from '../modules/dispute/IBondEscalationModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +// /** +// * @title BondEscalationAccounting +// * @notice Extension allowing users to deposit and pledge funds to be used for bond escalation +// */ +// interface IBondEscalationAccounting is IAccountingExtension { +// /*/////////////////////////////////////////////////////////////// +// EVENTS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice A user pledged tokens for one of the sides of a dispute +// * +// * @param _pledger The user who pledged the tokens +// * @param _requestId The ID of the bond-escalated request +// * @param _disputeId The ID of the bond-escalated dispute +// * @param _token The address of the token being pledged +// * @param _amount The amount of `_token` pledged by the user +// */ +// event Pledged( +// address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, IERC20 _token, uint256 _amount +// ); + +// /** +// * @notice The pledgers of the winning side of a dispute have been paid +// * +// * @param _requestId The ID of the bond-escalated request +// * @param _disputeId The ID of the bond-escalated dispute +// * @param _winningPledgers The users who got paid for pledging for the winning side +// * @param _token The address of the token being paid out +// * @param _amountPerPledger The amount of `_token` paid to each of the winning pledgers +// */ +// event WinningPledgersPaid( +// bytes32 indexed _requestId, +// bytes32 indexed _disputeId, +// address[] indexed _winningPledgers, +// IERC20 _token, +// uint256 _amountPerPledger +// ); + +// /** +// * @notice A bond escalation has been settled +// * +// * @param _requestId The ID of the bond-escalated request +// * @param _disputeId The ID of the bond-escalated dispute +// * @param _forVotesWon True if the winning side were the for votes +// * @param _token The address of the token being paid out +// * @param _amountPerPledger The amount of `_token` to be paid for each winning pledgers +// * @param _winningPledgersLength The number of winning pledgers +// */ +// event BondEscalationSettled( +// bytes32 _requestId, +// bytes32 _disputeId, +// bool _forVotesWon, +// IERC20 _token, +// 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 _token The address of the token being released +// * @param _amount The amount of `_token` released +// */ +// event PledgeReleased( +// bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, IERC20 _token, uint256 _amount +// ); + +// /** +// * @notice A user claimed their reward for pledging for the winning side of a dispute +// * +// * @param _requestId The ID of the bond-escalated request +// * @param _disputeId The ID of the bond-escalated dispute +// * @param _pledger The user who claimed their reward +// * @param _token The address of the token being paid out +// * @param _amount The amount of `_token` paid to the pledger +// */ +// event EscalationRewardClaimed( +// bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, IERC20 _token, uint256 _amount +// ); + +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Contains the data of the result of an escalation. Is used by users to claim their pledges +// * @param requestId The ID of the bond-escalated request +// * @param forVotesWon Whether the for votes won the dispute +// * @param token The address of the token being paid out +// * @param amountPerPledger The amount of token paid to each of the winning pledgers +// * @param bondEscalationModule The address of the bond escalation module that was used +// */ +// struct EscalationResult { +// bytes32 requestId; +// bool forVotesWon; +// IERC20 token; +// uint256 amountPerPledger; +// IBondEscalationModule bondEscalationModule; +// } + +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Thrown when the user tries to claim their pledge for an escalation that was already claimed +// */ +// error BondEscalationAccounting_AlreadyClaimed(); + +// /** +// * @notice Thrown when the user tries to claim their pledge for an escalation that wasn't finished yet +// */ +// error BondEscalationAccounting_NoEscalationResult(); + +// /** +// * @notice Thrown when the user doesn't have enough funds to pledge +// */ +// error BondEscalationAccounting_InsufficientFunds(); + +// /** +// * @notice Thrown when trying to settle an already settled escalation +// */ +// error BondEscalationAccounting_AlreadySettled(); + +// /*/////////////////////////////////////////////////////////////// +// VARIABLES +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice The amount pledged by the given pledger in the given dispute of the given request +// * +// * @param _disputeId The ID of the bond-escalated dispute +// * @param _token Address of the token being pledged +// * @return _amountPledged The amount of pledged tokens +// */ +// function pledges(bytes32 _disputeId, IERC20 _token) external returns (uint256 _amountPledged); + +// /** +// * @notice The result of the given dispute +// * +// * @param _disputeId The ID of the bond-escalated dispute +// * @return _requestId The ID of the bond-escalated request +// * @return _forVotesWon True if the for votes won the dispute +// * @return _token Address of the token being paid as a reward for winning the bond escalation +// * @return _amountPerPledger Amount of `_token` to be rewarded to each of the winning pledgers +// * @return _bondEscalationModule The address of the bond escalation module that was used +// */ +// function escalationResults(bytes32 _disputeId) +// external +// returns ( +// bytes32 _requestId, +// bool _forVotesWon, +// IERC20 _token, +// uint256 _amountPerPledger, +// IBondEscalationModule _bondEscalationModule +// ); + +// /** +// * @notice True if the given pledger has claimed their reward for the given dispute +// * +// * @param _requestId The ID of the bond-escalated request +// * @param _pledger Address of the pledger +// * @return _claimed True if the pledger has claimed their reward +// */ +// function pledgerClaimed(bytes32 _requestId, address _pledger) external returns (bool _claimed); + +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Pledges the given amount of token to the provided dispute id of the provided request id +// * +// * @dev This function must be called by an allowed module +// * +// * @param _pledger Address of the pledger +// * @param _requestId The ID of the bond-escalated request +// * @param _disputeId The ID of the bond-escalated dispute +// * @param _token Address of the token being paid as a reward for winning the bond escalation +// * @param _amount Amount of token to pledge +// */ +// function pledge(address _pledger, bytes32 _requestId, bytes32 _disputeId, IERC20 _token, uint256 _amount) external; + +// /** +// * @notice Updates the accounting of the given dispute to reflect the result of the bond escalation +// * @dev This function must be called by an allowed module +// * +// * @param _requestId The ID of the bond-escalated request +// * @param _disputeId The ID of the bond-escalated dispute +// * @param _forVotesWon True if the for votes won the dispute +// * @param _token Address of the token being paid as a reward for winning the bond escalation +// * @param _amountPerPledger Amount of `_token` to be rewarded to each of the winning pledgers +// * @param _winningPledgersLength Amount of pledges that won the dispute +// */ +// function onSettleBondEscalation( +// bytes32 _requestId, +// bytes32 _disputeId, +// bool _forVotesWon, +// IERC20 _token, +// uint256 _amountPerPledger, +// uint256 _winningPledgersLength +// ) external; + +// /** +// * @notice Releases a given amount of funds to the pledger +// * +// * @dev This function must be called by an allowed module +// * +// * @param _requestId The ID of the bond-escalated request +// * @param _disputeId The ID of the bond-escalated dispute +// * @param _pledger Address of the pledger +// * @param _token Address of the token to be released +// * @param _amount Amount of `_token` to be released to the pledger +// */ +// function releasePledge( +// bytes32 _requestId, +// bytes32 _disputeId, +// address _pledger, +// IERC20 _token, +// uint256 _amount +// ) external; + +// /** +// * @notice Claims the reward for the pledger the given dispute +// * @param _disputeId The ID of the bond-escalated dispute +// * @param _pledger Address of the pledger to claim the rewards +// */ +// function claimEscalationReward(bytes32 _disputeId, address _pledger) external; +// } diff --git a/solidity/interfaces/modules/dispute/IBondEscalationModule.sol b/solidity/interfaces/modules/dispute/IBondEscalationModule.sol index 79800363..4b511fc8 100644 --- a/solidity/interfaces/modules/dispute/IBondEscalationModule.sol +++ b/solidity/interfaces/modules/dispute/IBondEscalationModule.sol @@ -1,275 +1,275 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IDisputeModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IDisputeModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; -import {IBondEscalationAccounting} from '../../extensions/IBondEscalationAccounting.sol'; +// import {IBondEscalationAccounting} from '../../extensions/IBondEscalationAccounting.sol'; -/** - * @title BondEscalationModule - * @notice Module allowing users to have the first dispute of a request go through the bond escalation mechanism. - */ -interface IBondEscalationModule is IDisputeModule { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ +// /** +// * @title BondEscalationModule +// * @notice Module allowing users to have the first dispute of a request go through the bond escalation mechanism. +// */ +// interface IBondEscalationModule is IDisputeModule { +// /*/////////////////////////////////////////////////////////////// +// EVENTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice A pledge has been made in favor of a dispute. - * - * @param _disputeId The id of the dispute the pledger is pledging in favor of. - * @param _pledger The address of the pledger. - * @param _amount The amount pledged. - */ - event PledgedForDispute(bytes32 indexed _disputeId, address indexed _pledger, uint256 indexed _amount); +// /** +// * @notice A pledge has been made in favor of a dispute. +// * +// * @param _disputeId The id of the dispute the pledger is pledging in favor of. +// * @param _pledger The address of the pledger. +// * @param _amount The amount pledged. +// */ +// event PledgedForDispute(bytes32 indexed _disputeId, address indexed _pledger, uint256 indexed _amount); - /** - * @notice A pledge has been made against a dispute. - * - * @param _disputeId The id of the dispute the pledger is pledging against. - * @param _pledger The address of the pledger. - * @param _amount The amount pledged. - */ - event PledgedAgainstDispute(bytes32 indexed _disputeId, address indexed _pledger, uint256 indexed _amount); +// /** +// * @notice A pledge has been made against a dispute. +// * +// * @param _disputeId The id of the dispute the pledger is pledging against. +// * @param _pledger The address of the pledger. +// * @param _amount The amount pledged. +// */ +// event PledgedAgainstDispute(bytes32 indexed _disputeId, address indexed _pledger, uint256 indexed _amount); - /** - * @notice The status of the bond escalation mechanism has been updated. - * - * @param _requestId The id of the request associated with the bond escalation mechanism. - * @param _disputeId The id of the dispute going through the bond escalation mechanism. - * @param _status The new status. - */ - event BondEscalationStatusUpdated( - bytes32 indexed _requestId, bytes32 indexed _disputeId, BondEscalationStatus _status - ); +// /** +// * @notice The status of the bond escalation mechanism has been updated. +// * +// * @param _requestId The id of the request associated with the bond escalation mechanism. +// * @param _disputeId The id of the dispute going through the bond escalation mechanism. +// * @param _status The new status. +// */ +// event BondEscalationStatusUpdated( +// bytes32 indexed _requestId, bytes32 indexed _disputeId, BondEscalationStatus _status +// ); - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Thrown when trying to escalate a dispute going through the bond escalation module before its deadline. - */ - error BondEscalationModule_BondEscalationNotOver(); - /** - * @notice Thrown when trying to pledge for a dispute that is not going through the bond escalation mechanism. - */ - error BondEscalationModule_InvalidDispute(); - /** - * @notice Thrown when the number of escalation pledges of a given dispute has reached its maximum. - */ - error BondEscalationModule_MaxNumberOfEscalationsReached(); - /** - * @notice Thrown when trying to settle a dispute that went through the bond escalation when it's not active. - */ - error BondEscalationModule_BondEscalationCantBeSettled(); - /** - * @notice Thrown when trying to settle a bond escalation process that is not tied. - */ - error BondEscalationModule_ShouldBeEscalated(); - /** - * @notice Thrown when trying to break a tie after the tying buffer has started. - */ - error BondEscalationModule_CannotBreakTieDuringTyingBuffer(); - /** - * @notice Thrown when the max number of escalations or the bond size is set to 0. - */ - error BondEscalationModule_ZeroValue(); - /** - * @notice Thrown when trying to pledge after the bond escalation deadline. - */ - error BondEscalationModule_BondEscalationOver(); - /** - * @notice Thrown when trying to escalate a dispute going through the bond escalation process that is not tied - * or that is not active. - */ - error BondEscalationModule_NotEscalatable(); - /** - * @notice Thrown when trying to pledge for a dispute that does not exist - */ - error BondEscalationModule_DisputeDoesNotExist(); - /** - * @notice Thrown when trying to surpass the number of pledges of the other side by more than 1 in the bond escalation mechanism. - */ - error BondEscalationModule_CanOnlySurpassByOnePledge(); - /** - * @notice Thrown when trying to dispute a response after the dispute period expired. - */ - error BondEscalationModule_DisputeWindowOver(); - /** - * @notice Thrown when trying to set up a request with invalid bond size or maximum amount of escalations. - */ - error BondEscalationModule_InvalidEscalationParameters(); +// /** +// * @notice Thrown when trying to escalate a dispute going through the bond escalation module before its deadline. +// */ +// error BondEscalationModule_BondEscalationNotOver(); +// /** +// * @notice Thrown when trying to pledge for a dispute that is not going through the bond escalation mechanism. +// */ +// error BondEscalationModule_InvalidDispute(); +// /** +// * @notice Thrown when the number of escalation pledges of a given dispute has reached its maximum. +// */ +// error BondEscalationModule_MaxNumberOfEscalationsReached(); +// /** +// * @notice Thrown when trying to settle a dispute that went through the bond escalation when it's not active. +// */ +// error BondEscalationModule_BondEscalationCantBeSettled(); +// /** +// * @notice Thrown when trying to settle a bond escalation process that is not tied. +// */ +// error BondEscalationModule_ShouldBeEscalated(); +// /** +// * @notice Thrown when trying to break a tie after the tying buffer has started. +// */ +// error BondEscalationModule_CannotBreakTieDuringTyingBuffer(); +// /** +// * @notice Thrown when the max number of escalations or the bond size is set to 0. +// */ +// error BondEscalationModule_ZeroValue(); +// /** +// * @notice Thrown when trying to pledge after the bond escalation deadline. +// */ +// error BondEscalationModule_BondEscalationOver(); +// /** +// * @notice Thrown when trying to escalate a dispute going through the bond escalation process that is not tied +// * or that is not active. +// */ +// error BondEscalationModule_NotEscalatable(); +// /** +// * @notice Thrown when trying to pledge for a dispute that does not exist +// */ +// error BondEscalationModule_DisputeDoesNotExist(); +// /** +// * @notice Thrown when trying to surpass the number of pledges of the other side by more than 1 in the bond escalation mechanism. +// */ +// error BondEscalationModule_CanOnlySurpassByOnePledge(); +// /** +// * @notice Thrown when trying to dispute a response after the dispute period expired. +// */ +// error BondEscalationModule_DisputeWindowOver(); +// /** +// * @notice Thrown when trying to set up a request with invalid bond size or maximum amount of escalations. +// */ +// error BondEscalationModule_InvalidEscalationParameters(); - /*/////////////////////////////////////////////////////////////// - ENUMS - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// ENUMS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Enum holding all the possible statuses of a dispute going through the bond escalation mechanism. - */ - enum BondEscalationStatus { - None, // Dispute is not going through the bond escalation mechanism. - Active, // Dispute is going through the bond escalation mechanism. - Escalated, // Dispute is going through the bond escalation mechanism and has been escalated. - DisputerLost, // An escalated dispute has been settled and the disputer lost. - DisputerWon // An escalated dispute has been settled and the disputer won. - } +// /** +// * @notice Enum holding all the possible statuses of a dispute going through the bond escalation mechanism. +// */ +// enum BondEscalationStatus { +// None, // Dispute is not going through the bond escalation mechanism. +// Active, // Dispute is going through the bond escalation mechanism. +// Escalated, // Dispute is going through the bond escalation mechanism and has been escalated. +// DisputerLost, // An escalated dispute has been settled and the disputer lost. +// DisputerWon // An escalated dispute has been settled and the disputer won. +// } - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * - * @param _accountingExtension Address of the accounting extension associated with the given request - * @param _bondToken Address of the token associated with the given request - * @param _bondSize Amount to bond to dispute or propose an answer for the given request - * @param _numberOfEscalations Maximum allowed escalations or pledges for each side during the bond escalation process - * @param _bondEscalationDeadline Timestamp at which bond escalation process finishes when pledges are not tied - * @param _tyingBuffer Number of seconds to extend the bond escalation process to allow the losing - * party to tie if at the end of the initial deadline the pledges weren't tied. - * @param _disputeWindow Number of seconds disputers have to challenge the proposed response since its creation. - */ - struct RequestParameters { - IBondEscalationAccounting accountingExtension; - IERC20 bondToken; - uint256 bondSize; - uint256 maxNumberOfEscalations; - uint256 bondEscalationDeadline; - uint256 tyingBuffer; - uint256 disputeWindow; - } +// /** +// * @notice Parameters of the request as stored in the module +// * +// * @param _accountingExtension Address of the accounting extension associated with the given request +// * @param _bondToken Address of the token associated with the given request +// * @param _bondSize Amount to bond to dispute or propose an answer for the given request +// * @param _numberOfEscalations Maximum allowed escalations or pledges for each side during the bond escalation process +// * @param _bondEscalationDeadline Timestamp at which bond escalation process finishes when pledges are not tied +// * @param _tyingBuffer Number of seconds to extend the bond escalation process to allow the losing +// * party to tie if at the end of the initial deadline the pledges weren't tied. +// * @param _disputeWindow Number of seconds disputers have to challenge the proposed response since its creation. +// */ +// struct RequestParameters { +// IBondEscalationAccounting accountingExtension; +// IERC20 bondToken; +// uint256 bondSize; +// uint256 maxNumberOfEscalations; +// uint256 bondEscalationDeadline; +// uint256 tyingBuffer; +// uint256 disputeWindow; +// } - /** - * @notice Data of a dispute going through the bond escalation. - * - * @param disputeId The id of the dispute being bond-escalated. - * @param status The status of the bond escalation. - * @param amountOfPledgesForDispute The amount of pledges made in favor of the dispute. - * @param amountOfPledgesAgainstDispute The amount of pledges made against the dispute. - */ - struct BondEscalation { - bytes32 disputeId; - BondEscalationStatus status; - uint256 amountOfPledgesForDispute; - uint256 amountOfPledgesAgainstDispute; - } +// /** +// * @notice Data of a dispute going through the bond escalation. +// * +// * @param disputeId The id of the dispute being bond-escalated. +// * @param status The status of the bond escalation. +// * @param amountOfPledgesForDispute The amount of pledges made in favor of the dispute. +// * @param amountOfPledgesAgainstDispute The amount of pledges made against the dispute. +// */ +// struct BondEscalation { +// bytes32 disputeId; +// BondEscalationStatus status; +// uint256 amountOfPledgesForDispute; +// uint256 amountOfPledgesAgainstDispute; +// } - /*/////////////////////////////////////////////////////////////// - VARIABLES - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// VARIABLES +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the escalation data for a request. - * @param _requestId The id of the request to get its escalation data. - * @return _escalation The struct containing the escalation data. - */ - function getEscalation(bytes32 _requestId) external view returns (BondEscalation memory _escalation); +// /** +// * @notice Returns the escalation data for a request. +// * @param _requestId The id of the request to get its escalation data. +// * @return _escalation The struct containing the escalation data. +// */ +// function getEscalation(bytes32 _requestId) external view returns (BondEscalation memory _escalation); - /** - * @notice Decodes the request data associated with a request id. - * @param _requestId The id of the request to decode. - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); +// /** +// * @notice Decodes the request data associated with a request id. +// * @param _requestId The id of the request to decode. +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - /** - * @notice Returns the amount of pledges that a particular pledger has made for a given dispute. - * @param _requestId The id of the request to get the pledges for. - * @param _pledger The address of the pledger to get the pledges for. - * @return _numPledges The number of pledges made by the pledger for the dispute. - */ - function pledgesForDispute(bytes32 _requestId, address _pledger) external view returns (uint256 _numPledges); +// /** +// * @notice Returns the amount of pledges that a particular pledger has made for a given dispute. +// * @param _requestId The id of the request to get the pledges for. +// * @param _pledger The address of the pledger to get the pledges for. +// * @return _numPledges The number of pledges made by the pledger for the dispute. +// */ +// function pledgesForDispute(bytes32 _requestId, address _pledger) external view returns (uint256 _numPledges); - /** - * @notice Returns the amount of pledges that a particular pledger has made against a given dispute. - * @param _requestId The id of the request to get the pledges for. - * @param _pledger The address of the pledger to get the pledges for. - * @return _numPledges The number of pledges made by the pledger against the dispute. - */ - function pledgesAgainstDispute(bytes32 _requestId, address _pledger) external view returns (uint256 _numPledges); +// /** +// * @notice Returns the amount of pledges that a particular pledger has made against a given dispute. +// * @param _requestId The id of the request to get the pledges for. +// * @param _pledger The address of the pledger to get the pledges for. +// * @return _numPledges The number of pledges made by the pledger against the dispute. +// */ +// function pledgesAgainstDispute(bytes32 _requestId, address _pledger) external view returns (uint256 _numPledges); - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Disputes a response - * - * @dev If this is the first dispute of the request and the bond escalation window is not over, - * it will start the bond escalation process. This function must be called through the Oracle. - * - * @param _requestId The ID of the request containing the response to dispute. - * @param _responseId The ID of the request to dispute. - * @param _disputer The address of the disputer. - * @param _proposer The address of the proposer of the response. - * - * @return _dispute The data of the created dispute. - */ - function disputeResponse( - bytes32 _requestId, - bytes32 _responseId, - address _disputer, - address _proposer - ) external override returns (IOracle.Dispute memory _dispute); +// /** +// * @notice Disputes a response +// * +// * @dev If this is the first dispute of the request and the bond escalation window is not over, +// * it will start the bond escalation process. This function must be called through the Oracle. +// * +// * @param _requestId The ID of the request containing the response to dispute. +// * @param _responseId The ID of the request to dispute. +// * @param _disputer The address of the disputer. +// * @param _proposer The address of the proposer of the response. +// * +// * @return _dispute The data of the created dispute. +// */ +// function disputeResponse( +// bytes32 _requestId, +// bytes32 _responseId, +// address _disputer, +// address _proposer +// ) external override returns (IOracle.Dispute memory _dispute); - /** - * @notice Updates the status of a given disputeId and pays the proposer and disputer accordingly. If this - * dispute has gone through the bond escalation mechanism, then it will pay the winning pledgers as well. - * - * @param _disputeId The ID of the dispute to update the status for. - * @param _dispute The full dispute object. - * - */ - function onDisputeStatusChange(bytes32 _disputeId, IOracle.Dispute memory _dispute) external override; +// /** +// * @notice Updates the status of a given disputeId and pays the proposer and disputer accordingly. If this +// * dispute has gone through the bond escalation mechanism, then it will pay the winning pledgers as well. +// * +// * @param _disputeId The ID of the dispute to update the status for. +// * @param _dispute The full dispute object. +// * +// */ +// function onDisputeStatusChange(bytes32 _disputeId, IOracle.Dispute memory _dispute) external override; - /** - * @notice Verifies whether the dispute going through the bond escalation mechanism has reached a tie and - * updates its escalation status accordingly. - * - * @param _disputeId The ID of the dispute to escalate. - */ - function disputeEscalated(bytes32 _disputeId) external; +// /** +// * @notice Verifies whether the dispute going through the bond escalation mechanism has reached a tie and +// * updates its escalation status accordingly. +// * +// * @param _disputeId The ID of the dispute to escalate. +// */ +// function disputeEscalated(bytes32 _disputeId) external; - /** - * @notice Bonds funds in favor of a given dispute during the bond escalation process. - * - * @dev This function must be called directly through this contract. - * @dev If the bond escalation is not tied at the end of its deadline, a tying buffer is added - * to avoid scenarios where one of the parties breaks the tie very last second. - * During the tying buffer, the losing party can only tie, and once the escalation is tied - * no further funds can be pledged. - * - * @param _disputeId The ID of the dispute to pledge for. - */ - function pledgeForDispute(bytes32 _disputeId) external; +// /** +// * @notice Bonds funds in favor of a given dispute during the bond escalation process. +// * +// * @dev This function must be called directly through this contract. +// * @dev If the bond escalation is not tied at the end of its deadline, a tying buffer is added +// * to avoid scenarios where one of the parties breaks the tie very last second. +// * During the tying buffer, the losing party can only tie, and once the escalation is tied +// * no further funds can be pledged. +// * +// * @param _disputeId The ID of the dispute to pledge for. +// */ +// function pledgeForDispute(bytes32 _disputeId) external; - /** - * @notice Pledges funds against a given disputeId during its bond escalation process. - * - * @dev Must be called directly through this contract. Will revert if the disputeId is not going through - * the bond escalation process. - * @dev If the bond escalation is not tied at the end of its deadline, a tying buffer is added - * to avoid scenarios where one of the parties breaks the tie very last second. - * During the tying buffer, the losing party can only tie, and once the escalation is tied - * no further funds can be pledged. - * - * @param _disputeId ID of the dispute id to pledge against. - */ - function pledgeAgainstDispute(bytes32 _disputeId) external; +// /** +// * @notice Pledges funds against a given disputeId during its bond escalation process. +// * +// * @dev Must be called directly through this contract. Will revert if the disputeId is not going through +// * the bond escalation process. +// * @dev If the bond escalation is not tied at the end of its deadline, a tying buffer is added +// * to avoid scenarios where one of the parties breaks the tie very last second. +// * During the tying buffer, the losing party can only tie, and once the escalation is tied +// * no further funds can be pledged. +// * +// * @param _disputeId ID of the dispute id to pledge against. +// */ +// function pledgeAgainstDispute(bytes32 _disputeId) external; - /** - * @notice Settles the bond escalation process of a given requestId. - * - * @dev Must be called directly through this contract. - * @dev Can only be called if after the deadline + tyingBuffer window is over, the pledges weren't tied - * - * @param _requestId requestId of the request to settle the bond escalation process for. - */ - function settleBondEscalation(bytes32 _requestId) external; -} +// /** +// * @notice Settles the bond escalation process of a given requestId. +// * +// * @dev Must be called directly through this contract. +// * @dev Can only be called if after the deadline + tyingBuffer window is over, the pledges weren't tied +// * +// * @param _requestId requestId of the request to settle the bond escalation process for. +// */ +// function settleBondEscalation(bytes32 _requestId) external; +// } diff --git a/solidity/interfaces/modules/dispute/IBondedDisputeModule.sol b/solidity/interfaces/modules/dispute/IBondedDisputeModule.sol index dffa12e8..164e0a29 100644 --- a/solidity/interfaces/modules/dispute/IBondedDisputeModule.sol +++ b/solidity/interfaces/modules/dispute/IBondedDisputeModule.sol @@ -1,75 +1,75 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IDisputeModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IDisputeModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; -import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; +// import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; -/* - * @title BondedDisputeModule - * @notice Module allowing users to dispute a proposed response - * by bonding tokens. According to the result of the dispute, - * the tokens are either returned to the disputer or to the proposer. - */ -interface IBondedDisputeModule is IDisputeModule { - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ +// /* +// * @title BondedDisputeModule +// * @notice Module allowing users to dispute a proposed response +// * by bonding tokens. According to the result of the dispute, +// * the tokens are either returned to the disputer or to the proposer. +// */ +// interface IBondedDisputeModule is IDisputeModule { +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * @param ipfsHash The hash of the CID from IPFS - * @param requestModule The address of the request module - * @param responseModule The address of the response module - */ - struct RequestParameters { - IAccountingExtension accountingExtension; - IERC20 bondToken; - uint256 bondSize; - } +// /** +// * @notice Parameters of the request as stored in the module +// * @param ipfsHash The hash of the CID from IPFS +// * @param requestModule The address of the request module +// * @param responseModule The address of the response module +// */ +// struct RequestParameters { +// IAccountingExtension accountingExtension; +// IERC20 bondToken; +// uint256 bondSize; +// } - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - /** - * @notice Called by the oracle when a dispute has been made on a response. - * Bonds the tokens of the disputer. - * @param _requestId The ID of the request whose response is disputed - * @param _responseId The ID of the response being disputed - * @param _disputer The address of the user who disputed the response - * @param _proposer The address of the user who proposed the disputed response - * @return _dispute The dispute on the proposed response - */ - function disputeResponse( - bytes32 _requestId, - bytes32 _responseId, - address _disputer, - address _proposer - ) external returns (IOracle.Dispute memory _dispute); +// /** +// * @notice Called by the oracle when a dispute has been made on a response. +// * Bonds the tokens of the disputer. +// * @param _requestId The ID of the request whose response is disputed +// * @param _responseId The ID of the response being disputed +// * @param _disputer The address of the user who disputed the response +// * @param _proposer The address of the user who proposed the disputed response +// * @return _dispute The dispute on the proposed response +// */ +// function disputeResponse( +// bytes32 _requestId, +// bytes32 _responseId, +// address _disputer, +// address _proposer +// ) external returns (IOracle.Dispute memory _dispute); - /** - * @notice Called by the oracle when a dispute status has been updated. - * According to the result of the dispute, bonds are released to the proposer or - * paid to the disputer. - * @param _disputeId The ID of the dispute being updated - * @param _dispute The dispute object - */ - function onDisputeStatusChange(bytes32 _disputeId, IOracle.Dispute memory _dispute) external; +// /** +// * @notice Called by the oracle when a dispute status has been updated. +// * According to the result of the dispute, bonds are released to the proposer or +// * paid to the disputer. +// * @param _disputeId The ID of the dispute being updated +// * @param _dispute The dispute object +// */ +// function onDisputeStatusChange(bytes32 _disputeId, IOracle.Dispute memory _dispute) external; - /** - * @notice Called by the oracle when a dispute has been escalated. Not implemented in this module - * @param _disputeId The ID of the dispute being escalated - */ - function disputeEscalated(bytes32 _disputeId) external; -} +// /** +// * @notice Called by the oracle when a dispute has been escalated. Not implemented in this module +// * @param _disputeId The ID of the dispute being escalated +// */ +// function disputeEscalated(bytes32 _disputeId) external; +// } diff --git a/solidity/interfaces/modules/dispute/ICircuitResolverModule.sol b/solidity/interfaces/modules/dispute/ICircuitResolverModule.sol index 567fde91..fc224ce0 100644 --- a/solidity/interfaces/modules/dispute/ICircuitResolverModule.sol +++ b/solidity/interfaces/modules/dispute/ICircuitResolverModule.sol @@ -1,68 +1,68 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IDisputeModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IDisputeModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; -import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; +// import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; -/** - * @title CircuitResolverModule - * @notice Module allowing users to dispute a proposed response - * by bonding tokens. - * The module will invoke the circuit verifier supplied to calculate - * the proposed response and compare it to the correct response. - * - If the dispute is valid, the disputer wins and their bond is returned along with a reward. - * - If the dispute is invalid, the bond is forfeited and returned to the proposer. - * - * After the dispute is settled, the correct response is automatically proposed to the oracle - * and the request is finalized. - */ -interface ICircuitResolverModule is IDisputeModule { - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ +// /** +// * @title CircuitResolverModule +// * @notice Module allowing users to dispute a proposed response +// * by bonding tokens. +// * The module will invoke the circuit verifier supplied to calculate +// * the proposed response and compare it to the correct response. +// * - If the dispute is valid, the disputer wins and their bond is returned along with a reward. +// * - If the dispute is invalid, the bond is forfeited and returned to the proposer. +// * +// * After the dispute is settled, the correct response is automatically proposed to the oracle +// * and the request is finalized. +// */ +// interface ICircuitResolverModule is IDisputeModule { +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * @return callData The encoded data forwarded to the verifier - * @return verifier The address of the verifier contract - * @return accountingExtension The address of the accounting extension - * @return bondToken The address of the bond token - * @return bondSize The size of the bond - */ - struct RequestParameters { - bytes callData; - address verifier; - IAccountingExtension accountingExtension; - IERC20 bondToken; - uint256 bondSize; - } +// /** +// * @notice Parameters of the request as stored in the module +// * @return callData The encoded data forwarded to the verifier +// * @return verifier The address of the verifier contract +// * @return accountingExtension The address of the accounting extension +// * @return bondToken The address of the bond token +// * @return bondSize The size of the bond +// */ +// struct RequestParameters { +// bytes callData; +// address verifier; +// IAccountingExtension accountingExtension; +// IERC20 bondToken; +// uint256 bondSize; +// } - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The decoded parameters of the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The decoded parameters of the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - /// @inheritdoc IDisputeModule - function disputeResponse( - bytes32 _requestId, - bytes32 _responseId, - address _disputer, - address _proposer - ) external returns (IOracle.Dispute memory _dispute); +// /// @inheritdoc IDisputeModule +// function disputeResponse( +// bytes32 _requestId, +// bytes32 _responseId, +// address _disputer, +// address _proposer +// ) external returns (IOracle.Dispute memory _dispute); - /// @inheritdoc IDisputeModule - function onDisputeStatusChange(bytes32 _disputeId, IOracle.Dispute memory _dispute) external; +// /// @inheritdoc IDisputeModule +// function onDisputeStatusChange(bytes32 _disputeId, IOracle.Dispute memory _dispute) external; - /// @inheritdoc IDisputeModule - function disputeEscalated(bytes32 _disputeId) external; -} +// /// @inheritdoc IDisputeModule +// function disputeEscalated(bytes32 _disputeId) external; +// } diff --git a/solidity/interfaces/modules/dispute/IRootVerificationModule.sol b/solidity/interfaces/modules/dispute/IRootVerificationModule.sol index d18b2b79..682468eb 100644 --- a/solidity/interfaces/modules/dispute/IRootVerificationModule.sol +++ b/solidity/interfaces/modules/dispute/IRootVerificationModule.sol @@ -1,84 +1,84 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IDisputeModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IDisputeModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; -import {ITreeVerifier} from '../../ITreeVerifier.sol'; -import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; +// import {ITreeVerifier} from '../../ITreeVerifier.sol'; +// import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; -/* - * @title RootVerificationModule - * @notice Dispute module allowing disputers to calculate the correct root - * for a given request and propose it as a response. If the disputer wins the - * dispute, he is rewarded with the bond of the proposer. - * @dev This module is a pre-dispute module. It allows disputing - * and resolving a response in a single call. - */ -interface IRootVerificationModule is IDisputeModule { - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ +// /* +// * @title RootVerificationModule +// * @notice Dispute module allowing disputers to calculate the correct root +// * for a given request and propose it as a response. If the disputer wins the +// * dispute, he is rewarded with the bond of the proposer. +// * @dev This module is a pre-dispute module. It allows disputing +// * and resolving a response in a single call. +// */ +// interface IRootVerificationModule is IDisputeModule { +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * @param treeData The data of the tree - * @param leavesToInsert The leaves to insert in the tree - * @param treeVerifier The tree verifier to use to calculate the correct root - * @param accountingExtension The accounting extension to use for bonds and payments - * @param bondToken The token to use for bonds and payments - * @param bondSize The size of the bond to participate in the request - */ - struct RequestParameters { - bytes treeData; - bytes32[] leavesToInsert; - ITreeVerifier treeVerifier; - IAccountingExtension accountingExtension; - IERC20 bondToken; - uint256 bondSize; - } - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ +// /** +// * @notice Parameters of the request as stored in the module +// * @param treeData The data of the tree +// * @param leavesToInsert The leaves to insert in the tree +// * @param treeVerifier The tree verifier to use to calculate the correct root +// * @param accountingExtension The accounting extension to use for bonds and payments +// * @param bondToken The token to use for bonds and payments +// * @param bondSize The size of the bond to participate in the request +// */ +// struct RequestParameters { +// bytes treeData; +// bytes32[] leavesToInsert; +// ITreeVerifier treeVerifier; +// IAccountingExtension accountingExtension; +// IERC20 bondToken; +// uint256 bondSize; +// } +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - /** - * @notice Calculates the correct root and compares it to the proposed one. - * @dev Since this is a pre-dispute module, the dispute status is updated after checking - * if the disputed response is indeed wrong, since it is calculated on dispute. - * @param _requestId The id of the request from which the response is being disputed - * @param _responseId The id of the response being disputed - * @param _disputer The user who is disputing the response - * @param _proposer The proposer of the response being disputed - * @return _dispute The dispute of the current response with the updated status - */ - function disputeResponse( - bytes32 _requestId, - bytes32 _responseId, - address _disputer, - address _proposer - ) external returns (IOracle.Dispute memory _dispute); +// /** +// * @notice Calculates the correct root and compares it to the proposed one. +// * @dev Since this is a pre-dispute module, the dispute status is updated after checking +// * if the disputed response is indeed wrong, since it is calculated on dispute. +// * @param _requestId The id of the request from which the response is being disputed +// * @param _responseId The id of the response being disputed +// * @param _disputer The user who is disputing the response +// * @param _proposer The proposer of the response being disputed +// * @return _dispute The dispute of the current response with the updated status +// */ +// function disputeResponse( +// bytes32 _requestId, +// bytes32 _responseId, +// address _disputer, +// address _proposer +// ) external returns (IOracle.Dispute memory _dispute); - /** - * @notice Updates the status of the dispute and resolves it by proposing the correct root - * as a response and finalizing the request. - * @dev The correct root is retrieved from storage and compared to the proposed root. - * If the dispute is won, the disputer is paid. In both cases, the request is finalized. - * @param _dispute The dispute of the current response - */ - function onDisputeStatusChange(bytes32, IOracle.Dispute memory _dispute) external; +// /** +// * @notice Updates the status of the dispute and resolves it by proposing the correct root +// * as a response and finalizing the request. +// * @dev The correct root is retrieved from storage and compared to the proposed root. +// * If the dispute is won, the disputer is paid. In both cases, the request is finalized. +// * @param _dispute The dispute of the current response +// */ +// function onDisputeStatusChange(bytes32, IOracle.Dispute memory _dispute) external; - /** - * @dev This function is present to comply with the module interface but it - * is not implemented since this is a pre-dispute module. - */ - function disputeEscalated(bytes32 _disputeId) external; -} +// /** +// * @dev This function is present to comply with the module interface but it +// * is not implemented since this is a pre-dispute module. +// */ +// function disputeEscalated(bytes32 _disputeId) external; +// } diff --git a/solidity/interfaces/modules/finality/ICallbackModule.sol b/solidity/interfaces/modules/finality/ICallbackModule.sol index 1d0660f0..99b298ac 100644 --- a/solidity/interfaces/modules/finality/ICallbackModule.sol +++ b/solidity/interfaces/modules/finality/ICallbackModule.sol @@ -1,65 +1,65 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IFinalityModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/finality/IFinalityModule.sol'; +// import {IFinalityModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/finality/IFinalityModule.sol'; -/** - * @title CallbackModule - * @notice Module allowing users to call a function on a contract - * as a result of a request being finalized. - */ -interface ICallbackModule is IFinalityModule { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ +// /** +// * @title CallbackModule +// * @notice Module allowing users to call a function on a contract +// * as a result of a request being finalized. +// */ +// interface ICallbackModule is IFinalityModule { +// /*/////////////////////////////////////////////////////////////// +// EVENTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice A callback has been executed - * @param _requestId The id of the request being finalized - * @param _target The target address for the callback - * @param _data The calldata forwarded to the _target - */ - event Callback(bytes32 indexed _requestId, address indexed _target, bytes _data); +// /** +// * @notice A callback has been executed +// * @param _requestId The id of the request being finalized +// * @param _target The target address for the callback +// * @param _data The calldata forwarded to the _target +// */ +// event Callback(bytes32 indexed _requestId, address indexed _target, bytes _data); - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Thrown when the target address has no code (i.e. is not a contract) - */ - error CallbackModule_TargetHasNoCode(); +// /** +// * @notice Thrown when the target address has no code (i.e. is not a contract) +// */ +// error CallbackModule_TargetHasNoCode(); - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * @param target The target address for the callback - * @param data The calldata forwarded to the _target - */ - struct RequestParameters { - address target; - bytes data; - } +// /** +// * @notice Parameters of the request as stored in the module +// * @param target The target address for the callback +// * @param data The calldata forwarded to the _target +// */ +// struct RequestParameters { +// address target; +// bytes data; +// } - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - /** - * @notice Finalizes the request by executing the callback call on the target - * @dev The success of the callback call is purposely not checked - * @param _requestId The id of the request - */ - function finalizeRequest(bytes32 _requestId, address) external; -} +// /** +// * @notice Finalizes the request by executing the callback call on the target +// * @dev The success of the callback call is purposely not checked +// * @param _requestId The id of the request +// */ +// function finalizeRequest(bytes32 _requestId, address) external; +// } diff --git a/solidity/interfaces/modules/finality/IMultipleCallbacksModule.sol b/solidity/interfaces/modules/finality/IMultipleCallbacksModule.sol index a2267ff5..f6de01cc 100644 --- a/solidity/interfaces/modules/finality/IMultipleCallbacksModule.sol +++ b/solidity/interfaces/modules/finality/IMultipleCallbacksModule.sol @@ -1,69 +1,69 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IFinalityModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/finality/IFinalityModule.sol'; +// import {IFinalityModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/finality/IFinalityModule.sol'; -/** - * @title MultipleCallbackModule - * @notice Module allowing users to make multiple calls to different contracts - * as a result of a request being finalized. - */ -interface IMultipleCallbacksModule is IFinalityModule { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ +// /** +// * @title MultipleCallbackModule +// * @notice Module allowing users to make multiple calls to different contracts +// * as a result of a request being finalized. +// */ +// interface IMultipleCallbacksModule is IFinalityModule { +// /*/////////////////////////////////////////////////////////////// +// EVENTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice A callback has been executed - * @param _requestId The id of the request being finalized - * @param _target The target address for the callback - * @param _data The calldata forwarded to the _target - */ - event Callback(bytes32 indexed _requestId, address indexed _target, bytes _data); +// /** +// * @notice A callback has been executed +// * @param _requestId The id of the request being finalized +// * @param _target The target address for the callback +// * @param _data The calldata forwarded to the _target +// */ +// event Callback(bytes32 indexed _requestId, address indexed _target, bytes _data); - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Thrown when then target address has no code (i.e. is not a contract) - */ - error MultipleCallbackModule_TargetHasNoCode(); +// /** +// * @notice Thrown when then target address has no code (i.e. is not a contract) +// */ +// error MultipleCallbackModule_TargetHasNoCode(); - /** - * @notice Thrown when the targets array and the data array have different lengths - */ - error MultipleCallbackModule_InvalidParameters(); +// /** +// * @notice Thrown when the targets array and the data array have different lengths +// */ +// error MultipleCallbackModule_InvalidParameters(); - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * @param targets The target addresses for the callback - * @param data The calldata forwarded to the targets - */ - struct RequestParameters { - address[] targets; - bytes[] data; - } - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ +// /** +// * @notice Parameters of the request as stored in the module +// * @param targets The target addresses for the callback +// * @param data The calldata forwarded to the targets +// */ +// struct RequestParameters { +// address[] targets; +// bytes[] data; +// } +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the decoded data for a request - * @param _requestId The id of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The id of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - /** - * @notice Finalizes the request by executing the callback calls on the targets - * @dev The success of the callback calls is purposely not checked - * @param _requestId The id of the request - */ - function finalizeRequest(bytes32 _requestId, address) external; -} +// /** +// * @notice Finalizes the request by executing the callback calls on the targets +// * @dev The success of the callback calls is purposely not checked +// * @param _requestId The id of the request +// */ +// function finalizeRequest(bytes32 _requestId, address) external; +// } diff --git a/solidity/interfaces/modules/request/IContractCallRequestModule.sol b/solidity/interfaces/modules/request/IContractCallRequestModule.sol index bd361bdf..1d533d6b 100644 --- a/solidity/interfaces/modules/request/IContractCallRequestModule.sol +++ b/solidity/interfaces/modules/request/IContractCallRequestModule.sol @@ -1,45 +1,45 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IRequestModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/request/IRequestModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IRequestModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/request/IRequestModule.sol'; -import {IAccountingExtension} from '../../../interfaces/extensions/IAccountingExtension.sol'; +// import {IAccountingExtension} from '../../../interfaces/extensions/IAccountingExtension.sol'; -/** - * @title ContractCallRequestModule - * @notice Request module for making contract calls - */ -interface IContractCallRequestModule is IRequestModule { - /** - * @notice Parameters of the request as stored in the module - * @param target The address of the contract to do the call on - * @param functionSelector The selector of the function to call - * @param data The encoded arguments of the function to call (optional) - * @param accountingExtension The accounting extension to bond and release funds - * @param paymentToken The token in which the response proposer will be paid - * @param paymentAmount The amount of `paymentToken` to pay to the response proposer - */ - struct RequestParameters { - address target; - bytes4 functionSelector; - bytes data; - IAccountingExtension accountingExtension; - IERC20 paymentToken; - uint256 paymentAmount; - } +// /** +// * @title ContractCallRequestModule +// * @notice Request module for making contract calls +// */ +// interface IContractCallRequestModule is IRequestModule { +// /** +// * @notice Parameters of the request as stored in the module +// * @param target The address of the contract to do the call on +// * @param functionSelector The selector of the function to call +// * @param data The encoded arguments of the function to call (optional) +// * @param accountingExtension The accounting extension to bond and release funds +// * @param paymentToken The token in which the response proposer will be paid +// * @param paymentAmount The amount of `paymentToken` to pay to the response proposer +// */ +// struct RequestParameters { +// address target; +// bytes4 functionSelector; +// bytes data; +// IAccountingExtension accountingExtension; +// IERC20 paymentToken; +// uint256 paymentAmount; +// } - /** - * @notice Returns the decoded data for a request - * @param _requestId The id of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The id of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - /** - * @notice Finalizes a request by paying the response proposer - * @param _requestId The id of the request - */ - function finalizeRequest(bytes32 _requestId, address) external; -} +// /** +// * @notice Finalizes a request by paying the response proposer +// * @param _requestId The id of the request +// */ +// function finalizeRequest(bytes32 _requestId, address) external; +// } diff --git a/solidity/interfaces/modules/request/IHttpRequestModule.sol b/solidity/interfaces/modules/request/IHttpRequestModule.sol index b1aeb897..5c28a4c4 100644 --- a/solidity/interfaces/modules/request/IHttpRequestModule.sol +++ b/solidity/interfaces/modules/request/IHttpRequestModule.sol @@ -1,65 +1,65 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IRequestModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/request/IRequestModule.sol'; -import {IAccountingExtension} from '../../../interfaces/extensions/IAccountingExtension.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IRequestModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/request/IRequestModule.sol'; +// import {IAccountingExtension} from '../../../interfaces/extensions/IAccountingExtension.sol'; -/* - * @title HttpRequestModule - * @notice Module allowing users to request HTTP calls - */ -interface IHttpRequestModule is IRequestModule { - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ +// /* +// * @title HttpRequestModule +// * @notice Module allowing users to request HTTP calls +// */ +// interface IHttpRequestModule is IRequestModule { +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * @param url The url to make the request to - * @param method The HTTP method to use for the request - * @param body The HTTP body to use for the request - * @param accountingExtension The accounting extension used to bond and release tokens - * @param paymentToken The token used to pay for the request - * @param paymentAmount The amount of tokens to pay for the request - */ - struct RequestParameters { - string url; - string body; - HttpMethod method; - IAccountingExtension accountingExtension; - IERC20 paymentToken; - uint256 paymentAmount; - } +// /** +// * @notice Parameters of the request as stored in the module +// * @param url The url to make the request to +// * @param method The HTTP method to use for the request +// * @param body The HTTP body to use for the request +// * @param accountingExtension The accounting extension used to bond and release tokens +// * @param paymentToken The token used to pay for the request +// * @param paymentAmount The amount of tokens to pay for the request +// */ +// struct RequestParameters { +// string url; +// string body; +// HttpMethod method; +// IAccountingExtension accountingExtension; +// IERC20 paymentToken; +// uint256 paymentAmount; +// } - /*/////////////////////////////////////////////////////////////// - ENUMS - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// ENUMS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Available HTTP methods - */ - enum HttpMethod { - GET, - POST - } +// /** +// * @notice Available HTTP methods +// */ +// enum HttpMethod { +// GET, +// POST +// } - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - /** - * @notice Finalizes a request by paying the proposer if there is a valid response - * or releases the requester bond if no valid response was provided - * @param _requestId The ID of the request - */ - function finalizeRequest(bytes32 _requestId, address) external; -} +// /** +// * @notice Finalizes a request by paying the proposer if there is a valid response +// * or releases the requester bond if no valid response was provided +// * @param _requestId The ID of the request +// */ +// function finalizeRequest(bytes32 _requestId, address) external; +// } diff --git a/solidity/interfaces/modules/request/ISparseMerkleTreeRequestModule.sol b/solidity/interfaces/modules/request/ISparseMerkleTreeRequestModule.sol index 231b05cc..67590e91 100644 --- a/solidity/interfaces/modules/request/ISparseMerkleTreeRequestModule.sol +++ b/solidity/interfaces/modules/request/ISparseMerkleTreeRequestModule.sol @@ -1,57 +1,57 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IRequestModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/request/IRequestModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IRequestModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/request/IRequestModule.sol'; -import {ITreeVerifier} from '../../../interfaces/ITreeVerifier.sol'; -import {IAccountingExtension} from '../../../interfaces/extensions/IAccountingExtension.sol'; +// import {ITreeVerifier} from '../../../interfaces/ITreeVerifier.sol'; +// import {IAccountingExtension} from '../../../interfaces/extensions/IAccountingExtension.sol'; -/* - * @title SparseMerkleTreeRequestModule - * @notice Module allowing a user to request the calculation - * of a Merkle tree root from a set of leaves. - */ -interface ISparseMerkleTreeRequestModule is IRequestModule { - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ +// /* +// * @title SparseMerkleTreeRequestModule +// * @notice Module allowing a user to request the calculation +// * of a Merkle tree root from a set of leaves. +// */ +// interface ISparseMerkleTreeRequestModule is IRequestModule { +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * @param treeData The encoded Merkle tree data parameters for the tree verifier - * @param leavesToInsert The array of leaves to insert into the Merkle tree - * @param treeVerifier The tree verifier to calculate the root - * @param accountingExtension The accounting extension to use for the request - * @param paymentToken The payment token to use for the request - * @param paymentAmount The payment amount to use for the request - */ - struct RequestParameters { - bytes treeData; - bytes32[] leavesToInsert; - ITreeVerifier treeVerifier; - IAccountingExtension accountingExtension; - IERC20 paymentToken; - uint256 paymentAmount; - } +// /** +// * @notice Parameters of the request as stored in the module +// * @param treeData The encoded Merkle tree data parameters for the tree verifier +// * @param leavesToInsert The array of leaves to insert into the Merkle tree +// * @param treeVerifier The tree verifier to calculate the root +// * @param accountingExtension The accounting extension to use for the request +// * @param paymentToken The payment token to use for the request +// * @param paymentAmount The payment amount to use for the request +// */ +// struct RequestParameters { +// bytes treeData; +// bytes32[] leavesToInsert; +// ITreeVerifier treeVerifier; +// IAccountingExtension accountingExtension; +// IERC20 paymentToken; +// uint256 paymentAmount; +// } - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - /** - * @notice Called by the Oracle to finalize the request by paying the proposer for the response - * or releasing the requester's bond if no response was submitted - * @param _requestId The ID of the request being finalized - * @param _finalizer The address of the user who triggered the finalization of the request - */ - function finalizeRequest(bytes32 _requestId, address _finalizer) external; -} +// /** +// * @notice Called by the Oracle to finalize the request by paying the proposer for the response +// * or releasing the requester's bond if no response was submitted +// * @param _requestId The ID of the request being finalized +// * @param _finalizer The address of the user who triggered the finalization of the request +// */ +// function finalizeRequest(bytes32 _requestId, address _finalizer) external; +// } diff --git a/solidity/interfaces/modules/resolution/IArbitratorModule.sol b/solidity/interfaces/modules/resolution/IArbitratorModule.sol index 462c1ce6..b5bf211b 100644 --- a/solidity/interfaces/modules/resolution/IArbitratorModule.sol +++ b/solidity/interfaces/modules/resolution/IArbitratorModule.sol @@ -1,84 +1,84 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IResolutionModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; +// import {IResolutionModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; -/* - * @title ArbitratorModule - * @notice Module allowing an external arbitrator contract - * to resolve a dispute. - */ -interface IArbitratorModule is IResolutionModule { - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ +// /* +// * @title ArbitratorModule +// * @notice Module allowing an external arbitrator contract +// * to resolve a dispute. +// */ +// interface IArbitratorModule is IResolutionModule { +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Thrown when an unauthorized caller calls a function only the arbitrator can call - */ - error ArbitratorModule_OnlyArbitrator(); +// /** +// * @notice Thrown when an unauthorized caller calls a function only the arbitrator can call +// */ +// error ArbitratorModule_OnlyArbitrator(); - /** - * @notice Thrown when trying to resolve a dispute that is not escalated - */ - error ArbitratorModule_InvalidDisputeId(); +// /** +// * @notice Thrown when trying to resolve a dispute that is not escalated +// */ +// error ArbitratorModule_InvalidDisputeId(); - /** - * @notice Thrown when the arbitrator address is the address zero - */ - error ArbitratorModule_InvalidArbitrator(); +// /** +// * @notice Thrown when the arbitrator address is the address zero +// */ +// error ArbitratorModule_InvalidArbitrator(); - /** - * @notice Thrown when the arbitrator returns an invalid resolution status - */ - error ArbitratorModule_InvalidResolutionStatus(); +// /** +// * @notice Thrown when the arbitrator returns an invalid resolution status +// */ +// error ArbitratorModule_InvalidResolutionStatus(); - /*/////////////////////////////////////////////////////////////// - ENUMS - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// ENUMS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Available status of the arbitration process - */ - enum ArbitrationStatus { - Unknown, // The arbitration process has not started (default) - Active, // The arbitration process is active - Resolved // The arbitration process is resolved - } +// /** +// * @notice Available status of the arbitration process +// */ +// enum ArbitrationStatus { +// Unknown, // The arbitration process has not started (default) +// Active, // The arbitration process is active +// Resolved // The arbitration process is resolved +// } - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the current arbitration status of a dispute - * @param _disputeId The ID of the dispute - * @return _disputeStatus The `ArbitrationStatus` of the dispute - */ - function getStatus(bytes32 _disputeId) external view returns (ArbitrationStatus _disputeStatus); +// /** +// * @notice Returns the current arbitration status of a dispute +// * @param _disputeId The ID of the dispute +// * @return _disputeStatus The `ArbitrationStatus` of the dispute +// */ +// function getStatus(bytes32 _disputeId) external view returns (ArbitrationStatus _disputeStatus); - /** - * @notice Starts the arbitration process by calling `resolve` on the - * arbitrator and flags the dispute as Active - * @dev Only callable by the Oracle - * @dev Will revert if the arbitrator address is the address zero - * @param _disputeId The ID of the dispute - */ - function startResolution(bytes32 _disputeId) external; +// /** +// * @notice Starts the arbitration process by calling `resolve` on the +// * arbitrator and flags the dispute as Active +// * @dev Only callable by the Oracle +// * @dev Will revert if the arbitrator address is the address zero +// * @param _disputeId The ID of the dispute +// */ +// function startResolution(bytes32 _disputeId) external; - /** - * @notice Resolves the dispute by getting the answer from the arbitrator - * and updating the dispute status - * @dev Only callable by the Oracle - * @param _disputeId The ID of the dispute - */ - function resolveDispute(bytes32 _disputeId) external; +// /** +// * @notice Resolves the dispute by getting the answer from the arbitrator +// * and updating the dispute status +// * @dev Only callable by the Oracle +// * @param _disputeId The ID of the dispute +// */ +// function resolveDispute(bytes32 _disputeId) external; - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _arbitrator The address of the arbitrator - */ - function decodeRequestData(bytes32 _requestId) external view returns (address _arbitrator); -} +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _arbitrator The address of the arbitrator +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (address _arbitrator); +// } diff --git a/solidity/interfaces/modules/resolution/IBondEscalationResolutionModule.sol b/solidity/interfaces/modules/resolution/IBondEscalationResolutionModule.sol index f12a0c6f..764f713a 100644 --- a/solidity/interfaces/modules/resolution/IBondEscalationResolutionModule.sol +++ b/solidity/interfaces/modules/resolution/IBondEscalationResolutionModule.sol @@ -1,300 +1,300 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {IResolutionModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IBondEscalationAccounting} from '../../extensions/IBondEscalationAccounting.sol'; - -/** - * @title BondEscalationResolutionModule - * @notice Handles the bond escalation resolution process for disputes, in which sides take turns pledging for or against a dispute by bonding tokens. - * @dev This is a resolution module, similar in its mechanics to the BondEscalationModule. - */ -interface IBondEscalationResolutionModule is IResolutionModule { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Emitted when a dispute is escalated. - * - * @param _disputeId The ID of the dispute that was escalated. - * @param _requestId The ID of the request associated with the dispute. - */ - event DisputeEscalated(bytes32 indexed _disputeId, bytes32 indexed _requestId); - - /** - * @notice Emitted when a user pledges in favor of a dispute. - * - * @param _pledger The address of the user that pledged. - * @param _requestId The ID of the request associated with the dispute. - * @param _disputeId The ID of the dispute the user pledged in favor of. - * @param _pledgedAmount The amount of tokens the user pledged. - */ - event PledgedForDispute( - address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, uint256 _pledgedAmount - ); - - /** - * @notice Emitted when a user pledges against a dispute. - * - * @param _pledger The address of the user that pledged. - * @param _requestId The ID of the request associated with the dispute. - * @param _disputeId The ID of the dispute the user pledged against. - * @param _pledgedAmount The amount of tokens the user pledged. - */ - event PledgedAgainstDispute( - address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, uint256 _pledgedAmount - ); - - /** - * @notice Emitted when a user claims his pledges after a successful dispute. - * - * @param _requestId The ID of the request associated with the dispute. - * @param _disputeId The ID of the dispute the user supported. - * @param _pledger The address of the user that claimed his pledges. - * @param _token The token the user claimed his pledges in. - * @param _pledgeReleased The amount of tokens the user claimed. - * @param _resolution The outcome of the resolution - */ - event PledgeClaimed( - bytes32 indexed _requestId, - bytes32 indexed _disputeId, - address indexed _pledger, - IERC20 _token, - uint256 _pledgeReleased, - Resolution _resolution - ); - - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Thrown when the user tries to resolve a dispute that has already been resolved. - */ - error BondEscalationResolutionModule_AlreadyResolved(); - - /** - * @notice Thrown when trying to claim a pledge for a dispute that has not been resolved yet. - */ - error BondEscalationResolutionModule_NotResolved(); - - /** - * @notice Thrown when the user tries to pledge for or resolve a non-existent dispute. - */ - error BondEscalationResolutionModule_NotEscalated(); - - /** - * @notice Thrown when trying to pledge after the pledging phase is over. - */ - error BondEscalationResolutionModule_PledgingPhaseOver(); - - /** - * @notice Thrown when trying to resolve a dispute before the pledging phase is over. - */ - error BondEscalationResolutionModule_PledgingPhaseNotOver(); - - /** - * @notice Thrown when trying to pledge after the inequality timer has passed. - */ - error BondEscalationResolutionModule_MustBeResolved(); - - /** - * @notice Thrown when trying to pledge for a dispute during the opposing side's pledging turn. - */ - error BondEscalationResolutionModule_AgainstTurnToEqualize(); - - /** - * @notice Thrown when trying to pledge against a dispute during the supporting side's pledging turn. - */ - error BondEscalationResolutionModule_ForTurnToEqualize(); - - /*/////////////////////////////////////////////////////////////// - ENUMS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice The possible inequality statuses of a dispute - * - * @param Equalized The percentage difference between the for and against pledges is smaller than the set percentageDiff. This state allows any of the two - * parties to pledge. When the percentageDiff is surpassed, the status changes to AgainstTurnToEqualize or ForTurnToEqualize depending on - * which side surpassed the percentageDiff. When this happens, only the respective side can pledge. - * @param ForTurnToEqualize If the for pledges surpassed the percentageDiff, a timer is started and the against party has a set amount of time to - * reduce the percentageDiff so that the status is Equalized again, or to surpass the percentageDiff so that the status changes to ForTurnToEqualize. - * Until this happens, only the people pledging against a dispute can pledge. - * If the timer runs out without the status changing, then the dispute is considered finalized and the for party wins. - * @param AgainstTurnToEqualize The same as AgainstTurnToEqualize but for the parties that wish to pledge in favor a given dispute. - */ - enum InequalityStatus { - Equalized, - ForTurnToEqualize, - AgainstTurnToEqualize - } - - /** - * @notice The possible resolutions of a dispute - * - * @param Unresolved The dispute has not been resolved yet. - * @param DisputerWon The disputer won the dispute. - * @param DisputerLost The disputer lost the dispute. - * @param NoResolution The dispute was not resolved. - */ - enum Resolution { - Unresolved, - DisputerWon, - DisputerLost, - NoResolution - } - - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Parameters of the request as stored in the module - * - * @param _accountingExtension The accounting extension to use for this request. - * @param _token The token to use for this request. - * @param _percentageDiff The percentage difference between the for and against pledges that triggers the change in voting turns. This value should be between 1 and 100. - * @param _pledgeThreshold The amount of pledges that must be reached to achieve quorum and start triggering voting turns. - * @param _timeUntilDeadline The amount of time in seconds past the start time of the escalation until the resolution process is over. - * @param _timeToBreakInequality The amount of time the pledgers have to break the pledge inequality once the percentage difference has been surpassed. - */ - struct RequestParameters { - IBondEscalationAccounting accountingExtension; - IERC20 bondToken; - uint256 percentageDiff; - uint256 pledgeThreshold; - uint256 timeUntilDeadline; - uint256 timeToBreakInequality; - } - - /** - * @notice The inequality status and its last update time of a given dispute. - * - * @param _inequalityStatus The current status of the inequality. - * @param _time The time at which the inequality was last updated. - */ - struct InequalityData { - InequalityStatus inequalityStatus; - uint256 time; - } - - /** - * @notice The bond escalation progress and the balance of pledges for and against a given dispute. - * - * @param _resolution The current resolution of the dispute. - * @param _startTime The time at which the dispute was escalated. - * @param _pledgesFor The amount of pledges in favor of the dispute. - * @param _pledgesAgainst The amount of pledges against the dispute. - */ - struct Escalation { - Resolution resolution; - uint128 startTime; - uint256 pledgesFor; - uint256 pledgesAgainst; - } - - /*/////////////////////////////////////////////////////////////// - VARIABLES - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Base to avoid over/underflow - * - * @return _base The base to avoid over/underflow - */ - function BASE() external view returns (uint256 _base); - - /** - * @notice Returns the bond escalation progress and the balance of pledges for and against a given dispute. - * - * @param _disputeId The ID of the dispute. - * - * @return _resolution The current resolution of the dispute. - * @return _startTime The time at which the dispute was escalated. - * @return _pledgesFor The amount of pledges in favor of the dispute. - * @return _pledgesAgainst The amount of pledges against the dispute. - */ - function escalations(bytes32 _disputeId) - external - view - returns (Resolution _resolution, uint128 _startTime, uint256 _pledgesFor, uint256 _pledgesAgainst); - - /** - * @notice Returns the inequality status and its last update time of a given dispute. - * - * @param _disputeId The ID of the dispute. - * - * @return _inequalityStatus The current status of the inequality. - * @return _time The time at which the inequality was last updated. - */ - function inequalityData(bytes32 _disputeId) external view returns (InequalityStatus _inequalityStatus, uint256 _time); - - /** - * @notice Returns the amount pledged by a user for a given dispute. - * - * @param _disputeId The ID of the dispute. - * @param _pledger The address of the user. - * - * @return _pledgesForDispute The amount pledged by a user for a given dispute. - */ - function pledgesForDispute(bytes32 _disputeId, address _pledger) external view returns (uint256 _pledgesForDispute); - - /** - * @notice Returns the amount pledged by a user against a given dispute. - * - * @param _disputeId The ID of the dispute. - * @param _pledger The address of the user. - * - * @return _pledgesAgainstDispute The amount pledged by a user against a given dispute. - */ - function pledgesAgainstDispute( - bytes32 _disputeId, - address _pledger - ) external view returns (uint256 _pledgesAgainstDispute); - - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Allows users to pledge in favor of a given dispute. This means the user believes the proposed answer is - * incorrect and therefore wants the disputer to win his dispute. - * - * @param _requestId The ID of the request associated with the dispute. - * @param _disputeId The ID of the dispute to pledge in favor of. - * @param _pledgeAmount The amount of pledges to pledge. - */ - function pledgeForDispute(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) external; - - /** - * @notice Allows users to pledge against a given dispute. This means the user believes the proposed answer is - * correct and therefore wants the disputer to lose his dispute. - * - * @param _requestId The ID of the request associated with the dispute. - * @param _disputeId The ID of the dispute to pledge against of. - * @param _pledgeAmount The amount of pledges to pledge. - */ - function pledgeAgainstDispute(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) external; - - /** - * @notice Allows user to claim his corresponding pledges after a dispute is resolved. - * - * @dev Winning pledgers will claim their pledges along with their reward. In case of no resolution, users can - * claim their pledges back. Losing pledgers will go to the rewards of the winning pledgers. - * - * @param _requestId The ID of the request associated with dispute. - * @param _disputeId The ID of the dispute the user wants to claim pledges from. - */ - function claimPledge(bytes32 _requestId, bytes32 _disputeId) external; -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import {IResolutionModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IBondEscalationAccounting} from '../../extensions/IBondEscalationAccounting.sol'; + +// /** +// * @title BondEscalationResolutionModule +// * @notice Handles the bond escalation resolution process for disputes, in which sides take turns pledging for or against a dispute by bonding tokens. +// * @dev This is a resolution module, similar in its mechanics to the BondEscalationModule. +// */ +// interface IBondEscalationResolutionModule is IResolutionModule { +// /*/////////////////////////////////////////////////////////////// +// EVENTS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Emitted when a dispute is escalated. +// * +// * @param _disputeId The ID of the dispute that was escalated. +// * @param _requestId The ID of the request associated with the dispute. +// */ +// event DisputeEscalated(bytes32 indexed _disputeId, bytes32 indexed _requestId); + +// /** +// * @notice Emitted when a user pledges in favor of a dispute. +// * +// * @param _pledger The address of the user that pledged. +// * @param _requestId The ID of the request associated with the dispute. +// * @param _disputeId The ID of the dispute the user pledged in favor of. +// * @param _pledgedAmount The amount of tokens the user pledged. +// */ +// event PledgedForDispute( +// address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, uint256 _pledgedAmount +// ); + +// /** +// * @notice Emitted when a user pledges against a dispute. +// * +// * @param _pledger The address of the user that pledged. +// * @param _requestId The ID of the request associated with the dispute. +// * @param _disputeId The ID of the dispute the user pledged against. +// * @param _pledgedAmount The amount of tokens the user pledged. +// */ +// event PledgedAgainstDispute( +// address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, uint256 _pledgedAmount +// ); + +// /** +// * @notice Emitted when a user claims his pledges after a successful dispute. +// * +// * @param _requestId The ID of the request associated with the dispute. +// * @param _disputeId The ID of the dispute the user supported. +// * @param _pledger The address of the user that claimed his pledges. +// * @param _token The token the user claimed his pledges in. +// * @param _pledgeReleased The amount of tokens the user claimed. +// * @param _resolution The outcome of the resolution +// */ +// event PledgeClaimed( +// bytes32 indexed _requestId, +// bytes32 indexed _disputeId, +// address indexed _pledger, +// IERC20 _token, +// uint256 _pledgeReleased, +// Resolution _resolution +// ); + +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Thrown when the user tries to resolve a dispute that has already been resolved. +// */ +// error BondEscalationResolutionModule_AlreadyResolved(); + +// /** +// * @notice Thrown when trying to claim a pledge for a dispute that has not been resolved yet. +// */ +// error BondEscalationResolutionModule_NotResolved(); + +// /** +// * @notice Thrown when the user tries to pledge for or resolve a non-existent dispute. +// */ +// error BondEscalationResolutionModule_NotEscalated(); + +// /** +// * @notice Thrown when trying to pledge after the pledging phase is over. +// */ +// error BondEscalationResolutionModule_PledgingPhaseOver(); + +// /** +// * @notice Thrown when trying to resolve a dispute before the pledging phase is over. +// */ +// error BondEscalationResolutionModule_PledgingPhaseNotOver(); + +// /** +// * @notice Thrown when trying to pledge after the inequality timer has passed. +// */ +// error BondEscalationResolutionModule_MustBeResolved(); + +// /** +// * @notice Thrown when trying to pledge for a dispute during the opposing side's pledging turn. +// */ +// error BondEscalationResolutionModule_AgainstTurnToEqualize(); + +// /** +// * @notice Thrown when trying to pledge against a dispute during the supporting side's pledging turn. +// */ +// error BondEscalationResolutionModule_ForTurnToEqualize(); + +// /*/////////////////////////////////////////////////////////////// +// ENUMS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice The possible inequality statuses of a dispute +// * +// * @param Equalized The percentage difference between the for and against pledges is smaller than the set percentageDiff. This state allows any of the two +// * parties to pledge. When the percentageDiff is surpassed, the status changes to AgainstTurnToEqualize or ForTurnToEqualize depending on +// * which side surpassed the percentageDiff. When this happens, only the respective side can pledge. +// * @param ForTurnToEqualize If the for pledges surpassed the percentageDiff, a timer is started and the against party has a set amount of time to +// * reduce the percentageDiff so that the status is Equalized again, or to surpass the percentageDiff so that the status changes to ForTurnToEqualize. +// * Until this happens, only the people pledging against a dispute can pledge. +// * If the timer runs out without the status changing, then the dispute is considered finalized and the for party wins. +// * @param AgainstTurnToEqualize The same as AgainstTurnToEqualize but for the parties that wish to pledge in favor a given dispute. +// */ +// enum InequalityStatus { +// Equalized, +// ForTurnToEqualize, +// AgainstTurnToEqualize +// } + +// /** +// * @notice The possible resolutions of a dispute +// * +// * @param Unresolved The dispute has not been resolved yet. +// * @param DisputerWon The disputer won the dispute. +// * @param DisputerLost The disputer lost the dispute. +// * @param NoResolution The dispute was not resolved. +// */ +// enum Resolution { +// Unresolved, +// DisputerWon, +// DisputerLost, +// NoResolution +// } + +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Parameters of the request as stored in the module +// * +// * @param _accountingExtension The accounting extension to use for this request. +// * @param _token The token to use for this request. +// * @param _percentageDiff The percentage difference between the for and against pledges that triggers the change in voting turns. This value should be between 1 and 100. +// * @param _pledgeThreshold The amount of pledges that must be reached to achieve quorum and start triggering voting turns. +// * @param _timeUntilDeadline The amount of time in seconds past the start time of the escalation until the resolution process is over. +// * @param _timeToBreakInequality The amount of time the pledgers have to break the pledge inequality once the percentage difference has been surpassed. +// */ +// struct RequestParameters { +// IBondEscalationAccounting accountingExtension; +// IERC20 bondToken; +// uint256 percentageDiff; +// uint256 pledgeThreshold; +// uint256 timeUntilDeadline; +// uint256 timeToBreakInequality; +// } + +// /** +// * @notice The inequality status and its last update time of a given dispute. +// * +// * @param _inequalityStatus The current status of the inequality. +// * @param _time The time at which the inequality was last updated. +// */ +// struct InequalityData { +// InequalityStatus inequalityStatus; +// uint256 time; +// } + +// /** +// * @notice The bond escalation progress and the balance of pledges for and against a given dispute. +// * +// * @param _resolution The current resolution of the dispute. +// * @param _startTime The time at which the dispute was escalated. +// * @param _pledgesFor The amount of pledges in favor of the dispute. +// * @param _pledgesAgainst The amount of pledges against the dispute. +// */ +// struct Escalation { +// Resolution resolution; +// uint128 startTime; +// uint256 pledgesFor; +// uint256 pledgesAgainst; +// } + +// /*/////////////////////////////////////////////////////////////// +// VARIABLES +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Base to avoid over/underflow +// * +// * @return _base The base to avoid over/underflow +// */ +// function BASE() external view returns (uint256 _base); + +// /** +// * @notice Returns the bond escalation progress and the balance of pledges for and against a given dispute. +// * +// * @param _disputeId The ID of the dispute. +// * +// * @return _resolution The current resolution of the dispute. +// * @return _startTime The time at which the dispute was escalated. +// * @return _pledgesFor The amount of pledges in favor of the dispute. +// * @return _pledgesAgainst The amount of pledges against the dispute. +// */ +// function escalations(bytes32 _disputeId) +// external +// view +// returns (Resolution _resolution, uint128 _startTime, uint256 _pledgesFor, uint256 _pledgesAgainst); + +// /** +// * @notice Returns the inequality status and its last update time of a given dispute. +// * +// * @param _disputeId The ID of the dispute. +// * +// * @return _inequalityStatus The current status of the inequality. +// * @return _time The time at which the inequality was last updated. +// */ +// function inequalityData(bytes32 _disputeId) external view returns (InequalityStatus _inequalityStatus, uint256 _time); + +// /** +// * @notice Returns the amount pledged by a user for a given dispute. +// * +// * @param _disputeId The ID of the dispute. +// * @param _pledger The address of the user. +// * +// * @return _pledgesForDispute The amount pledged by a user for a given dispute. +// */ +// function pledgesForDispute(bytes32 _disputeId, address _pledger) external view returns (uint256 _pledgesForDispute); + +// /** +// * @notice Returns the amount pledged by a user against a given dispute. +// * +// * @param _disputeId The ID of the dispute. +// * @param _pledger The address of the user. +// * +// * @return _pledgesAgainstDispute The amount pledged by a user against a given dispute. +// */ +// function pledgesAgainstDispute( +// bytes32 _disputeId, +// address _pledger +// ) external view returns (uint256 _pledgesAgainstDispute); + +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); + +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Allows users to pledge in favor of a given dispute. This means the user believes the proposed answer is +// * incorrect and therefore wants the disputer to win his dispute. +// * +// * @param _requestId The ID of the request associated with the dispute. +// * @param _disputeId The ID of the dispute to pledge in favor of. +// * @param _pledgeAmount The amount of pledges to pledge. +// */ +// function pledgeForDispute(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) external; + +// /** +// * @notice Allows users to pledge against a given dispute. This means the user believes the proposed answer is +// * correct and therefore wants the disputer to lose his dispute. +// * +// * @param _requestId The ID of the request associated with the dispute. +// * @param _disputeId The ID of the dispute to pledge against of. +// * @param _pledgeAmount The amount of pledges to pledge. +// */ +// function pledgeAgainstDispute(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) external; + +// /** +// * @notice Allows user to claim his corresponding pledges after a dispute is resolved. +// * +// * @dev Winning pledgers will claim their pledges along with their reward. In case of no resolution, users can +// * claim their pledges back. Losing pledgers will go to the rewards of the winning pledgers. +// * +// * @param _requestId The ID of the request associated with dispute. +// * @param _disputeId The ID of the dispute the user wants to claim pledges from. +// */ +// function claimPledge(bytes32 _requestId, bytes32 _disputeId) external; +// } diff --git a/solidity/interfaces/modules/resolution/IERC20ResolutionModule.sol b/solidity/interfaces/modules/resolution/IERC20ResolutionModule.sol index 6a26b555..6e4bc7ad 100644 --- a/solidity/interfaces/modules/resolution/IERC20ResolutionModule.sol +++ b/solidity/interfaces/modules/resolution/IERC20ResolutionModule.sol @@ -1,142 +1,142 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {IResolutionModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -/** - * @title ERC20ResolutionModule - * @notice This contract allows for disputes to be resolved by a voting process. - * The voting process is started by the oracle and - * the voting phase lasts for a certain amount of time. During this time, anyone can vote on the dispute. Once the voting - * phase is over, the votes are tallied and if the votes in favor of the dispute are greater than the votes against the - * dispute, the dispute is resolved in favor of the dispute. Otherwise, the dispute is resolved against the dispute. - */ -interface IERC20ResolutionModule is IResolutionModule { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Emitted when a voter casts their vote on a dispute - * @param _voter The address of the voter - * @param _disputeId The id of the dispute - * @param _numberOfVotes The number of votes cast by the voter - */ - event VoteCast(address _voter, bytes32 _disputeId, uint256 _numberOfVotes); - - /** - * @notice Emitted when the voting phase has started - * @param _startTime The time when the voting phase started - * @param _disputeId The ID of the dispute - */ - event VotingPhaseStarted(uint256 _startTime, bytes32 _disputeId); - - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Throws if the caller is not the dispute module - */ - error ERC20ResolutionModule_OnlyDisputeModule(); - - /** - * @notice Throws if the dispute has not been escalated - */ - error ERC20ResolutionModule_DisputeNotEscalated(); - - /** - * @notice Throws if the dispute is unresolved - */ - error ERC20ResolutionModule_UnresolvedDispute(); - - /** - * @notice Throws if the voting phase is over - */ - error ERC20ResolutionModule_VotingPhaseOver(); - - /** - * @notice Throws if the voting phase is ongoing - */ - error ERC20ResolutionModule_OnGoingVotingPhase(); - - /** - * @notice Throws if the dispute does not exist - */ - error ERC20ResolutionModule_NonExistentDispute(); - - /** - * @notice Throws if the dispute has already been resolved - */ - error ERC20ResolutionModule_AlreadyResolved(); - - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Parameters of the request as stored in the module - * @param votingToken The token used to vote - * @param minVotesForQuorum The minimum amount of votes to win the dispute - * @param timeUntilDeadline The time until the voting phase ends - */ - struct RequestParameters { - IERC20 votingToken; - uint256 minVotesForQuorum; - uint256 timeUntilDeadline; - } - - /** - * @notice Escalation data for a dispute - * @param startTime The timestamp at which the dispute was escalated - * @param totalVotes The total amount of votes cast for the dispute - */ - struct Escalation { - uint256 startTime; - uint256 totalVotes; - } - - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Returns the escalation data for a dispute - * @param _disputeId The id of the dispute - * @return _startTime The timestamp at which the dispute was escalated - * @return _totalVotes The total amount of votes cast for the dispute - */ - function escalations(bytes32 _disputeId) external view returns (uint256 _startTime, uint256 _totalVotes); - - function votes(bytes32 _disputeId, address _voter) external view returns (uint256 _votes); - - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - - /// @inheritdoc IResolutionModule - function startResolution(bytes32 _disputeId) external; - - /** - * @notice Casts a vote in favor of a dispute - * @param _requestId The id of the request being disputed - * @param _disputeId The id of the dispute being voted on - * @param _numberOfVotes The number of votes to cast - */ - function castVote(bytes32 _requestId, bytes32 _disputeId, uint256 _numberOfVotes) external; - - /// @inheritdoc IResolutionModule - function resolveDispute(bytes32 _disputeId) external; - - /** - * @notice Gets the voters of a dispute - * @param _disputeId The id of the dispute - * @return _voters The addresses of the voters - */ - function getVoters(bytes32 _disputeId) external view returns (address[] memory _voters); -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import {IResolutionModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +// /** +// * @title ERC20ResolutionModule +// * @notice This contract allows for disputes to be resolved by a voting process. +// * The voting process is started by the oracle and +// * the voting phase lasts for a certain amount of time. During this time, anyone can vote on the dispute. Once the voting +// * phase is over, the votes are tallied and if the votes in favor of the dispute are greater than the votes against the +// * dispute, the dispute is resolved in favor of the dispute. Otherwise, the dispute is resolved against the dispute. +// */ +// interface IERC20ResolutionModule is IResolutionModule { +// /*/////////////////////////////////////////////////////////////// +// EVENTS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Emitted when a voter casts their vote on a dispute +// * @param _voter The address of the voter +// * @param _disputeId The id of the dispute +// * @param _numberOfVotes The number of votes cast by the voter +// */ +// event VoteCast(address _voter, bytes32 _disputeId, uint256 _numberOfVotes); + +// /** +// * @notice Emitted when the voting phase has started +// * @param _startTime The time when the voting phase started +// * @param _disputeId The ID of the dispute +// */ +// event VotingPhaseStarted(uint256 _startTime, bytes32 _disputeId); + +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Throws if the caller is not the dispute module +// */ +// error ERC20ResolutionModule_OnlyDisputeModule(); + +// /** +// * @notice Throws if the dispute has not been escalated +// */ +// error ERC20ResolutionModule_DisputeNotEscalated(); + +// /** +// * @notice Throws if the dispute is unresolved +// */ +// error ERC20ResolutionModule_UnresolvedDispute(); + +// /** +// * @notice Throws if the voting phase is over +// */ +// error ERC20ResolutionModule_VotingPhaseOver(); + +// /** +// * @notice Throws if the voting phase is ongoing +// */ +// error ERC20ResolutionModule_OnGoingVotingPhase(); + +// /** +// * @notice Throws if the dispute does not exist +// */ +// error ERC20ResolutionModule_NonExistentDispute(); + +// /** +// * @notice Throws if the dispute has already been resolved +// */ +// error ERC20ResolutionModule_AlreadyResolved(); + +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Parameters of the request as stored in the module +// * @param votingToken The token used to vote +// * @param minVotesForQuorum The minimum amount of votes to win the dispute +// * @param timeUntilDeadline The time until the voting phase ends +// */ +// struct RequestParameters { +// IERC20 votingToken; +// uint256 minVotesForQuorum; +// uint256 timeUntilDeadline; +// } + +// /** +// * @notice Escalation data for a dispute +// * @param startTime The timestamp at which the dispute was escalated +// * @param totalVotes The total amount of votes cast for the dispute +// */ +// struct Escalation { +// uint256 startTime; +// uint256 totalVotes; +// } + +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Returns the escalation data for a dispute +// * @param _disputeId The id of the dispute +// * @return _startTime The timestamp at which the dispute was escalated +// * @return _totalVotes The total amount of votes cast for the dispute +// */ +// function escalations(bytes32 _disputeId) external view returns (uint256 _startTime, uint256 _totalVotes); + +// function votes(bytes32 _disputeId, address _voter) external view returns (uint256 _votes); + +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); + +// /// @inheritdoc IResolutionModule +// function startResolution(bytes32 _disputeId) external; + +// /** +// * @notice Casts a vote in favor of a dispute +// * @param _requestId The id of the request being disputed +// * @param _disputeId The id of the dispute being voted on +// * @param _numberOfVotes The number of votes to cast +// */ +// function castVote(bytes32 _requestId, bytes32 _disputeId, uint256 _numberOfVotes) external; + +// /// @inheritdoc IResolutionModule +// function resolveDispute(bytes32 _disputeId) external; + +// /** +// * @notice Gets the voters of a dispute +// * @param _disputeId The id of the dispute +// * @return _voters The addresses of the voters +// */ +// function getVoters(bytes32 _disputeId) external view returns (address[] memory _voters); +// } diff --git a/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol b/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol index c3499683..66b1249b 100644 --- a/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol +++ b/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol @@ -1,200 +1,200 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {IResolutionModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; - -/* - * @title PrivateERC20ResolutionModule - * @notice Module allowing users to vote on a dispute using ERC20 - * tokens through a commit/reveal pattern. - */ -interface IPrivateERC20ResolutionModule is IResolutionModule { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice A commitment has been provided by a voter - * @param _voter The user who provided a commitment of a vote - * @param _disputeId The id of the dispute being voted on - * @param _commitment The commitment provided by the voter - */ - event VoteCommitted(address _voter, bytes32 _disputeId, bytes32 _commitment); - - /** - * @notice A vote has been revealed by a voter providing - * the salt used to compute the commitment - * @param _voter The user who revealed his vote - * @param _disputeId The id of the dispute being voted on - * @param _numberOfVotes The number of votes cast - */ - event VoteRevealed(address _voter, bytes32 _disputeId, uint256 _numberOfVotes); - - /** - * @notice The phase of committing votes has started - * @param _startTime The timestamp at which the phase started - * @param _disputeId The id of the dispute being voted on - */ - event CommittingPhaseStarted(uint256 _startTime, bytes32 _disputeId); - - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Thrown when the dispute has not been escalated - */ - error PrivateERC20ResolutionModule_DisputeNotEscalated(); - - /** - * @notice Thrown when trying to commit a vote after the committing deadline - */ - error PrivateERC20ResolutionModule_CommittingPhaseOver(); - - /** - * @notice Thrown when trying to reveal a vote after the revealing deadline - */ - error PrivateERC20ResolutionModule_RevealingPhaseOver(); - - /** - * @notice Thrown when trying to resolve a dispute during the committing phase - */ - error PrivateERC20ResolutionModule_OnGoingCommittingPhase(); - - /** - * @notice Thrown when trying to resolve a dispute during the revealing phase - */ - error PrivateERC20ResolutionModule_OnGoingRevealingPhase(); - - /** - * @notice Thrown when trying to resolve a dispute that does not exist - */ - error PrivateERC20ResolutionModule_NonExistentDispute(); - - /** - * @notice Thrown when trying to commit an empty commitment - */ - error PrivateERC20ResolutionModule_EmptyCommitment(); - - /** - * @notice Thrown when trying to reveal a vote with data that does not match the stored commitment - */ - error PrivateERC20ResolutionModule_WrongRevealData(); - - /** - * @notice Thrown when trying to resolve a dispute that is already resolved - */ - error PrivateERC20ResolutionModule_AlreadyResolved(); - - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Parameters of the request as stored in the module - * @param accountingExtension The accounting extension used to bond and release tokens - * @param token The token used to vote - * @param minVotesForQuorum The minimum amount of votes to win the dispute - * @param committingTimeWindow The amount of time to commit votes from the escalation of the dispute - * @param revealingTimeWindow The amount of time to reveal votes from the committing phase - */ - struct RequestParameters { - IAccountingExtension accountingExtension; - IERC20 votingToken; - uint256 minVotesForQuorum; - uint256 committingTimeWindow; - uint256 revealingTimeWindow; - } - - /** - * @notice Escalation data for a dispute - * @param startTime The timestamp at which the dispute was escalated - * @param totalVotes The total amount of votes cast for the dispute - */ - - struct Escalation { - uint256 startTime; - uint256 totalVotes; - } - - /** - * @notice Voting data for each voter - * @param numOfVotes The amount of votes cast for the dispute - * @param commitment The commitment provided by the voter - */ - struct VoterData { - uint256 numOfVotes; - bytes32 commitment; - } - - /*/////////////////////////////////////////////////////////////// - VARIABLES - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Returns the escalation data for a dispute - * @param _disputeId The id of the dispute - * @return _startTime The timestamp at which the dispute was escalated - * @return _totalVotes The total amount of votes cast for the dispute - */ - function escalations(bytes32 _disputeId) external view returns (uint256 _startTime, uint256 _totalVotes); - - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Starts the committing phase for a dispute - * @dev Only callable by the Oracle - * @param _disputeId The id of the dispute to start resolution of - */ - function startResolution(bytes32 _disputeId) external; - - /** - * @notice Stores a commitment for a vote cast by a voter - * @dev Committing multiple times and overwriting a previous commitment is allowed - * @param _requestId The id of the request being disputed - * @param _disputeId The id of the dispute being voted on - * @param _commitment The commitment computed from the provided data and the user's address - */ - function commitVote(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) external; - - /** - * @notice Reveals a vote cast by a voter - * @dev The user must have previously approved the module to transfer the tokens - * @param _requestId The id of the request being disputed - * @param _disputeId The id of the dispute being voted on - * @param _numberOfVotes The amount of votes being revealed - * @param _salt The salt used to compute the commitment - */ - function revealVote(bytes32 _requestId, bytes32 _disputeId, uint256 _numberOfVotes, bytes32 _salt) external; - - /** - * @notice Resolves a dispute by tallying the votes and executing the winning outcome - * @dev Only callable by the Oracle - * @param _disputeId The id of the dispute being resolved - */ - function resolveDispute(bytes32 _disputeId) external; - - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - - /** - * @notice Computes a valid commitment for the revealing phase - * @param _disputeId The id of the dispute being voted on - * @param _numberOfVotes The amount of votes being cast - * @return _commitment The commitment computed from the provided data and the user's address - */ - function computeCommitment( - bytes32 _disputeId, - uint256 _numberOfVotes, - bytes32 _salt - ) external view returns (bytes32 _commitment); -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import {IResolutionModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; + +// /* +// * @title PrivateERC20ResolutionModule +// * @notice Module allowing users to vote on a dispute using ERC20 +// * tokens through a commit/reveal pattern. +// */ +// interface IPrivateERC20ResolutionModule is IResolutionModule { +// /*/////////////////////////////////////////////////////////////// +// EVENTS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice A commitment has been provided by a voter +// * @param _voter The user who provided a commitment of a vote +// * @param _disputeId The id of the dispute being voted on +// * @param _commitment The commitment provided by the voter +// */ +// event VoteCommitted(address _voter, bytes32 _disputeId, bytes32 _commitment); + +// /** +// * @notice A vote has been revealed by a voter providing +// * the salt used to compute the commitment +// * @param _voter The user who revealed his vote +// * @param _disputeId The id of the dispute being voted on +// * @param _numberOfVotes The number of votes cast +// */ +// event VoteRevealed(address _voter, bytes32 _disputeId, uint256 _numberOfVotes); + +// /** +// * @notice The phase of committing votes has started +// * @param _startTime The timestamp at which the phase started +// * @param _disputeId The id of the dispute being voted on +// */ +// event CommittingPhaseStarted(uint256 _startTime, bytes32 _disputeId); + +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Thrown when the dispute has not been escalated +// */ +// error PrivateERC20ResolutionModule_DisputeNotEscalated(); + +// /** +// * @notice Thrown when trying to commit a vote after the committing deadline +// */ +// error PrivateERC20ResolutionModule_CommittingPhaseOver(); + +// /** +// * @notice Thrown when trying to reveal a vote after the revealing deadline +// */ +// error PrivateERC20ResolutionModule_RevealingPhaseOver(); + +// /** +// * @notice Thrown when trying to resolve a dispute during the committing phase +// */ +// error PrivateERC20ResolutionModule_OnGoingCommittingPhase(); + +// /** +// * @notice Thrown when trying to resolve a dispute during the revealing phase +// */ +// error PrivateERC20ResolutionModule_OnGoingRevealingPhase(); + +// /** +// * @notice Thrown when trying to resolve a dispute that does not exist +// */ +// error PrivateERC20ResolutionModule_NonExistentDispute(); + +// /** +// * @notice Thrown when trying to commit an empty commitment +// */ +// error PrivateERC20ResolutionModule_EmptyCommitment(); + +// /** +// * @notice Thrown when trying to reveal a vote with data that does not match the stored commitment +// */ +// error PrivateERC20ResolutionModule_WrongRevealData(); + +// /** +// * @notice Thrown when trying to resolve a dispute that is already resolved +// */ +// error PrivateERC20ResolutionModule_AlreadyResolved(); + +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Parameters of the request as stored in the module +// * @param accountingExtension The accounting extension used to bond and release tokens +// * @param token The token used to vote +// * @param minVotesForQuorum The minimum amount of votes to win the dispute +// * @param committingTimeWindow The amount of time to commit votes from the escalation of the dispute +// * @param revealingTimeWindow The amount of time to reveal votes from the committing phase +// */ +// struct RequestParameters { +// IAccountingExtension accountingExtension; +// IERC20 votingToken; +// uint256 minVotesForQuorum; +// uint256 committingTimeWindow; +// uint256 revealingTimeWindow; +// } + +// /** +// * @notice Escalation data for a dispute +// * @param startTime The timestamp at which the dispute was escalated +// * @param totalVotes The total amount of votes cast for the dispute +// */ + +// struct Escalation { +// uint256 startTime; +// uint256 totalVotes; +// } + +// /** +// * @notice Voting data for each voter +// * @param numOfVotes The amount of votes cast for the dispute +// * @param commitment The commitment provided by the voter +// */ +// struct VoterData { +// uint256 numOfVotes; +// bytes32 commitment; +// } + +// /*/////////////////////////////////////////////////////////////// +// VARIABLES +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Returns the escalation data for a dispute +// * @param _disputeId The id of the dispute +// * @return _startTime The timestamp at which the dispute was escalated +// * @return _totalVotes The total amount of votes cast for the dispute +// */ +// function escalations(bytes32 _disputeId) external view returns (uint256 _startTime, uint256 _totalVotes); + +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Starts the committing phase for a dispute +// * @dev Only callable by the Oracle +// * @param _disputeId The id of the dispute to start resolution of +// */ +// function startResolution(bytes32 _disputeId) external; + +// /** +// * @notice Stores a commitment for a vote cast by a voter +// * @dev Committing multiple times and overwriting a previous commitment is allowed +// * @param _requestId The id of the request being disputed +// * @param _disputeId The id of the dispute being voted on +// * @param _commitment The commitment computed from the provided data and the user's address +// */ +// function commitVote(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) external; + +// /** +// * @notice Reveals a vote cast by a voter +// * @dev The user must have previously approved the module to transfer the tokens +// * @param _requestId The id of the request being disputed +// * @param _disputeId The id of the dispute being voted on +// * @param _numberOfVotes The amount of votes being revealed +// * @param _salt The salt used to compute the commitment +// */ +// function revealVote(bytes32 _requestId, bytes32 _disputeId, uint256 _numberOfVotes, bytes32 _salt) external; + +// /** +// * @notice Resolves a dispute by tallying the votes and executing the winning outcome +// * @dev Only callable by the Oracle +// * @param _disputeId The id of the dispute being resolved +// */ +// function resolveDispute(bytes32 _disputeId) external; + +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); + +// /** +// * @notice Computes a valid commitment for the revealing phase +// * @param _disputeId The id of the dispute being voted on +// * @param _numberOfVotes The amount of votes being cast +// * @return _commitment The commitment computed from the provided data and the user's address +// */ +// function computeCommitment( +// bytes32 _disputeId, +// uint256 _numberOfVotes, +// bytes32 _salt +// ) external view returns (bytes32 _commitment); +// } diff --git a/solidity/interfaces/modules/resolution/ISequentialResolutionModule.sol b/solidity/interfaces/modules/resolution/ISequentialResolutionModule.sol index 9b0c3108..8a7fc2db 100644 --- a/solidity/interfaces/modules/resolution/ISequentialResolutionModule.sol +++ b/solidity/interfaces/modules/resolution/ISequentialResolutionModule.sol @@ -1,116 +1,116 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IResolutionModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; - -interface ISequentialResolutionModule is IOracle, IResolutionModule { - /*/////////////////////////////////////////////////////////////// - EVENTS - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Emitted when a new resolution sequence is added - */ - event ResolutionSequenceAdded(uint256 _sequenceId, IResolutionModule[] _modules); - - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Thrown when the caller is not a valid sub-module - */ - error SequentialResolutionModule_OnlySubmodule(); - - /** - * @notice Thrown when the function called is not implemented - */ - error SequentialResolutionModule_NotImplemented(); - - /** - * @notice Thrown when trying to add a new sequenceId that was already used - * @param _sequenceId The sequenceId that was already used - */ - error SequentialResolutionModule_SequenceIdAlreadyUsed(uint256 _sequenceId); - - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * @param sequenceId The sequence ID to use in the request. - * @param submoduleData The array of data to pass to the submodules - */ - struct RequestParameters { - uint256 sequenceId; - bytes[] submoduleData; - } - - /*/////////////////////////////////////////////////////////////// - VARIABLES - //////////////////////////////////////////////////////////////*/ - - /** - * @notice Returns the last sequence id that was created - * @return _currentSequenceId The sequence id - */ - function currentSequenceId() external view returns (uint256 _currentSequenceId); - - /** - * @notice Returns the current index of the submodule in use for a dispute - * @param _disputeId The disputeId - * @return _moduleIndex The index of the module - */ - function currentModuleIndex(bytes32 _disputeId) external view returns (uint256 _moduleIndex); - - /** - * @notice Returns the requestId corresponding to a dispute - * @param _disputeId The disputeId - * @return _requestId The requestId - */ - function requestIdForDispute(bytes32 _disputeId) external view returns (bytes32 _requestId); - - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - - /*/////////////////////////////////////////////////////////////// - FUNCTIONS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the list of submodules - * @param _startFrom The index to start from - * @param _batchSize The number of submodules to return - * @param _sequenceId The sequence to get the submodules from - * @return _list The list of submodules - */ - function listSubmodules( - uint256 _startFrom, - uint256 _batchSize, - uint256 _sequenceId - ) external view returns (IResolutionModule[] memory _list); - - /** - * @notice Adds a sequence of modules to the resolution module registry. - * @param _modules The modules to add to the sequence. - * @return _sequenceId The sequenceId created - */ - function addResolutionModuleSequence(IResolutionModule[] memory _modules) external returns (uint256 _sequenceId); - - /** - * @notice Returns the module that is currently resolving the specified dispute - * @param _disputeId The id of the dispute - * @return _module Te current resolution module - */ - function getCurrentResolutionModule(bytes32 _disputeId) external returns (IResolutionModule _module); - - /** - * @notice Resolves a dispute - * @param _disputeId The id of the dispute to resolve - */ - function resolveDispute(bytes32 _disputeId) external override(IOracle, IResolutionModule); -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IResolutionModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; + +// interface ISequentialResolutionModule is IOracle, IResolutionModule { +// /*/////////////////////////////////////////////////////////////// +// EVENTS +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Emitted when a new resolution sequence is added +// */ +// event ResolutionSequenceAdded(uint256 _sequenceId, IResolutionModule[] _modules); + +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ +// /** +// * @notice Thrown when the caller is not a valid sub-module +// */ +// error SequentialResolutionModule_OnlySubmodule(); + +// /** +// * @notice Thrown when the function called is not implemented +// */ +// error SequentialResolutionModule_NotImplemented(); + +// /** +// * @notice Thrown when trying to add a new sequenceId that was already used +// * @param _sequenceId The sequenceId that was already used +// */ +// error SequentialResolutionModule_SequenceIdAlreadyUsed(uint256 _sequenceId); + +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ +// /** +// * @notice Parameters of the request as stored in the module +// * @param sequenceId The sequence ID to use in the request. +// * @param submoduleData The array of data to pass to the submodules +// */ +// struct RequestParameters { +// uint256 sequenceId; +// bytes[] submoduleData; +// } + +// /*/////////////////////////////////////////////////////////////// +// VARIABLES +// //////////////////////////////////////////////////////////////*/ + +// /** +// * @notice Returns the last sequence id that was created +// * @return _currentSequenceId The sequence id +// */ +// function currentSequenceId() external view returns (uint256 _currentSequenceId); + +// /** +// * @notice Returns the current index of the submodule in use for a dispute +// * @param _disputeId The disputeId +// * @return _moduleIndex The index of the module +// */ +// function currentModuleIndex(bytes32 _disputeId) external view returns (uint256 _moduleIndex); + +// /** +// * @notice Returns the requestId corresponding to a dispute +// * @param _disputeId The disputeId +// * @return _requestId The requestId +// */ +// function requestIdForDispute(bytes32 _disputeId) external view returns (bytes32 _requestId); + +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); + +// /*/////////////////////////////////////////////////////////////// +// FUNCTIONS +// //////////////////////////////////////////////////////////////*/ +// /** +// * @notice Returns the list of submodules +// * @param _startFrom The index to start from +// * @param _batchSize The number of submodules to return +// * @param _sequenceId The sequence to get the submodules from +// * @return _list The list of submodules +// */ +// function listSubmodules( +// uint256 _startFrom, +// uint256 _batchSize, +// uint256 _sequenceId +// ) external view returns (IResolutionModule[] memory _list); + +// /** +// * @notice Adds a sequence of modules to the resolution module registry. +// * @param _modules The modules to add to the sequence. +// * @return _sequenceId The sequenceId created +// */ +// function addResolutionModuleSequence(IResolutionModule[] memory _modules) external returns (uint256 _sequenceId); + +// /** +// * @notice Returns the module that is currently resolving the specified dispute +// * @param _disputeId The id of the dispute +// * @return _module Te current resolution module +// */ +// function getCurrentResolutionModule(bytes32 _disputeId) external returns (IResolutionModule _module); + +// /** +// * @notice Resolves a dispute +// * @param _disputeId The id of the dispute to resolve +// */ +// function resolveDispute(bytes32 _disputeId) external override(IOracle, IResolutionModule); +// } diff --git a/solidity/interfaces/modules/response/IBondedResponseModule.sol b/solidity/interfaces/modules/response/IBondedResponseModule.sol index 5ddcdc51..c159b988 100644 --- a/solidity/interfaces/modules/response/IBondedResponseModule.sol +++ b/solidity/interfaces/modules/response/IBondedResponseModule.sol @@ -1,117 +1,117 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IResponseModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/response/IResponseModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IResponseModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/response/IResponseModule.sol'; -import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; +// import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; -/* - * @title BondedResponseModule - * @notice Module allowing users to propose a response for a request - * by bonding tokens. - */ -interface IBondedResponseModule is IResponseModule { - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ - /** - * @notice Emitted when a response is proposed - * @param _requestId The ID of the request that the response was proposed - * @param _proposer The user that proposed the response - * @param _responseData The data for the response - */ - event ProposeResponse(bytes32 indexed _requestId, address _proposer, bytes _responseData); - /*/////////////////////////////////////////////////////////////// - ERRORS - //////////////////////////////////////////////////////////////*/ +// /* +// * @title BondedResponseModule +// * @notice Module allowing users to propose a response for a request +// * by bonding tokens. +// */ +// interface IBondedResponseModule is IResponseModule { +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ +// /** +// * @notice Emitted when a response is proposed +// * @param _requestId The ID of the request that the response was proposed +// * @param _proposer The user that proposed the response +// * @param _responseData The data for the response +// */ +// event ProposeResponse(bytes32 indexed _requestId, address _proposer, bytes _responseData); +// /*/////////////////////////////////////////////////////////////// +// ERRORS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Thrown when trying to finalize a request before the deadline - */ - error BondedResponseModule_TooEarlyToFinalize(); +// /** +// * @notice Thrown when trying to finalize a request before the deadline +// */ +// error BondedResponseModule_TooEarlyToFinalize(); - /** - * @notice Thrown when trying to propose a response after deadline - */ - error BondedResponseModule_TooLateToPropose(); +// /** +// * @notice Thrown when trying to propose a response after deadline +// */ +// error BondedResponseModule_TooLateToPropose(); - /** - * @notice Thrown when trying to propose a response while an undisputed response is already proposed - */ - error BondedResponseModule_AlreadyResponded(); +// /** +// * @notice Thrown when trying to propose a response while an undisputed response is already proposed +// */ +// error BondedResponseModule_AlreadyResponded(); - /** - * @notice Thrown when trying to delete a response after the proposing deadline - */ - error BondedResponseModule_TooLateToDelete(); +// /** +// * @notice Thrown when trying to delete a response after the proposing deadline +// */ +// error BondedResponseModule_TooLateToDelete(); - /** - * @notice Thrown when trying to create an invalid request - */ - error BondedResponseModule_InvalidRequest(); +// /** +// * @notice Thrown when trying to create an invalid request +// */ +// error BondedResponseModule_InvalidRequest(); - /*/////////////////////////////////////////////////////////////// - STRUCTS - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// STRUCTS +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Parameters of the request as stored in the module - * @param accountingExtension The accounting extension used to bond and release tokens - * @param bondToken The token used for bonds in the request - * @param bondSize The amount of `_bondToken` to bond to propose a response and dispute - * @param deadline The timestamp after which no responses can be proposed - * @param disputeWindow The time buffer required to finalize a request - */ - struct RequestParameters { - IAccountingExtension accountingExtension; - IERC20 bondToken; - uint256 bondSize; - uint256 deadline; - uint256 disputeWindow; - } +// /** +// * @notice Parameters of the request as stored in the module +// * @param accountingExtension The accounting extension used to bond and release tokens +// * @param bondToken The token used for bonds in the request +// * @param bondSize The amount of `_bondToken` to bond to propose a response and dispute +// * @param deadline The timestamp after which no responses can be proposed +// * @param disputeWindow The time buffer required to finalize a request +// */ +// struct RequestParameters { +// IAccountingExtension accountingExtension; +// IERC20 bondToken; +// uint256 bondSize; +// uint256 deadline; +// uint256 disputeWindow; +// } - /*/////////////////////////////////////////////////////////////// - LOGIC - //////////////////////////////////////////////////////////////*/ +// /*/////////////////////////////////////////////////////////////// +// LOGIC +// //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the decoded data for a request - * @param _requestId The ID of the request - * @return _params The struct containing the parameters for the request - */ - function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); +// /** +// * @notice Returns the decoded data for a request +// * @param _requestId The ID of the request +// * @return _params The struct containing the parameters for the request +// */ +// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); - /** - * @notice Proposes a response for a request, bonding the proposer's tokens - * @dev The user must have previously deposited tokens into the accounting extension - * @param _requestId The ID of the request to propose a response for - * @param _proposer The user proposing the response - * @param _responseData The data for the response - * @param _sender The address calling propose on the Oracle - * @return _response The struct of proposed response - */ - function propose( - bytes32 _requestId, - address _proposer, - bytes calldata _responseData, - address _sender - ) external returns (IOracle.Response memory _response); +// /** +// * @notice Proposes a response for a request, bonding the proposer's tokens +// * @dev The user must have previously deposited tokens into the accounting extension +// * @param _requestId The ID of the request to propose a response for +// * @param _proposer The user proposing the response +// * @param _responseData The data for the response +// * @param _sender The address calling propose on the Oracle +// * @return _response The struct of proposed response +// */ +// function propose( +// bytes32 _requestId, +// address _proposer, +// bytes calldata _responseData, +// address _sender +// ) external returns (IOracle.Response memory _response); - /** - * @notice Allows a user to delete an undisputed response they proposed before the deadline, releasing the bond - * @param _requestId The ID of the request to delete the response from - * @param _responseId The ID of the response to delete - * @param _proposer The user who proposed the response - */ - function deleteResponse(bytes32 _requestId, bytes32 _responseId, address _proposer) external; +// /** +// * @notice Allows a user to delete an undisputed response they proposed before the deadline, releasing the bond +// * @param _requestId The ID of the request to delete the response from +// * @param _responseId The ID of the response to delete +// * @param _proposer The user who proposed the response +// */ +// function deleteResponse(bytes32 _requestId, bytes32 _responseId, address _proposer) external; - /** - * @notice Finalizes the request by releasing the bond of the proposer - * @param _requestId The ID of the request to finalize - * @param _finalizer The user who triggered the finalization - */ - function finalizeRequest(bytes32 _requestId, address _finalizer) external; -} +// /** +// * @notice Finalizes the request by releasing the bond of the proposer +// * @param _requestId The ID of the request to finalize +// * @param _finalizer The user who triggered the finalization +// */ +// function finalizeRequest(bytes32 _requestId, address _finalizer) external; +// } diff --git a/solidity/scripts/Deploy.sol b/solidity/scripts/Deploy.sol index 15b23cfa..0610e161 100644 --- a/solidity/scripts/Deploy.sol +++ b/solidity/scripts/Deploy.sol @@ -1,135 +1,135 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {Script, console} from 'forge-std/Script.sol'; - -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IResolutionModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; - -import {ArbitratorModule} from '../contracts/modules/resolution/ArbitratorModule.sol'; -import {BondedDisputeModule} from '../contracts/modules/dispute/BondedDisputeModule.sol'; -import {BondedResponseModule} from '../contracts/modules/response/BondedResponseModule.sol'; -import {BondEscalationModule} from '../contracts/modules/dispute/BondEscalationModule.sol'; -import {CallbackModule} from '../contracts/modules/finality/CallbackModule.sol'; -import {HttpRequestModule} from '../contracts/modules/request/HttpRequestModule.sol'; -import {ContractCallRequestModule} from '../contracts/modules/request/ContractCallRequestModule.sol'; -import {ERC20ResolutionModule} from '../contracts/modules/resolution/ERC20ResolutionModule.sol'; -import {MultipleCallbacksModule} from '../contracts/modules/finality/MultipleCallbacksModule.sol'; -import {PrivateERC20ResolutionModule} from '../contracts/modules/resolution/PrivateERC20ResolutionModule.sol'; -import {BondEscalationResolutionModule} from '../contracts/modules/resolution/BondEscalationResolutionModule.sol'; -import {SequentialResolutionModule} from '../contracts/modules/resolution/SequentialResolutionModule.sol'; -import {RootVerificationModule} from '../contracts/modules/dispute/RootVerificationModule.sol'; -import {SparseMerkleTreeRequestModule} from '../contracts/modules/request/SparseMerkleTreeRequestModule.sol'; -import {CircuitResolverModule} from '../contracts/modules/dispute/CircuitResolverModule.sol'; - -import {AccountingExtension} from '../contracts/extensions/AccountingExtension.sol'; -import {BondEscalationAccounting} from '../contracts/extensions/BondEscalationAccounting.sol'; - -// solhint-disable no-console -contract Deploy is Script { - IOracle oracle = IOracle(0xe40DED509A3806Eed8065b478BB681953bD9B554); - - ArbitratorModule arbitratorModule; - BondedDisputeModule bondedDisputeModule; - BondedResponseModule bondedResponseModule; - BondEscalationModule bondEscalationModule; - CallbackModule callbackModule; - HttpRequestModule httpRequestModule; - ContractCallRequestModule contractCallRequestModule; - ERC20ResolutionModule erc20ResolutionModule; - MultipleCallbacksModule multipleCallbacksModule; - - PrivateERC20ResolutionModule privateErc20ResolutionModule; - BondEscalationResolutionModule bondEscalationResolutionModule; - SequentialResolutionModule sequentialResolutionModule; - RootVerificationModule rootVerificationModule; - SparseMerkleTreeRequestModule sparseMerkleTreeRequestModule; - CircuitResolverModule circuitResolverModule; - - AccountingExtension accountingExtension; - BondEscalationAccounting bondEscalationAccounting; - - IResolutionModule[] resolutionModules = new IResolutionModule[](3); - - function run() public { - address deployer = vm.rememberKey(vm.envUint('DEPLOYER_PRIVATE_KEY')); - - vm.startBroadcast(deployer); - - // Deploy oracle - console.log('ORACLE:', address(oracle)); - - // Deploy arbitrator module - arbitratorModule = new ArbitratorModule(oracle); - console.log('ARBITRATOR_MODULE:', address(arbitratorModule)); - - // Deploy bonded dispute module - bondedDisputeModule = new BondedDisputeModule(oracle); - console.log('BONDED_DISPUTE_MODULE:', address(bondedDisputeModule)); - - // Deploy bonded response module - bondedResponseModule = new BondedResponseModule(oracle); - console.log('BONDED_RESPONSE_MODULE:', address(bondedResponseModule)); - - // Deploy bond escalation module - bondEscalationModule = new BondEscalationModule(oracle); - console.log('BOND_ESCALATION_MODULE:', address(bondEscalationModule)); - - // Deploy callback module - callbackModule = new CallbackModule(oracle); - console.log('CALLBACK_MODULE:', address(callbackModule)); - - // Deploy http request module - httpRequestModule = new HttpRequestModule(oracle); - console.log('HTTP_REQUEST_MODULE:', address(httpRequestModule)); - - // Deploy contract call module - contractCallRequestModule = new ContractCallRequestModule(oracle); - console.log('CONTRACT_CALL_MODULE:', address(contractCallRequestModule)); - - // Deploy ERC20 resolution module - erc20ResolutionModule = new ERC20ResolutionModule(oracle); - console.log('ERC20_RESOLUTION_MODULE:', address(erc20ResolutionModule)); - resolutionModules.push(IResolutionModule(address(erc20ResolutionModule))); - - // Deploy private ERC20 resolution module - privateErc20ResolutionModule = new PrivateERC20ResolutionModule(oracle); - console.log('PRIVATE_ERC20_RESOLUTION_MODULE:', address(privateErc20ResolutionModule)); - resolutionModules.push(IResolutionModule(address(privateErc20ResolutionModule))); - - // Deploy bond escalation resolution module - bondEscalationResolutionModule = new BondEscalationResolutionModule(oracle); - console.log('BOND_ESCALATION_RESOLUTION_MODULE:', address(bondEscalationResolutionModule)); - resolutionModules.push(IResolutionModule(address(bondEscalationResolutionModule))); - - // Deploy multiple callbacks module - multipleCallbacksModule = new MultipleCallbacksModule(oracle); - console.log('MULTIPLE_CALLBACKS_MODULE:', address(multipleCallbacksModule)); - - // Deploy root verification module - rootVerificationModule = new RootVerificationModule(oracle); - console.log('ROOT_VERIFICATION_MODULE:', address(rootVerificationModule)); - - // Deploy root verification module - sparseMerkleTreeRequestModule = new SparseMerkleTreeRequestModule(oracle); - console.log('SPARSE_MERKLE_TREE_REQUEST_MODULE:', address(sparseMerkleTreeRequestModule)); - - // Deploy accounting extension - accountingExtension = new AccountingExtension(oracle); - console.log('ACCOUNTING_EXTENSION:', address(accountingExtension)); - - // Deploy bond escalation accounting - bondEscalationAccounting = new BondEscalationAccounting(oracle); - console.log('BOND_ESCALATION_ACCOUNTING_EXTENSION:', address(bondEscalationAccounting)); - - // Deploy multiple callbacks module - sequentialResolutionModule = new SequentialResolutionModule(oracle); - console.log('SEQUENTIAL_RESOLUTION_MODULE:', address(sequentialResolutionModule)); - sequentialResolutionModule.addResolutionModuleSequence(resolutionModules); - - // Deploy circuit resolver module - circuitResolverModule = new CircuitResolverModule(oracle); - console.log('CIRCUIT_RESOLVER_MODULE:', address(circuitResolverModule)); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import {Script, console} from 'forge-std/Script.sol'; + +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IResolutionModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; + +// import {ArbitratorModule} from '../contracts/modules/resolution/ArbitratorModule.sol'; +// import {BondedDisputeModule} from '../contracts/modules/dispute/BondedDisputeModule.sol'; +// import {BondedResponseModule} from '../contracts/modules/response/BondedResponseModule.sol'; +// import {BondEscalationModule} from '../contracts/modules/dispute/BondEscalationModule.sol'; +// import {CallbackModule} from '../contracts/modules/finality/CallbackModule.sol'; +// import {HttpRequestModule} from '../contracts/modules/request/HttpRequestModule.sol'; +// import {ContractCallRequestModule} from '../contracts/modules/request/ContractCallRequestModule.sol'; +// import {ERC20ResolutionModule} from '../contracts/modules/resolution/ERC20ResolutionModule.sol'; +// import {MultipleCallbacksModule} from '../contracts/modules/finality/MultipleCallbacksModule.sol'; +// import {PrivateERC20ResolutionModule} from '../contracts/modules/resolution/PrivateERC20ResolutionModule.sol'; +// import {BondEscalationResolutionModule} from '../contracts/modules/resolution/BondEscalationResolutionModule.sol'; +// import {SequentialResolutionModule} from '../contracts/modules/resolution/SequentialResolutionModule.sol'; +// import {RootVerificationModule} from '../contracts/modules/dispute/RootVerificationModule.sol'; +// import {SparseMerkleTreeRequestModule} from '../contracts/modules/request/SparseMerkleTreeRequestModule.sol'; +// import {CircuitResolverModule} from '../contracts/modules/dispute/CircuitResolverModule.sol'; + +// import {AccountingExtension} from '../contracts/extensions/AccountingExtension.sol'; +// import {BondEscalationAccounting} from '../contracts/extensions/BondEscalationAccounting.sol'; + +// // solhint-disable no-console +// contract Deploy is Script { +// IOracle oracle = IOracle(0xe40DED509A3806Eed8065b478BB681953bD9B554); + +// ArbitratorModule arbitratorModule; +// BondedDisputeModule bondedDisputeModule; +// BondedResponseModule bondedResponseModule; +// BondEscalationModule bondEscalationModule; +// CallbackModule callbackModule; +// HttpRequestModule httpRequestModule; +// ContractCallRequestModule contractCallRequestModule; +// ERC20ResolutionModule erc20ResolutionModule; +// MultipleCallbacksModule multipleCallbacksModule; + +// PrivateERC20ResolutionModule privateErc20ResolutionModule; +// BondEscalationResolutionModule bondEscalationResolutionModule; +// SequentialResolutionModule sequentialResolutionModule; +// RootVerificationModule rootVerificationModule; +// SparseMerkleTreeRequestModule sparseMerkleTreeRequestModule; +// CircuitResolverModule circuitResolverModule; + +// AccountingExtension accountingExtension; +// BondEscalationAccounting bondEscalationAccounting; + +// IResolutionModule[] resolutionModules = new IResolutionModule[](3); + +// function run() public { +// address deployer = vm.rememberKey(vm.envUint('DEPLOYER_PRIVATE_KEY')); + +// vm.startBroadcast(deployer); + +// // Deploy oracle +// console.log('ORACLE:', address(oracle)); + +// // Deploy arbitrator module +// arbitratorModule = new ArbitratorModule(oracle); +// console.log('ARBITRATOR_MODULE:', address(arbitratorModule)); + +// // Deploy bonded dispute module +// bondedDisputeModule = new BondedDisputeModule(oracle); +// console.log('BONDED_DISPUTE_MODULE:', address(bondedDisputeModule)); + +// // Deploy bonded response module +// bondedResponseModule = new BondedResponseModule(oracle); +// console.log('BONDED_RESPONSE_MODULE:', address(bondedResponseModule)); + +// // Deploy bond escalation module +// bondEscalationModule = new BondEscalationModule(oracle); +// console.log('BOND_ESCALATION_MODULE:', address(bondEscalationModule)); + +// // Deploy callback module +// callbackModule = new CallbackModule(oracle); +// console.log('CALLBACK_MODULE:', address(callbackModule)); + +// // Deploy http request module +// httpRequestModule = new HttpRequestModule(oracle); +// console.log('HTTP_REQUEST_MODULE:', address(httpRequestModule)); + +// // Deploy contract call module +// contractCallRequestModule = new ContractCallRequestModule(oracle); +// console.log('CONTRACT_CALL_MODULE:', address(contractCallRequestModule)); + +// // Deploy ERC20 resolution module +// erc20ResolutionModule = new ERC20ResolutionModule(oracle); +// console.log('ERC20_RESOLUTION_MODULE:', address(erc20ResolutionModule)); +// resolutionModules.push(IResolutionModule(address(erc20ResolutionModule))); + +// // Deploy private ERC20 resolution module +// privateErc20ResolutionModule = new PrivateERC20ResolutionModule(oracle); +// console.log('PRIVATE_ERC20_RESOLUTION_MODULE:', address(privateErc20ResolutionModule)); +// resolutionModules.push(IResolutionModule(address(privateErc20ResolutionModule))); + +// // Deploy bond escalation resolution module +// bondEscalationResolutionModule = new BondEscalationResolutionModule(oracle); +// console.log('BOND_ESCALATION_RESOLUTION_MODULE:', address(bondEscalationResolutionModule)); +// resolutionModules.push(IResolutionModule(address(bondEscalationResolutionModule))); + +// // Deploy multiple callbacks module +// multipleCallbacksModule = new MultipleCallbacksModule(oracle); +// console.log('MULTIPLE_CALLBACKS_MODULE:', address(multipleCallbacksModule)); + +// // Deploy root verification module +// rootVerificationModule = new RootVerificationModule(oracle); +// console.log('ROOT_VERIFICATION_MODULE:', address(rootVerificationModule)); + +// // Deploy root verification module +// sparseMerkleTreeRequestModule = new SparseMerkleTreeRequestModule(oracle); +// console.log('SPARSE_MERKLE_TREE_REQUEST_MODULE:', address(sparseMerkleTreeRequestModule)); + +// // Deploy accounting extension +// accountingExtension = new AccountingExtension(oracle); +// console.log('ACCOUNTING_EXTENSION:', address(accountingExtension)); + +// // Deploy bond escalation accounting +// bondEscalationAccounting = new BondEscalationAccounting(oracle); +// console.log('BOND_ESCALATION_ACCOUNTING_EXTENSION:', address(bondEscalationAccounting)); + +// // Deploy multiple callbacks module +// sequentialResolutionModule = new SequentialResolutionModule(oracle); +// console.log('SEQUENTIAL_RESOLUTION_MODULE:', address(sequentialResolutionModule)); +// sequentialResolutionModule.addResolutionModuleSequence(resolutionModules); + +// // Deploy circuit resolver module +// circuitResolverModule = new CircuitResolverModule(oracle); +// console.log('CIRCUIT_RESOLVER_MODULE:', address(circuitResolverModule)); +// } +// } diff --git a/solidity/test/integration/AccountingExtension.t.sol b/solidity/test/integration/AccountingExtension.t.sol index db7f35a8..60b8b7cb 100644 --- a/solidity/test/integration/AccountingExtension.t.sol +++ b/solidity/test/integration/AccountingExtension.t.sol @@ -1,121 +1,121 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import './IntegrationBase.sol'; - -contract Integration_AccountingExtension is IntegrationBase { - address public user = makeAddr('user'); - - function test_depositERC20(uint256 _initialBalance, uint256 _depositAmount) public { - vm.assume(_initialBalance >= _depositAmount); - _forBondDepositERC20(_accountingExtension, user, usdc, _depositAmount, _initialBalance); - // Check: is virtual balance updated? - assertEq(_depositAmount, _accountingExtension.balanceOf(user, usdc)); - // Check: is token contract balance updated? - assertEq(_initialBalance - _depositAmount, usdc.balanceOf(user)); - } - - function test_withdrawERC20(uint256 _initialBalance, uint256 _depositAmount, uint256 _withdrawAmount) public { - vm.assume(_withdrawAmount <= _depositAmount); - // Deposit some USDC - _forBondDepositERC20(_accountingExtension, user, usdc, _depositAmount, _initialBalance); - - vm.prank(user); - _accountingExtension.withdraw(usdc, _withdrawAmount); - - // Check: is virtual balance updated? - assertEq(_depositAmount - _withdrawAmount, _accountingExtension.balanceOf(user, usdc)); - // Check: is token contract balance updated? - assertEq(_initialBalance - _depositAmount + _withdrawAmount, usdc.balanceOf(user)); - } - - function test_depositERC20_invalidAmount(uint256 _initialBalance, uint256 _invalidDepositAmount) public { - vm.assume(_invalidDepositAmount > _initialBalance); - deal(address(usdc), user, _initialBalance); - - vm.startPrank(user); - usdc.approve(address(_accountingExtension), _invalidDepositAmount); - - // Check: does it revert if trying to deposit an amount greater than balance? - vm.expectRevert(bytes('ERC20: transfer amount exceeds balance')); - - _accountingExtension.deposit(usdc, _invalidDepositAmount); - vm.stopPrank(); - } - - function test_withdrawERC20_insufficientFunds( - uint256 _initialBalance, - uint256 _depositAmount, - uint256 _withdrawAmount - ) public { - vm.assume(_withdrawAmount > _depositAmount); - _forBondDepositERC20(_accountingExtension, user, usdc, _depositAmount, _initialBalance); - - // Check: does it revert if trying to withdraw an amount greater than virtual balance? - vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); - vm.prank(user); - _accountingExtension.withdraw(usdc, _withdrawAmount); - } - - function test_withdrawETH_insufficientFunds( - uint256 _initialBalance, - uint256 _depositAmount, - uint256 _withdrawAmount - ) public { - vm.assume(_withdrawAmount > _depositAmount); - _forBondDepositERC20(_accountingExtension, user, IERC20(address(weth)), _depositAmount, _initialBalance); - - // Check: does it revert if trying to withdraw an amount greater than virtual balance? - vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); - vm.prank(user); - _accountingExtension.withdraw(weth, _withdrawAmount); - } - - function test_withdrawBondedFunds(uint256 _initialBalance, uint256 _bondAmount) public { - vm.assume(_bondAmount > 0); - _forBondDepositERC20(_accountingExtension, user, usdc, _bondAmount, _initialBalance); - - HttpRequestModule _requestModule = new HttpRequestModule(oracle); - BondedResponseModule _responseModule = new BondedResponseModule(oracle); - BondedDisputeModule _bondedDisputeModule = new BondedDisputeModule(oracle); - - IOracle.NewRequest memory _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - IHttpRequestModule.RequestParameters({ - url: '', - method: IHttpRequestModule.HttpMethod.GET, - body: '', - accountingExtension: _accountingExtension, - paymentToken: usdc, - paymentAmount: _bondAmount - }) - ), - responseModuleData: abi.encode( - IBondedResponseModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: usdc, - bondSize: _bondAmount, - deadline: block.timestamp + BLOCK_TIME * 600, - disputeWindow: _baseDisputeWindow - }) - ), - disputeModuleData: abi.encode(), - resolutionModuleData: abi.encode(), - finalityModuleData: abi.encode(), - requestModule: _requestModule, - responseModule: _responseModule, - disputeModule: _bondedDisputeModule, - resolutionModule: IResolutionModule(address(0)), - finalityModule: IFinalityModule(address(0)), - ipfsHash: _ipfsHash - }); - - vm.startPrank(user); - _accountingExtension.approveModule(address(_requestModule)); - oracle.createRequest(_request); - // Check: does it revert if trying to withdraw an amount that is bonded to a request? - vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); - _accountingExtension.withdraw(usdc, _bondAmount); - vm.stopPrank(); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import './IntegrationBase.sol'; + +// contract Integration_AccountingExtension is IntegrationBase { +// address public user = makeAddr('user'); + +// function test_depositERC20(uint256 _initialBalance, uint256 _depositAmount) public { +// vm.assume(_initialBalance >= _depositAmount); +// _forBondDepositERC20(_accountingExtension, user, usdc, _depositAmount, _initialBalance); +// // Check: is virtual balance updated? +// assertEq(_depositAmount, _accountingExtension.balanceOf(user, usdc)); +// // Check: is token contract balance updated? +// assertEq(_initialBalance - _depositAmount, usdc.balanceOf(user)); +// } + +// function test_withdrawERC20(uint256 _initialBalance, uint256 _depositAmount, uint256 _withdrawAmount) public { +// vm.assume(_withdrawAmount <= _depositAmount); +// // Deposit some USDC +// _forBondDepositERC20(_accountingExtension, user, usdc, _depositAmount, _initialBalance); + +// vm.prank(user); +// _accountingExtension.withdraw(usdc, _withdrawAmount); + +// // Check: is virtual balance updated? +// assertEq(_depositAmount - _withdrawAmount, _accountingExtension.balanceOf(user, usdc)); +// // Check: is token contract balance updated? +// assertEq(_initialBalance - _depositAmount + _withdrawAmount, usdc.balanceOf(user)); +// } + +// function test_depositERC20_invalidAmount(uint256 _initialBalance, uint256 _invalidDepositAmount) public { +// vm.assume(_invalidDepositAmount > _initialBalance); +// deal(address(usdc), user, _initialBalance); + +// vm.startPrank(user); +// usdc.approve(address(_accountingExtension), _invalidDepositAmount); + +// // Check: does it revert if trying to deposit an amount greater than balance? +// vm.expectRevert(bytes('ERC20: transfer amount exceeds balance')); + +// _accountingExtension.deposit(usdc, _invalidDepositAmount); +// vm.stopPrank(); +// } + +// function test_withdrawERC20_insufficientFunds( +// uint256 _initialBalance, +// uint256 _depositAmount, +// uint256 _withdrawAmount +// ) public { +// vm.assume(_withdrawAmount > _depositAmount); +// _forBondDepositERC20(_accountingExtension, user, usdc, _depositAmount, _initialBalance); + +// // Check: does it revert if trying to withdraw an amount greater than virtual balance? +// vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); +// vm.prank(user); +// _accountingExtension.withdraw(usdc, _withdrawAmount); +// } + +// function test_withdrawETH_insufficientFunds( +// uint256 _initialBalance, +// uint256 _depositAmount, +// uint256 _withdrawAmount +// ) public { +// vm.assume(_withdrawAmount > _depositAmount); +// _forBondDepositERC20(_accountingExtension, user, IERC20(address(weth)), _depositAmount, _initialBalance); + +// // Check: does it revert if trying to withdraw an amount greater than virtual balance? +// vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); +// vm.prank(user); +// _accountingExtension.withdraw(weth, _withdrawAmount); +// } + +// function test_withdrawBondedFunds(uint256 _initialBalance, uint256 _bondAmount) public { +// vm.assume(_bondAmount > 0); +// _forBondDepositERC20(_accountingExtension, user, usdc, _bondAmount, _initialBalance); + +// HttpRequestModule _requestModule = new HttpRequestModule(oracle); +// BondedResponseModule _responseModule = new BondedResponseModule(oracle); +// BondedDisputeModule _bondedDisputeModule = new BondedDisputeModule(oracle); + +// IOracle.NewRequest memory _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: '', +// method: IHttpRequestModule.HttpMethod.GET, +// body: '', +// accountingExtension: _accountingExtension, +// paymentToken: usdc, +// paymentAmount: _bondAmount +// }) +// ), +// responseModuleData: abi.encode( +// IBondedResponseModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: usdc, +// bondSize: _bondAmount, +// deadline: block.timestamp + BLOCK_TIME * 600, +// disputeWindow: _baseDisputeWindow +// }) +// ), +// disputeModuleData: abi.encode(), +// resolutionModuleData: abi.encode(), +// finalityModuleData: abi.encode(), +// requestModule: _requestModule, +// responseModule: _responseModule, +// disputeModule: _bondedDisputeModule, +// resolutionModule: IResolutionModule(address(0)), +// finalityModule: IFinalityModule(address(0)), +// ipfsHash: _ipfsHash +// }); + +// vm.startPrank(user); +// _accountingExtension.approveModule(address(_requestModule)); +// oracle.createRequest(_request); +// // Check: does it revert if trying to withdraw an amount that is bonded to a request? +// vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); +// _accountingExtension.withdraw(usdc, _bondAmount); +// vm.stopPrank(); +// } +// } diff --git a/solidity/test/integration/Arbitration.t.sol b/solidity/test/integration/Arbitration.t.sol index 19b4d949..a72f3b86 100644 --- a/solidity/test/integration/Arbitration.t.sol +++ b/solidity/test/integration/Arbitration.t.sol @@ -1,212 +1,212 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import './IntegrationBase.sol'; -import {IArbitrator} from '../../interfaces/IArbitrator.sol'; -import {MockAtomicArbitrator} from '../mocks/MockAtomicArbitrator.sol'; +// import './IntegrationBase.sol'; +// import {IArbitrator} from '../../interfaces/IArbitrator.sol'; +// import {MockAtomicArbitrator} from '../mocks/MockAtomicArbitrator.sol'; -contract Integration_Arbitration is IntegrationBase { - MockAtomicArbitrator internal _mockAtomicArbitrator; +// contract Integration_Arbitration is IntegrationBase { +// MockAtomicArbitrator internal _mockAtomicArbitrator; - function setUp() public override { - super.setUp(); +// function setUp() public override { +// super.setUp(); - vm.prank(governance); - _mockAtomicArbitrator = new MockAtomicArbitrator(oracle); +// vm.prank(governance); +// _mockAtomicArbitrator = new MockAtomicArbitrator(oracle); - _expectedDeadline = block.timestamp + BLOCK_TIME * 600; +// _expectedDeadline = block.timestamp + BLOCK_TIME * 600; - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - _forBondDepositERC20(_accountingExtension, disputer, usdc, _expectedBondSize, _expectedBondSize); - } +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); +// _forBondDepositERC20(_accountingExtension, disputer, usdc, _expectedBondSize, _expectedBondSize); +// } - function test_resolveCorrectDispute_twoStep() public { - (bytes32 _requestId,, bytes32 _disputeId) = _setupDispute(address(_mockArbitrator)); - // Check: is the dispute status unknown before starting the resolution? - assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Unknown)); +// function test_resolveCorrectDispute_twoStep() public { +// (bytes32 _requestId,, bytes32 _disputeId) = _setupDispute(address(_mockArbitrator)); +// // Check: is the dispute status unknown before starting the resolution? +// assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Unknown)); - // First step: escalating the dispute - vm.prank(disputer); - oracle.escalateDispute(_disputeId); +// // First step: escalating the dispute +// vm.prank(disputer); +// oracle.escalateDispute(_disputeId); - // Check: is the dispute status active after starting the resolution? - assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Active)); +// // Check: is the dispute status active after starting the resolution? +// assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Active)); - // Second step: resolving the dispute - vm.prank(disputer); - oracle.resolveDispute(_disputeId); +// // Second step: resolving the dispute +// vm.prank(disputer); +// oracle.resolveDispute(_disputeId); - // Check: is the dispute status resolved after calling resolve? - assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); +// // Check: is the dispute status resolved after calling resolve? +// assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - // Check: is the dispute updated as won? - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won)); +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// // Check: is the dispute updated as won? +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won)); - // Check: does the disputer receive the proposer's bond? - uint256 _disputerBalance = _accountingExtension.balanceOf(disputer, usdc); - assertEq(_disputerBalance, _expectedBondSize * 2); +// // Check: does the disputer receive the proposer's bond? +// uint256 _disputerBalance = _accountingExtension.balanceOf(disputer, usdc); +// assertEq(_disputerBalance, _expectedBondSize * 2); - // Check: does the proposer get its bond slashed? - uint256 _proposerBondedAmount = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); - assertEq(_proposerBondedAmount, 0); - } +// // Check: does the proposer get its bond slashed? +// uint256 _proposerBondedAmount = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); +// assertEq(_proposerBondedAmount, 0); +// } - function test_resolveCorrectDispute_atomically() public { - (bytes32 _requestId,, bytes32 _disputeId) = _setupDispute(address(_mockAtomicArbitrator)); +// function test_resolveCorrectDispute_atomically() public { +// (bytes32 _requestId,, bytes32 _disputeId) = _setupDispute(address(_mockAtomicArbitrator)); - // Check: is the dispute status unknown before starting the resolution? - assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Unknown)); - - // First step: escalating the dispute - vm.prank(disputer); - oracle.escalateDispute(_disputeId); - - // Check: is the dispute status resolved after calling resolve? - assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); - - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - // Check: is the dispute updated as won? - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won)); - - // Check: does the disputer receive the proposer's bond? - uint256 _disputerBalance = _accountingExtension.balanceOf(disputer, usdc); - assertEq(_disputerBalance, _expectedBondSize * 2); - - // Check: does the proposer get its bond slashed? - uint256 _proposerBondedAmount = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); - assertEq(_proposerBondedAmount, 0); - } - - function test_resolveIncorrectDispute_twoStep() public { - (bytes32 _requestId,, bytes32 _disputeId) = _setupDispute(address(_mockArbitrator)); - // Check: is the dispute status unknown before starting the resolution? - assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Unknown)); - - // First step: escalating the dispute - vm.prank(disputer); - oracle.escalateDispute(_disputeId); - - // Check: is the dispute status active after starting the resolution? - assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Active)); - - // Mocking the answer to return false ==> dispute lost - vm.mockCall( - address(_mockArbitrator), - abi.encodeCall(IArbitrator.getAnswer, (_disputeId)), - abi.encode(IOracle.DisputeStatus.Lost) - ); - - // Second step: resolving the dispute - vm.prank(disputer); - oracle.resolveDispute(_disputeId); - - // Check: is the dispute status resolved after calling resolve? - assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); - - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - // Check: is the dispute updated as lost? - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Lost)); - - // Check: does the disputer receive the disputer's bond? - uint256 _proposerBalance = _accountingExtension.balanceOf(proposer, usdc); - assertEq(_proposerBalance, _expectedBondSize * 2); - - // Check: does the disputer get its bond slashed? - uint256 _disputerBondedAmount = _accountingExtension.bondedAmountOf(disputer, usdc, _requestId); - assertEq(_disputerBondedAmount, 0); - } - - function test_resolveIncorrectDispute_atomically() public { - (bytes32 _requestId,, bytes32 _disputeId) = _setupDispute(address(_mockAtomicArbitrator)); - - // Check: is the dispute status unknown before starting the resolution? - assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Unknown)); - - // Mocking the answer to return false ==> dispute lost - vm.mockCall( - address(_mockAtomicArbitrator), - abi.encodeCall(IArbitrator.getAnswer, (_disputeId)), - abi.encode(IOracle.DisputeStatus.Lost) - ); - - // First step: escalating and resolving the dispute - vm.prank(disputer); - oracle.escalateDispute(_disputeId); - - // Check: is the dispute status resolved after calling escalate? - assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); - - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - // Check: is the dispute updated as lost? - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Lost)); - - // Check: does the disputer receive the disputer's bond? - uint256 _proposerBalance = _accountingExtension.balanceOf(proposer, usdc); - assertEq(_proposerBalance, _expectedBondSize * 2); - - // Check: does the disputer get its bond slashed? - uint256 _disputerBondedAmount = _accountingExtension.bondedAmountOf(disputer, usdc, _requestId); - assertEq(_disputerBondedAmount, 0); - } - - function _setupDispute(address _arbitrator) - internal - returns (bytes32 _requestId, bytes32 _responseId, bytes32 _disputeId) - { - IOracle.NewRequest memory _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accountingExtension, - paymentToken: IERC20(USDC_ADDRESS), - paymentAmount: _expectedReward - }) - ), - responseModuleData: abi.encode( - IBondedResponseModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize, - deadline: _expectedDeadline, - disputeWindow: _baseDisputeWindow - }) - ), - disputeModuleData: abi.encode( - IBondedDisputeModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize - }) - ), - resolutionModuleData: abi.encode(_arbitrator), - finalityModuleData: abi.encode( - ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) - ), - requestModule: _requestModule, - responseModule: _responseModule, - disputeModule: _bondedDisputeModule, - resolutionModule: _arbitratorModule, - finalityModule: IFinalityModule(_callbackModule), - ipfsHash: _ipfsHash - }); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, abi.encode('response')); - vm.stopPrank(); - - vm.startPrank(disputer); - _accountingExtension.approveModule(address(_bondedDisputeModule)); - _disputeId = oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - } -} +// // Check: is the dispute status unknown before starting the resolution? +// assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Unknown)); + +// // First step: escalating the dispute +// vm.prank(disputer); +// oracle.escalateDispute(_disputeId); + +// // Check: is the dispute status resolved after calling resolve? +// assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); + +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// // Check: is the dispute updated as won? +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won)); + +// // Check: does the disputer receive the proposer's bond? +// uint256 _disputerBalance = _accountingExtension.balanceOf(disputer, usdc); +// assertEq(_disputerBalance, _expectedBondSize * 2); + +// // Check: does the proposer get its bond slashed? +// uint256 _proposerBondedAmount = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); +// assertEq(_proposerBondedAmount, 0); +// } + +// function test_resolveIncorrectDispute_twoStep() public { +// (bytes32 _requestId,, bytes32 _disputeId) = _setupDispute(address(_mockArbitrator)); +// // Check: is the dispute status unknown before starting the resolution? +// assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Unknown)); + +// // First step: escalating the dispute +// vm.prank(disputer); +// oracle.escalateDispute(_disputeId); + +// // Check: is the dispute status active after starting the resolution? +// assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Active)); + +// // Mocking the answer to return false ==> dispute lost +// vm.mockCall( +// address(_mockArbitrator), +// abi.encodeCall(IArbitrator.getAnswer, (_disputeId)), +// abi.encode(IOracle.DisputeStatus.Lost) +// ); + +// // Second step: resolving the dispute +// vm.prank(disputer); +// oracle.resolveDispute(_disputeId); + +// // Check: is the dispute status resolved after calling resolve? +// assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); + +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// // Check: is the dispute updated as lost? +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Lost)); + +// // Check: does the disputer receive the disputer's bond? +// uint256 _proposerBalance = _accountingExtension.balanceOf(proposer, usdc); +// assertEq(_proposerBalance, _expectedBondSize * 2); + +// // Check: does the disputer get its bond slashed? +// uint256 _disputerBondedAmount = _accountingExtension.bondedAmountOf(disputer, usdc, _requestId); +// assertEq(_disputerBondedAmount, 0); +// } + +// function test_resolveIncorrectDispute_atomically() public { +// (bytes32 _requestId,, bytes32 _disputeId) = _setupDispute(address(_mockAtomicArbitrator)); + +// // Check: is the dispute status unknown before starting the resolution? +// assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Unknown)); + +// // Mocking the answer to return false ==> dispute lost +// vm.mockCall( +// address(_mockAtomicArbitrator), +// abi.encodeCall(IArbitrator.getAnswer, (_disputeId)), +// abi.encode(IOracle.DisputeStatus.Lost) +// ); + +// // First step: escalating and resolving the dispute +// vm.prank(disputer); +// oracle.escalateDispute(_disputeId); + +// // Check: is the dispute status resolved after calling escalate? +// assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); + +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// // Check: is the dispute updated as lost? +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Lost)); + +// // Check: does the disputer receive the disputer's bond? +// uint256 _proposerBalance = _accountingExtension.balanceOf(proposer, usdc); +// assertEq(_proposerBalance, _expectedBondSize * 2); + +// // Check: does the disputer get its bond slashed? +// uint256 _disputerBondedAmount = _accountingExtension.bondedAmountOf(disputer, usdc, _requestId); +// assertEq(_disputerBondedAmount, 0); +// } + +// function _setupDispute(address _arbitrator) +// internal +// returns (bytes32 _requestId, bytes32 _responseId, bytes32 _disputeId) +// { +// IOracle.NewRequest memory _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accountingExtension, +// paymentToken: IERC20(USDC_ADDRESS), +// paymentAmount: _expectedReward +// }) +// ), +// responseModuleData: abi.encode( +// IBondedResponseModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize, +// deadline: _expectedDeadline, +// disputeWindow: _baseDisputeWindow +// }) +// ), +// disputeModuleData: abi.encode( +// IBondedDisputeModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize +// }) +// ), +// resolutionModuleData: abi.encode(_arbitrator), +// finalityModuleData: abi.encode( +// ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) +// ), +// requestModule: _requestModule, +// responseModule: _responseModule, +// disputeModule: _bondedDisputeModule, +// resolutionModule: _arbitratorModule, +// finalityModule: IFinalityModule(_callbackModule), +// ipfsHash: _ipfsHash +// }); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, abi.encode('response')); +// vm.stopPrank(); + +// vm.startPrank(disputer); +// _accountingExtension.approveModule(address(_bondedDisputeModule)); +// _disputeId = oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); +// } +// } diff --git a/solidity/test/integration/BondEscalation.t.sol b/solidity/test/integration/BondEscalation.t.sol index cb3cb8e8..a34492c0 100644 --- a/solidity/test/integration/BondEscalation.t.sol +++ b/solidity/test/integration/BondEscalation.t.sol @@ -1,459 +1,459 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import './IntegrationBase.sol'; - -contract Integration_BondEscalation is IntegrationBase { - bytes internal _responseData = abi.encode('response'); - bytes32 internal _requestId; - bytes32 internal _responseId; - bytes32 internal _disputeId; - uint256 internal _bondEscalationDeadline; - uint256 internal _tyingBuffer = 1 days; - uint256 internal _disputeWindow = 3 days; - // TODO: There is a bug in the accounting, try with pledge size = 1 ether - // uint256 internal _pledgeSize = 5 ether; - uint256 internal _pledgeSize = _expectedBondSize; - - function setUp() public override { - super.setUp(); - _expectedDeadline = block.timestamp + 10 days; - _bondEscalationDeadline = block.timestamp + 5 days; - - IOracle.NewRequest memory _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _bondEscalationAccounting, - paymentToken: usdc, - paymentAmount: _expectedReward - }) - ), - responseModuleData: abi.encode( - IBondedResponseModule.RequestParameters({ - accountingExtension: _bondEscalationAccounting, - bondToken: usdc, - bondSize: _expectedBondSize, - deadline: _expectedDeadline, - disputeWindow: _baseDisputeWindow - }) - ), - disputeModuleData: abi.encode( - IBondEscalationModule.RequestParameters({ - accountingExtension: _bondEscalationAccounting, - bondToken: usdc, - bondSize: _pledgeSize, - maxNumberOfEscalations: 10, - bondEscalationDeadline: _bondEscalationDeadline, - tyingBuffer: _tyingBuffer, - disputeWindow: _disputeWindow - }) - ), - resolutionModuleData: abi.encode(_mockArbitrator), - finalityModuleData: abi.encode( - ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) - ), - requestModule: _requestModule, - responseModule: _responseModule, - disputeModule: _bondEscalationModule, - resolutionModule: _arbitratorModule, - finalityModule: IFinalityModule(_callbackModule), - ipfsHash: _ipfsHash - }); - - // Requester creates a request - _forBondDepositERC20(_bondEscalationAccounting, requester, usdc, _expectedReward, _expectedReward); - vm.startPrank(requester); - _bondEscalationAccounting.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - // Proposer proposes a response - _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(proposer); - _bondEscalationAccounting.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, _responseData); - vm.stopPrank(); - - // Disputer disputes the response - _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(disputer); - _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); - _disputeId = oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - } - - function test_proposerWins() public { - // Step 1: Proposer pledges against the dispute - _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(proposer); - _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); - _bondEscalationModule.pledgeAgainstDispute(_disputeId); - vm.stopPrank(); - - // Step 2: Disputer doubles down - _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(disputer); - _bondEscalationModule.pledgeForDispute(_disputeId); - vm.stopPrank(); - - // Step 3: Proposer doubles down - _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(proposer); - _bondEscalationModule.pledgeAgainstDispute(_disputeId); - vm.stopPrank(); - - // Step 4: Disputer runs out of capital - // Step 5: External parties see that Disputer's dispute was wrong so they don't join to escalate - // Step 6: Proposer response's is deemed correct and final once the bond escalation window is over - vm.warp(_expectedDeadline + _tyingBuffer + 1); - _bondEscalationModule.settleBondEscalation(_requestId); - - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Lost), 'Mismatch: Dispute status'); - - // Step 7: Participants claim the rewards - // Test: The requester has not participated in pledging, claiming shouldn't change his balance - _bondEscalationAccounting.claimEscalationReward(_disputeId, requester); - assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); - - // Test: The proposer receives 2x pledging amount + disputer's bond + disputer's pledge - _bondEscalationAccounting.claimEscalationReward(_disputeId, proposer); - assertEq( - _bondEscalationAccounting.balanceOf(proposer, usdc), - _pledgeSize * 3 + _expectedBondSize, - 'Mismatch: Proposer balance' - ); - - // Test: The disputer has lost his pledge - _bondEscalationAccounting.claimEscalationReward(_disputeId, disputer); - assertEq(_bondEscalationAccounting.balanceOf(disputer, usdc), 0, 'Mismatch: Disputer balance'); - - // Step 8: Finalize request and check balances again - oracle.finalize(_requestId, _responseId); - - // Test: The requester has no balance because he has paid the proposer - assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); - - // Test: The proposer receives the requester's reward for proposing a correct response and his bond back - assertEq( - _bondEscalationAccounting.balanceOf(proposer, usdc), - _pledgeSize * 3 + _expectedBondSize * 2 + _expectedReward, - 'Mismatch: Proposer balance' - ); - - // Test: The disputer's balance has not changed - assertEq(_bondEscalationAccounting.balanceOf(disputer, usdc), 0, 'Mismatch: Disputer balance'); - } - - function test_proposerLoses() public { - // Step 1: Proposer pledges against the dispute - _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(proposer); - _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); - _bondEscalationModule.pledgeAgainstDispute(_disputeId); - vm.stopPrank(); - - // Step 2: Disputer doubles down - _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(disputer); - _bondEscalationModule.pledgeForDispute(_disputeId); - vm.stopPrank(); - - // Step 3: Another party joins the dispute - address _secondDisputer = makeAddr('secondDisputer'); - _forBondDepositERC20(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(_secondDisputer); - _bondEscalationModule.pledgeForDispute(_disputeId); - vm.stopPrank(); - - // Step 4: Proposer runs out of capital and doesn't pledge anymore - // External parties see that Proposer's proposal was wrong so they don't join to escalate - - // Step 5: Proposer response's is deemed incorrect. The bond escalation process along with the tying buffer is terminated - vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); - _bondEscalationModule.settleBondEscalation(_requestId); - - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won), 'Mismatch: Dispute status'); - - // Step 6: Participants claim the rewards - // Test: The requester has not participated in pledging, claiming shouldn't change his balance - _bondEscalationAccounting.claimEscalationReward(_disputeId, requester); - assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); - - // Test: The proposer has lost his pledge - _bondEscalationAccounting.claimEscalationReward(_disputeId, proposer); - assertEq(_bondEscalationAccounting.balanceOf(proposer, usdc), 0, 'Mismatch: Proposer balance'); - - // Test: The disputer has received his pledge and bond back, a half of the proposer's pledge and the proposer's bond - _bondEscalationAccounting.claimEscalationReward(_disputeId, disputer); - assertEq( - _bondEscalationAccounting.balanceOf(disputer, usdc), - _pledgeSize + _pledgeSize / 2 + _expectedBondSize * 2, - 'Mismatch: Disputer balance' - ); - - // Test: The second disputer has received his pledge back and a half of the proposer's pledge - _bondEscalationAccounting.claimEscalationReward(_disputeId, _secondDisputer); - assertEq( - _bondEscalationAccounting.balanceOf(_secondDisputer, usdc), - _pledgeSize + _pledgeSize / 2, - 'Mismatch: Second Disputer balance' - ); - - // Step 7: Other parties can now propose different answers. Another proposer proposes a new answer - address _anotherProposer = makeAddr('anotherProposer'); - _forBondDepositERC20(_bondEscalationAccounting, _anotherProposer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(_anotherProposer); - _bondEscalationAccounting.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, abi.encode('anotherResponse')); - vm.stopPrank(); - - // Step 8: Disputer disputes Another proposer's answer - // _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(disputer); - _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); - _disputeId = oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - - // Step 9: Shouldn't be able to pledge for or against the dispute due to the bond escalation deadline being over - _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _pledgeSize, _pledgeSize); - vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); - vm.startPrank(disputer); - _bondEscalationModule.pledgeForDispute(_disputeId); - vm.stopPrank(); - - // Step 10: The dispute goes to the resolution module - oracle.escalateDispute(_disputeId); - _dispute = oracle.getDispute(_disputeId); - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Escalated), 'Mismatch: Dispute status'); - - // Step 11: Because Another proposer's answer is disputed, a third party can propose a new answer - address _thirdProposer = makeAddr('thirdProposer'); - _forBondDepositERC20(_bondEscalationAccounting, _thirdProposer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(_thirdProposer); - _bondEscalationAccounting.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, abi.encode('thirdResponse')); - vm.stopPrank(); - - // Step 12: It goes undisputed for three days, therefore it's deemed correct and final - vm.warp(_expectedDeadline + 1); - oracle.finalize(_requestId, _responseId); - - // Test: The requester has paid out the reward - assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); - - // Test: The first proposer has received nothing - assertEq(_bondEscalationAccounting.balanceOf(proposer, usdc), 0, 'Mismatch: Proposer balance'); - - // Test: The second proposer has received nothing - assertEq(_bondEscalationAccounting.balanceOf(_anotherProposer, usdc), 0, 'Mismatch: Another Proposer balance'); - - // Test: The third proposer has received the reward and this bond - assertEq( - _bondEscalationAccounting.balanceOf(_thirdProposer, usdc), - _expectedReward + _expectedBondSize, - 'Mismatch: Third Proposer balance' - ); - - // Test: The disputer has received his pledge and bond back, a half of the proposer's pledge and the proposer's bond - assertEq( - _bondEscalationAccounting.balanceOf(disputer, usdc), - _pledgeSize + _pledgeSize / 2 + _expectedBondSize * 2, - 'Mismatch: Disputer balance' - ); - - // Test: The second disputer has not participated in a new dispute, his balance is the same - assertEq( - _bondEscalationAccounting.balanceOf(_secondDisputer, usdc), - _pledgeSize + _pledgeSize / 2, - 'Mismatch: Second Disputer balance' - ); - - // Step 13: Two days after the deadline, the resolution module says that Another proposer's answer was correct - // So Another proposer gets paid Disputer's bond - vm.warp(_expectedDeadline + 2 days); - _mockArbitrator.setAnswer(IOracle.DisputeStatus.Lost); - oracle.resolveDispute(_disputeId); - - // Test: The requester still has nothing - assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); - - // Test: The first proposer still has nothing - assertEq(_bondEscalationAccounting.balanceOf(proposer, usdc), 0, 'Mismatch: Proposer balance'); - - // Test: The second proposer has received the Disputer's bond - assertEq( - _bondEscalationAccounting.balanceOf(_anotherProposer, usdc), - _expectedBondSize, - 'Mismatch: Another Proposer balance' - ); - - // Test: The third proposer has not done anything - assertEq( - _bondEscalationAccounting.balanceOf(_thirdProposer, usdc), - _expectedReward + _expectedBondSize, - 'Mismatch: Third Proposer balance' - ); - - // Test: The disputer has lost a bond - assertEq( - _bondEscalationAccounting.balanceOf(disputer, usdc), - _pledgeSize + _pledgeSize / 2 + _expectedBondSize * 2, - 'Mismatch: Disputer balance' - ); - - // Test: The second disputer has not has not done anything - assertEq( - _bondEscalationAccounting.balanceOf(_secondDisputer, usdc), - _pledgeSize + _pledgeSize / 2, - 'Mismatch: Second Disputer balance' - ); - } - - function test_bondEscalationTied() public { - // Step 1: Proposer pledges against the dispute - _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(proposer); - _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); - _bondEscalationModule.pledgeAgainstDispute(_disputeId); - vm.stopPrank(); - - // Step 2: Disputer doubles down - _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(disputer); - _bondEscalationModule.pledgeForDispute(_disputeId); - vm.stopPrank(); - - // Step 3: Proposer doubles down - _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(proposer); - _bondEscalationModule.pledgeAgainstDispute(_disputeId); - vm.stopPrank(); - - // Step 4: Disputer runs out of capital - // Step 5: The tying buffer kicks in - vm.warp(_bondEscalationDeadline + 1); - - // Step 6: An external party sees that Proposer's response is incorrect, so they bond the required WETH - address _secondDisputer = makeAddr('secondDisputer'); - _forBondDepositERC20(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(_secondDisputer); - _bondEscalationModule.pledgeForDispute(_disputeId); - vm.stopPrank(); - - // Step 7: They go into the dispute resolution module - oracle.escalateDispute(_disputeId); - - // Step 8: At this point, new answers can be proposed - address _secondProposer = makeAddr('secondProposer'); - _forBondDepositERC20(_bondEscalationAccounting, _secondProposer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(_secondProposer); - _bondEscalationAccounting.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, _responseData); - vm.stopPrank(); - - // Step 9: After some time, the resolution module deems Disputer's dispute as correct - _mineBlocks(100); - oracle.resolveDispute(_disputeId); - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won), 'Mismatch: Dispute status'); - - // Step 10: Participants claim their rewards - // Test: The requester has paid out the reward and is left with no balance - _bondEscalationAccounting.claimEscalationReward(_disputeId, requester); - assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); - - // Test: The proposer has lost his pledge and bond - _bondEscalationAccounting.claimEscalationReward(_disputeId, proposer); - assertEq(_bondEscalationAccounting.balanceOf(proposer, usdc), 0, 'Mismatch: Proposer balance'); - - // Test: The second proposer hasn't received the reward yet - _bondEscalationAccounting.claimEscalationReward(_disputeId, _secondProposer); - assertEq(_bondEscalationAccounting.balanceOf(_secondProposer, usdc), 0, 'Mismatch: Second Proposer balance'); - assertEq( - _bondEscalationAccounting.bondedAmountOf(_secondProposer, usdc, _requestId), - _expectedBondSize, - 'Mismatch: Second Proposer bonded balance' - ); - - // Test: The Disputer has received his pledge and bond, the proposer's pledge and the proposer's bond - _bondEscalationAccounting.claimEscalationReward(_disputeId, disputer); - assertEq( - _bondEscalationAccounting.balanceOf(disputer, usdc), - _pledgeSize * 2 + _expectedBondSize * 2, - 'Mismatch: Disputer balance' - ); - - // Test: The second disputer has received his pledge and the proposer's pledge - _bondEscalationAccounting.claimEscalationReward(_disputeId, _secondDisputer); - assertEq( - _bondEscalationAccounting.balanceOf(_secondDisputer, usdc), _pledgeSize * 2, 'Mismatch: Second Disputer balance' - ); - } - - function test_externalParties() public { - // Step 1: Proposer pledges against the dispute - _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(proposer); - _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); - _bondEscalationModule.pledgeAgainstDispute(_disputeId); - vm.stopPrank(); - - // Step 2: Disputer doesn't have money - // Step 3: External actor sees that Proposer's answer was incorrect so they pledge in favor of the dispute - address _secondDisputer = makeAddr('secondDisputer'); - _forBondDepositERC20(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(_secondDisputer); - _bondEscalationModule.pledgeForDispute(_disputeId); - vm.stopPrank(); - - // Step 4: Proposer doubles down - _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(proposer); - _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); - _bondEscalationModule.pledgeAgainstDispute(_disputeId); - vm.stopPrank(); - - // Step 5: External actor sees that Proposer's answer was incorrect so they pledge in favor of the dispute, tying the bond escalation - address _thirdDisputer = makeAddr('thirdDisputer'); - _forBondDepositERC20(_bondEscalationAccounting, _thirdDisputer, usdc, _pledgeSize, _pledgeSize); - vm.startPrank(_thirdDisputer); - _bondEscalationModule.pledgeForDispute(_disputeId); - vm.stopPrank(); - - // Step 6: Proposer loses in resolution - vm.warp(_bondEscalationDeadline + 1); - oracle.escalateDispute(_disputeId); - oracle.resolveDispute(_disputeId); - - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won), 'Mismatch: Dispute status'); - - // Step 7: Participants claim the rewards - // Test: The requester has not participated in pledging, claiming shouldn't change his balance - _bondEscalationAccounting.claimEscalationReward(_disputeId, requester); - assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); - - // Test: Proposer's initial bond goes to Disputer - _bondEscalationAccounting.claimEscalationReward(_disputeId, proposer); - assertEq(_bondEscalationAccounting.balanceOf(proposer, usdc), 0, 'Mismatch: Proposer balance'); - - // Test: Disputers split the proposer's pledges - _bondEscalationAccounting.claimEscalationReward(_disputeId, disputer); - assertEq(_bondEscalationAccounting.balanceOf(disputer, usdc), _pledgeSize * 2, 'Mismatch: Disputer balance'); - - _bondEscalationAccounting.claimEscalationReward(_disputeId, _secondDisputer); - assertEq( - _bondEscalationAccounting.balanceOf(_secondDisputer, usdc), _pledgeSize * 2, 'Mismatch: Second Disputer balance' - ); - - _bondEscalationAccounting.claimEscalationReward(_disputeId, _thirdDisputer); - assertEq( - _bondEscalationAccounting.balanceOf(_thirdDisputer, usdc), _pledgeSize * 2, 'Mismatch: Third Disputer balance' - ); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import './IntegrationBase.sol'; + +// contract Integration_BondEscalation is IntegrationBase { +// bytes internal _responseData = abi.encode('response'); +// bytes32 internal _requestId; +// bytes32 internal _responseId; +// bytes32 internal _disputeId; +// uint256 internal _bondEscalationDeadline; +// uint256 internal _tyingBuffer = 1 days; +// uint256 internal _disputeWindow = 3 days; +// // TODO: There is a bug in the accounting, try with pledge size = 1 ether +// // uint256 internal _pledgeSize = 5 ether; +// uint256 internal _pledgeSize = _expectedBondSize; + +// function setUp() public override { +// super.setUp(); +// _expectedDeadline = block.timestamp + 10 days; +// _bondEscalationDeadline = block.timestamp + 5 days; + +// IOracle.NewRequest memory _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _bondEscalationAccounting, +// paymentToken: usdc, +// paymentAmount: _expectedReward +// }) +// ), +// responseModuleData: abi.encode( +// IBondedResponseModule.RequestParameters({ +// accountingExtension: _bondEscalationAccounting, +// bondToken: usdc, +// bondSize: _expectedBondSize, +// deadline: _expectedDeadline, +// disputeWindow: _baseDisputeWindow +// }) +// ), +// disputeModuleData: abi.encode( +// IBondEscalationModule.RequestParameters({ +// accountingExtension: _bondEscalationAccounting, +// bondToken: usdc, +// bondSize: _pledgeSize, +// maxNumberOfEscalations: 10, +// bondEscalationDeadline: _bondEscalationDeadline, +// tyingBuffer: _tyingBuffer, +// disputeWindow: _disputeWindow +// }) +// ), +// resolutionModuleData: abi.encode(_mockArbitrator), +// finalityModuleData: abi.encode( +// ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) +// ), +// requestModule: _requestModule, +// responseModule: _responseModule, +// disputeModule: _bondEscalationModule, +// resolutionModule: _arbitratorModule, +// finalityModule: IFinalityModule(_callbackModule), +// ipfsHash: _ipfsHash +// }); + +// // Requester creates a request +// _forBondDepositERC20(_bondEscalationAccounting, requester, usdc, _expectedReward, _expectedReward); +// vm.startPrank(requester); +// _bondEscalationAccounting.approveModule(address(_requestModule)); +// _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// // Proposer proposes a response +// _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(proposer); +// _bondEscalationAccounting.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, _responseData); +// vm.stopPrank(); + +// // Disputer disputes the response +// _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(disputer); +// _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); +// _disputeId = oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); +// } + +// function test_proposerWins() public { +// // Step 1: Proposer pledges against the dispute +// _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(proposer); +// _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); +// _bondEscalationModule.pledgeAgainstDispute(_disputeId); +// vm.stopPrank(); + +// // Step 2: Disputer doubles down +// _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(disputer); +// _bondEscalationModule.pledgeForDispute(_disputeId); +// vm.stopPrank(); + +// // Step 3: Proposer doubles down +// _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(proposer); +// _bondEscalationModule.pledgeAgainstDispute(_disputeId); +// vm.stopPrank(); + +// // Step 4: Disputer runs out of capital +// // Step 5: External parties see that Disputer's dispute was wrong so they don't join to escalate +// // Step 6: Proposer response's is deemed correct and final once the bond escalation window is over +// vm.warp(_expectedDeadline + _tyingBuffer + 1); +// _bondEscalationModule.settleBondEscalation(_requestId); + +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Lost), 'Mismatch: Dispute status'); + +// // Step 7: Participants claim the rewards +// // Test: The requester has not participated in pledging, claiming shouldn't change his balance +// _bondEscalationAccounting.claimEscalationReward(_disputeId, requester); +// assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); + +// // Test: The proposer receives 2x pledging amount + disputer's bond + disputer's pledge +// _bondEscalationAccounting.claimEscalationReward(_disputeId, proposer); +// assertEq( +// _bondEscalationAccounting.balanceOf(proposer, usdc), +// _pledgeSize * 3 + _expectedBondSize, +// 'Mismatch: Proposer balance' +// ); + +// // Test: The disputer has lost his pledge +// _bondEscalationAccounting.claimEscalationReward(_disputeId, disputer); +// assertEq(_bondEscalationAccounting.balanceOf(disputer, usdc), 0, 'Mismatch: Disputer balance'); + +// // Step 8: Finalize request and check balances again +// oracle.finalize(_requestId, _responseId); + +// // Test: The requester has no balance because he has paid the proposer +// assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); + +// // Test: The proposer receives the requester's reward for proposing a correct response and his bond back +// assertEq( +// _bondEscalationAccounting.balanceOf(proposer, usdc), +// _pledgeSize * 3 + _expectedBondSize * 2 + _expectedReward, +// 'Mismatch: Proposer balance' +// ); + +// // Test: The disputer's balance has not changed +// assertEq(_bondEscalationAccounting.balanceOf(disputer, usdc), 0, 'Mismatch: Disputer balance'); +// } + +// function test_proposerLoses() public { +// // Step 1: Proposer pledges against the dispute +// _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(proposer); +// _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); +// _bondEscalationModule.pledgeAgainstDispute(_disputeId); +// vm.stopPrank(); + +// // Step 2: Disputer doubles down +// _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(disputer); +// _bondEscalationModule.pledgeForDispute(_disputeId); +// vm.stopPrank(); + +// // Step 3: Another party joins the dispute +// address _secondDisputer = makeAddr('secondDisputer'); +// _forBondDepositERC20(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(_secondDisputer); +// _bondEscalationModule.pledgeForDispute(_disputeId); +// vm.stopPrank(); + +// // Step 4: Proposer runs out of capital and doesn't pledge anymore +// // External parties see that Proposer's proposal was wrong so they don't join to escalate + +// // Step 5: Proposer response's is deemed incorrect. The bond escalation process along with the tying buffer is terminated +// vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); +// _bondEscalationModule.settleBondEscalation(_requestId); + +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won), 'Mismatch: Dispute status'); + +// // Step 6: Participants claim the rewards +// // Test: The requester has not participated in pledging, claiming shouldn't change his balance +// _bondEscalationAccounting.claimEscalationReward(_disputeId, requester); +// assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); + +// // Test: The proposer has lost his pledge +// _bondEscalationAccounting.claimEscalationReward(_disputeId, proposer); +// assertEq(_bondEscalationAccounting.balanceOf(proposer, usdc), 0, 'Mismatch: Proposer balance'); + +// // Test: The disputer has received his pledge and bond back, a half of the proposer's pledge and the proposer's bond +// _bondEscalationAccounting.claimEscalationReward(_disputeId, disputer); +// assertEq( +// _bondEscalationAccounting.balanceOf(disputer, usdc), +// _pledgeSize + _pledgeSize / 2 + _expectedBondSize * 2, +// 'Mismatch: Disputer balance' +// ); + +// // Test: The second disputer has received his pledge back and a half of the proposer's pledge +// _bondEscalationAccounting.claimEscalationReward(_disputeId, _secondDisputer); +// assertEq( +// _bondEscalationAccounting.balanceOf(_secondDisputer, usdc), +// _pledgeSize + _pledgeSize / 2, +// 'Mismatch: Second Disputer balance' +// ); + +// // Step 7: Other parties can now propose different answers. Another proposer proposes a new answer +// address _anotherProposer = makeAddr('anotherProposer'); +// _forBondDepositERC20(_bondEscalationAccounting, _anotherProposer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(_anotherProposer); +// _bondEscalationAccounting.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, abi.encode('anotherResponse')); +// vm.stopPrank(); + +// // Step 8: Disputer disputes Another proposer's answer +// // _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(disputer); +// _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); +// _disputeId = oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); + +// // Step 9: Shouldn't be able to pledge for or against the dispute due to the bond escalation deadline being over +// _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _pledgeSize, _pledgeSize); +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); +// vm.startPrank(disputer); +// _bondEscalationModule.pledgeForDispute(_disputeId); +// vm.stopPrank(); + +// // Step 10: The dispute goes to the resolution module +// oracle.escalateDispute(_disputeId); +// _dispute = oracle.getDispute(_disputeId); +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Escalated), 'Mismatch: Dispute status'); + +// // Step 11: Because Another proposer's answer is disputed, a third party can propose a new answer +// address _thirdProposer = makeAddr('thirdProposer'); +// _forBondDepositERC20(_bondEscalationAccounting, _thirdProposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(_thirdProposer); +// _bondEscalationAccounting.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, abi.encode('thirdResponse')); +// vm.stopPrank(); + +// // Step 12: It goes undisputed for three days, therefore it's deemed correct and final +// vm.warp(_expectedDeadline + 1); +// oracle.finalize(_requestId, _responseId); + +// // Test: The requester has paid out the reward +// assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); + +// // Test: The first proposer has received nothing +// assertEq(_bondEscalationAccounting.balanceOf(proposer, usdc), 0, 'Mismatch: Proposer balance'); + +// // Test: The second proposer has received nothing +// assertEq(_bondEscalationAccounting.balanceOf(_anotherProposer, usdc), 0, 'Mismatch: Another Proposer balance'); + +// // Test: The third proposer has received the reward and this bond +// assertEq( +// _bondEscalationAccounting.balanceOf(_thirdProposer, usdc), +// _expectedReward + _expectedBondSize, +// 'Mismatch: Third Proposer balance' +// ); + +// // Test: The disputer has received his pledge and bond back, a half of the proposer's pledge and the proposer's bond +// assertEq( +// _bondEscalationAccounting.balanceOf(disputer, usdc), +// _pledgeSize + _pledgeSize / 2 + _expectedBondSize * 2, +// 'Mismatch: Disputer balance' +// ); + +// // Test: The second disputer has not participated in a new dispute, his balance is the same +// assertEq( +// _bondEscalationAccounting.balanceOf(_secondDisputer, usdc), +// _pledgeSize + _pledgeSize / 2, +// 'Mismatch: Second Disputer balance' +// ); + +// // Step 13: Two days after the deadline, the resolution module says that Another proposer's answer was correct +// // So Another proposer gets paid Disputer's bond +// vm.warp(_expectedDeadline + 2 days); +// _mockArbitrator.setAnswer(IOracle.DisputeStatus.Lost); +// oracle.resolveDispute(_disputeId); + +// // Test: The requester still has nothing +// assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); + +// // Test: The first proposer still has nothing +// assertEq(_bondEscalationAccounting.balanceOf(proposer, usdc), 0, 'Mismatch: Proposer balance'); + +// // Test: The second proposer has received the Disputer's bond +// assertEq( +// _bondEscalationAccounting.balanceOf(_anotherProposer, usdc), +// _expectedBondSize, +// 'Mismatch: Another Proposer balance' +// ); + +// // Test: The third proposer has not done anything +// assertEq( +// _bondEscalationAccounting.balanceOf(_thirdProposer, usdc), +// _expectedReward + _expectedBondSize, +// 'Mismatch: Third Proposer balance' +// ); + +// // Test: The disputer has lost a bond +// assertEq( +// _bondEscalationAccounting.balanceOf(disputer, usdc), +// _pledgeSize + _pledgeSize / 2 + _expectedBondSize * 2, +// 'Mismatch: Disputer balance' +// ); + +// // Test: The second disputer has not has not done anything +// assertEq( +// _bondEscalationAccounting.balanceOf(_secondDisputer, usdc), +// _pledgeSize + _pledgeSize / 2, +// 'Mismatch: Second Disputer balance' +// ); +// } + +// function test_bondEscalationTied() public { +// // Step 1: Proposer pledges against the dispute +// _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(proposer); +// _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); +// _bondEscalationModule.pledgeAgainstDispute(_disputeId); +// vm.stopPrank(); + +// // Step 2: Disputer doubles down +// _forBondDepositERC20(_bondEscalationAccounting, disputer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(disputer); +// _bondEscalationModule.pledgeForDispute(_disputeId); +// vm.stopPrank(); + +// // Step 3: Proposer doubles down +// _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(proposer); +// _bondEscalationModule.pledgeAgainstDispute(_disputeId); +// vm.stopPrank(); + +// // Step 4: Disputer runs out of capital +// // Step 5: The tying buffer kicks in +// vm.warp(_bondEscalationDeadline + 1); + +// // Step 6: An external party sees that Proposer's response is incorrect, so they bond the required WETH +// address _secondDisputer = makeAddr('secondDisputer'); +// _forBondDepositERC20(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(_secondDisputer); +// _bondEscalationModule.pledgeForDispute(_disputeId); +// vm.stopPrank(); + +// // Step 7: They go into the dispute resolution module +// oracle.escalateDispute(_disputeId); + +// // Step 8: At this point, new answers can be proposed +// address _secondProposer = makeAddr('secondProposer'); +// _forBondDepositERC20(_bondEscalationAccounting, _secondProposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(_secondProposer); +// _bondEscalationAccounting.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, _responseData); +// vm.stopPrank(); + +// // Step 9: After some time, the resolution module deems Disputer's dispute as correct +// _mineBlocks(100); +// oracle.resolveDispute(_disputeId); +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won), 'Mismatch: Dispute status'); + +// // Step 10: Participants claim their rewards +// // Test: The requester has paid out the reward and is left with no balance +// _bondEscalationAccounting.claimEscalationReward(_disputeId, requester); +// assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); + +// // Test: The proposer has lost his pledge and bond +// _bondEscalationAccounting.claimEscalationReward(_disputeId, proposer); +// assertEq(_bondEscalationAccounting.balanceOf(proposer, usdc), 0, 'Mismatch: Proposer balance'); + +// // Test: The second proposer hasn't received the reward yet +// _bondEscalationAccounting.claimEscalationReward(_disputeId, _secondProposer); +// assertEq(_bondEscalationAccounting.balanceOf(_secondProposer, usdc), 0, 'Mismatch: Second Proposer balance'); +// assertEq( +// _bondEscalationAccounting.bondedAmountOf(_secondProposer, usdc, _requestId), +// _expectedBondSize, +// 'Mismatch: Second Proposer bonded balance' +// ); + +// // Test: The Disputer has received his pledge and bond, the proposer's pledge and the proposer's bond +// _bondEscalationAccounting.claimEscalationReward(_disputeId, disputer); +// assertEq( +// _bondEscalationAccounting.balanceOf(disputer, usdc), +// _pledgeSize * 2 + _expectedBondSize * 2, +// 'Mismatch: Disputer balance' +// ); + +// // Test: The second disputer has received his pledge and the proposer's pledge +// _bondEscalationAccounting.claimEscalationReward(_disputeId, _secondDisputer); +// assertEq( +// _bondEscalationAccounting.balanceOf(_secondDisputer, usdc), _pledgeSize * 2, 'Mismatch: Second Disputer balance' +// ); +// } + +// function test_externalParties() public { +// // Step 1: Proposer pledges against the dispute +// _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(proposer); +// _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); +// _bondEscalationModule.pledgeAgainstDispute(_disputeId); +// vm.stopPrank(); + +// // Step 2: Disputer doesn't have money +// // Step 3: External actor sees that Proposer's answer was incorrect so they pledge in favor of the dispute +// address _secondDisputer = makeAddr('secondDisputer'); +// _forBondDepositERC20(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(_secondDisputer); +// _bondEscalationModule.pledgeForDispute(_disputeId); +// vm.stopPrank(); + +// // Step 4: Proposer doubles down +// _forBondDepositERC20(_bondEscalationAccounting, proposer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(proposer); +// _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); +// _bondEscalationModule.pledgeAgainstDispute(_disputeId); +// vm.stopPrank(); + +// // Step 5: External actor sees that Proposer's answer was incorrect so they pledge in favor of the dispute, tying the bond escalation +// address _thirdDisputer = makeAddr('thirdDisputer'); +// _forBondDepositERC20(_bondEscalationAccounting, _thirdDisputer, usdc, _pledgeSize, _pledgeSize); +// vm.startPrank(_thirdDisputer); +// _bondEscalationModule.pledgeForDispute(_disputeId); +// vm.stopPrank(); + +// // Step 6: Proposer loses in resolution +// vm.warp(_bondEscalationDeadline + 1); +// oracle.escalateDispute(_disputeId); +// oracle.resolveDispute(_disputeId); + +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won), 'Mismatch: Dispute status'); + +// // Step 7: Participants claim the rewards +// // Test: The requester has not participated in pledging, claiming shouldn't change his balance +// _bondEscalationAccounting.claimEscalationReward(_disputeId, requester); +// assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); + +// // Test: Proposer's initial bond goes to Disputer +// _bondEscalationAccounting.claimEscalationReward(_disputeId, proposer); +// assertEq(_bondEscalationAccounting.balanceOf(proposer, usdc), 0, 'Mismatch: Proposer balance'); + +// // Test: Disputers split the proposer's pledges +// _bondEscalationAccounting.claimEscalationReward(_disputeId, disputer); +// assertEq(_bondEscalationAccounting.balanceOf(disputer, usdc), _pledgeSize * 2, 'Mismatch: Disputer balance'); + +// _bondEscalationAccounting.claimEscalationReward(_disputeId, _secondDisputer); +// assertEq( +// _bondEscalationAccounting.balanceOf(_secondDisputer, usdc), _pledgeSize * 2, 'Mismatch: Second Disputer balance' +// ); + +// _bondEscalationAccounting.claimEscalationReward(_disputeId, _thirdDisputer); +// assertEq( +// _bondEscalationAccounting.balanceOf(_thirdDisputer, usdc), _pledgeSize * 2, 'Mismatch: Third Disputer balance' +// ); +// } +// } diff --git a/solidity/test/integration/EscalateDispute.t.sol b/solidity/test/integration/EscalateDispute.t.sol index 8cb41902..46fe38d2 100644 --- a/solidity/test/integration/EscalateDispute.t.sol +++ b/solidity/test/integration/EscalateDispute.t.sol @@ -1,128 +1,128 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import './IntegrationBase.sol'; - -contract Integration_EscalateDispute is IntegrationBase { - bytes internal _responseData = abi.encode('response'); - uint256 internal _blocksDeadline = 600; - - function setUp() public override { - super.setUp(); - _expectedDeadline = block.timestamp + BLOCK_TIME * _blocksDeadline; - } - - function test_escalateDispute() public { - /// Escalate dispute reverts if dispute does not exist - bytes32 _invalidDisputeId = bytes32(0); - vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidDisputeId.selector, _invalidDisputeId)); - oracle.escalateDispute(_invalidDisputeId); - - /// Create a dispute with bond escalation module and arbitrator module - (bytes32 _requestId,, bytes32 _disputeId) = _createRequestAndDispute( - _bondEscalationAccounting, - _bondEscalationModule, - abi.encode( - IBondEscalationModule.RequestParameters({ - accountingExtension: _bondEscalationAccounting, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize, - maxNumberOfEscalations: 1, - bondEscalationDeadline: _expectedDeadline, - tyingBuffer: 0, - disputeWindow: 0 - }) - ), - _arbitratorModule, - abi.encode(_mockArbitrator) - ); - - /// The oracle should call the dispute module - vm.expectCall(address(_bondEscalationModule), abi.encodeCall(IDisputeModule.disputeEscalated, _disputeId)); - - /// The oracle should call startResolution in the resolution module - vm.expectCall(address(_arbitratorModule), abi.encodeCall(IResolutionModule.startResolution, _disputeId)); - - /// The arbitrator module should call the arbitrator - vm.expectCall(address(_mockArbitrator), abi.encodeCall(MockArbitrator.resolve, _disputeId)); - - /// We escalate the dispute - _mineBlocks(_blocksDeadline + 1); - oracle.escalateDispute(_disputeId); - - /// We check that the dispute was escalated - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - assertTrue(_dispute.status == IOracle.DisputeStatus.Escalated); - - /// The BondEscalationModule should now have the escalation status escalated - IBondEscalationModule.BondEscalation memory _bondEscalation = _bondEscalationModule.getEscalation(_requestId); - assertTrue(_bondEscalation.status == IBondEscalationModule.BondEscalationStatus.Escalated); - - /// The ArbitratorModule should have updated the status of the dispute - assertTrue(_arbitratorModule.getStatus(_disputeId) == IArbitratorModule.ArbitrationStatus.Active); - - /// Escalate dispute reverts if dispute is not active - vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_CannotEscalate.selector, _disputeId)); - oracle.escalateDispute(_disputeId); - } - - function _createRequestAndDispute( - IAccountingExtension _accounting, - IDisputeModule _disputeModule, - bytes memory _disputeModuleData, - IResolutionModule _resolutionModule, - bytes memory _resolutionModuleData - ) internal returns (bytes32 _requestId, bytes32 _responseId, bytes32 _disputeId) { - _forBondDepositERC20(_accounting, requester, usdc, _expectedBondSize, _expectedBondSize); - - IOracle.NewRequest memory _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accounting, - paymentToken: IERC20(USDC_ADDRESS), - paymentAmount: _expectedReward - }) - ), - responseModuleData: abi.encode( - IBondedResponseModule.RequestParameters({ - accountingExtension: _accounting, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize, - deadline: _expectedDeadline, - disputeWindow: _baseDisputeWindow - }) - ), - disputeModuleData: _disputeModuleData, - resolutionModuleData: _resolutionModuleData, - finalityModuleData: abi.encode( - ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) - ), - requestModule: _requestModule, - responseModule: _responseModule, - disputeModule: _disputeModule, - resolutionModule: _resolutionModule, - finalityModule: IFinalityModule(_callbackModule), - ipfsHash: _ipfsHash - }); - - vm.startPrank(requester); - _accounting.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - _forBondDepositERC20(_accounting, proposer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(proposer); - _accounting.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, _responseData); - vm.stopPrank(); - - _forBondDepositERC20(_accounting, disputer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(disputer); - _accounting.approveModule(address(_disputeModule)); - _disputeId = oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import './IntegrationBase.sol'; + +// contract Integration_EscalateDispute is IntegrationBase { +// bytes internal _responseData = abi.encode('response'); +// uint256 internal _blocksDeadline = 600; + +// function setUp() public override { +// super.setUp(); +// _expectedDeadline = block.timestamp + BLOCK_TIME * _blocksDeadline; +// } + +// function test_escalateDispute() public { +// /// Escalate dispute reverts if dispute does not exist +// bytes32 _invalidDisputeId = bytes32(0); +// vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidDisputeId.selector, _invalidDisputeId)); +// oracle.escalateDispute(_invalidDisputeId); + +// /// Create a dispute with bond escalation module and arbitrator module +// (bytes32 _requestId,, bytes32 _disputeId) = _createRequestAndDispute( +// _bondEscalationAccounting, +// _bondEscalationModule, +// abi.encode( +// IBondEscalationModule.RequestParameters({ +// accountingExtension: _bondEscalationAccounting, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize, +// maxNumberOfEscalations: 1, +// bondEscalationDeadline: _expectedDeadline, +// tyingBuffer: 0, +// disputeWindow: 0 +// }) +// ), +// _arbitratorModule, +// abi.encode(_mockArbitrator) +// ); + +// /// The oracle should call the dispute module +// vm.expectCall(address(_bondEscalationModule), abi.encodeCall(IDisputeModule.disputeEscalated, _disputeId)); + +// /// The oracle should call startResolution in the resolution module +// vm.expectCall(address(_arbitratorModule), abi.encodeCall(IResolutionModule.startResolution, _disputeId)); + +// /// The arbitrator module should call the arbitrator +// vm.expectCall(address(_mockArbitrator), abi.encodeCall(MockArbitrator.resolve, _disputeId)); + +// /// We escalate the dispute +// _mineBlocks(_blocksDeadline + 1); +// oracle.escalateDispute(_disputeId); + +// /// We check that the dispute was escalated +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// assertTrue(_dispute.status == IOracle.DisputeStatus.Escalated); + +// /// The BondEscalationModule should now have the escalation status escalated +// IBondEscalationModule.BondEscalation memory _bondEscalation = _bondEscalationModule.getEscalation(_requestId); +// assertTrue(_bondEscalation.status == IBondEscalationModule.BondEscalationStatus.Escalated); + +// /// The ArbitratorModule should have updated the status of the dispute +// assertTrue(_arbitratorModule.getStatus(_disputeId) == IArbitratorModule.ArbitrationStatus.Active); + +// /// Escalate dispute reverts if dispute is not active +// vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_CannotEscalate.selector, _disputeId)); +// oracle.escalateDispute(_disputeId); +// } + +// function _createRequestAndDispute( +// IAccountingExtension _accounting, +// IDisputeModule _disputeModule, +// bytes memory _disputeModuleData, +// IResolutionModule _resolutionModule, +// bytes memory _resolutionModuleData +// ) internal returns (bytes32 _requestId, bytes32 _responseId, bytes32 _disputeId) { +// _forBondDepositERC20(_accounting, requester, usdc, _expectedBondSize, _expectedBondSize); + +// IOracle.NewRequest memory _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accounting, +// paymentToken: IERC20(USDC_ADDRESS), +// paymentAmount: _expectedReward +// }) +// ), +// responseModuleData: abi.encode( +// IBondedResponseModule.RequestParameters({ +// accountingExtension: _accounting, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize, +// deadline: _expectedDeadline, +// disputeWindow: _baseDisputeWindow +// }) +// ), +// disputeModuleData: _disputeModuleData, +// resolutionModuleData: _resolutionModuleData, +// finalityModuleData: abi.encode( +// ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) +// ), +// requestModule: _requestModule, +// responseModule: _responseModule, +// disputeModule: _disputeModule, +// resolutionModule: _resolutionModule, +// finalityModule: IFinalityModule(_callbackModule), +// ipfsHash: _ipfsHash +// }); + +// vm.startPrank(requester); +// _accounting.approveModule(address(_requestModule)); +// _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// _forBondDepositERC20(_accounting, proposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(proposer); +// _accounting.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, _responseData); +// vm.stopPrank(); + +// _forBondDepositERC20(_accounting, disputer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(disputer); +// _accounting.approveModule(address(_disputeModule)); +// _disputeId = oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); +// } +// } diff --git a/solidity/test/integration/Finalization.t.sol b/solidity/test/integration/Finalization.t.sol index 394cd352..eed07fdc 100644 --- a/solidity/test/integration/Finalization.t.sol +++ b/solidity/test/integration/Finalization.t.sol @@ -1,285 +1,285 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import './IntegrationBase.sol'; - -contract Integration_Finalization is IntegrationBase { - bytes internal _responseData; - - address internal _finalizer = makeAddr('finalizer'); - - function setUp() public override { - super.setUp(); - _expectedDeadline = block.timestamp + BLOCK_TIME * 600; - } - - /** - * @notice Test to check if another module can be set as callback module. - */ - function test_targetIsAnotherModule() public { - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); - - IOracle.NewRequest memory _request = _customFinalizationRequest( - address(_callbackModule), - abi.encode( - ICallbackModule.RequestParameters({ - target: address(_callbackModule), - data: abi.encodeWithSignature('callback()') - }) - ) - ); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - bytes32 _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - bytes32 _responseId = _setupFinalizationStage(_requestId); - - vm.warp(block.timestamp + _baseDisputeWindow); - vm.prank(_finalizer); - oracle.finalize(_requestId, _responseId); - } - - /** - * @notice Test to check that finalization data is set and callback calls are made. - */ - function test_makeAndIgnoreLowLevelCalls(bytes memory _calldata) public { - address _callbackTarget = makeAddr('target'); - vm.etch(_callbackTarget, hex'069420'); - - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); - - IOracle.NewRequest memory _request = _customFinalizationRequest( - address(_callbackModule), - abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: _calldata})) - ); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - bytes32 _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - bytes32 _responseId = _setupFinalizationStage(_requestId); - - // Check: all low-level calls are made? - vm.expectCall(_callbackTarget, _calldata); - - vm.warp(block.timestamp + _baseDisputeWindow); - vm.prank(_finalizer); - oracle.finalize(_requestId, _responseId); - - IOracle.Response memory _finalizedResponse = oracle.getFinalizedResponse(_requestId); - // Check: is response finalized? - assertEq(_finalizedResponse.requestId, _requestId); - } - - /** - * @notice Test to check that finalizing a request that has no response will revert. - */ - function test_revertFinalizeIfNoResponse(bytes32 _responseId) public { - address _callbackTarget = makeAddr('target'); - vm.etch(_callbackTarget, hex'069420'); - - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); - - IOracle.NewRequest memory _request = _customFinalizationRequest( - address(_callbackModule), - abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: bytes('')})) - ); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - bytes32 _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - vm.prank(_finalizer); - - // Check: reverts if request has no response? - vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidFinalizedResponse.selector, _responseId)); - oracle.finalize(_requestId, _responseId); - } - - /** - * @notice Test to check that finalizing a request with a ongoing dispute with revert. - */ - function test_revertFinalizeWithDisputedResponse() public { - address _callbackTarget = makeAddr('target'); - vm.etch(_callbackTarget, hex'069420'); - - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); - - IOracle.NewRequest memory _request = _customFinalizationRequest( - address(_callbackModule), - abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: bytes('')})) - ); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - bytes32 _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - bytes32 _responseId = oracle.proposeResponse(_requestId, abi.encode('responsedata')); - vm.stopPrank(); - - _forBondDepositERC20(_accountingExtension, disputer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(disputer); - _accountingExtension.approveModule(address(_bondedDisputeModule)); - oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - - vm.prank(_finalizer); - vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidFinalizedResponse.selector, _responseId)); - oracle.finalize(_requestId, _responseId); - } - - /** - * @notice Test to check that finalizing a request with a ongoing dispute with revert. - */ - function test_revertFinalizeInDisputeWindow(uint256 _timestamp) public { - address _callbackTarget = makeAddr('target'); - vm.etch(_callbackTarget, hex'069420'); - - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); - - IOracle.NewRequest memory _request = _customFinalizationRequest( - address(_callbackModule), - abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: bytes('')})) - ); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - bytes32 _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - bytes32 _responseId = oracle.proposeResponse(_requestId, abi.encode('responsedata')); - vm.stopPrank(); - - vm.warp(_timestamp); - vm.prank(_finalizer); - if (_timestamp < _expectedDeadline + _baseDisputeWindow) { - vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooEarlyToFinalize.selector); - } - oracle.finalize(_requestId, _responseId); - } - /** - * @notice Test to check that finalizing a request without disputes triggers callback calls and executes without reverting. - */ - - function test_finalizeWithUndisputedResponse(bytes calldata _calldata) public { - address _callbackTarget = makeAddr('target'); - vm.etch(_callbackTarget, hex'069420'); - - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); - - IOracle.NewRequest memory _request = _customFinalizationRequest( - address(_callbackModule), - abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: _calldata})) - ); - - vm.expectCall(_callbackTarget, _calldata); - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - bytes32 _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - bytes32 _responseId = _setupFinalizationStage(_requestId); - - vm.warp(block.timestamp + _baseDisputeWindow); - vm.prank(_finalizer); - oracle.finalize(_requestId, _responseId); - } - - /** - * @notice Test to check that finalizing a request before the disputing deadline will revert. - */ - function test_revertFinalizeBeforeDeadline(bytes calldata _calldata) public { - address _callbackTarget = makeAddr('target'); - vm.etch(_callbackTarget, hex'069420'); - - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); - - IOracle.NewRequest memory _request = _customFinalizationRequest( - address(_callbackModule), - abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: _calldata})) - ); - - vm.expectCall(_callbackTarget, _calldata); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - bytes32 _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - bytes32 _responseId = oracle.proposeResponse(_requestId, bytes('response_data')); - vm.stopPrank(); - - vm.prank(_finalizer); - vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooEarlyToFinalize.selector); - oracle.finalize(_requestId, _responseId); - } - - /** - * @notice Internal helper function to setup the finalization stage of a request. - */ - function _setupFinalizationStage(bytes32 _requestId) internal returns (bytes32 _responseId) { - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, abi.encode('responsedata')); - vm.stopPrank(); - - vm.warp(_expectedDeadline + 1); - } - - function _customFinalizationRequest( - address _finalityModule, - bytes memory _finalityModuleData - ) internal view returns (IOracle.NewRequest memory _request) { - _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accountingExtension, - paymentToken: IERC20(USDC_ADDRESS), - paymentAmount: _expectedReward - }) - ), - responseModuleData: abi.encode( - IBondedResponseModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize, - deadline: _expectedDeadline, - disputeWindow: _baseDisputeWindow - }) - ), - disputeModuleData: abi.encode( - IBondedDisputeModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize - }) - ), - resolutionModuleData: abi.encode(_mockArbitrator), - finalityModuleData: _finalityModuleData, - requestModule: _requestModule, - responseModule: _responseModule, - disputeModule: _bondedDisputeModule, - resolutionModule: _arbitratorModule, - finalityModule: IFinalityModule(_finalityModule), - ipfsHash: _ipfsHash - }); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import './IntegrationBase.sol'; + +// contract Integration_Finalization is IntegrationBase { +// bytes internal _responseData; + +// address internal _finalizer = makeAddr('finalizer'); + +// function setUp() public override { +// super.setUp(); +// _expectedDeadline = block.timestamp + BLOCK_TIME * 600; +// } + +// /** +// * @notice Test to check if another module can be set as callback module. +// */ +// function test_targetIsAnotherModule() public { +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); + +// IOracle.NewRequest memory _request = _customFinalizationRequest( +// address(_callbackModule), +// abi.encode( +// ICallbackModule.RequestParameters({ +// target: address(_callbackModule), +// data: abi.encodeWithSignature('callback()') +// }) +// ) +// ); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// bytes32 _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// bytes32 _responseId = _setupFinalizationStage(_requestId); + +// vm.warp(block.timestamp + _baseDisputeWindow); +// vm.prank(_finalizer); +// oracle.finalize(_requestId, _responseId); +// } + +// /** +// * @notice Test to check that finalization data is set and callback calls are made. +// */ +// function test_makeAndIgnoreLowLevelCalls(bytes memory _calldata) public { +// address _callbackTarget = makeAddr('target'); +// vm.etch(_callbackTarget, hex'069420'); + +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); + +// IOracle.NewRequest memory _request = _customFinalizationRequest( +// address(_callbackModule), +// abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: _calldata})) +// ); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// bytes32 _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// bytes32 _responseId = _setupFinalizationStage(_requestId); + +// // Check: all low-level calls are made? +// vm.expectCall(_callbackTarget, _calldata); + +// vm.warp(block.timestamp + _baseDisputeWindow); +// vm.prank(_finalizer); +// oracle.finalize(_requestId, _responseId); + +// IOracle.Response memory _finalizedResponse = oracle.getFinalizedResponse(_requestId); +// // Check: is response finalized? +// assertEq(_finalizedResponse.requestId, _requestId); +// } + +// /** +// * @notice Test to check that finalizing a request that has no response will revert. +// */ +// function test_revertFinalizeIfNoResponse(bytes32 _responseId) public { +// address _callbackTarget = makeAddr('target'); +// vm.etch(_callbackTarget, hex'069420'); + +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); + +// IOracle.NewRequest memory _request = _customFinalizationRequest( +// address(_callbackModule), +// abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: bytes('')})) +// ); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// bytes32 _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// vm.prank(_finalizer); + +// // Check: reverts if request has no response? +// vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidFinalizedResponse.selector, _responseId)); +// oracle.finalize(_requestId, _responseId); +// } + +// /** +// * @notice Test to check that finalizing a request with a ongoing dispute with revert. +// */ +// function test_revertFinalizeWithDisputedResponse() public { +// address _callbackTarget = makeAddr('target'); +// vm.etch(_callbackTarget, hex'069420'); + +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); + +// IOracle.NewRequest memory _request = _customFinalizationRequest( +// address(_callbackModule), +// abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: bytes('')})) +// ); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// bytes32 _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// bytes32 _responseId = oracle.proposeResponse(_requestId, abi.encode('responsedata')); +// vm.stopPrank(); + +// _forBondDepositERC20(_accountingExtension, disputer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(disputer); +// _accountingExtension.approveModule(address(_bondedDisputeModule)); +// oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); + +// vm.prank(_finalizer); +// vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidFinalizedResponse.selector, _responseId)); +// oracle.finalize(_requestId, _responseId); +// } + +// /** +// * @notice Test to check that finalizing a request with a ongoing dispute with revert. +// */ +// function test_revertFinalizeInDisputeWindow(uint256 _timestamp) public { +// address _callbackTarget = makeAddr('target'); +// vm.etch(_callbackTarget, hex'069420'); + +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); + +// IOracle.NewRequest memory _request = _customFinalizationRequest( +// address(_callbackModule), +// abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: bytes('')})) +// ); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// bytes32 _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// bytes32 _responseId = oracle.proposeResponse(_requestId, abi.encode('responsedata')); +// vm.stopPrank(); + +// vm.warp(_timestamp); +// vm.prank(_finalizer); +// if (_timestamp < _expectedDeadline + _baseDisputeWindow) { +// vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooEarlyToFinalize.selector); +// } +// oracle.finalize(_requestId, _responseId); +// } +// /** +// * @notice Test to check that finalizing a request without disputes triggers callback calls and executes without reverting. +// */ + +// function test_finalizeWithUndisputedResponse(bytes calldata _calldata) public { +// address _callbackTarget = makeAddr('target'); +// vm.etch(_callbackTarget, hex'069420'); + +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); + +// IOracle.NewRequest memory _request = _customFinalizationRequest( +// address(_callbackModule), +// abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: _calldata})) +// ); + +// vm.expectCall(_callbackTarget, _calldata); +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// bytes32 _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// bytes32 _responseId = _setupFinalizationStage(_requestId); + +// vm.warp(block.timestamp + _baseDisputeWindow); +// vm.prank(_finalizer); +// oracle.finalize(_requestId, _responseId); +// } + +// /** +// * @notice Test to check that finalizing a request before the disputing deadline will revert. +// */ +// function test_revertFinalizeBeforeDeadline(bytes calldata _calldata) public { +// address _callbackTarget = makeAddr('target'); +// vm.etch(_callbackTarget, hex'069420'); + +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); + +// IOracle.NewRequest memory _request = _customFinalizationRequest( +// address(_callbackModule), +// abi.encode(ICallbackModule.RequestParameters({target: _callbackTarget, data: _calldata})) +// ); + +// vm.expectCall(_callbackTarget, _calldata); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// bytes32 _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// bytes32 _responseId = oracle.proposeResponse(_requestId, bytes('response_data')); +// vm.stopPrank(); + +// vm.prank(_finalizer); +// vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooEarlyToFinalize.selector); +// oracle.finalize(_requestId, _responseId); +// } + +// /** +// * @notice Internal helper function to setup the finalization stage of a request. +// */ +// function _setupFinalizationStage(bytes32 _requestId) internal returns (bytes32 _responseId) { +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, abi.encode('responsedata')); +// vm.stopPrank(); + +// vm.warp(_expectedDeadline + 1); +// } + +// function _customFinalizationRequest( +// address _finalityModule, +// bytes memory _finalityModuleData +// ) internal view returns (IOracle.NewRequest memory _request) { +// _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accountingExtension, +// paymentToken: IERC20(USDC_ADDRESS), +// paymentAmount: _expectedReward +// }) +// ), +// responseModuleData: abi.encode( +// IBondedResponseModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize, +// deadline: _expectedDeadline, +// disputeWindow: _baseDisputeWindow +// }) +// ), +// disputeModuleData: abi.encode( +// IBondedDisputeModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize +// }) +// ), +// resolutionModuleData: abi.encode(_mockArbitrator), +// finalityModuleData: _finalityModuleData, +// requestModule: _requestModule, +// responseModule: _responseModule, +// disputeModule: _bondedDisputeModule, +// resolutionModule: _arbitratorModule, +// finalityModule: IFinalityModule(_finalityModule), +// ipfsHash: _ipfsHash +// }); +// } +// } diff --git a/solidity/test/integration/IntegrationBase.sol b/solidity/test/integration/IntegrationBase.sol index 28ab52a4..3efe338a 100644 --- a/solidity/test/integration/IntegrationBase.sol +++ b/solidity/test/integration/IntegrationBase.sol @@ -1,135 +1,135 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -// solhint-disable no-unused-import -// solhint-disable-next-line no-console -import {console} from 'forge-std/console.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {DSTestPlus} from '@defi-wonderland/solidity-utils/solidity/test/DSTestPlus.sol'; -import {Oracle, IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Oracle.sol'; -import {IDisputeModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; -import {IRequestModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/request/IRequestModule.sol'; -import {IResponseModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/response/IResponseModule.sol'; -import {IResolutionModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; -import {IFinalityModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/finality/IFinalityModule.sol'; - -import {IWETH9} from '../../interfaces/external/IWETH9.sol'; - -import {HttpRequestModule, IHttpRequestModule} from '../../contracts/modules/request/HttpRequestModule.sol'; -import {BondedResponseModule, IBondedResponseModule} from '../../contracts/modules/response/BondedResponseModule.sol'; -import {BondedDisputeModule, IBondedDisputeModule} from '../../contracts/modules/dispute/BondedDisputeModule.sol'; -import {ArbitratorModule, IArbitratorModule} from '../../contracts/modules/resolution/ArbitratorModule.sol'; -import {AccountingExtension, IAccountingExtension} from '../../contracts/extensions/AccountingExtension.sol'; -import {CallbackModule, ICallbackModule} from '../../contracts/modules/finality/CallbackModule.sol'; -import {BondEscalationModule, IBondEscalationModule} from '../../contracts/modules/dispute/BondEscalationModule.sol'; -import { - BondEscalationAccounting, IBondEscalationAccounting -} from '../../contracts/extensions/BondEscalationAccounting.sol'; - -import {MockCallback} from '../mocks/MockCallback.sol'; -import {MockArbitrator} from '../mocks/MockArbitrator.sol'; - -import {TestConstants} from '../utils/TestConstants.sol'; -import {Helpers} from '../utils/Helpers.sol'; -// solhint-enable no-unused-import - -contract IntegrationBase is DSTestPlus, TestConstants, Helpers { - uint256 public constant FORK_BLOCK = 756_611; - - uint256 internal _initialBalance = 100_000 ether; - - address public requester = makeAddr('requester'); - address public proposer = makeAddr('proposer'); - address public disputer = makeAddr('disputer'); - address public keeper = makeAddr('keeper'); - address public governance = makeAddr('governance'); - - Oracle public oracle; - HttpRequestModule internal _requestModule; - BondedResponseModule internal _responseModule; - AccountingExtension internal _accountingExtension; - BondEscalationAccounting internal _bondEscalationAccounting; - BondedDisputeModule internal _bondedDisputeModule; - ArbitratorModule internal _arbitratorModule; - CallbackModule internal _callbackModule; - MockCallback internal _mockCallback; - MockArbitrator internal _mockArbitrator; - BondEscalationModule internal _bondEscalationModule; - - IERC20 public usdc = IERC20(label(USDC_ADDRESS, 'USDC')); - IWETH9 public weth = IWETH9(label(WETH_ADDRESS, 'WETH')); - - string internal _expectedUrl = 'https://api.coingecko.com/api/v3/simple/price?'; - IHttpRequestModule.HttpMethod internal _expectedMethod = IHttpRequestModule.HttpMethod.GET; - string internal _expectedBody = 'ids=ethereum&vs_currencies=usd'; - string internal _expectedResponse = '{"ethereum":{"usd":1000}}'; - uint256 internal _expectedBondSize = 100 ether; - uint256 internal _expectedReward = 30 ether; - uint256 internal _expectedDeadline; - uint256 internal _expectedCallbackValue = 42; - uint256 internal _baseDisputeWindow = 12 hours; - bytes32 internal _ipfsHash = bytes32('QmR4uiJH654k3Ta2uLLQ8r'); - - function setUp() public virtual { - vm.createSelectFork(vm.rpcUrl('optimism'), FORK_BLOCK); - - // Transfer some DAI and WETH to the users - deal(address(weth), requester, _initialBalance); - deal(address(usdc), requester, _initialBalance); - - deal(address(weth), proposer, _initialBalance); - deal(address(usdc), proposer, _initialBalance); - - deal(address(weth), disputer, _initialBalance); - deal(address(usdc), disputer, _initialBalance); - - // Deploy every contract needed - vm.startPrank(governance); - - oracle = new Oracle(); - label(address(oracle), 'Oracle'); - - _requestModule = new HttpRequestModule(oracle); - label(address(_requestModule), 'RequestModule'); - - _responseModule = new BondedResponseModule(oracle); - label(address(_responseModule), 'ResponseModule'); - - _bondedDisputeModule = new BondedDisputeModule(oracle); - label(address(_bondedDisputeModule), 'DisputeModule'); - - _arbitratorModule = new ArbitratorModule(oracle); - label(address(_arbitratorModule), 'ResolutionModule'); - - _callbackModule = new CallbackModule(oracle); - label(address(_callbackModule), 'CallbackModule'); - - _accountingExtension = new AccountingExtension(oracle); - label(address(_accountingExtension), 'AccountingExtension'); - - _bondEscalationModule = new BondEscalationModule(oracle); - label(address(_bondEscalationModule), 'BondEscalationModule'); - - _bondEscalationAccounting = new BondEscalationAccounting(oracle); - label(address(_bondEscalationAccounting), 'BondEscalationAccounting'); - - _mockCallback = new MockCallback(); - _mockArbitrator = new MockArbitrator(); - vm.stopPrank(); - } - - function _mineBlock() internal { - _mineBlocks(1); - } - - function _mineBlocks(uint256 _blocks) internal { - vm.warp(block.timestamp + _blocks * BLOCK_TIME); - vm.roll(block.number + _blocks); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// // solhint-disable no-unused-import +// // solhint-disable-next-line no-console +// import {console} from 'forge-std/console.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {DSTestPlus} from '@defi-wonderland/solidity-utils/solidity/test/DSTestPlus.sol'; +// import {Oracle, IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Oracle.sol'; +// import {IDisputeModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; +// import {IRequestModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/request/IRequestModule.sol'; +// import {IResponseModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/response/IResponseModule.sol'; +// import {IResolutionModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/resolution/IResolutionModule.sol'; +// import {IFinalityModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/finality/IFinalityModule.sol'; + +// import {IWETH9} from '../../interfaces/external/IWETH9.sol'; + +// import {HttpRequestModule, IHttpRequestModule} from '../../contracts/modules/request/HttpRequestModule.sol'; +// import {BondedResponseModule, IBondedResponseModule} from '../../contracts/modules/response/BondedResponseModule.sol'; +// import {BondedDisputeModule, IBondedDisputeModule} from '../../contracts/modules/dispute/BondedDisputeModule.sol'; +// import {ArbitratorModule, IArbitratorModule} from '../../contracts/modules/resolution/ArbitratorModule.sol'; +// import {AccountingExtension, IAccountingExtension} from '../../contracts/extensions/AccountingExtension.sol'; +// import {CallbackModule, ICallbackModule} from '../../contracts/modules/finality/CallbackModule.sol'; +// import {BondEscalationModule, IBondEscalationModule} from '../../contracts/modules/dispute/BondEscalationModule.sol'; +// import { +// BondEscalationAccounting, IBondEscalationAccounting +// } from '../../contracts/extensions/BondEscalationAccounting.sol'; + +// import {MockCallback} from '../mocks/MockCallback.sol'; +// import {MockArbitrator} from '../mocks/MockArbitrator.sol'; + +// import {TestConstants} from '../utils/TestConstants.sol'; +// import {Helpers} from '../utils/Helpers.sol'; +// // solhint-enable no-unused-import + +// contract IntegrationBase is DSTestPlus, TestConstants, Helpers { +// uint256 public constant FORK_BLOCK = 756_611; + +// uint256 internal _initialBalance = 100_000 ether; + +// address public requester = makeAddr('requester'); +// address public proposer = makeAddr('proposer'); +// address public disputer = makeAddr('disputer'); +// address public keeper = makeAddr('keeper'); +// address public governance = makeAddr('governance'); + +// Oracle public oracle; +// HttpRequestModule internal _requestModule; +// BondedResponseModule internal _responseModule; +// AccountingExtension internal _accountingExtension; +// BondEscalationAccounting internal _bondEscalationAccounting; +// BondedDisputeModule internal _bondedDisputeModule; +// ArbitratorModule internal _arbitratorModule; +// CallbackModule internal _callbackModule; +// MockCallback internal _mockCallback; +// MockArbitrator internal _mockArbitrator; +// BondEscalationModule internal _bondEscalationModule; + +// IERC20 public usdc = IERC20(label(USDC_ADDRESS, 'USDC')); +// IWETH9 public weth = IWETH9(label(WETH_ADDRESS, 'WETH')); + +// string internal _expectedUrl = 'https://api.coingecko.com/api/v3/simple/price?'; +// IHttpRequestModule.HttpMethod internal _expectedMethod = IHttpRequestModule.HttpMethod.GET; +// string internal _expectedBody = 'ids=ethereum&vs_currencies=usd'; +// string internal _expectedResponse = '{"ethereum":{"usd":1000}}'; +// uint256 internal _expectedBondSize = 100 ether; +// uint256 internal _expectedReward = 30 ether; +// uint256 internal _expectedDeadline; +// uint256 internal _expectedCallbackValue = 42; +// uint256 internal _baseDisputeWindow = 12 hours; +// bytes32 internal _ipfsHash = bytes32('QmR4uiJH654k3Ta2uLLQ8r'); + +// function setUp() public virtual { +// vm.createSelectFork(vm.rpcUrl('optimism'), FORK_BLOCK); + +// // Transfer some DAI and WETH to the users +// deal(address(weth), requester, _initialBalance); +// deal(address(usdc), requester, _initialBalance); + +// deal(address(weth), proposer, _initialBalance); +// deal(address(usdc), proposer, _initialBalance); + +// deal(address(weth), disputer, _initialBalance); +// deal(address(usdc), disputer, _initialBalance); + +// // Deploy every contract needed +// vm.startPrank(governance); + +// oracle = new Oracle(); +// label(address(oracle), 'Oracle'); + +// _requestModule = new HttpRequestModule(oracle); +// label(address(_requestModule), 'RequestModule'); + +// _responseModule = new BondedResponseModule(oracle); +// label(address(_responseModule), 'ResponseModule'); + +// _bondedDisputeModule = new BondedDisputeModule(oracle); +// label(address(_bondedDisputeModule), 'DisputeModule'); + +// _arbitratorModule = new ArbitratorModule(oracle); +// label(address(_arbitratorModule), 'ResolutionModule'); + +// _callbackModule = new CallbackModule(oracle); +// label(address(_callbackModule), 'CallbackModule'); + +// _accountingExtension = new AccountingExtension(oracle); +// label(address(_accountingExtension), 'AccountingExtension'); + +// _bondEscalationModule = new BondEscalationModule(oracle); +// label(address(_bondEscalationModule), 'BondEscalationModule'); + +// _bondEscalationAccounting = new BondEscalationAccounting(oracle); +// label(address(_bondEscalationAccounting), 'BondEscalationAccounting'); + +// _mockCallback = new MockCallback(); +// _mockArbitrator = new MockArbitrator(); +// vm.stopPrank(); +// } + +// function _mineBlock() internal { +// _mineBlocks(1); +// } + +// function _mineBlocks(uint256 _blocks) internal { +// vm.warp(block.timestamp + _blocks * BLOCK_TIME); +// vm.roll(block.number + _blocks); +// } +// } diff --git a/solidity/test/integration/Payments.t.sol b/solidity/test/integration/Payments.t.sol index a87e5fb4..a411f62e 100644 --- a/solidity/test/integration/Payments.t.sol +++ b/solidity/test/integration/Payments.t.sol @@ -1,267 +1,267 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import './IntegrationBase.sol'; - -contract Integration_Payments is IntegrationBase { - bytes32 internal _requestId; - bytes32 internal _responseId; - - function setUp() public override { - super.setUp(); - _expectedDeadline = block.timestamp + BLOCK_TIME * 600; - } - - function test_releaseValidResponse_ERC20(uint256 _rewardSize, uint256 _bondSize) public { - // Exception to avoid overflow when depositing. - vm.assume(_rewardSize < type(uint256).max - _bondSize); - - // Requester bonds and creates a request. - _forBondDepositERC20(_accountingExtension, requester, usdc, _rewardSize, _rewardSize); - IOracle.NewRequest memory _erc20Request = _standardRequest(_rewardSize, _bondSize, usdc); - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_erc20Request); - vm.stopPrank(); - - // Proposer bonds and proposes a response. - _forBondDepositERC20(_accountingExtension, proposer, usdc, _bondSize, _bondSize); - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, bytes('response')); - vm.stopPrank(); - - // Check that both users have had their funds bonded. - uint256 _requesterBondedBalanceBefore = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); - assertEq(_requesterBondedBalanceBefore, _rewardSize); - - uint256 _proposerBondedBalanceBefore = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); - assertEq(_proposerBondedBalanceBefore, _bondSize); - - // Warp to finalization time. - vm.warp(_expectedDeadline + _baseDisputeWindow); - // Finalize request/response - oracle.finalize(_requestId, _responseId); - - uint256 _requesterBalanceAfter = _accountingExtension.balanceOf(requester, usdc); - uint256 _proposerBalanceAfter = _accountingExtension.balanceOf(proposer, usdc); - - // Check: requester paid for response? - assertEq(_requesterBalanceAfter, 0); - // Check: proposer got the reward + the bonded amount back? - assertEq(_proposerBalanceAfter, _rewardSize + _bondSize); - - uint256 _requesterBondedBalanceAfter = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); - - uint256 _proposerBondedBalanceAfter = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); - - assertEq(_requesterBondedBalanceAfter, 0); - assertEq(_proposerBondedBalanceAfter, 0); - } - - function test_releaseValidResponse_ETH(uint256 _rewardSize, uint256 _bondSize) public { - // Exception to avoid overflow when depositing. - vm.assume(_rewardSize < type(uint256).max - _bondSize); - - // Requester bonds and creates request. - _forBondDepositERC20(_accountingExtension, requester, IERC20(address(weth)), _rewardSize, _rewardSize); - IOracle.NewRequest memory _ethRequest = _standardRequest(_rewardSize, _bondSize, weth); - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_ethRequest); - vm.stopPrank(); - - // Proposer bonds and creates request. - _forBondDepositERC20(_accountingExtension, proposer, IERC20(address(weth)), _bondSize, _bondSize); - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, bytes('response')); - vm.stopPrank(); - - // Check that both users have had their funds bonded. - uint256 _requesterBondedBalanceBefore = _accountingExtension.bondedAmountOf(requester, weth, _requestId); - assertEq(_requesterBondedBalanceBefore, _rewardSize); - - uint256 _proposerBondedBalanceBefore = _accountingExtension.bondedAmountOf(proposer, weth, _requestId); - assertEq(_proposerBondedBalanceBefore, _bondSize); - - // Warp to finalization time. - vm.warp(_expectedDeadline + _baseDisputeWindow); - // Finalize request/response. - oracle.finalize(_requestId, _responseId); - - uint256 _requesterBalanceAfter = _accountingExtension.balanceOf(requester, weth); - uint256 _proposerBalanceAfter = _accountingExtension.balanceOf(proposer, weth); - - // Check: requester has no balance left? - assertEq(_requesterBalanceAfter, 0); - // Check: proposer got the reward + the bonded amount back? - assertEq(_proposerBalanceAfter, _rewardSize + _bondSize); - - uint256 _requesterBondedBalanceAfter = _accountingExtension.bondedAmountOf(requester, weth, _requestId); - - uint256 _proposerBondedBalanceAfter = _accountingExtension.bondedAmountOf(proposer, weth, _requestId); - - assertEq(_requesterBondedBalanceAfter, 0); - assertEq(_proposerBondedBalanceAfter, 0); - } - - function test_releaseSuccessfulDispute_ERC20(uint256 _rewardSize, uint256 _bondSize) public { - // Exceptions to avoid overflow when depositing. - vm.assume(_bondSize < type(uint256).max / 2); - vm.assume(_rewardSize < type(uint256).max - _bondSize * 2); - - // Requester bonds and creates request. - _forBondDepositERC20(_accountingExtension, requester, usdc, _rewardSize, _rewardSize); - IOracle.NewRequest memory _erc20Request = _standardRequest(_rewardSize, _bondSize, usdc); - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_erc20Request); - vm.stopPrank(); - - // Proposer bonds and proposes response. - _forBondDepositERC20(_accountingExtension, proposer, usdc, _bondSize, _bondSize); - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, bytes('response')); - vm.stopPrank(); - - // Disputer bonds and disputes response. - _forBondDepositERC20(_accountingExtension, disputer, usdc, _bondSize, _bondSize); - vm.startPrank(disputer); - _accountingExtension.approveModule(address(_bondedDisputeModule)); - bytes32 _disputeId = oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - - // Overriding dispute status and finalizing. - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - _dispute.status = IOracle.DisputeStatus.Won; - vm.prank(address(oracle)); - _bondedDisputeModule.onDisputeStatusChange(bytes32(0), _dispute); - vm.prank(address(oracle)); - _requestModule.finalizeRequest(_requestId, address(oracle)); - - uint256 _requesterBalanceAfter = _accountingExtension.balanceOf(requester, usdc); - uint256 _proposerBalanceAfter = _accountingExtension.balanceOf(proposer, usdc); - uint256 _disputerBalanceAfter = _accountingExtension.balanceOf(disputer, usdc); - - // Check: requester gets its reward back? - assertEq(_requesterBalanceAfter, _rewardSize); - // Check: proposer get slashed? - assertEq(_proposerBalanceAfter, 0); - // Check: disputer gets proposer's bond? - assertEq(_disputerBalanceAfter, _bondSize * 2); - - uint256 _requesterBondedBalanceAfter = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); - - uint256 _proposerBondedBalanceAfter = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); - - uint256 _disputerBondedBalanceAfter = _accountingExtension.bondedAmountOf(disputer, usdc, _requestId); - - assertEq(_requesterBondedBalanceAfter, 0); - assertEq(_proposerBondedBalanceAfter, 0); - assertEq(_disputerBondedBalanceAfter, 0); - } - - function test_releaseSuccessfulDispute_ETH(uint256 _rewardSize, uint256 _bondSize) public { - // Exceptions to avoid overflow when depositing. - vm.assume(_bondSize < type(uint256).max / 2); - vm.assume(_rewardSize < type(uint256).max - _bondSize * 2); - - // Requester bonds and creates request. - _forBondDepositERC20(_accountingExtension, requester, weth, _rewardSize, _rewardSize); - IOracle.NewRequest memory _erc20Request = _standardRequest(_rewardSize, _bondSize, weth); - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_erc20Request); - vm.stopPrank(); - - // Proposer bonds and proposes response. - _forBondDepositERC20(_accountingExtension, proposer, weth, _bondSize, _bondSize); - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, bytes('response')); - vm.stopPrank(); - - // Disputer bonds and disputes response. - _forBondDepositERC20(_accountingExtension, disputer, weth, _bondSize, _bondSize); - vm.startPrank(disputer); - _accountingExtension.approveModule(address(_bondedDisputeModule)); - bytes32 _disputeId = oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - - // Overriding dispute status and finalizing. - IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); - _dispute.status = IOracle.DisputeStatus.Won; - vm.prank(address(oracle)); - _bondedDisputeModule.onDisputeStatusChange(bytes32(0), _dispute); - vm.prank(address(oracle)); - _requestModule.finalizeRequest(_requestId, address(oracle)); - - uint256 _requesterBalanceAfter = _accountingExtension.balanceOf(requester, weth); - uint256 _proposerBalanceAfter = _accountingExtension.balanceOf(proposer, weth); - uint256 _disputerBalanceAfter = _accountingExtension.balanceOf(disputer, weth); - - // Check: requester gets its reward back? - assertEq(_requesterBalanceAfter, _rewardSize); - // Check: proposer get slashed? - assertEq(_proposerBalanceAfter, 0); - // Check: disputer gets proposer's bond? - assertEq(_disputerBalanceAfter, _bondSize * 2); - - uint256 _requesterBondedBalanceAfter = _accountingExtension.bondedAmountOf(requester, weth, _requestId); - - uint256 _proposerBondedBalanceAfter = _accountingExtension.bondedAmountOf(proposer, weth, _requestId); - - uint256 _disputerBondedBalanceAfter = _accountingExtension.bondedAmountOf(disputer, weth, _requestId); - - assertEq(_requesterBondedBalanceAfter, 0); - assertEq(_proposerBondedBalanceAfter, 0); - assertEq(_disputerBondedBalanceAfter, 0); - } - - function _standardRequest( - uint256 _rewardSize, - uint256 _bondSize, - IERC20 _paymentToken - ) internal view returns (IOracle.NewRequest memory _request) { - _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accountingExtension, - paymentToken: _paymentToken, - paymentAmount: _rewardSize - }) - ), - responseModuleData: abi.encode( - IBondedResponseModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: _paymentToken, - bondSize: _bondSize, - deadline: _expectedDeadline, - disputeWindow: _baseDisputeWindow - }) - ), - disputeModuleData: abi.encode( - IBondedDisputeModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: _paymentToken, - bondSize: _bondSize - }) - ), - resolutionModuleData: abi.encode(_mockArbitrator), - finalityModuleData: abi.encode( - ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) - ), - requestModule: _requestModule, - responseModule: _responseModule, - disputeModule: _bondedDisputeModule, - resolutionModule: _arbitratorModule, - finalityModule: IFinalityModule(_callbackModule), - ipfsHash: _ipfsHash - }); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import './IntegrationBase.sol'; + +// contract Integration_Payments is IntegrationBase { +// bytes32 internal _requestId; +// bytes32 internal _responseId; + +// function setUp() public override { +// super.setUp(); +// _expectedDeadline = block.timestamp + BLOCK_TIME * 600; +// } + +// function test_releaseValidResponse_ERC20(uint256 _rewardSize, uint256 _bondSize) public { +// // Exception to avoid overflow when depositing. +// vm.assume(_rewardSize < type(uint256).max - _bondSize); + +// // Requester bonds and creates a request. +// _forBondDepositERC20(_accountingExtension, requester, usdc, _rewardSize, _rewardSize); +// IOracle.NewRequest memory _erc20Request = _standardRequest(_rewardSize, _bondSize, usdc); +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// _requestId = oracle.createRequest(_erc20Request); +// vm.stopPrank(); + +// // Proposer bonds and proposes a response. +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _bondSize, _bondSize); +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, bytes('response')); +// vm.stopPrank(); + +// // Check that both users have had their funds bonded. +// uint256 _requesterBondedBalanceBefore = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); +// assertEq(_requesterBondedBalanceBefore, _rewardSize); + +// uint256 _proposerBondedBalanceBefore = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); +// assertEq(_proposerBondedBalanceBefore, _bondSize); + +// // Warp to finalization time. +// vm.warp(_expectedDeadline + _baseDisputeWindow); +// // Finalize request/response +// oracle.finalize(_requestId, _responseId); + +// uint256 _requesterBalanceAfter = _accountingExtension.balanceOf(requester, usdc); +// uint256 _proposerBalanceAfter = _accountingExtension.balanceOf(proposer, usdc); + +// // Check: requester paid for response? +// assertEq(_requesterBalanceAfter, 0); +// // Check: proposer got the reward + the bonded amount back? +// assertEq(_proposerBalanceAfter, _rewardSize + _bondSize); + +// uint256 _requesterBondedBalanceAfter = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); + +// uint256 _proposerBondedBalanceAfter = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); + +// assertEq(_requesterBondedBalanceAfter, 0); +// assertEq(_proposerBondedBalanceAfter, 0); +// } + +// function test_releaseValidResponse_ETH(uint256 _rewardSize, uint256 _bondSize) public { +// // Exception to avoid overflow when depositing. +// vm.assume(_rewardSize < type(uint256).max - _bondSize); + +// // Requester bonds and creates request. +// _forBondDepositERC20(_accountingExtension, requester, IERC20(address(weth)), _rewardSize, _rewardSize); +// IOracle.NewRequest memory _ethRequest = _standardRequest(_rewardSize, _bondSize, weth); +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// _requestId = oracle.createRequest(_ethRequest); +// vm.stopPrank(); + +// // Proposer bonds and creates request. +// _forBondDepositERC20(_accountingExtension, proposer, IERC20(address(weth)), _bondSize, _bondSize); +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, bytes('response')); +// vm.stopPrank(); + +// // Check that both users have had their funds bonded. +// uint256 _requesterBondedBalanceBefore = _accountingExtension.bondedAmountOf(requester, weth, _requestId); +// assertEq(_requesterBondedBalanceBefore, _rewardSize); + +// uint256 _proposerBondedBalanceBefore = _accountingExtension.bondedAmountOf(proposer, weth, _requestId); +// assertEq(_proposerBondedBalanceBefore, _bondSize); + +// // Warp to finalization time. +// vm.warp(_expectedDeadline + _baseDisputeWindow); +// // Finalize request/response. +// oracle.finalize(_requestId, _responseId); + +// uint256 _requesterBalanceAfter = _accountingExtension.balanceOf(requester, weth); +// uint256 _proposerBalanceAfter = _accountingExtension.balanceOf(proposer, weth); + +// // Check: requester has no balance left? +// assertEq(_requesterBalanceAfter, 0); +// // Check: proposer got the reward + the bonded amount back? +// assertEq(_proposerBalanceAfter, _rewardSize + _bondSize); + +// uint256 _requesterBondedBalanceAfter = _accountingExtension.bondedAmountOf(requester, weth, _requestId); + +// uint256 _proposerBondedBalanceAfter = _accountingExtension.bondedAmountOf(proposer, weth, _requestId); + +// assertEq(_requesterBondedBalanceAfter, 0); +// assertEq(_proposerBondedBalanceAfter, 0); +// } + +// function test_releaseSuccessfulDispute_ERC20(uint256 _rewardSize, uint256 _bondSize) public { +// // Exceptions to avoid overflow when depositing. +// vm.assume(_bondSize < type(uint256).max / 2); +// vm.assume(_rewardSize < type(uint256).max - _bondSize * 2); + +// // Requester bonds and creates request. +// _forBondDepositERC20(_accountingExtension, requester, usdc, _rewardSize, _rewardSize); +// IOracle.NewRequest memory _erc20Request = _standardRequest(_rewardSize, _bondSize, usdc); +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// _requestId = oracle.createRequest(_erc20Request); +// vm.stopPrank(); + +// // Proposer bonds and proposes response. +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _bondSize, _bondSize); +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, bytes('response')); +// vm.stopPrank(); + +// // Disputer bonds and disputes response. +// _forBondDepositERC20(_accountingExtension, disputer, usdc, _bondSize, _bondSize); +// vm.startPrank(disputer); +// _accountingExtension.approveModule(address(_bondedDisputeModule)); +// bytes32 _disputeId = oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); + +// // Overriding dispute status and finalizing. +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// _dispute.status = IOracle.DisputeStatus.Won; +// vm.prank(address(oracle)); +// _bondedDisputeModule.onDisputeStatusChange(bytes32(0), _dispute); +// vm.prank(address(oracle)); +// _requestModule.finalizeRequest(_requestId, address(oracle)); + +// uint256 _requesterBalanceAfter = _accountingExtension.balanceOf(requester, usdc); +// uint256 _proposerBalanceAfter = _accountingExtension.balanceOf(proposer, usdc); +// uint256 _disputerBalanceAfter = _accountingExtension.balanceOf(disputer, usdc); + +// // Check: requester gets its reward back? +// assertEq(_requesterBalanceAfter, _rewardSize); +// // Check: proposer get slashed? +// assertEq(_proposerBalanceAfter, 0); +// // Check: disputer gets proposer's bond? +// assertEq(_disputerBalanceAfter, _bondSize * 2); + +// uint256 _requesterBondedBalanceAfter = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); + +// uint256 _proposerBondedBalanceAfter = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); + +// uint256 _disputerBondedBalanceAfter = _accountingExtension.bondedAmountOf(disputer, usdc, _requestId); + +// assertEq(_requesterBondedBalanceAfter, 0); +// assertEq(_proposerBondedBalanceAfter, 0); +// assertEq(_disputerBondedBalanceAfter, 0); +// } + +// function test_releaseSuccessfulDispute_ETH(uint256 _rewardSize, uint256 _bondSize) public { +// // Exceptions to avoid overflow when depositing. +// vm.assume(_bondSize < type(uint256).max / 2); +// vm.assume(_rewardSize < type(uint256).max - _bondSize * 2); + +// // Requester bonds and creates request. +// _forBondDepositERC20(_accountingExtension, requester, weth, _rewardSize, _rewardSize); +// IOracle.NewRequest memory _erc20Request = _standardRequest(_rewardSize, _bondSize, weth); +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// _requestId = oracle.createRequest(_erc20Request); +// vm.stopPrank(); + +// // Proposer bonds and proposes response. +// _forBondDepositERC20(_accountingExtension, proposer, weth, _bondSize, _bondSize); +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, bytes('response')); +// vm.stopPrank(); + +// // Disputer bonds and disputes response. +// _forBondDepositERC20(_accountingExtension, disputer, weth, _bondSize, _bondSize); +// vm.startPrank(disputer); +// _accountingExtension.approveModule(address(_bondedDisputeModule)); +// bytes32 _disputeId = oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); + +// // Overriding dispute status and finalizing. +// IOracle.Dispute memory _dispute = oracle.getDispute(_disputeId); +// _dispute.status = IOracle.DisputeStatus.Won; +// vm.prank(address(oracle)); +// _bondedDisputeModule.onDisputeStatusChange(bytes32(0), _dispute); +// vm.prank(address(oracle)); +// _requestModule.finalizeRequest(_requestId, address(oracle)); + +// uint256 _requesterBalanceAfter = _accountingExtension.balanceOf(requester, weth); +// uint256 _proposerBalanceAfter = _accountingExtension.balanceOf(proposer, weth); +// uint256 _disputerBalanceAfter = _accountingExtension.balanceOf(disputer, weth); + +// // Check: requester gets its reward back? +// assertEq(_requesterBalanceAfter, _rewardSize); +// // Check: proposer get slashed? +// assertEq(_proposerBalanceAfter, 0); +// // Check: disputer gets proposer's bond? +// assertEq(_disputerBalanceAfter, _bondSize * 2); + +// uint256 _requesterBondedBalanceAfter = _accountingExtension.bondedAmountOf(requester, weth, _requestId); + +// uint256 _proposerBondedBalanceAfter = _accountingExtension.bondedAmountOf(proposer, weth, _requestId); + +// uint256 _disputerBondedBalanceAfter = _accountingExtension.bondedAmountOf(disputer, weth, _requestId); + +// assertEq(_requesterBondedBalanceAfter, 0); +// assertEq(_proposerBondedBalanceAfter, 0); +// assertEq(_disputerBondedBalanceAfter, 0); +// } + +// function _standardRequest( +// uint256 _rewardSize, +// uint256 _bondSize, +// IERC20 _paymentToken +// ) internal view returns (IOracle.NewRequest memory _request) { +// _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accountingExtension, +// paymentToken: _paymentToken, +// paymentAmount: _rewardSize +// }) +// ), +// responseModuleData: abi.encode( +// IBondedResponseModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: _paymentToken, +// bondSize: _bondSize, +// deadline: _expectedDeadline, +// disputeWindow: _baseDisputeWindow +// }) +// ), +// disputeModuleData: abi.encode( +// IBondedDisputeModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: _paymentToken, +// bondSize: _bondSize +// }) +// ), +// resolutionModuleData: abi.encode(_mockArbitrator), +// finalityModuleData: abi.encode( +// ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) +// ), +// requestModule: _requestModule, +// responseModule: _responseModule, +// disputeModule: _bondedDisputeModule, +// resolutionModule: _arbitratorModule, +// finalityModule: IFinalityModule(_callbackModule), +// ipfsHash: _ipfsHash +// }); +// } +// } diff --git a/solidity/test/integration/RequestCreation.t.sol b/solidity/test/integration/RequestCreation.t.sol index 38fa3926..d9563d5b 100644 --- a/solidity/test/integration/RequestCreation.t.sol +++ b/solidity/test/integration/RequestCreation.t.sol @@ -1,284 +1,284 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import './IntegrationBase.sol'; - -contract Integration_RequestCreation is IntegrationBase { - bytes32 internal _requestId; - - function setUp() public override { - super.setUp(); - _expectedDeadline = block.timestamp + BLOCK_TIME * 600; - } - - function test_createRequestWithoutResolutionAndFinalityModules() public { - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); - - // Request without resolution and finality modules. - IOracle.NewRequest memory _request = _standardRequest(); - _request.resolutionModule = IResolutionModule(address(0)); - _request.finalityModule = IFinalityModule(address(0)); - _request.resolutionModuleData = bytes(''); - _request.finalityModuleData = bytes(''); +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import './IntegrationBase.sol'; + +// contract Integration_RequestCreation is IntegrationBase { +// bytes32 internal _requestId; + +// function setUp() public override { +// super.setUp(); +// _expectedDeadline = block.timestamp + BLOCK_TIME * 600; +// } + +// function test_createRequestWithoutResolutionAndFinalityModules() public { +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); + +// // Request without resolution and finality modules. +// IOracle.NewRequest memory _request = _standardRequest(); +// _request.resolutionModule = IResolutionModule(address(0)); +// _request.finalityModule = IFinalityModule(address(0)); +// _request.resolutionModuleData = bytes(''); +// _request.finalityModuleData = bytes(''); - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_request); - - // Check: request data was stored in request module? - IHttpRequestModule.RequestParameters memory _reqParams = _requestModule.decodeRequestData(_requestId); +// _requestId = oracle.createRequest(_request); + +// // Check: request data was stored in request module? +// IHttpRequestModule.RequestParameters memory _reqParams = _requestModule.decodeRequestData(_requestId); - assertEq(_reqParams.url, _expectedUrl); - assertEq(uint256(_reqParams.method), uint256(_expectedMethod)); - assertEq(_reqParams.body, _expectedBody); - assertEq(address(_reqParams.accountingExtension), address(_accountingExtension)); - assertEq(address(_reqParams.paymentToken), address(usdc)); - assertEq(_reqParams.paymentAmount, _expectedReward); - - // Check: request data was stored in response module? - IBondedResponseModule.RequestParameters memory _params = _responseModule.decodeRequestData(_requestId); - assertEq(address(_accountingExtension), address(_params.accountingExtension)); - assertEq(address(_params.bondToken), address(usdc)); - assertEq(_expectedBondSize, _params.bondSize); - assertEq(_expectedDeadline, _params.deadline); - - // Check: request data was stored in dispute module? - IBondedDisputeModule.RequestParameters memory _params2 = _bondedDisputeModule.decodeRequestData(_requestId); - - assertEq(address(_accountingExtension), address(_params2.accountingExtension)); - assertEq(address(_params.bondToken), address(_params2.bondToken)); - assertEq(_expectedBondSize, _params2.bondSize); - - // Check: is finality and resolution data stored as empty? - IOracle.FullRequest memory _fullRequest = oracle.getFullRequest(_requestId); - assertEq(_fullRequest.finalityModuleData, bytes('')); - assertEq(_fullRequest.resolutionModuleData, bytes('')); - assertEq(address(_fullRequest.finalityModule), address(0)); - assertEq(address(_fullRequest.resolutionModule), address(0)); - } - - function test_createRequestWithAllModules() public { - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); - - // Request with all modules. - IOracle.NewRequest memory _request = _standardRequest(); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_request); - - // Check: request data was stored in request module? - IHttpRequestModule.RequestParameters memory _reqParams = _requestModule.decodeRequestData(_requestId); - - assertEq(_reqParams.url, _expectedUrl); - assertEq(uint256(_reqParams.method), uint256(_expectedMethod)); - assertEq(_reqParams.body, _expectedBody); - assertEq(address(_reqParams.accountingExtension), address(_accountingExtension)); - assertEq(address(_reqParams.paymentToken), address(usdc)); - assertEq(_reqParams.paymentAmount, _expectedReward); - - // Check: request data was stored in response module? - IBondedResponseModule.RequestParameters memory _params = _responseModule.decodeRequestData(_requestId); - - assertEq(address(_accountingExtension), address(_params.accountingExtension)); - assertEq(address(_params.bondToken), address(usdc)); - assertEq(_expectedBondSize, _params.bondSize); - assertEq(_expectedDeadline, _params.deadline); - - // Check: request data was stored in dispute module? - IBondedDisputeModule.RequestParameters memory _params2 = _bondedDisputeModule.decodeRequestData(_requestId); - - assertEq(address(_accountingExtension), address(_params2.accountingExtension)); - assertEq(address(_params.bondToken), address(_params2.bondToken)); - assertEq(_expectedBondSize, _params2.bondSize); - - // Check: request data was stored in resolution module? - (address _arbitrator) = _arbitratorModule.decodeRequestData(_requestId); - assertEq(_arbitrator, address(_mockArbitrator)); - - // Check: request data was stored in finality module? - ICallbackModule.RequestParameters memory _callbackParams = _callbackModule.decodeRequestData(_requestId); - assertEq(_callbackParams.target, address(_mockCallback)); - assertEq(_callbackParams.data, abi.encode(_expectedCallbackValue)); - } - - function test_createRequestWithReward_UserHasBonded() public { - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); - - // Request with rewards. - IOracle.NewRequest memory _request = _standardRequest(); - - // Check: should not revert as user has bonded. - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - - oracle.createRequest(_request); - } - - function test_createRequestWithReward_UserHasNotBonded() public { - // Request with rewards. - IOracle.NewRequest memory _request = _standardRequest(); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - - // Check: should revert with `InsufficientFunds` as user has not deposited. - vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); - _requestId = oracle.createRequest(_request); - } - - function test_createRequestWithoutReward_UserHasBonded() public { - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); - - // Request without rewards. - IOracle.NewRequest memory _request = _standardRequest(); - _request.requestModuleData = abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accountingExtension, - paymentToken: IERC20(USDC_ADDRESS), - paymentAmount: 0 - }) - ); - // Check: should not revert as user has set no rewards and bonded. - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - - oracle.createRequest(_request); - } - - function test_createRequestWithoutReward_UserHasNotBonded() public { - // Request without rewards - IOracle.NewRequest memory _request = _standardRequest(); - _request.requestModuleData = abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accountingExtension, - paymentToken: IERC20(USDC_ADDRESS), - paymentAmount: 0 - }) - ); - - vm.startPrank(requester); - // Approving the request module to bond the requester tokens - _accountingExtension.approveModule(address(_requestModule)); - - // Check: should not revert as user has set no rewards. - oracle.createRequest(_request); - } - - function test_createRequestDuplicate() public { - // Double token amount as each request is a unique bond. - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward * 2, _expectedReward * 2); - - IOracle.NewRequest memory _request = _standardRequest(); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - - bytes32 _firstRequestId = oracle.createRequest(_request); - bytes32 _secondRequestId = oracle.createRequest(_request); - vm.stopPrank(); - - assertTrue(_firstRequestId != _secondRequestId, 'Request IDs should not be equal'); - } - - function test_createRequestWithInvalidParameters() public { - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); - - // Request with invalid token address. - IOracle.NewRequest memory _invalidTokenRequest = _standardRequest(); - _invalidTokenRequest.requestModuleData = abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accountingExtension, - paymentToken: IERC20(address(0)), - paymentAmount: _expectedReward - }) - ); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - - vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); - oracle.createRequest(_invalidTokenRequest); - - // Request with past deadline. - IOracle.NewRequest memory _invalidDeadlineRequest = _standardRequest(); - _invalidDeadlineRequest.responseModuleData = - abi.encode(_accountingExtension, USDC_ADDRESS, _expectedBondSize, block.timestamp - 1 hours); - - vm.expectRevert(); - oracle.createRequest(_invalidDeadlineRequest); - } - - function test_createRequestWithDisallowedModule() public { - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); - - IOracle.NewRequest memory _request = _standardRequest(); - _request.requestModule = IRequestModule(address(_responseModule)); - _request.responseModule = IResponseModule(address(_requestModule)); - - vm.startPrank(requester); - // Check: reverts with `EVM error`? - vm.expectRevert(); - oracle.createRequest(_request); - - // Check: switch modules back and give a non-existent module. Reverts? - vm.expectRevert(); - _request.requestModule = _requestModule; - _request.responseModule = _responseModule; - _request.disputeModule = IDisputeModule(makeAddr('NON-EXISTENT DISPUTE MODULE')); - oracle.createRequest(_request); - - vm.stopPrank(); - } - - function _standardRequest() internal view returns (IOracle.NewRequest memory _request) { - _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accountingExtension, - paymentToken: IERC20(USDC_ADDRESS), - paymentAmount: _expectedReward - }) - ), - responseModuleData: abi.encode( - IBondedResponseModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize, - deadline: _expectedDeadline, - disputeWindow: _baseDisputeWindow - }) - ), - disputeModuleData: abi.encode( - IBondedDisputeModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize - }) - ), - resolutionModuleData: abi.encode(_mockArbitrator), - finalityModuleData: abi.encode( - ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) - ), - requestModule: _requestModule, - responseModule: _responseModule, - disputeModule: _bondedDisputeModule, - resolutionModule: _arbitratorModule, - finalityModule: IFinalityModule(_callbackModule), - ipfsHash: _ipfsHash - }); - } -} +// assertEq(_reqParams.url, _expectedUrl); +// assertEq(uint256(_reqParams.method), uint256(_expectedMethod)); +// assertEq(_reqParams.body, _expectedBody); +// assertEq(address(_reqParams.accountingExtension), address(_accountingExtension)); +// assertEq(address(_reqParams.paymentToken), address(usdc)); +// assertEq(_reqParams.paymentAmount, _expectedReward); + +// // Check: request data was stored in response module? +// IBondedResponseModule.RequestParameters memory _params = _responseModule.decodeRequestData(_requestId); +// assertEq(address(_accountingExtension), address(_params.accountingExtension)); +// assertEq(address(_params.bondToken), address(usdc)); +// assertEq(_expectedBondSize, _params.bondSize); +// assertEq(_expectedDeadline, _params.deadline); + +// // Check: request data was stored in dispute module? +// IBondedDisputeModule.RequestParameters memory _params2 = _bondedDisputeModule.decodeRequestData(_requestId); + +// assertEq(address(_accountingExtension), address(_params2.accountingExtension)); +// assertEq(address(_params.bondToken), address(_params2.bondToken)); +// assertEq(_expectedBondSize, _params2.bondSize); + +// // Check: is finality and resolution data stored as empty? +// IOracle.FullRequest memory _fullRequest = oracle.getFullRequest(_requestId); +// assertEq(_fullRequest.finalityModuleData, bytes('')); +// assertEq(_fullRequest.resolutionModuleData, bytes('')); +// assertEq(address(_fullRequest.finalityModule), address(0)); +// assertEq(address(_fullRequest.resolutionModule), address(0)); +// } + +// function test_createRequestWithAllModules() public { +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); + +// // Request with all modules. +// IOracle.NewRequest memory _request = _standardRequest(); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// _requestId = oracle.createRequest(_request); + +// // Check: request data was stored in request module? +// IHttpRequestModule.RequestParameters memory _reqParams = _requestModule.decodeRequestData(_requestId); + +// assertEq(_reqParams.url, _expectedUrl); +// assertEq(uint256(_reqParams.method), uint256(_expectedMethod)); +// assertEq(_reqParams.body, _expectedBody); +// assertEq(address(_reqParams.accountingExtension), address(_accountingExtension)); +// assertEq(address(_reqParams.paymentToken), address(usdc)); +// assertEq(_reqParams.paymentAmount, _expectedReward); + +// // Check: request data was stored in response module? +// IBondedResponseModule.RequestParameters memory _params = _responseModule.decodeRequestData(_requestId); + +// assertEq(address(_accountingExtension), address(_params.accountingExtension)); +// assertEq(address(_params.bondToken), address(usdc)); +// assertEq(_expectedBondSize, _params.bondSize); +// assertEq(_expectedDeadline, _params.deadline); + +// // Check: request data was stored in dispute module? +// IBondedDisputeModule.RequestParameters memory _params2 = _bondedDisputeModule.decodeRequestData(_requestId); + +// assertEq(address(_accountingExtension), address(_params2.accountingExtension)); +// assertEq(address(_params.bondToken), address(_params2.bondToken)); +// assertEq(_expectedBondSize, _params2.bondSize); + +// // Check: request data was stored in resolution module? +// (address _arbitrator) = _arbitratorModule.decodeRequestData(_requestId); +// assertEq(_arbitrator, address(_mockArbitrator)); + +// // Check: request data was stored in finality module? +// ICallbackModule.RequestParameters memory _callbackParams = _callbackModule.decodeRequestData(_requestId); +// assertEq(_callbackParams.target, address(_mockCallback)); +// assertEq(_callbackParams.data, abi.encode(_expectedCallbackValue)); +// } + +// function test_createRequestWithReward_UserHasBonded() public { +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); + +// // Request with rewards. +// IOracle.NewRequest memory _request = _standardRequest(); + +// // Check: should not revert as user has bonded. +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); + +// oracle.createRequest(_request); +// } + +// function test_createRequestWithReward_UserHasNotBonded() public { +// // Request with rewards. +// IOracle.NewRequest memory _request = _standardRequest(); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); + +// // Check: should revert with `InsufficientFunds` as user has not deposited. +// vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); +// _requestId = oracle.createRequest(_request); +// } + +// function test_createRequestWithoutReward_UserHasBonded() public { +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); + +// // Request without rewards. +// IOracle.NewRequest memory _request = _standardRequest(); +// _request.requestModuleData = abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accountingExtension, +// paymentToken: IERC20(USDC_ADDRESS), +// paymentAmount: 0 +// }) +// ); +// // Check: should not revert as user has set no rewards and bonded. +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); + +// oracle.createRequest(_request); +// } + +// function test_createRequestWithoutReward_UserHasNotBonded() public { +// // Request without rewards +// IOracle.NewRequest memory _request = _standardRequest(); +// _request.requestModuleData = abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accountingExtension, +// paymentToken: IERC20(USDC_ADDRESS), +// paymentAmount: 0 +// }) +// ); + +// vm.startPrank(requester); +// // Approving the request module to bond the requester tokens +// _accountingExtension.approveModule(address(_requestModule)); + +// // Check: should not revert as user has set no rewards. +// oracle.createRequest(_request); +// } + +// function test_createRequestDuplicate() public { +// // Double token amount as each request is a unique bond. +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward * 2, _expectedReward * 2); + +// IOracle.NewRequest memory _request = _standardRequest(); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); + +// bytes32 _firstRequestId = oracle.createRequest(_request); +// bytes32 _secondRequestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// assertTrue(_firstRequestId != _secondRequestId, 'Request IDs should not be equal'); +// } + +// function test_createRequestWithInvalidParameters() public { +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); + +// // Request with invalid token address. +// IOracle.NewRequest memory _invalidTokenRequest = _standardRequest(); +// _invalidTokenRequest.requestModuleData = abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accountingExtension, +// paymentToken: IERC20(address(0)), +// paymentAmount: _expectedReward +// }) +// ); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); + +// vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); +// oracle.createRequest(_invalidTokenRequest); + +// // Request with past deadline. +// IOracle.NewRequest memory _invalidDeadlineRequest = _standardRequest(); +// _invalidDeadlineRequest.responseModuleData = +// abi.encode(_accountingExtension, USDC_ADDRESS, _expectedBondSize, block.timestamp - 1 hours); + +// vm.expectRevert(); +// oracle.createRequest(_invalidDeadlineRequest); +// } + +// function test_createRequestWithDisallowedModule() public { +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); + +// IOracle.NewRequest memory _request = _standardRequest(); +// _request.requestModule = IRequestModule(address(_responseModule)); +// _request.responseModule = IResponseModule(address(_requestModule)); + +// vm.startPrank(requester); +// // Check: reverts with `EVM error`? +// vm.expectRevert(); +// oracle.createRequest(_request); + +// // Check: switch modules back and give a non-existent module. Reverts? +// vm.expectRevert(); +// _request.requestModule = _requestModule; +// _request.responseModule = _responseModule; +// _request.disputeModule = IDisputeModule(makeAddr('NON-EXISTENT DISPUTE MODULE')); +// oracle.createRequest(_request); + +// vm.stopPrank(); +// } + +// function _standardRequest() internal view returns (IOracle.NewRequest memory _request) { +// _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accountingExtension, +// paymentToken: IERC20(USDC_ADDRESS), +// paymentAmount: _expectedReward +// }) +// ), +// responseModuleData: abi.encode( +// IBondedResponseModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize, +// deadline: _expectedDeadline, +// disputeWindow: _baseDisputeWindow +// }) +// ), +// disputeModuleData: abi.encode( +// IBondedDisputeModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize +// }) +// ), +// resolutionModuleData: abi.encode(_mockArbitrator), +// finalityModuleData: abi.encode( +// ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) +// ), +// requestModule: _requestModule, +// responseModule: _responseModule, +// disputeModule: _bondedDisputeModule, +// resolutionModule: _arbitratorModule, +// finalityModule: IFinalityModule(_callbackModule), +// ipfsHash: _ipfsHash +// }); +// } +// } diff --git a/solidity/test/integration/ResponseDispute.t.sol b/solidity/test/integration/ResponseDispute.t.sol index c27af683..cb8c85d4 100644 --- a/solidity/test/integration/ResponseDispute.t.sol +++ b/solidity/test/integration/ResponseDispute.t.sol @@ -1,171 +1,171 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import './IntegrationBase.sol'; - -contract Integration_ResponseDispute is IntegrationBase { - bytes internal _responseData; - bytes32 internal _requestId; - bytes32 internal _responseId; - - function setUp() public override { - super.setUp(); - - _expectedDeadline = block.timestamp + BLOCK_TIME * 600; - _responseData = abi.encode('response'); - - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); - - IOracle.NewRequest memory _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accountingExtension, - paymentToken: IERC20(USDC_ADDRESS), - paymentAmount: _expectedReward - }) - ), - responseModuleData: abi.encode( - IBondedResponseModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize, - deadline: _expectedDeadline, - disputeWindow: _baseDisputeWindow - }) - ), - disputeModuleData: abi.encode( - IBondedDisputeModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize - }) - ), - resolutionModuleData: abi.encode(_mockArbitrator), - finalityModuleData: abi.encode( - ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) - ), - requestModule: _requestModule, - responseModule: _responseModule, - disputeModule: _bondedDisputeModule, - resolutionModule: _arbitratorModule, - finalityModule: IFinalityModule(_callbackModule), - ipfsHash: _ipfsHash - }); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_request); - vm.stopPrank(); - - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(_requestId, _responseData); - vm.stopPrank(); - } - - // check that the dispute id is stored in the response struct - function test_disputeResponse_disputeIdStoredInResponse() public { - _forBondDepositERC20(_accountingExtension, disputer, usdc, _expectedBondSize, _expectedBondSize); - - vm.startPrank(disputer); - _accountingExtension.approveModule(address(_bondedDisputeModule)); - bytes32 _disputeId = oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - - IOracle.Response memory _disputedResponse = oracle.getResponse(_responseId); - assertEq(_disputedResponse.disputeId, _disputeId); - } - - // dispute a non-existent response - function test_disputeResponse_nonExistentResponse(bytes32 _nonExistentResponseId) public { - vm.assume(_nonExistentResponseId != _responseId); - vm.prank(disputer); - - vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidResponseId.selector, _nonExistentResponseId)); - oracle.disputeResponse(_requestId, _nonExistentResponseId); - } - - function test_disputeResponse_requestAndResponseMismatch() public { - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); - IOracle.NewRequest memory _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accountingExtension, - paymentToken: IERC20(USDC_ADDRESS), - paymentAmount: _expectedReward - }) - ), - responseModuleData: abi.encode( - _accountingExtension, USDC_ADDRESS, _expectedBondSize, _expectedDeadline, _baseDisputeWindow - ), - disputeModuleData: abi.encode( - _accountingExtension, USDC_ADDRESS, _expectedBondSize, _expectedDeadline, _mockArbitrator - ), - resolutionModuleData: abi.encode(_mockArbitrator), - finalityModuleData: abi.encode( - ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) - ), - requestModule: _requestModule, - responseModule: _responseModule, - disputeModule: _bondedDisputeModule, - resolutionModule: _arbitratorModule, - finalityModule: IFinalityModule(_callbackModule), - ipfsHash: _ipfsHash - }); - vm.prank(requester); - bytes32 _secondRequest = oracle.createRequest(_request); - - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - vm.prank(proposer); - bytes32 _secondResponseId = oracle.proposeResponse(_secondRequest, _responseData); - - vm.prank(disputer); - vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidResponseId.selector, _secondResponseId)); - oracle.disputeResponse(_requestId, _secondResponseId); - } - - function test_disputeResponse_noBondedFunds() public { - vm.startPrank(disputer); - _accountingExtension.approveModule(address(_bondedDisputeModule)); - vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); - oracle.disputeResponse(_requestId, _responseId); - } - - function test_disputeResponse_alreadyFinalized() public { - vm.warp(_expectedDeadline + _baseDisputeWindow); - oracle.finalize(_requestId, _responseId); - - vm.prank(disputer); - vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_AlreadyFinalized.selector, _requestId)); - oracle.disputeResponse(_requestId, _responseId); - } - - function test_disputeResponse_alreadyDisputed() public { - _forBondDepositERC20(_accountingExtension, disputer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(disputer); - _accountingExtension.approveModule(address(_bondedDisputeModule)); - oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - - vm.prank(disputer); - vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_ResponseAlreadyDisputed.selector, _responseId)); - oracle.disputeResponse(_requestId, _responseId); - } - - // TODO: discuss and decide on the implementation of a dispute deadline - // function test_disputeResponse_afterDeadline(uint256 _timestamp) public { - // vm.assume(_timestamp > _expectedDeadline); - // _bondDisputerFunds(); - // vm.warp(_timestamp); - // vm.prank(disputer); - // vm.expectRevert(abi.encodeWithSelector(IBondedDisputeModule.BondedDisputeModule_TooLateToDispute.selector, _responseId)); - // oracle.disputeResponse(_requestId, _responseId); - // } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import './IntegrationBase.sol'; + +// contract Integration_ResponseDispute is IntegrationBase { +// bytes internal _responseData; +// bytes32 internal _requestId; +// bytes32 internal _responseId; + +// function setUp() public override { +// super.setUp(); + +// _expectedDeadline = block.timestamp + BLOCK_TIME * 600; +// _responseData = abi.encode('response'); + +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); + +// IOracle.NewRequest memory _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accountingExtension, +// paymentToken: IERC20(USDC_ADDRESS), +// paymentAmount: _expectedReward +// }) +// ), +// responseModuleData: abi.encode( +// IBondedResponseModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize, +// deadline: _expectedDeadline, +// disputeWindow: _baseDisputeWindow +// }) +// ), +// disputeModuleData: abi.encode( +// IBondedDisputeModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize +// }) +// ), +// resolutionModuleData: abi.encode(_mockArbitrator), +// finalityModuleData: abi.encode( +// ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) +// ), +// requestModule: _requestModule, +// responseModule: _responseModule, +// disputeModule: _bondedDisputeModule, +// resolutionModule: _arbitratorModule, +// finalityModule: IFinalityModule(_callbackModule), +// ipfsHash: _ipfsHash +// }); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// _requestId = oracle.createRequest(_request); +// vm.stopPrank(); + +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// _responseId = oracle.proposeResponse(_requestId, _responseData); +// vm.stopPrank(); +// } + +// // check that the dispute id is stored in the response struct +// function test_disputeResponse_disputeIdStoredInResponse() public { +// _forBondDepositERC20(_accountingExtension, disputer, usdc, _expectedBondSize, _expectedBondSize); + +// vm.startPrank(disputer); +// _accountingExtension.approveModule(address(_bondedDisputeModule)); +// bytes32 _disputeId = oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); + +// IOracle.Response memory _disputedResponse = oracle.getResponse(_responseId); +// assertEq(_disputedResponse.disputeId, _disputeId); +// } + +// // dispute a non-existent response +// function test_disputeResponse_nonExistentResponse(bytes32 _nonExistentResponseId) public { +// vm.assume(_nonExistentResponseId != _responseId); +// vm.prank(disputer); + +// vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidResponseId.selector, _nonExistentResponseId)); +// oracle.disputeResponse(_requestId, _nonExistentResponseId); +// } + +// function test_disputeResponse_requestAndResponseMismatch() public { +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedBondSize, _expectedBondSize); +// IOracle.NewRequest memory _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accountingExtension, +// paymentToken: IERC20(USDC_ADDRESS), +// paymentAmount: _expectedReward +// }) +// ), +// responseModuleData: abi.encode( +// _accountingExtension, USDC_ADDRESS, _expectedBondSize, _expectedDeadline, _baseDisputeWindow +// ), +// disputeModuleData: abi.encode( +// _accountingExtension, USDC_ADDRESS, _expectedBondSize, _expectedDeadline, _mockArbitrator +// ), +// resolutionModuleData: abi.encode(_mockArbitrator), +// finalityModuleData: abi.encode( +// ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) +// ), +// requestModule: _requestModule, +// responseModule: _responseModule, +// disputeModule: _bondedDisputeModule, +// resolutionModule: _arbitratorModule, +// finalityModule: IFinalityModule(_callbackModule), +// ipfsHash: _ipfsHash +// }); +// vm.prank(requester); +// bytes32 _secondRequest = oracle.createRequest(_request); + +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.prank(proposer); +// bytes32 _secondResponseId = oracle.proposeResponse(_secondRequest, _responseData); + +// vm.prank(disputer); +// vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidResponseId.selector, _secondResponseId)); +// oracle.disputeResponse(_requestId, _secondResponseId); +// } + +// function test_disputeResponse_noBondedFunds() public { +// vm.startPrank(disputer); +// _accountingExtension.approveModule(address(_bondedDisputeModule)); +// vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); +// oracle.disputeResponse(_requestId, _responseId); +// } + +// function test_disputeResponse_alreadyFinalized() public { +// vm.warp(_expectedDeadline + _baseDisputeWindow); +// oracle.finalize(_requestId, _responseId); + +// vm.prank(disputer); +// vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_AlreadyFinalized.selector, _requestId)); +// oracle.disputeResponse(_requestId, _responseId); +// } + +// function test_disputeResponse_alreadyDisputed() public { +// _forBondDepositERC20(_accountingExtension, disputer, usdc, _expectedBondSize, _expectedBondSize); +// vm.startPrank(disputer); +// _accountingExtension.approveModule(address(_bondedDisputeModule)); +// oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); + +// vm.prank(disputer); +// vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_ResponseAlreadyDisputed.selector, _responseId)); +// oracle.disputeResponse(_requestId, _responseId); +// } + +// // TODO: discuss and decide on the implementation of a dispute deadline +// // function test_disputeResponse_afterDeadline(uint256 _timestamp) public { +// // vm.assume(_timestamp > _expectedDeadline); +// // _bondDisputerFunds(); +// // vm.warp(_timestamp); +// // vm.prank(disputer); +// // vm.expectRevert(abi.encodeWithSelector(IBondedDisputeModule.BondedDisputeModule_TooLateToDispute.selector, _responseId)); +// // oracle.disputeResponse(_requestId, _responseId); +// // } +// } diff --git a/solidity/test/integration/ResponseProposal.t.sol b/solidity/test/integration/ResponseProposal.t.sol index f329ff57..d7809076 100644 --- a/solidity/test/integration/ResponseProposal.t.sol +++ b/solidity/test/integration/ResponseProposal.t.sol @@ -1,188 +1,188 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import './IntegrationBase.sol'; - -contract Integration_ResponseProposal is IntegrationBase { - bytes32 internal _requestId; - - function setUp() public override { - super.setUp(); - - _expectedDeadline = block.timestamp + BLOCK_TIME * 600; - - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); - - IOracle.NewRequest memory _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - IHttpRequestModule.RequestParameters({ - url: _expectedUrl, - method: _expectedMethod, - body: _expectedBody, - accountingExtension: _accountingExtension, - paymentToken: IERC20(USDC_ADDRESS), - paymentAmount: _expectedReward - }) - ), - responseModuleData: abi.encode( - IBondedResponseModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize, - deadline: _expectedDeadline, - disputeWindow: _baseDisputeWindow - }) - ), - disputeModuleData: abi.encode( - IBondedDisputeModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize - }) - ), - resolutionModuleData: abi.encode(_mockArbitrator), - finalityModuleData: abi.encode( - ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) - ), - requestModule: _requestModule, - responseModule: _responseModule, - disputeModule: _bondedDisputeModule, - resolutionModule: _arbitratorModule, - finalityModule: IFinalityModule(_callbackModule), - ipfsHash: _ipfsHash - }); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(_request); - } - - function test_proposeResponse_validResponse(bytes memory _response) public { - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - bytes32 _responseId = oracle.proposeResponse(_requestId, _response); - vm.stopPrank(); - - IOracle.Response memory _responseData = oracle.getResponse(_responseId); - - // Check: response data is correctly stored? - assertEq(_responseData.proposer, proposer); - assertEq(_responseData.response, _response); - assertEq(_responseData.createdAt, block.timestamp); - assertEq(_responseData.disputeId, bytes32(0)); - } - - function test_proposeResponse_afterDeadline(uint256 _timestamp, bytes memory _response) public { - vm.assume(_timestamp > _expectedDeadline); - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - - // Warp to timestamp after deadline - vm.warp(_timestamp); - // Check: does revert if deadline is passed? - vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooLateToPropose.selector); - - vm.prank(proposer); - oracle.proposeResponse(_requestId, _response); - } - - function test_proposeResponse_alreadyResponded(bytes memory _response) public { - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - - // First response - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - oracle.proposeResponse(_requestId, _response); - vm.stopPrank(); - - // Check: does revert if already responded? - vm.expectRevert(IBondedResponseModule.BondedResponseModule_AlreadyResponded.selector); - - // Second response - vm.prank(proposer); - oracle.proposeResponse(_requestId, _response); - } - - function test_proposeResponse_nonExistentRequest(bytes memory _response, bytes32 _nonExistentRequestId) public { - vm.assume(_nonExistentRequestId != _requestId); - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - - // Check: does revert if request does not exist? - vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidRequestId.selector, _nonExistentRequestId)); - - vm.prank(proposer); - oracle.proposeResponse(_nonExistentRequestId, _response); - } - // Proposing without enough funds bonded (should revert insufficient funds) - - function test_proposeResponse_insufficientFunds(bytes memory _response) public { - // Check: does revert if proposer does not have enough funds bonded? - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - - vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); - oracle.proposeResponse(_requestId, _response); - } - - function test_deleteResponse(bytes memory _responseData) public { - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - bytes32 _responseId = oracle.proposeResponse(_requestId, _responseData); - vm.stopPrank(); - - IOracle.Response memory _response = oracle.getResponse(_responseId); - assertEq(_response.proposer, proposer); - assertEq(_response.response, _responseData); - assertEq(_response.createdAt, block.timestamp); - assertEq(_response.disputeId, bytes32(0)); - - vm.prank(proposer); - oracle.deleteResponse(_responseId); - - // Check: response data is correctly deleted? - IOracle.Response memory _deletedResponse = oracle.getResponse(_responseId); - assertEq(_deletedResponse.proposer, address(0)); - assertEq(_deletedResponse.response.length, 0); - assertEq(_deletedResponse.createdAt, 0); - assertEq(_deletedResponse.disputeId, bytes32(0)); - } - - function test_deleteResponse_afterDeadline(bytes memory _responseData, uint256 _timestamp) public { - vm.assume(_timestamp > _expectedDeadline); - - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - bytes32 _responseId = oracle.proposeResponse(_requestId, _responseData); - vm.stopPrank(); +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import './IntegrationBase.sol'; + +// contract Integration_ResponseProposal is IntegrationBase { +// bytes32 internal _requestId; + +// function setUp() public override { +// super.setUp(); + +// _expectedDeadline = block.timestamp + BLOCK_TIME * 600; + +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); + +// IOracle.NewRequest memory _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: _expectedUrl, +// method: _expectedMethod, +// body: _expectedBody, +// accountingExtension: _accountingExtension, +// paymentToken: IERC20(USDC_ADDRESS), +// paymentAmount: _expectedReward +// }) +// ), +// responseModuleData: abi.encode( +// IBondedResponseModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize, +// deadline: _expectedDeadline, +// disputeWindow: _baseDisputeWindow +// }) +// ), +// disputeModuleData: abi.encode( +// IBondedDisputeModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize +// }) +// ), +// resolutionModuleData: abi.encode(_mockArbitrator), +// finalityModuleData: abi.encode( +// ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) +// ), +// requestModule: _requestModule, +// responseModule: _responseModule, +// disputeModule: _bondedDisputeModule, +// resolutionModule: _arbitratorModule, +// finalityModule: IFinalityModule(_callbackModule), +// ipfsHash: _ipfsHash +// }); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_requestModule)); +// _requestId = oracle.createRequest(_request); +// } + +// function test_proposeResponse_validResponse(bytes memory _response) public { +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); + +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// bytes32 _responseId = oracle.proposeResponse(_requestId, _response); +// vm.stopPrank(); + +// IOracle.Response memory _responseData = oracle.getResponse(_responseId); + +// // Check: response data is correctly stored? +// assertEq(_responseData.proposer, proposer); +// assertEq(_responseData.response, _response); +// assertEq(_responseData.createdAt, block.timestamp); +// assertEq(_responseData.disputeId, bytes32(0)); +// } + +// function test_proposeResponse_afterDeadline(uint256 _timestamp, bytes memory _response) public { +// vm.assume(_timestamp > _expectedDeadline); +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); + +// // Warp to timestamp after deadline +// vm.warp(_timestamp); +// // Check: does revert if deadline is passed? +// vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooLateToPropose.selector); + +// vm.prank(proposer); +// oracle.proposeResponse(_requestId, _response); +// } + +// function test_proposeResponse_alreadyResponded(bytes memory _response) public { +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); + +// // First response +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// oracle.proposeResponse(_requestId, _response); +// vm.stopPrank(); + +// // Check: does revert if already responded? +// vm.expectRevert(IBondedResponseModule.BondedResponseModule_AlreadyResponded.selector); + +// // Second response +// vm.prank(proposer); +// oracle.proposeResponse(_requestId, _response); +// } + +// function test_proposeResponse_nonExistentRequest(bytes memory _response, bytes32 _nonExistentRequestId) public { +// vm.assume(_nonExistentRequestId != _requestId); +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); + +// // Check: does revert if request does not exist? +// vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidRequestId.selector, _nonExistentRequestId)); + +// vm.prank(proposer); +// oracle.proposeResponse(_nonExistentRequestId, _response); +// } +// // Proposing without enough funds bonded (should revert insufficient funds) + +// function test_proposeResponse_insufficientFunds(bytes memory _response) public { +// // Check: does revert if proposer does not have enough funds bonded? +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); + +// vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); +// oracle.proposeResponse(_requestId, _response); +// } + +// function test_deleteResponse(bytes memory _responseData) public { +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); + +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// bytes32 _responseId = oracle.proposeResponse(_requestId, _responseData); +// vm.stopPrank(); + +// IOracle.Response memory _response = oracle.getResponse(_responseId); +// assertEq(_response.proposer, proposer); +// assertEq(_response.response, _responseData); +// assertEq(_response.createdAt, block.timestamp); +// assertEq(_response.disputeId, bytes32(0)); + +// vm.prank(proposer); +// oracle.deleteResponse(_responseId); + +// // Check: response data is correctly deleted? +// IOracle.Response memory _deletedResponse = oracle.getResponse(_responseId); +// assertEq(_deletedResponse.proposer, address(0)); +// assertEq(_deletedResponse.response.length, 0); +// assertEq(_deletedResponse.createdAt, 0); +// assertEq(_deletedResponse.disputeId, bytes32(0)); +// } + +// function test_deleteResponse_afterDeadline(bytes memory _responseData, uint256 _timestamp) public { +// vm.assume(_timestamp > _expectedDeadline); + +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); + +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// bytes32 _responseId = oracle.proposeResponse(_requestId, _responseData); +// vm.stopPrank(); - vm.warp(_timestamp); - - vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooLateToDelete.selector); +// vm.warp(_timestamp); + +// vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooLateToDelete.selector); - vm.prank(proposer); - oracle.deleteResponse(_responseId); - } - - function test_proposeResponse_finalizedRequest(bytes memory _responseData, uint256 _timestamp) public { - vm.assume(_timestamp > _expectedDeadline + _baseDisputeWindow); - - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); +// vm.prank(proposer); +// oracle.deleteResponse(_responseId); +// } + +// function test_proposeResponse_finalizedRequest(bytes memory _responseData, uint256 _timestamp) public { +// vm.assume(_timestamp > _expectedDeadline + _baseDisputeWindow); + +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - bytes32 _responseId = oracle.proposeResponse(_requestId, _responseData); - vm.stopPrank(); +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// bytes32 _responseId = oracle.proposeResponse(_requestId, _responseData); +// vm.stopPrank(); - vm.warp(_timestamp); - oracle.finalize(_requestId, _responseId); +// vm.warp(_timestamp); +// oracle.finalize(_requestId, _responseId); - vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_AlreadyFinalized.selector, _requestId)); - vm.prank(proposer); - oracle.proposeResponse(_requestId, _responseData); - } -} +// vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_AlreadyFinalized.selector, _requestId)); +// vm.prank(proposer); +// oracle.proposeResponse(_requestId, _responseData); +// } +// } diff --git a/solidity/test/integration/RootVerification.t.sol b/solidity/test/integration/RootVerification.t.sol index dc1add92..7d0764a4 100644 --- a/solidity/test/integration/RootVerification.t.sol +++ b/solidity/test/integration/RootVerification.t.sol @@ -1,195 +1,195 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -import './IntegrationBase.sol'; -import { - SparseMerkleTreeRequestModule, - ISparseMerkleTreeRequestModule, - IOracle -} from '../../contracts/modules/request/SparseMerkleTreeRequestModule.sol'; -import {SparseMerkleTreeL32Verifier} from '../../contracts/periphery/SparseMerkleTreeL32Verifier.sol'; -import { - RootVerificationModule, IRootVerificationModule -} from '../../contracts/modules/dispute/RootVerificationModule.sol'; -import {ITreeVerifier} from '../../interfaces/ITreeVerifier.sol'; - -contract Integration_RootVerification is IntegrationBase { - SparseMerkleTreeL32Verifier internal _treeVerifier; - - bytes32 internal _requestId; - bytes32[32] internal _treeBranches = [ - bytes32('branch1'), - bytes32('branch2'), - bytes32('branch3'), - bytes32('branch4'), - bytes32('branch5'), - bytes32('branch6'), - bytes32('branch7'), - bytes32('branch8'), - bytes32('branch9'), - bytes32('branch10'), - bytes32('branch11'), - bytes32('branch12'), - bytes32('branch13'), - bytes32('branch14'), - bytes32('branch15'), - bytes32('branch16'), - bytes32('branch17'), - bytes32('branch18'), - bytes32('branch19'), - bytes32('branch20'), - bytes32('branch21'), - bytes32('branch22'), - bytes32('branch23'), - bytes32('branch24'), - bytes32('branch25'), - bytes32('branch26'), - bytes32('branch27'), - bytes32('branch28'), - bytes32('branch29'), - bytes32('branch30'), - bytes32('branch31'), - bytes32('branch32') - ]; - uint256 internal _treeCount = 1; - bytes internal _treeData = abi.encode(_treeBranches, _treeCount); - bytes32[] internal _leavesToInsert = [bytes32('leave1'), bytes32('leave2')]; - - function setUp() public override { - super.setUp(); - _expectedDeadline = block.timestamp + BLOCK_TIME * 600; - - SparseMerkleTreeRequestModule _sparseMerkleTreeModule = new SparseMerkleTreeRequestModule(oracle); - label(address(_sparseMerkleTreeModule), 'SparseMerkleTreeModule'); - - RootVerificationModule _rootVerificationModule = new RootVerificationModule(oracle); - label(address(_rootVerificationModule), 'RootVerificationModule'); - - _treeVerifier = new SparseMerkleTreeL32Verifier(); - label(address(_treeVerifier), 'TreeVerifier'); - - IOracle.NewRequest memory _request = IOracle.NewRequest({ - requestModuleData: abi.encode( - ISparseMerkleTreeRequestModule.RequestParameters({ - treeData: _treeData, - leavesToInsert: _leavesToInsert, - treeVerifier: ITreeVerifier(_treeVerifier), - accountingExtension: _accountingExtension, - paymentToken: IERC20(USDC_ADDRESS), - paymentAmount: _expectedReward - }) - ), - responseModuleData: abi.encode( - IBondedResponseModule.RequestParameters({ - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize, - deadline: _expectedDeadline, - disputeWindow: _baseDisputeWindow - }) - ), - disputeModuleData: abi.encode( - IRootVerificationModule.RequestParameters({ - treeData: _treeData, - leavesToInsert: _leavesToInsert, - treeVerifier: ITreeVerifier(_treeVerifier), - accountingExtension: _accountingExtension, - bondToken: IERC20(USDC_ADDRESS), - bondSize: _expectedBondSize - }) - ), - resolutionModuleData: abi.encode(_mockArbitrator), - finalityModuleData: abi.encode( - ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) - ), - requestModule: _sparseMerkleTreeModule, - responseModule: _responseModule, - disputeModule: _rootVerificationModule, - resolutionModule: _arbitratorModule, - finalityModule: IFinalityModule(_callbackModule), - ipfsHash: _ipfsHash - }); - - _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); - - vm.startPrank(requester); - _accountingExtension.approveModule(address(_sparseMerkleTreeModule)); - _requestId = oracle.createRequest(_request); - vm.stopPrank(); - } - - function test_validResponse() public { - bytes32 _correctRoot = ITreeVerifier(_treeVerifier).calculateRoot(_treeData, _leavesToInsert); - - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - bytes32 _responseId = oracle.proposeResponse(_requestId, abi.encode(_correctRoot)); - vm.stopPrank(); - - vm.warp(_expectedDeadline + _baseDisputeWindow); - - oracle.finalize(_requestId, _responseId); - } - - function test_disputeResponse_incorrectResponse(bytes32 _invalidRoot) public { - bytes32 _correctRoot = ITreeVerifier(_treeVerifier).calculateRoot(_treeData, _leavesToInsert); - vm.assume(_correctRoot != _invalidRoot); - - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - bytes32 _responseId = oracle.proposeResponse(_requestId, abi.encode(_invalidRoot)); - vm.stopPrank(); - - vm.startPrank(disputer); - _accountingExtension.approveModule(address(_responseModule)); - oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - - uint256 _requesterBondedBalance = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); - uint256 _proposerBondedBalance = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); - - uint256 _requesterVirtualBalance = _accountingExtension.balanceOf(requester, usdc); - uint256 _proposerVirtualBalance = _accountingExtension.balanceOf(proposer, usdc); - uint256 _disputerVirtualBalance = _accountingExtension.balanceOf(disputer, usdc); - - assertEq(_requesterBondedBalance, 0); - assertEq(_proposerBondedBalance, 0); - - assertEq(_requesterVirtualBalance, 0); - assertEq(_proposerVirtualBalance, 0); - assertEq(_disputerVirtualBalance, _expectedBondSize + _expectedReward); - } - - function test_disputeResponse_correctResponse() public { - bytes32 _correctRoot = ITreeVerifier(_treeVerifier).calculateRoot(_treeData, _leavesToInsert); - - _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); - - vm.startPrank(proposer); - _accountingExtension.approveModule(address(_responseModule)); - bytes32 _responseId = oracle.proposeResponse(_requestId, abi.encode(_correctRoot)); - vm.stopPrank(); - - vm.startPrank(disputer); - _accountingExtension.approveModule(address(_responseModule)); - oracle.disputeResponse(_requestId, _responseId); - vm.stopPrank(); - uint256 _requesterBondedBalance = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); - uint256 _proposerBondedBalance = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); - - uint256 _requesterVirtualBalance = _accountingExtension.balanceOf(requester, usdc); - uint256 _proposerVirtualBalance = _accountingExtension.balanceOf(proposer, usdc); - - assertEq(_requesterBondedBalance, 0); - assertEq(_proposerBondedBalance, 0); - - assertEq(_requesterVirtualBalance, 0); - assertEq(_proposerVirtualBalance, _expectedBondSize + _expectedReward); - } -} +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +// import './IntegrationBase.sol'; +// import { +// SparseMerkleTreeRequestModule, +// ISparseMerkleTreeRequestModule, +// IOracle +// } from '../../contracts/modules/request/SparseMerkleTreeRequestModule.sol'; +// import {SparseMerkleTreeL32Verifier} from '../../contracts/periphery/SparseMerkleTreeL32Verifier.sol'; +// import { +// RootVerificationModule, IRootVerificationModule +// } from '../../contracts/modules/dispute/RootVerificationModule.sol'; +// import {ITreeVerifier} from '../../interfaces/ITreeVerifier.sol'; + +// contract Integration_RootVerification is IntegrationBase { +// SparseMerkleTreeL32Verifier internal _treeVerifier; + +// bytes32 internal _requestId; +// bytes32[32] internal _treeBranches = [ +// bytes32('branch1'), +// bytes32('branch2'), +// bytes32('branch3'), +// bytes32('branch4'), +// bytes32('branch5'), +// bytes32('branch6'), +// bytes32('branch7'), +// bytes32('branch8'), +// bytes32('branch9'), +// bytes32('branch10'), +// bytes32('branch11'), +// bytes32('branch12'), +// bytes32('branch13'), +// bytes32('branch14'), +// bytes32('branch15'), +// bytes32('branch16'), +// bytes32('branch17'), +// bytes32('branch18'), +// bytes32('branch19'), +// bytes32('branch20'), +// bytes32('branch21'), +// bytes32('branch22'), +// bytes32('branch23'), +// bytes32('branch24'), +// bytes32('branch25'), +// bytes32('branch26'), +// bytes32('branch27'), +// bytes32('branch28'), +// bytes32('branch29'), +// bytes32('branch30'), +// bytes32('branch31'), +// bytes32('branch32') +// ]; +// uint256 internal _treeCount = 1; +// bytes internal _treeData = abi.encode(_treeBranches, _treeCount); +// bytes32[] internal _leavesToInsert = [bytes32('leave1'), bytes32('leave2')]; + +// function setUp() public override { +// super.setUp(); +// _expectedDeadline = block.timestamp + BLOCK_TIME * 600; + +// SparseMerkleTreeRequestModule _sparseMerkleTreeModule = new SparseMerkleTreeRequestModule(oracle); +// label(address(_sparseMerkleTreeModule), 'SparseMerkleTreeModule'); + +// RootVerificationModule _rootVerificationModule = new RootVerificationModule(oracle); +// label(address(_rootVerificationModule), 'RootVerificationModule'); + +// _treeVerifier = new SparseMerkleTreeL32Verifier(); +// label(address(_treeVerifier), 'TreeVerifier'); + +// IOracle.NewRequest memory _request = IOracle.NewRequest({ +// requestModuleData: abi.encode( +// ISparseMerkleTreeRequestModule.RequestParameters({ +// treeData: _treeData, +// leavesToInsert: _leavesToInsert, +// treeVerifier: ITreeVerifier(_treeVerifier), +// accountingExtension: _accountingExtension, +// paymentToken: IERC20(USDC_ADDRESS), +// paymentAmount: _expectedReward +// }) +// ), +// responseModuleData: abi.encode( +// IBondedResponseModule.RequestParameters({ +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize, +// deadline: _expectedDeadline, +// disputeWindow: _baseDisputeWindow +// }) +// ), +// disputeModuleData: abi.encode( +// IRootVerificationModule.RequestParameters({ +// treeData: _treeData, +// leavesToInsert: _leavesToInsert, +// treeVerifier: ITreeVerifier(_treeVerifier), +// accountingExtension: _accountingExtension, +// bondToken: IERC20(USDC_ADDRESS), +// bondSize: _expectedBondSize +// }) +// ), +// resolutionModuleData: abi.encode(_mockArbitrator), +// finalityModuleData: abi.encode( +// ICallbackModule.RequestParameters({target: address(_mockCallback), data: abi.encode(_expectedCallbackValue)}) +// ), +// requestModule: _sparseMerkleTreeModule, +// responseModule: _responseModule, +// disputeModule: _rootVerificationModule, +// resolutionModule: _arbitratorModule, +// finalityModule: IFinalityModule(_callbackModule), +// ipfsHash: _ipfsHash +// }); + +// _forBondDepositERC20(_accountingExtension, requester, usdc, _expectedReward, _expectedReward); + +// vm.startPrank(requester); +// _accountingExtension.approveModule(address(_sparseMerkleTreeModule)); +// _requestId = oracle.createRequest(_request); +// vm.stopPrank(); +// } + +// function test_validResponse() public { +// bytes32 _correctRoot = ITreeVerifier(_treeVerifier).calculateRoot(_treeData, _leavesToInsert); + +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); + +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// bytes32 _responseId = oracle.proposeResponse(_requestId, abi.encode(_correctRoot)); +// vm.stopPrank(); + +// vm.warp(_expectedDeadline + _baseDisputeWindow); + +// oracle.finalize(_requestId, _responseId); +// } + +// function test_disputeResponse_incorrectResponse(bytes32 _invalidRoot) public { +// bytes32 _correctRoot = ITreeVerifier(_treeVerifier).calculateRoot(_treeData, _leavesToInsert); +// vm.assume(_correctRoot != _invalidRoot); + +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); + +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// bytes32 _responseId = oracle.proposeResponse(_requestId, abi.encode(_invalidRoot)); +// vm.stopPrank(); + +// vm.startPrank(disputer); +// _accountingExtension.approveModule(address(_responseModule)); +// oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); + +// uint256 _requesterBondedBalance = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); +// uint256 _proposerBondedBalance = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); + +// uint256 _requesterVirtualBalance = _accountingExtension.balanceOf(requester, usdc); +// uint256 _proposerVirtualBalance = _accountingExtension.balanceOf(proposer, usdc); +// uint256 _disputerVirtualBalance = _accountingExtension.balanceOf(disputer, usdc); + +// assertEq(_requesterBondedBalance, 0); +// assertEq(_proposerBondedBalance, 0); + +// assertEq(_requesterVirtualBalance, 0); +// assertEq(_proposerVirtualBalance, 0); +// assertEq(_disputerVirtualBalance, _expectedBondSize + _expectedReward); +// } + +// function test_disputeResponse_correctResponse() public { +// bytes32 _correctRoot = ITreeVerifier(_treeVerifier).calculateRoot(_treeData, _leavesToInsert); + +// _forBondDepositERC20(_accountingExtension, proposer, usdc, _expectedBondSize, _expectedBondSize); + +// vm.startPrank(proposer); +// _accountingExtension.approveModule(address(_responseModule)); +// bytes32 _responseId = oracle.proposeResponse(_requestId, abi.encode(_correctRoot)); +// vm.stopPrank(); + +// vm.startPrank(disputer); +// _accountingExtension.approveModule(address(_responseModule)); +// oracle.disputeResponse(_requestId, _responseId); +// vm.stopPrank(); +// uint256 _requesterBondedBalance = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); +// uint256 _proposerBondedBalance = _accountingExtension.bondedAmountOf(proposer, usdc, _requestId); + +// uint256 _requesterVirtualBalance = _accountingExtension.balanceOf(requester, usdc); +// uint256 _proposerVirtualBalance = _accountingExtension.balanceOf(proposer, usdc); + +// assertEq(_requesterBondedBalance, 0); +// assertEq(_proposerBondedBalance, 0); + +// assertEq(_requesterVirtualBalance, 0); +// assertEq(_proposerVirtualBalance, _expectedBondSize + _expectedReward); +// } +// } diff --git a/solidity/test/invariant/InvariantsTest.t.sol b/solidity/test/invariant/InvariantsTest.t.sol index f0c1b84f..1b342dd4 100644 --- a/solidity/test/invariant/InvariantsTest.t.sol +++ b/solidity/test/invariant/InvariantsTest.t.sol @@ -1,182 +1,182 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; -import 'forge-std/Test.sol'; +// import 'forge-std/Test.sol'; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {Oracle, IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Oracle.sol'; -import {IFinalityModule} from - '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/finality/IFinalityModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {Oracle, IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Oracle.sol'; +// import {IFinalityModule} from +// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/finality/IFinalityModule.sol'; -import {HttpRequestModule} from '../../contracts/modules/request/HttpRequestModule.sol'; -import {BondedResponseModule} from '../../contracts/modules/response/BondedResponseModule.sol'; -import {BondedDisputeModule} from '../../contracts/modules/dispute/BondedDisputeModule.sol'; -import {BondEscalationResolutionModule} from '../../contracts/modules/resolution/BondEscalationResolutionModule.sol'; -import {AccountingExtension} from '../../contracts/extensions/AccountingExtension.sol'; -import {BondEscalationAccounting} from '../../contracts/extensions/BondEscalationAccounting.sol'; - -import {IWETH9} from '../../interfaces/external/IWETH9.sol'; -import {WETH9} from './imports/WETH9.sol'; - -/** - * @title Invariant tests - */ -contract InvariantsTest is Test { - using stdStorage for StdStorage; - - Oracle public oracle; - HandlerProphet public handler; - - function setUp() public { - oracle = new Oracle(); - handler = new HandlerProphet(oracle); - - targetContract(address(handler)); - } -} - -contract HandlerProphet is Test { - Oracle public oracle; - - HttpRequestModule public httpRequestModule; - BondedResponseModule public bondedResponseModule; - BondedDisputeModule public bondedDisputeModule; - BondEscalationResolutionModule public bondEscalationResolutionModule; - - AccountingExtension public accountingExtension; - BondEscalationAccounting public bondEscalationAccounting; - - IWETH9 public weth; +// import {HttpRequestModule} from '../../contracts/modules/request/HttpRequestModule.sol'; +// import {BondedResponseModule} from '../../contracts/modules/response/BondedResponseModule.sol'; +// import {BondedDisputeModule} from '../../contracts/modules/dispute/BondedDisputeModule.sol'; +// import {BondEscalationResolutionModule} from '../../contracts/modules/resolution/BondEscalationResolutionModule.sol'; +// import {AccountingExtension} from '../../contracts/extensions/AccountingExtension.sol'; +// import {BondEscalationAccounting} from '../../contracts/extensions/BondEscalationAccounting.sol'; + +// import {IWETH9} from '../../interfaces/external/IWETH9.sol'; +// import {WETH9} from './imports/WETH9.sol'; + +// /** +// * @title Invariant tests +// */ +// contract InvariantsTest is Test { +// using stdStorage for StdStorage; + +// Oracle public oracle; +// HandlerProphet public handler; + +// function setUp() public { +// oracle = new Oracle(); +// handler = new HandlerProphet(oracle); + +// targetContract(address(handler)); +// } +// } + +// contract HandlerProphet is Test { +// Oracle public oracle; + +// HttpRequestModule public httpRequestModule; +// BondedResponseModule public bondedResponseModule; +// BondedDisputeModule public bondedDisputeModule; +// BondEscalationResolutionModule public bondEscalationResolutionModule; + +// AccountingExtension public accountingExtension; +// BondEscalationAccounting public bondEscalationAccounting; + +// IWETH9 public weth; - bytes32 public requestId; - - mapping(bytes32 response => bytes32 request) public ghostResponseIdToRequestId; - bool public responseRequestDiscrepancy; +// bytes32 public requestId; + +// mapping(bytes32 response => bytes32 request) public ghostResponseIdToRequestId; +// bool public responseRequestDiscrepancy; - mapping(bytes32 request => bool) public finalized; - bool public finalizedDiscrepancy; +// mapping(bytes32 request => bool) public finalized; +// bool public finalizedDiscrepancy; - uint256 public ghostNumberOfDispute; - uint256 public ghostNumberOfResponse; - uint256 public ghostNumberOfRequest; +// uint256 public ghostNumberOfDispute; +// uint256 public ghostNumberOfResponse; +// uint256 public ghostNumberOfRequest; - mapping(uint256 => bytes32) public ghostDisputeToResponseId; +// mapping(uint256 => bytes32) public ghostDisputeToResponseId; - constructor(Oracle _oracle) { - oracle = _oracle; +// constructor(Oracle _oracle) { +// oracle = _oracle; - httpRequestModule = new HttpRequestModule(oracle); - bondedResponseModule = new BondedResponseModule(oracle); - bondedDisputeModule = new BondedDisputeModule(oracle); - bondEscalationResolutionModule = new BondEscalationResolutionModule(oracle); +// httpRequestModule = new HttpRequestModule(oracle); +// bondedResponseModule = new BondedResponseModule(oracle); +// bondedDisputeModule = new BondedDisputeModule(oracle); +// bondEscalationResolutionModule = new BondEscalationResolutionModule(oracle); - weth = IWETH9(address(new WETH9())); - accountingExtension = new AccountingExtension(oracle); +// weth = IWETH9(address(new WETH9())); +// accountingExtension = new AccountingExtension(oracle); - requestId = _createRequest(1 ether, 1 ether); // TODO: fuzz payment amount - } +// requestId = _createRequest(1 ether, 1 ether); // TODO: fuzz payment amount +// } - ///////////////////////////////////////////////////////////////////// - // Test helpers // - ///////////////////////////////////////////////////////////////////// - - function _createRequest(uint256 _payment, uint256 _bondedAmount) internal returns (bytes32 _requestId) { - bytes memory _httpRequestModuleData = abi.encode('_url', '_method', '_body', accountingExtension, weth, _payment); - bytes memory _bondedResponseModuleData = - abi.encode(accountingExtension, weth, _bondedAmount, block.timestamp + 1 days); - bytes memory _bondedDisputeModuleData = abi.encode(accountingExtension, weth, _bondedAmount); - - // TODO: fuzz? not too constrained? - uint256 _percentageDiff = 10; - uint256 _pledgeThreshold = 100; - uint256 _timeUntilDeadline = 1 days; - uint256 _timeToBreakInequality = 1 days; - - bytes memory _bondEscalationResolutionModuleData = abi.encode( - accountingExtension, weth, _percentageDiff, _pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality - ); - - vm.deal(address(this), _bondedAmount); - weth.deposit{value: msg.value}(); - accountingExtension.deposit(IERC20(address(weth)), _bondedAmount); - - IOracle.NewRequest memory _request = IOracle.NewRequest({ - requestModuleData: _httpRequestModuleData, - responseModuleData: _bondedResponseModuleData, - disputeModuleData: _bondedDisputeModuleData, - resolutionModuleData: _bondEscalationResolutionModuleData, - finalityModuleData: '', - ipfsHash: bytes32(''), - requestModule: httpRequestModule, - responseModule: bondedResponseModule, - disputeModule: bondedDisputeModule, - resolutionModule: bondEscalationResolutionModule, - finalityModule: IFinalityModule(address(0)) - }); +// ///////////////////////////////////////////////////////////////////// +// // Test helpers // +// ///////////////////////////////////////////////////////////////////// + +// function _createRequest(uint256 _payment, uint256 _bondedAmount) internal returns (bytes32 _requestId) { +// bytes memory _httpRequestModuleData = abi.encode('_url', '_method', '_body', accountingExtension, weth, _payment); +// bytes memory _bondedResponseModuleData = +// abi.encode(accountingExtension, weth, _bondedAmount, block.timestamp + 1 days); +// bytes memory _bondedDisputeModuleData = abi.encode(accountingExtension, weth, _bondedAmount); + +// // TODO: fuzz? not too constrained? +// uint256 _percentageDiff = 10; +// uint256 _pledgeThreshold = 100; +// uint256 _timeUntilDeadline = 1 days; +// uint256 _timeToBreakInequality = 1 days; + +// bytes memory _bondEscalationResolutionModuleData = abi.encode( +// accountingExtension, weth, _percentageDiff, _pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality +// ); + +// vm.deal(address(this), _bondedAmount); +// weth.deposit{value: msg.value}(); +// accountingExtension.deposit(IERC20(address(weth)), _bondedAmount); + +// IOracle.NewRequest memory _request = IOracle.NewRequest({ +// requestModuleData: _httpRequestModuleData, +// responseModuleData: _bondedResponseModuleData, +// disputeModuleData: _bondedDisputeModuleData, +// resolutionModuleData: _bondEscalationResolutionModuleData, +// finalityModuleData: '', +// ipfsHash: bytes32(''), +// requestModule: httpRequestModule, +// responseModule: bondedResponseModule, +// disputeModule: bondedDisputeModule, +// resolutionModule: bondEscalationResolutionModule, +// finalityModule: IFinalityModule(address(0)) +// }); - return oracle.createRequest(_request); - } - - ///////////////////////////////////////////////////////////////////// - // Original logic handling // - ///////////////////////////////////////////////////////////////////// - - function createRequest(IOracle.NewRequest memory _request) public { - oracle.createRequest(_request); - ghostNumberOfRequest++; - } +// return oracle.createRequest(_request); +// } + +// ///////////////////////////////////////////////////////////////////// +// // Original logic handling // +// ///////////////////////////////////////////////////////////////////// + +// function createRequest(IOracle.NewRequest memory _request) public { +// oracle.createRequest(_request); +// ghostNumberOfRequest++; +// } - function proposeResponse(bytes calldata _responseData) external { - bytes32 _responseId = oracle.proposeResponse(msg.sender, requestId, _responseData); - // This request has already a response which is different? - if (ghostResponseIdToRequestId[_responseId] != bytes32(0) && ghostResponseIdToRequestId[_responseId] != requestId) { - responseRequestDiscrepancy = true; - } - - ghostResponseIdToRequestId[_responseId] = requestId; +// function proposeResponse(bytes calldata _responseData) external { +// bytes32 _responseId = oracle.proposeResponse(msg.sender, requestId, _responseData); +// // This request has already a response which is different? +// if (ghostResponseIdToRequestId[_responseId] != bytes32(0) && ghostResponseIdToRequestId[_responseId] != requestId) { +// responseRequestDiscrepancy = true; +// } + +// ghostResponseIdToRequestId[_responseId] = requestId; - ghostNumberOfResponse++; - } +// ghostNumberOfResponse++; +// } - function proposeResponse(address _proposer, bytes calldata _responseData) external { - bytes32 _responseId = oracle.proposeResponse(_proposer, requestId, _responseData); - - // This request has already a response which is different? - if (ghostResponseIdToRequestId[_responseId] != bytes32(0) && ghostResponseIdToRequestId[_responseId] != requestId) { - responseRequestDiscrepancy = true; - } +// function proposeResponse(address _proposer, bytes calldata _responseData) external { +// bytes32 _responseId = oracle.proposeResponse(_proposer, requestId, _responseData); + +// // This request has already a response which is different? +// if (ghostResponseIdToRequestId[_responseId] != bytes32(0) && ghostResponseIdToRequestId[_responseId] != requestId) { +// responseRequestDiscrepancy = true; +// } - ghostResponseIdToRequestId[_responseId] = requestId; - - ghostNumberOfResponse++; - } - - function disputeResponse(bytes32, /* _requestId */ bytes32 _responseId) external { - oracle.disputeResponse(requestId, _responseId); - - ghostDisputeToResponseId[ghostNumberOfDispute] = _responseId; - ghostNumberOfDispute++; - } - - function escalateDispute(bytes32 _disputeId) external { - oracle.escalateDispute(_disputeId); - } - - function resolveDispute(bytes32 _disputeId) external { - oracle.resolveDispute(_disputeId); - } - - function updateDisputeStatus(bytes32 _disputeId, IOracle.DisputeStatus _status) external { - oracle.updateDisputeStatus(_disputeId, _status); - } - - function finalize(bytes32 _requestId, bytes32 _finalizedResponseId) external { - oracle.finalize(requestId, _finalizedResponseId); - - if (!finalized[_requestId]) { - finalized[_requestId] = true; - } else { - finalizedDiscrepancy = true; - } - } -} +// ghostResponseIdToRequestId[_responseId] = requestId; + +// ghostNumberOfResponse++; +// } + +// function disputeResponse(bytes32, /* _requestId */ bytes32 _responseId) external { +// oracle.disputeResponse(requestId, _responseId); + +// ghostDisputeToResponseId[ghostNumberOfDispute] = _responseId; +// ghostNumberOfDispute++; +// } + +// function escalateDispute(bytes32 _disputeId) external { +// oracle.escalateDispute(_disputeId); +// } + +// function resolveDispute(bytes32 _disputeId) external { +// oracle.resolveDispute(_disputeId); +// } + +// function updateDisputeStatus(bytes32 _disputeId, IOracle.DisputeStatus _status) external { +// oracle.updateDisputeStatus(_disputeId, _status); +// } + +// function finalize(bytes32 _requestId, bytes32 _finalizedResponseId) external { +// oracle.finalize(requestId, _finalizedResponseId); + +// if (!finalized[_requestId]) { +// finalized[_requestId] = true; +// } else { +// finalizedDiscrepancy = true; +// } +// } +// } diff --git a/solidity/test/mocks/MockAtomicArbitrator.sol b/solidity/test/mocks/MockAtomicArbitrator.sol index c248ee02..7d3e38bb 100644 --- a/solidity/test/mocks/MockAtomicArbitrator.sol +++ b/solidity/test/mocks/MockAtomicArbitrator.sol @@ -1,28 +1,28 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IArbitrator} from '../../interfaces/IArbitrator.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IArbitrator} from '../../interfaces/IArbitrator.sol'; -contract MockAtomicArbitrator is IArbitrator { - IOracle.DisputeStatus public answer; - IOracle public oracle; +// contract MockAtomicArbitrator is IArbitrator { +// IOracle.DisputeStatus public answer; +// IOracle public oracle; - constructor(IOracle _oracle) { - oracle = _oracle; - } +// constructor(IOracle _oracle) { +// oracle = _oracle; +// } - function resolve(bytes32 _dispute) external returns (bytes memory _result) { - _result = new bytes(0); - answer = IOracle.DisputeStatus.Won; - oracle.resolveDispute(_dispute); - } +// function resolve(bytes32 _dispute) external returns (bytes memory _result) { +// _result = new bytes(0); +// answer = IOracle.DisputeStatus.Won; +// oracle.resolveDispute(_dispute); +// } - function getAnswer(bytes32 /* _dispute */ ) external view returns (IOracle.DisputeStatus _answer) { - _answer = answer; - } +// function getAnswer(bytes32 /* _dispute */ ) external view returns (IOracle.DisputeStatus _answer) { +// _answer = answer; +// } - function supportsInterface(bytes4 /* interfaceId */ ) external pure returns (bool _supported) { - _supported = true; - } -} +// function supportsInterface(bytes4 /* interfaceId */ ) external pure returns (bool _supported) { +// _supported = true; +// } +// } diff --git a/solidity/test/unit/AccountingExtension.t.sol b/solidity/test/unit/AccountingExtension.t.sol deleted file mode 100644 index a834ee78..00000000 --- a/solidity/test/unit/AccountingExtension.t.sol +++ /dev/null @@ -1,481 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../utils/Helpers.sol'; - -import { - AccountingExtension, - IAccountingExtension, - IERC20, - IOracle -} from '../../contracts/extensions/AccountingExtension.sol'; -import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; - -contract ForTest_AccountingExtension is AccountingExtension { - using EnumerableSet for EnumerableSet.AddressSet; - - constructor(IOracle _oracle) AccountingExtension(_oracle) {} - - function forTest_setBalanceOf(address _user, IERC20 _token, uint256 _amount) public { - balanceOf[_user][_token] = _amount; - } - - function forTest_setBondedBalanceOf(bytes32 _requestId, address _user, IERC20 _token, uint256 _amount) public { - bondedAmountOf[_user][_token][_requestId] = _amount; - } -} - -/** - * @title Accounting Extension Unit tests - */ -contract BaseTest is Test, Helpers { - // The target contract - ForTest_AccountingExtension public extension; - // A mock oracle - IOracle public oracle; - // Mock deposit token - IERC20 public token; - // Mock sender - address public sender = makeAddr('sender'); - - // Events tested - event Deposited(address indexed _depositor, IERC20 indexed _token, uint256 _amount); - event Withdrew(address indexed _depositor, IERC20 indexed _token, uint256 _amount); - event Paid( - bytes32 indexed _requestId, address indexed _beneficiary, address indexed _payer, IERC20 _token, uint256 _amount - ); - event Bonded(bytes32 indexed _requestId, address indexed _depositor, IERC20 indexed _token, uint256 _amount); - event Released(bytes32 indexed _requestId, address indexed _depositor, IERC20 indexed _token, uint256 _amount); - - /** - * @notice Deploy the target and mock oracle extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - token = IERC20(makeAddr('Token')); - vm.etch(address(token), hex'069420'); - - extension = new ForTest_AccountingExtension(oracle); - } -} - -contract AccountingExtension_Unit_DepositAndWithdraw is BaseTest { - /** - * @notice Test an ERC20 deposit - */ - function test_depositERC20(uint256 _amount) public { - // Mock and expect the ERC20 transfer - _mockAndExpect( - address(token), abi.encodeCall(IERC20.transferFrom, (sender, address(extension), _amount)), abi.encode(true) - ); - - // Expect the event - vm.expectEmit(true, true, true, true, address(extension)); - emit Deposited(sender, token, _amount); - - vm.prank(sender); - extension.deposit(token, _amount); - - // Check: balance of token deposit increased? - assertEq(extension.balanceOf(sender, token), _amount); - } - - /** - * @notice Test withdrawing ERC20. Should update balance and emit event - */ - function test_withdrawERC20(uint256 _amount, uint256 _initialBalance) public { - vm.assume(_amount > 0); - - // Set the initial balance - _initialBalance = bound(_initialBalance, _amount, type(uint256).max); - extension.forTest_setBalanceOf(sender, token, _initialBalance); - - _mockAndExpect(address(token), abi.encodeCall(IERC20.transfer, (sender, _amount)), abi.encode(true)); - - // Expect the event - vm.expectEmit(true, true, true, true, address(extension)); - emit Withdrew(sender, token, _amount); - - vm.prank(sender); - extension.withdraw(token, _amount); - - // Check: balance of token deposit decreased? - assertEq(extension.balanceOf(sender, token), _initialBalance - _amount); - } - - /** - * @notice Should revert if balance is insufficient - */ - function test_withdrawRevert(uint256 _amount, uint256 _initialBalance) public { - vm.assume(_amount > 0); - - // Set the initial balance - _initialBalance = bound(_initialBalance, 0, _amount - 1); - extension.forTest_setBalanceOf(sender, token, _initialBalance); - - // Check: does it revert if balance is insufficient? - vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientFunds.selector)); - vm.prank(sender); - extension.withdraw(token, _amount); - } -} - -contract AccountingExtension_Unit_Bond is BaseTest { - /** - * @notice Test bonding an amount (which is taken from the bonder balanceOf) - */ - function test_updateBalance( - bytes32 _requestId, - uint256 _amount, - uint256 _initialBalance, - address _bonder, - address _sender - ) public { - _amount = bound(_amount, 0, _initialBalance); - - vm.prank(_bonder); - extension.approveModule(_sender); - - // Mock and expect the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); - - // Mock and expect the module checking for participant - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); - - // Set the initial balance - extension.forTest_setBalanceOf(_bonder, token, _initialBalance); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(extension)); - emit Bonded(_requestId, _bonder, token, _amount); - - vm.prank(_sender); - extension.bond({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); - - // Check: is the balanceOf decreased? - assertEq(extension.balanceOf(_bonder, token), _initialBalance - _amount); - - // Check: is the bondedAmountOf increased? - assertEq(extension.bondedAmountOf(_bonder, token, _requestId), _amount); - } - - /** - * @notice Test bonding reverting if balanceOf is less than the amount to bond - */ - function test_revertIfInsufficientBalance( - bytes32 _requestId, - uint256 _amount, - uint248 _initialBalance, - address _bonder, - address _sender - ) public { - _amount = bound(_amount, uint256(_initialBalance) + 1, type(uint256).max); - - vm.prank(_bonder); - extension.approveModule(_sender); - - // Mock and expect the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); - - // Mock and expect the module checking for participant - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); - - // Set the initial balance - extension.forTest_setBalanceOf(_bonder, token, _initialBalance); - - // Check: does it revert if balance is insufficient? - vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientFunds.selector)); - - vm.prank(_sender); - extension.bond({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); - } - - /** - * @notice Test bonding reverting if balanceOf is less than the amount to bond - */ - function test_revertIfDisallowedModuleCalling( - bytes32 _requestId, - uint256 _amount, - address _bonder, - address _sender - ) public { - // Mock and expect the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(false)); - - // Check: does it revert if the module is not allowed? - vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector)); - - vm.prank(_sender); - extension.bond({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); - } - - /** - * @notice Test bonding reverting if the module is not approved to bond the _bonder funds - */ - function test_revertIfInsufficientAllowance( - bytes32 _requestId, - uint256 _amount, - address _bonder, - address _module - ) public { - // Mock and expect the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _module)), abi.encode(true)); - - // Mock and expect the module checking for a participant - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); - - // Check: does it revert if the module is not approved? - vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientAllowance.selector)); - - vm.prank(_module); - extension.bond({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); - } - - /** - * @notice Test bonding reverting if the caller is not approved to bond the _bonder funds - */ - function test_withCaller_revertIfInsufficientAllowance( - bytes32 _requestId, - uint256 _amount, - address _bonder, - address _sender - ) public { - // mock the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); - - // Mock and expect the module checking for a participant - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); - - // Check: does it revert if the caller is not approved? - vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientAllowance.selector)); - - vm.prank(_sender); - extension.bond({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount, _sender: _sender}); - } -} - -contract AccountingExtension_Unit_Pay is BaseTest { - /** - * @notice Test paying a receiver. Should update balance and emit event. - */ - function test_payUpdateBalance( - bytes32 _requestId, - uint256 _amount, - uint256 _initialBalance, - address _payer, - address _receiver, - address _sender - ) public { - _amount = bound(_amount, 0, _initialBalance); - - // Mock and expect the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); - - // Mock and expect the module checking for participant - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _payer)), abi.encode(true)); - - // Mock and expect the module checking for participant - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _receiver)), abi.encode(true)); - - // Set the initial bonded balance - extension.forTest_setBondedBalanceOf(_requestId, _payer, token, _initialBalance); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(extension)); - emit Paid(_requestId, _receiver, _payer, token, _amount); - - vm.prank(_sender); - extension.pay({_requestId: _requestId, _payer: _payer, _receiver: _receiver, _token: token, _amount: _amount}); - - // Check: is the receiver's balance increased? - assertEq(extension.balanceOf(_receiver, token), _amount); - - // Check: is the payer's balance decreased? - assertEq(extension.bondedAmountOf(_payer, token, _requestId), _initialBalance - _amount); - } - - /** - * @notice Test if pay reverts if bonded funds are not enough - */ - function test_payRevertInsufficientBond( - bytes32 _requestId, - uint256 _amount, - uint248 _initialBalance, - address _payer, - address _receiver, - address _sender - ) public { - _amount = bound(_amount, uint256(_initialBalance) + 1, type(uint256).max); - - // Mock and expect the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); - - // Mock and expect the module checking for participant - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _payer)), abi.encode(true)); - - // Mock and expect the module checking for participant - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _receiver)), abi.encode(true)); - - // Set the initial bonded balance - extension.forTest_setBondedBalanceOf(_requestId, _payer, token, _initialBalance); - - // Check: does it revert if the payer has insufficient funds? - vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientFunds.selector)); - - vm.prank(_sender); - extension.pay({_requestId: _requestId, _payer: _payer, _receiver: _receiver, _token: token, _amount: _amount}); - } - - /** - * @notice Test if pay reverts if the caller is not a allowed module (checked via the oracle) - */ - function test_payRevertInvalidCallingModule( - bytes32 _requestId, - uint256 _amount, - uint248 _initialBalance, - address _payer, - address _receiver, - address _sender - ) public { - _amount = bound(_amount, uint256(_initialBalance) + 1, type(uint256).max); - - // Mock and expect the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(false)); - - // Check: does it revert if the module calling is not approved? - vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector)); - - vm.prank(_sender); - extension.pay({_requestId: _requestId, _payer: _payer, _receiver: _receiver, _token: token, _amount: _amount}); - } -} - -contract AccountingExtension_Unit_Release is BaseTest { - /** - * @notice Test releasing an amount (which is added to the bonder balanceOf) - */ - function test_releaseUpdateBalance( - bytes32 _requestId, - uint256 _amount, - uint256 _initialBalance, - address _bonder, - address _sender - ) public { - _amount = bound(_amount, 0, _initialBalance); - - // Mock and expect the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); - - // Mock and expect the module checking for participant - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); - - // Set the initial bonded balance - extension.forTest_setBondedBalanceOf(_requestId, _bonder, token, _initialBalance); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(extension)); - emit Released(_requestId, _bonder, token, _amount); - - vm.prank(_sender); - extension.release({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); - - // Check: is the balance increased? - assertEq(extension.balanceOf(_bonder, token), _amount); - - // check: is the bonded balance decreased? - assertEq(extension.bondedAmountOf(_bonder, token, _requestId), _initialBalance - _amount); - } - - /** - * @notice Test releasing reverting if bondedAmountOf is less than the amount to release - */ - function test_releaseInsufficientBalance( - bytes32 _requestId, - uint256 _amount, - uint248 _initialBalance, - address _bonder, - address _sender - ) public { - _amount = bound(_amount, uint256(_initialBalance) + 1, type(uint256).max); - - // Mock and expect the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); - - // Mock and expect the module checking for participant - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); - - // Set the initial bonded balance - extension.forTest_setBondedBalanceOf(_requestId, _bonder, token, _initialBalance); - - // Check: does it revert if calling with insufficient balance? - vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientFunds.selector)); - - vm.prank(_sender); - extension.release({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); - } - - /** - * @notice Test releasing reverting if the caller is not a allowed module - */ - function test_releaseDisallowedModuleCalling( - bytes32 _requestId, - uint256 _amount, - address _bonder, - address _sender - ) public { - // Mock and expect the module calling validation - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(false)); - - // Check: does it revert if the module is not approved? - vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector)); - - vm.prank(_sender); - extension.release({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); - } -} - -contract AccountingExtension_Unit_Approvals is BaseTest { - /** - * @notice Test approving modules / callers - */ - function test_approvedModules(address _user, uint8 _modulesAmount) public { - // Approve all modules from the array and storing them in memory - address[] memory _modules = new address[](_modulesAmount); - for (uint256 _i; _i < _modulesAmount; _i++) { - address _module = vm.addr(_i + 1); - _modules[_i] = _module; - vm.prank(_user); - extension.approveModule(_module); - } - - // Check: does the approved modules equals the modules stored in the array? - assertEq(_modules, extension.approvedModules(_user)); - } - - /** - * @notice Test revoking approvals. - */ - function test_revokeModules(address _user, address _module) public { - // Approve a module - vm.prank(_user); - extension.approveModule(_module); - - // Create an array with just the approved module - address[] memory _approvedModules = new address[](1); - _approvedModules[0] = _module; - - // Check: does the returned approved modules match? - assertEq(_approvedModules, extension.approvedModules(_user)); - - vm.prank(_user); - extension.revokeModule(_module); - - // Check: does it return an empty array after revoking the module? - address[] memory _emptyArray = new address[](0); - assertEq(_emptyArray, extension.approvedModules(_user)); - } -} diff --git a/solidity/test/unit/extensions/AccountingExtension.t.sol b/solidity/test/unit/extensions/AccountingExtension.t.sol new file mode 100644 index 00000000..e0e0da37 --- /dev/null +++ b/solidity/test/unit/extensions/AccountingExtension.t.sol @@ -0,0 +1,481 @@ +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../utils/Helpers.sol'; + +// import { +// AccountingExtension, +// IAccountingExtension, +// IERC20, +// IOracle +// } from '../../contracts/extensions/AccountingExtension.sol'; +// import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; + +// contract ForTest_AccountingExtension is AccountingExtension { +// using EnumerableSet for EnumerableSet.AddressSet; + +// constructor(IOracle _oracle) AccountingExtension(_oracle) {} + +// function forTest_setBalanceOf(address _user, IERC20 _token, uint256 _amount) public { +// balanceOf[_user][_token] = _amount; +// } + +// function forTest_setBondedBalanceOf(bytes32 _requestId, address _user, IERC20 _token, uint256 _amount) public { +// bondedAmountOf[_user][_token][_requestId] = _amount; +// } +// } + +// /** +// * @title Accounting Extension Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_AccountingExtension public extension; +// // A mock oracle +// IOracle public oracle; +// // Mock deposit token +// IERC20 public token; +// // Mock sender +// address public sender = makeAddr('sender'); + +// // Events tested +// event Deposited(address indexed _depositor, IERC20 indexed _token, uint256 _amount); +// event Withdrew(address indexed _depositor, IERC20 indexed _token, uint256 _amount); +// event Paid( +// bytes32 indexed _requestId, address indexed _beneficiary, address indexed _payer, IERC20 _token, uint256 _amount +// ); +// event Bonded(bytes32 indexed _requestId, address indexed _depositor, IERC20 indexed _token, uint256 _amount); +// event Released(bytes32 indexed _requestId, address indexed _depositor, IERC20 indexed _token, uint256 _amount); + +// /** +// * @notice Deploy the target and mock oracle extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// token = IERC20(makeAddr('Token')); +// vm.etch(address(token), hex'069420'); + +// extension = new ForTest_AccountingExtension(oracle); +// } +// } + +// contract AccountingExtension_Unit_DepositAndWithdraw is BaseTest { +// /** +// * @notice Test an ERC20 deposit +// */ +// function test_depositERC20(uint256 _amount) public { +// // Mock and expect the ERC20 transfer +// _mockAndExpect( +// address(token), abi.encodeCall(IERC20.transferFrom, (sender, address(extension), _amount)), abi.encode(true) +// ); + +// // Expect the event +// vm.expectEmit(true, true, true, true, address(extension)); +// emit Deposited(sender, token, _amount); + +// vm.prank(sender); +// extension.deposit(token, _amount); + +// // Check: balance of token deposit increased? +// assertEq(extension.balanceOf(sender, token), _amount); +// } + +// /** +// * @notice Test withdrawing ERC20. Should update balance and emit event +// */ +// function test_withdrawERC20(uint256 _amount, uint256 _initialBalance) public { +// vm.assume(_amount > 0); + +// // Set the initial balance +// _initialBalance = bound(_initialBalance, _amount, type(uint256).max); +// extension.forTest_setBalanceOf(sender, token, _initialBalance); + +// _mockAndExpect(address(token), abi.encodeCall(IERC20.transfer, (sender, _amount)), abi.encode(true)); + +// // Expect the event +// vm.expectEmit(true, true, true, true, address(extension)); +// emit Withdrew(sender, token, _amount); + +// vm.prank(sender); +// extension.withdraw(token, _amount); + +// // Check: balance of token deposit decreased? +// assertEq(extension.balanceOf(sender, token), _initialBalance - _amount); +// } + +// /** +// * @notice Should revert if balance is insufficient +// */ +// function test_withdrawRevert(uint256 _amount, uint256 _initialBalance) public { +// vm.assume(_amount > 0); + +// // Set the initial balance +// _initialBalance = bound(_initialBalance, 0, _amount - 1); +// extension.forTest_setBalanceOf(sender, token, _initialBalance); + +// // Check: does it revert if balance is insufficient? +// vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientFunds.selector)); +// vm.prank(sender); +// extension.withdraw(token, _amount); +// } +// } + +// contract AccountingExtension_Unit_Bond is BaseTest { +// /** +// * @notice Test bonding an amount (which is taken from the bonder balanceOf) +// */ +// function test_updateBalance( +// bytes32 _requestId, +// uint256 _amount, +// uint256 _initialBalance, +// address _bonder, +// address _sender +// ) public { +// _amount = bound(_amount, 0, _initialBalance); + +// vm.prank(_bonder); +// extension.approveModule(_sender); + +// // Mock and expect the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); + +// // Mock and expect the module checking for participant +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); + +// // Set the initial balance +// extension.forTest_setBalanceOf(_bonder, token, _initialBalance); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(extension)); +// emit Bonded(_requestId, _bonder, token, _amount); + +// vm.prank(_sender); +// extension.bond({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); + +// // Check: is the balanceOf decreased? +// assertEq(extension.balanceOf(_bonder, token), _initialBalance - _amount); + +// // Check: is the bondedAmountOf increased? +// assertEq(extension.bondedAmountOf(_bonder, token, _requestId), _amount); +// } + +// /** +// * @notice Test bonding reverting if balanceOf is less than the amount to bond +// */ +// function test_revertIfInsufficientBalance( +// bytes32 _requestId, +// uint256 _amount, +// uint248 _initialBalance, +// address _bonder, +// address _sender +// ) public { +// _amount = bound(_amount, uint256(_initialBalance) + 1, type(uint256).max); + +// vm.prank(_bonder); +// extension.approveModule(_sender); + +// // Mock and expect the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); + +// // Mock and expect the module checking for participant +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); + +// // Set the initial balance +// extension.forTest_setBalanceOf(_bonder, token, _initialBalance); + +// // Check: does it revert if balance is insufficient? +// vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientFunds.selector)); + +// vm.prank(_sender); +// extension.bond({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); +// } + +// /** +// * @notice Test bonding reverting if balanceOf is less than the amount to bond +// */ +// function test_revertIfDisallowedModuleCalling( +// bytes32 _requestId, +// uint256 _amount, +// address _bonder, +// address _sender +// ) public { +// // Mock and expect the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(false)); + +// // Check: does it revert if the module is not allowed? +// vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector)); + +// vm.prank(_sender); +// extension.bond({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); +// } + +// /** +// * @notice Test bonding reverting if the module is not approved to bond the _bonder funds +// */ +// function test_revertIfInsufficientAllowance( +// bytes32 _requestId, +// uint256 _amount, +// address _bonder, +// address _module +// ) public { +// // Mock and expect the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _module)), abi.encode(true)); + +// // Mock and expect the module checking for a participant +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); + +// // Check: does it revert if the module is not approved? +// vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientAllowance.selector)); + +// vm.prank(_module); +// extension.bond({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); +// } + +// /** +// * @notice Test bonding reverting if the caller is not approved to bond the _bonder funds +// */ +// function test_withCaller_revertIfInsufficientAllowance( +// bytes32 _requestId, +// uint256 _amount, +// address _bonder, +// address _sender +// ) public { +// // mock the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); + +// // Mock and expect the module checking for a participant +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); + +// // Check: does it revert if the caller is not approved? +// vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientAllowance.selector)); + +// vm.prank(_sender); +// extension.bond({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount, _sender: _sender}); +// } +// } + +// contract AccountingExtension_Unit_Pay is BaseTest { +// /** +// * @notice Test paying a receiver. Should update balance and emit event. +// */ +// function test_payUpdateBalance( +// bytes32 _requestId, +// uint256 _amount, +// uint256 _initialBalance, +// address _payer, +// address _receiver, +// address _sender +// ) public { +// _amount = bound(_amount, 0, _initialBalance); + +// // Mock and expect the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); + +// // Mock and expect the module checking for participant +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _payer)), abi.encode(true)); + +// // Mock and expect the module checking for participant +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _receiver)), abi.encode(true)); + +// // Set the initial bonded balance +// extension.forTest_setBondedBalanceOf(_requestId, _payer, token, _initialBalance); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(extension)); +// emit Paid(_requestId, _receiver, _payer, token, _amount); + +// vm.prank(_sender); +// extension.pay({_requestId: _requestId, _payer: _payer, _receiver: _receiver, _token: token, _amount: _amount}); + +// // Check: is the receiver's balance increased? +// assertEq(extension.balanceOf(_receiver, token), _amount); + +// // Check: is the payer's balance decreased? +// assertEq(extension.bondedAmountOf(_payer, token, _requestId), _initialBalance - _amount); +// } + +// /** +// * @notice Test if pay reverts if bonded funds are not enough +// */ +// function test_payRevertInsufficientBond( +// bytes32 _requestId, +// uint256 _amount, +// uint248 _initialBalance, +// address _payer, +// address _receiver, +// address _sender +// ) public { +// _amount = bound(_amount, uint256(_initialBalance) + 1, type(uint256).max); + +// // Mock and expect the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); + +// // Mock and expect the module checking for participant +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _payer)), abi.encode(true)); + +// // Mock and expect the module checking for participant +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _receiver)), abi.encode(true)); + +// // Set the initial bonded balance +// extension.forTest_setBondedBalanceOf(_requestId, _payer, token, _initialBalance); + +// // Check: does it revert if the payer has insufficient funds? +// vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientFunds.selector)); + +// vm.prank(_sender); +// extension.pay({_requestId: _requestId, _payer: _payer, _receiver: _receiver, _token: token, _amount: _amount}); +// } + +// /** +// * @notice Test if pay reverts if the caller is not a allowed module (checked via the oracle) +// */ +// function test_payRevertInvalidCallingModule( +// bytes32 _requestId, +// uint256 _amount, +// uint248 _initialBalance, +// address _payer, +// address _receiver, +// address _sender +// ) public { +// _amount = bound(_amount, uint256(_initialBalance) + 1, type(uint256).max); + +// // Mock and expect the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(false)); + +// // Check: does it revert if the module calling is not approved? +// vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector)); + +// vm.prank(_sender); +// extension.pay({_requestId: _requestId, _payer: _payer, _receiver: _receiver, _token: token, _amount: _amount}); +// } +// } + +// contract AccountingExtension_Unit_Release is BaseTest { +// /** +// * @notice Test releasing an amount (which is added to the bonder balanceOf) +// */ +// function test_releaseUpdateBalance( +// bytes32 _requestId, +// uint256 _amount, +// uint256 _initialBalance, +// address _bonder, +// address _sender +// ) public { +// _amount = bound(_amount, 0, _initialBalance); + +// // Mock and expect the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); + +// // Mock and expect the module checking for participant +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); + +// // Set the initial bonded balance +// extension.forTest_setBondedBalanceOf(_requestId, _bonder, token, _initialBalance); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(extension)); +// emit Released(_requestId, _bonder, token, _amount); + +// vm.prank(_sender); +// extension.release({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); + +// // Check: is the balance increased? +// assertEq(extension.balanceOf(_bonder, token), _amount); + +// // check: is the bonded balance decreased? +// assertEq(extension.bondedAmountOf(_bonder, token, _requestId), _initialBalance - _amount); +// } + +// /** +// * @notice Test releasing reverting if bondedAmountOf is less than the amount to release +// */ +// function test_releaseInsufficientBalance( +// bytes32 _requestId, +// uint256 _amount, +// uint248 _initialBalance, +// address _bonder, +// address _sender +// ) public { +// _amount = bound(_amount, uint256(_initialBalance) + 1, type(uint256).max); + +// // Mock and expect the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(true)); + +// // Mock and expect the module checking for participant +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.isParticipant, (_requestId, _bonder)), abi.encode(true)); + +// // Set the initial bonded balance +// extension.forTest_setBondedBalanceOf(_requestId, _bonder, token, _initialBalance); + +// // Check: does it revert if calling with insufficient balance? +// vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_InsufficientFunds.selector)); + +// vm.prank(_sender); +// extension.release({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); +// } + +// /** +// * @notice Test releasing reverting if the caller is not a allowed module +// */ +// function test_releaseDisallowedModuleCalling( +// bytes32 _requestId, +// uint256 _amount, +// address _bonder, +// address _sender +// ) public { +// // Mock and expect the module calling validation +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _sender)), abi.encode(false)); + +// // Check: does it revert if the module is not approved? +// vm.expectRevert(abi.encodeWithSelector(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector)); + +// vm.prank(_sender); +// extension.release({_bonder: _bonder, _requestId: _requestId, _token: token, _amount: _amount}); +// } +// } + +// contract AccountingExtension_Unit_Approvals is BaseTest { +// /** +// * @notice Test approving modules / callers +// */ +// function test_approvedModules(address _user, uint8 _modulesAmount) public { +// // Approve all modules from the array and storing them in memory +// address[] memory _modules = new address[](_modulesAmount); +// for (uint256 _i; _i < _modulesAmount; _i++) { +// address _module = vm.addr(_i + 1); +// _modules[_i] = _module; +// vm.prank(_user); +// extension.approveModule(_module); +// } + +// // Check: does the approved modules equals the modules stored in the array? +// assertEq(_modules, extension.approvedModules(_user)); +// } + +// /** +// * @notice Test revoking approvals. +// */ +// function test_revokeModules(address _user, address _module) public { +// // Approve a module +// vm.prank(_user); +// extension.approveModule(_module); + +// // Create an array with just the approved module +// address[] memory _approvedModules = new address[](1); +// _approvedModules[0] = _module; + +// // Check: does the returned approved modules match? +// assertEq(_approvedModules, extension.approvedModules(_user)); + +// vm.prank(_user); +// extension.revokeModule(_module); + +// // Check: does it return an empty array after revoking the module? +// address[] memory _emptyArray = new address[](0); +// assertEq(_emptyArray, extension.approvedModules(_user)); +// } +// } diff --git a/solidity/test/unit/modules/dispute/BondEscalationAccounting.t.sol b/solidity/test/unit/modules/dispute/BondEscalationAccounting.t.sol index 4228770e..775ef06a 100644 --- a/solidity/test/unit/modules/dispute/BondEscalationAccounting.t.sol +++ b/solidity/test/unit/modules/dispute/BondEscalationAccounting.t.sol @@ -1,542 +1,542 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IOracle, IBondEscalationModule} from '../../../../contracts/modules/dispute/BondEscalationModule.sol'; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import { - IBondEscalationAccounting, - BondEscalationAccounting -} from '../../../../contracts/extensions/BondEscalationAccounting.sol'; - -import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; -import {IWETH9} from '../../../../interfaces/external/IWETH9.sol'; - -import {Strings} from '@openzeppelin/contracts/utils/Strings.sol'; - -contract ForTest_BondEscalationAccounting is BondEscalationAccounting { - constructor(IOracle _oracle) BondEscalationAccounting(_oracle) {} - - function forTest_setPledge(bytes32 _disputeId, IERC20 _token, uint256 _amount) public { - pledges[_disputeId][_token] = _amount; - } - - function forTest_setBalanceOf(address _bonder, IERC20 _token, uint256 _balance) public { - balanceOf[_bonder][_token] = _balance; - } - - function forTest_setBondedAmountOf(address _bonder, IERC20 _token, bytes32 _requestId, uint256 _amount) public { - bondedAmountOf[_bonder][_token][_requestId] = _amount; - } - - function forTest_setClaimed(address _pledger, bytes32 _requestId, bool _claimed) public { - pledgerClaimed[_requestId][_pledger] = _claimed; - } - - function forTest_setEscalationResult( - bytes32 _disputeId, - bytes32 _requestId, - bool _forVotesWon, - IERC20 _token, - uint256 _amountPerPledger, - IBondEscalationModule _bondEscalationModule - ) public { - escalationResults[_disputeId] = EscalationResult({ - requestId: _requestId, - forVotesWon: _forVotesWon, - token: _token, - amountPerPledger: _amountPerPledger, - bondEscalationModule: _bondEscalationModule - }); - } -} - -/** - * @title Bonded Response Module Unit tests - */ -contract BaseTest is Test, Helpers { - // The target contract - ForTest_BondEscalationAccounting public bondEscalationAccounting; - // A mock oracle - IOracle public oracle; - // Mock WETH - IWETH9 public weth; - // A mock token - IERC20 public token; - // Mock EOA bonder - address public bonder = makeAddr('bonder'); - address public pledger = makeAddr('pledger'); - - // Pledged Event - event Pledged( - address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, IERC20 _token, uint256 _amount - ); - - event BondEscalationSettled( - bytes32 _requestId, - bytes32 _disputeId, - bool _forVotesWon, - IERC20 _token, - uint256 _amountPerPledger, - uint256 _winningPledgersLength - ); - - event EscalationRewardClaimed( - bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, IERC20 _token, uint256 _amount - ); - - event PledgeReleased( - bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, IERC20 _token, uint256 _amount - ); - - function _createWinningPledgersArray(uint256 _numWinningPledgers) - internal - returns (address[] memory _winningPledgers) - { - _winningPledgers = new address[](_numWinningPledgers); - address _winningPledger; - - for (uint256 _i; _i < _numWinningPledgers; _i++) { - _winningPledger = makeAddr(string.concat('winningPledger', Strings.toString(_i))); - _winningPledgers[_i] = _winningPledger; - } - } - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - token = IERC20(makeAddr('ERC20')); - vm.etch(address(token), hex'069420'); - - bondEscalationAccounting = new ForTest_BondEscalationAccounting(oracle); - } -} - -contract BondEscalationAccounting_Unit_Pledge is BaseTest { - function test_revertIfDisallowedModule( - address _pledger, - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amount - ) public { - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(false) - ); - - // Check: does it revert if called by an unauthorized module? - vm.expectRevert(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector); - - bondEscalationAccounting.pledge({ - _pledger: _pledger, - _requestId: _requestId, - _disputeId: _disputeId, - _token: token, - _amount: _amount - }); - } - - function test_revertIfNotEnoughDeposited( - address _pledger, - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amount - ) public { - vm.assume(_amount > 0); - - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) - ); - - // Check: does it revert if the pledger doesn't have enough deposited? - vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_InsufficientFunds.selector); - - bondEscalationAccounting.pledge({ - _pledger: _pledger, - _requestId: _requestId, - _disputeId: _disputeId, - _token: token, - _amount: _amount - }); - } - - function test_successfulCall(address _pledger, bytes32 _requestId, bytes32 _disputeId, uint256 _amount) public { - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) - ); - - bondEscalationAccounting.forTest_setBalanceOf(_pledger, token, _amount); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationAccounting)); - emit Pledged(_pledger, _requestId, _disputeId, token, _amount); - - uint256 _balanceBeforePledge = bondEscalationAccounting.balanceOf(_pledger, token); - uint256 _pledgesBeforePledge = bondEscalationAccounting.pledges(_disputeId, token); - - bondEscalationAccounting.pledge({ - _pledger: _pledger, - _requestId: _requestId, - _disputeId: _disputeId, - _token: token, - _amount: _amount - }); - - uint256 _balanceAfterPledge = bondEscalationAccounting.balanceOf(_pledger, token); - uint256 _pledgesAfterPledge = bondEscalationAccounting.pledges(_disputeId, token); - - // Check: is the balance before decreased? - assertEq(_balanceAfterPledge, _balanceBeforePledge - _amount); - // Check: is the balance after increased? - assertEq(_pledgesAfterPledge, _pledgesBeforePledge + _amount); - } -} - -contract BondEscalationAccounting_Unit_OnSettleBondEscalation is BaseTest { - function test_revertIfDisallowedModule( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _numOfWinningPledgers, - uint256 _amountPerPledger - ) public { - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(false) - ); - - // Check: does it revert if the module is not allowed? - vm.expectRevert(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector); - - bondEscalationAccounting.onSettleBondEscalation({ - _requestId: _requestId, - _disputeId: _disputeId, - _forVotesWon: true, - _token: token, - _amountPerPledger: _amountPerPledger, - _winningPledgersLength: _numOfWinningPledgers - }); - } - - function test_revertIfAlreadySettled( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _numOfWinningPledgers, - uint256 _amountPerPledger - ) public { - vm.assume(_amountPerPledger > 0); - vm.assume(_numOfWinningPledgers > 0); - vm.assume(_amountPerPledger < type(uint256).max / _numOfWinningPledgers); - vm.assume(_requestId != bytes32(0)); - - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) - ); - - bondEscalationAccounting.forTest_setEscalationResult( - _disputeId, _requestId, true, token, _amountPerPledger, IBondEscalationModule(address(this)) - ); - - bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amountPerPledger * _numOfWinningPledgers); - - // Check: does it revert if the escalation is already settled? - vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_AlreadySettled.selector); - - bondEscalationAccounting.onSettleBondEscalation({ - _requestId: _requestId, - _disputeId: _disputeId, - _forVotesWon: true, - _token: token, - _amountPerPledger: _amountPerPledger, - _winningPledgersLength: _numOfWinningPledgers - }); - } - - function test_revertIfInsufficientFunds( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amountPerPledger, - uint256 _numOfWinningPledgers - ) public { - // Note, bounding to a max of 30 so that the tests doesn't take forever to run - _numOfWinningPledgers = bound(_numOfWinningPledgers, 1, 30); - _amountPerPledger = bound(_amountPerPledger, 1, type(uint256).max / _numOfWinningPledgers); - - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) - ); - - address[] memory _winningPledgers = _createWinningPledgersArray(_numOfWinningPledgers); - - uint256 _totalAmountToPay = _amountPerPledger * _winningPledgers.length; - uint256 _insufficientPledges = _totalAmountToPay - 1; - - bondEscalationAccounting.forTest_setPledge(_disputeId, token, _insufficientPledges); - - // Check: does it revert if the pledger does not have enough funds? - vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_InsufficientFunds.selector); - - bondEscalationAccounting.onSettleBondEscalation({ - _requestId: _requestId, - _disputeId: _disputeId, - _forVotesWon: true, - _token: token, - _amountPerPledger: _amountPerPledger, - _winningPledgersLength: _numOfWinningPledgers - }); - } - - function test_successfulCall( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _numOfWinningPledgers, - uint256 _amountPerPledger - ) public { - // Note, bounding to a max of 30 so that the tests doesn't take forever to run - _numOfWinningPledgers = bound(_numOfWinningPledgers, 1, 30); - _amountPerPledger = bound(_amountPerPledger, 1, type(uint256).max / _numOfWinningPledgers); - - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) - ); - - address[] memory _winningPledgers = _createWinningPledgersArray(_numOfWinningPledgers); - uint256 _totalAmountToPay = _amountPerPledger * _winningPledgers.length; - - bondEscalationAccounting.forTest_setPledge(_disputeId, token, _totalAmountToPay); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationAccounting)); - emit BondEscalationSettled(_requestId, _disputeId, true, token, _amountPerPledger, _numOfWinningPledgers); - - bondEscalationAccounting.onSettleBondEscalation({ - _requestId: _requestId, - _disputeId: _disputeId, - _forVotesWon: true, - _token: token, - _amountPerPledger: _amountPerPledger, - _winningPledgersLength: _numOfWinningPledgers - }); - - ( - bytes32 _requestIdSaved, - bool _forVotesWon, - IERC20 _token, - uint256 _amountPerPledgerSaved, - IBondEscalationModule _bondEscalationModule - ) = bondEscalationAccounting.escalationResults(_disputeId); - - // Check: are the escalation results properly stored? - assertEq(_requestIdSaved, _requestId); - assertEq(_forVotesWon, true); - assertEq(address(_token), address(token)); - assertEq(_amountPerPledgerSaved, _amountPerPledger); - assertEq(address(_bondEscalationModule), address(this)); - } -} - -contract BondEscalationAccounting_Unit_ReleasePledge is BaseTest { - function test_revertIfDisallowedModule( - bytes32 _requestId, - bytes32 _disputeId, - address _pledger, - uint256 _amount - ) public { - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(false) - ); - - // Check: does it revert if the module is not authorized? - vm.expectRevert(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector); - - bondEscalationAccounting.releasePledge({ - _requestId: _requestId, - _disputeId: _disputeId, - _pledger: _pledger, - _token: token, - _amount: _amount - }); - } - - function test_revertIfInsufficientFunds( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amount, - address _pledger - ) public { - vm.assume(_amount < type(uint256).max); - - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) - ); - - bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount); - uint256 _underflowAmount = _amount + 1; - - // Check: does it revert if the pledger does not have enough funds pledged? - vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_InsufficientFunds.selector); - - bondEscalationAccounting.releasePledge({ - _requestId: _requestId, - _disputeId: _disputeId, - _pledger: _pledger, - _token: token, - _amount: _underflowAmount - }); - } - - function test_successfulCall(bytes32 _requestId, bytes32 _disputeId, uint256 _amount, address _pledger) public { - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) - ); - - bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount); - - bondEscalationAccounting.releasePledge({ - _requestId: _requestId, - _disputeId: _disputeId, - _pledger: _pledger, - _token: token, - _amount: _amount - }); - - // Check: are the pledger's funds released? - assertEq(bondEscalationAccounting.balanceOf(_pledger, token), _amount); - } - - function test_emitsEvent(bytes32 _requestId, bytes32 _disputeId, uint256 _amount, address _pledger) public { - // Mock and expect the call to oracle checking if the module is allowed - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) - ); - - bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationAccounting)); - emit PledgeReleased(_requestId, _disputeId, _pledger, token, _amount); - - bondEscalationAccounting.releasePledge({ - _requestId: _requestId, - _disputeId: _disputeId, - _pledger: _pledger, - _token: token, - _amount: _amount - }); - } -} - -contract BondEscalationAccounting_Unit_ClaimEscalationReward is BaseTest { - function test_revertIfInvalidEscalation(bytes32 _disputeId) public { - // Check: does it revert if the escalation is not valid? - vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_NoEscalationResult.selector); - - bondEscalationAccounting.claimEscalationReward(_disputeId, pledger); - } - - function test_revertIfAlreadyClaimed(bytes32 _disputeId, bytes32 _requestId) public { - bondEscalationAccounting.forTest_setEscalationResult( - _disputeId, _requestId, true, token, 0, IBondEscalationModule(address(this)) - ); - - bondEscalationAccounting.forTest_setClaimed(pledger, _requestId, true); - - // Check: does it revert if the reward is already claimed? - vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_AlreadyClaimed.selector); - - bondEscalationAccounting.claimEscalationReward(_disputeId, pledger); - } - - function test_forVotesWon( - bytes32 _disputeId, - bytes32 _requestId, - uint256 _amount, - uint256 _pledges, - address _bondEscalationModule - ) public assumeFuzzable(_bondEscalationModule) { - vm.assume(_amount > 0); - vm.assume(_pledges > 0); - vm.assume(_amount < type(uint256).max / _pledges); - - bondEscalationAccounting.forTest_setEscalationResult( - _disputeId, _requestId, true, token, _amount, IBondEscalationModule(_bondEscalationModule) - ); - - bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount * _pledges); - - // Mock and expect the call to the escalation module asking for pledges - _mockAndExpect( - _bondEscalationModule, - abi.encodeCall(IBondEscalationModule.pledgesForDispute, (_requestId, pledger)), - abi.encode(_pledges) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationAccounting)); - emit EscalationRewardClaimed(_requestId, _disputeId, pledger, token, _amount * _pledges); - - vm.prank(_bondEscalationModule); - bondEscalationAccounting.claimEscalationReward(_disputeId, pledger); - - // Check: is the balance of the pledger properly updated? - assertEq(bondEscalationAccounting.balanceOf(pledger, token), _amount * _pledges); - // Check: is the reward marked as claimed for the pledger? - assertTrue(bondEscalationAccounting.pledgerClaimed(_requestId, pledger)); - // Check: are the pledges updated? - assertEq(bondEscalationAccounting.pledges(_disputeId, token), 0); - } - - function test_againstVotesWon( - bytes32 _disputeId, - bytes32 _requestId, - uint256 _amount, - uint256 _pledges, - address _bondEscalationModule - ) public assumeFuzzable(_bondEscalationModule) { - vm.assume(_amount > 0); - vm.assume(_pledges > 0); - - _amount = bound(_amount, 0, type(uint256).max / _pledges); - - bondEscalationAccounting.forTest_setEscalationResult( - _disputeId, _requestId, false, token, _amount, IBondEscalationModule(_bondEscalationModule) - ); - - bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount * _pledges); - - // Mock and expect to call the escalation module asking for pledges - _mockAndExpect( - _bondEscalationModule, - abi.encodeCall(IBondEscalationModule.pledgesAgainstDispute, (_requestId, pledger)), - abi.encode(_pledges) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationAccounting)); - emit EscalationRewardClaimed(_requestId, _disputeId, pledger, token, _amount * _pledges); - - vm.prank(_bondEscalationModule); - bondEscalationAccounting.claimEscalationReward(_disputeId, pledger); - - // Check: is the balance of the pledger properly updated? - assertEq(bondEscalationAccounting.balanceOf(pledger, token), _amount * _pledges); - // Check: is the reward marked as claimed for the pledger? - assertTrue(bondEscalationAccounting.pledgerClaimed(_requestId, pledger)); - // Check: are the pledges updated? - assertEq(bondEscalationAccounting.pledges(_disputeId, token), 0); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IOracle, IBondEscalationModule} from '../../../../contracts/modules/dispute/BondEscalationModule.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import { +// IBondEscalationAccounting, +// BondEscalationAccounting +// } from '../../../../contracts/extensions/BondEscalationAccounting.sol'; + +// import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; +// import {IWETH9} from '../../../../interfaces/external/IWETH9.sol'; + +// import {Strings} from '@openzeppelin/contracts/utils/Strings.sol'; + +// contract ForTest_BondEscalationAccounting is BondEscalationAccounting { +// constructor(IOracle _oracle) BondEscalationAccounting(_oracle) {} + +// function forTest_setPledge(bytes32 _disputeId, IERC20 _token, uint256 _amount) public { +// pledges[_disputeId][_token] = _amount; +// } + +// function forTest_setBalanceOf(address _bonder, IERC20 _token, uint256 _balance) public { +// balanceOf[_bonder][_token] = _balance; +// } + +// function forTest_setBondedAmountOf(address _bonder, IERC20 _token, bytes32 _requestId, uint256 _amount) public { +// bondedAmountOf[_bonder][_token][_requestId] = _amount; +// } + +// function forTest_setClaimed(address _pledger, bytes32 _requestId, bool _claimed) public { +// pledgerClaimed[_requestId][_pledger] = _claimed; +// } + +// function forTest_setEscalationResult( +// bytes32 _disputeId, +// bytes32 _requestId, +// bool _forVotesWon, +// IERC20 _token, +// uint256 _amountPerPledger, +// IBondEscalationModule _bondEscalationModule +// ) public { +// escalationResults[_disputeId] = EscalationResult({ +// requestId: _requestId, +// forVotesWon: _forVotesWon, +// token: _token, +// amountPerPledger: _amountPerPledger, +// bondEscalationModule: _bondEscalationModule +// }); +// } +// } + +// /** +// * @title Bonded Response Module Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_BondEscalationAccounting public bondEscalationAccounting; +// // A mock oracle +// IOracle public oracle; +// // Mock WETH +// IWETH9 public weth; +// // A mock token +// IERC20 public token; +// // Mock EOA bonder +// address public bonder = makeAddr('bonder'); +// address public pledger = makeAddr('pledger'); + +// // Pledged Event +// event Pledged( +// address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, IERC20 _token, uint256 _amount +// ); + +// event BondEscalationSettled( +// bytes32 _requestId, +// bytes32 _disputeId, +// bool _forVotesWon, +// IERC20 _token, +// uint256 _amountPerPledger, +// uint256 _winningPledgersLength +// ); + +// event EscalationRewardClaimed( +// bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, IERC20 _token, uint256 _amount +// ); + +// event PledgeReleased( +// bytes32 indexed _requestId, bytes32 indexed _disputeId, address indexed _pledger, IERC20 _token, uint256 _amount +// ); + +// function _createWinningPledgersArray(uint256 _numWinningPledgers) +// internal +// returns (address[] memory _winningPledgers) +// { +// _winningPledgers = new address[](_numWinningPledgers); +// address _winningPledger; + +// for (uint256 _i; _i < _numWinningPledgers; _i++) { +// _winningPledger = makeAddr(string.concat('winningPledger', Strings.toString(_i))); +// _winningPledgers[_i] = _winningPledger; +// } +// } + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// token = IERC20(makeAddr('ERC20')); +// vm.etch(address(token), hex'069420'); + +// bondEscalationAccounting = new ForTest_BondEscalationAccounting(oracle); +// } +// } + +// contract BondEscalationAccounting_Unit_Pledge is BaseTest { +// function test_revertIfDisallowedModule( +// address _pledger, +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _amount +// ) public { +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(false) +// ); + +// // Check: does it revert if called by an unauthorized module? +// vm.expectRevert(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector); + +// bondEscalationAccounting.pledge({ +// _pledger: _pledger, +// _requestId: _requestId, +// _disputeId: _disputeId, +// _token: token, +// _amount: _amount +// }); +// } + +// function test_revertIfNotEnoughDeposited( +// address _pledger, +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _amount +// ) public { +// vm.assume(_amount > 0); + +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) +// ); + +// // Check: does it revert if the pledger doesn't have enough deposited? +// vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_InsufficientFunds.selector); + +// bondEscalationAccounting.pledge({ +// _pledger: _pledger, +// _requestId: _requestId, +// _disputeId: _disputeId, +// _token: token, +// _amount: _amount +// }); +// } + +// function test_successfulCall(address _pledger, bytes32 _requestId, bytes32 _disputeId, uint256 _amount) public { +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) +// ); + +// bondEscalationAccounting.forTest_setBalanceOf(_pledger, token, _amount); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationAccounting)); +// emit Pledged(_pledger, _requestId, _disputeId, token, _amount); + +// uint256 _balanceBeforePledge = bondEscalationAccounting.balanceOf(_pledger, token); +// uint256 _pledgesBeforePledge = bondEscalationAccounting.pledges(_disputeId, token); + +// bondEscalationAccounting.pledge({ +// _pledger: _pledger, +// _requestId: _requestId, +// _disputeId: _disputeId, +// _token: token, +// _amount: _amount +// }); + +// uint256 _balanceAfterPledge = bondEscalationAccounting.balanceOf(_pledger, token); +// uint256 _pledgesAfterPledge = bondEscalationAccounting.pledges(_disputeId, token); + +// // Check: is the balance before decreased? +// assertEq(_balanceAfterPledge, _balanceBeforePledge - _amount); +// // Check: is the balance after increased? +// assertEq(_pledgesAfterPledge, _pledgesBeforePledge + _amount); +// } +// } + +// contract BondEscalationAccounting_Unit_OnSettleBondEscalation is BaseTest { +// function test_revertIfDisallowedModule( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _numOfWinningPledgers, +// uint256 _amountPerPledger +// ) public { +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(false) +// ); + +// // Check: does it revert if the module is not allowed? +// vm.expectRevert(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector); + +// bondEscalationAccounting.onSettleBondEscalation({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _forVotesWon: true, +// _token: token, +// _amountPerPledger: _amountPerPledger, +// _winningPledgersLength: _numOfWinningPledgers +// }); +// } + +// function test_revertIfAlreadySettled( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _numOfWinningPledgers, +// uint256 _amountPerPledger +// ) public { +// vm.assume(_amountPerPledger > 0); +// vm.assume(_numOfWinningPledgers > 0); +// vm.assume(_amountPerPledger < type(uint256).max / _numOfWinningPledgers); +// vm.assume(_requestId != bytes32(0)); + +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) +// ); + +// bondEscalationAccounting.forTest_setEscalationResult( +// _disputeId, _requestId, true, token, _amountPerPledger, IBondEscalationModule(address(this)) +// ); + +// bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amountPerPledger * _numOfWinningPledgers); + +// // Check: does it revert if the escalation is already settled? +// vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_AlreadySettled.selector); + +// bondEscalationAccounting.onSettleBondEscalation({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _forVotesWon: true, +// _token: token, +// _amountPerPledger: _amountPerPledger, +// _winningPledgersLength: _numOfWinningPledgers +// }); +// } + +// function test_revertIfInsufficientFunds( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _amountPerPledger, +// uint256 _numOfWinningPledgers +// ) public { +// // Note, bounding to a max of 30 so that the tests doesn't take forever to run +// _numOfWinningPledgers = bound(_numOfWinningPledgers, 1, 30); +// _amountPerPledger = bound(_amountPerPledger, 1, type(uint256).max / _numOfWinningPledgers); + +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) +// ); + +// address[] memory _winningPledgers = _createWinningPledgersArray(_numOfWinningPledgers); + +// uint256 _totalAmountToPay = _amountPerPledger * _winningPledgers.length; +// uint256 _insufficientPledges = _totalAmountToPay - 1; + +// bondEscalationAccounting.forTest_setPledge(_disputeId, token, _insufficientPledges); + +// // Check: does it revert if the pledger does not have enough funds? +// vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_InsufficientFunds.selector); + +// bondEscalationAccounting.onSettleBondEscalation({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _forVotesWon: true, +// _token: token, +// _amountPerPledger: _amountPerPledger, +// _winningPledgersLength: _numOfWinningPledgers +// }); +// } + +// function test_successfulCall( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _numOfWinningPledgers, +// uint256 _amountPerPledger +// ) public { +// // Note, bounding to a max of 30 so that the tests doesn't take forever to run +// _numOfWinningPledgers = bound(_numOfWinningPledgers, 1, 30); +// _amountPerPledger = bound(_amountPerPledger, 1, type(uint256).max / _numOfWinningPledgers); + +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) +// ); + +// address[] memory _winningPledgers = _createWinningPledgersArray(_numOfWinningPledgers); +// uint256 _totalAmountToPay = _amountPerPledger * _winningPledgers.length; + +// bondEscalationAccounting.forTest_setPledge(_disputeId, token, _totalAmountToPay); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationAccounting)); +// emit BondEscalationSettled(_requestId, _disputeId, true, token, _amountPerPledger, _numOfWinningPledgers); + +// bondEscalationAccounting.onSettleBondEscalation({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _forVotesWon: true, +// _token: token, +// _amountPerPledger: _amountPerPledger, +// _winningPledgersLength: _numOfWinningPledgers +// }); + +// ( +// bytes32 _requestIdSaved, +// bool _forVotesWon, +// IERC20 _token, +// uint256 _amountPerPledgerSaved, +// IBondEscalationModule _bondEscalationModule +// ) = bondEscalationAccounting.escalationResults(_disputeId); + +// // Check: are the escalation results properly stored? +// assertEq(_requestIdSaved, _requestId); +// assertEq(_forVotesWon, true); +// assertEq(address(_token), address(token)); +// assertEq(_amountPerPledgerSaved, _amountPerPledger); +// assertEq(address(_bondEscalationModule), address(this)); +// } +// } + +// contract BondEscalationAccounting_Unit_ReleasePledge is BaseTest { +// function test_revertIfDisallowedModule( +// bytes32 _requestId, +// bytes32 _disputeId, +// address _pledger, +// uint256 _amount +// ) public { +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(false) +// ); + +// // Check: does it revert if the module is not authorized? +// vm.expectRevert(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector); + +// bondEscalationAccounting.releasePledge({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _pledger: _pledger, +// _token: token, +// _amount: _amount +// }); +// } + +// function test_revertIfInsufficientFunds( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _amount, +// address _pledger +// ) public { +// vm.assume(_amount < type(uint256).max); + +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) +// ); + +// bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount); +// uint256 _underflowAmount = _amount + 1; + +// // Check: does it revert if the pledger does not have enough funds pledged? +// vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_InsufficientFunds.selector); + +// bondEscalationAccounting.releasePledge({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _pledger: _pledger, +// _token: token, +// _amount: _underflowAmount +// }); +// } + +// function test_successfulCall(bytes32 _requestId, bytes32 _disputeId, uint256 _amount, address _pledger) public { +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) +// ); + +// bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount); + +// bondEscalationAccounting.releasePledge({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _pledger: _pledger, +// _token: token, +// _amount: _amount +// }); + +// // Check: are the pledger's funds released? +// assertEq(bondEscalationAccounting.balanceOf(_pledger, token), _amount); +// } + +// function test_emitsEvent(bytes32 _requestId, bytes32 _disputeId, uint256 _amount, address _pledger) public { +// // Mock and expect the call to oracle checking if the module is allowed +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) +// ); + +// bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationAccounting)); +// emit PledgeReleased(_requestId, _disputeId, _pledger, token, _amount); + +// bondEscalationAccounting.releasePledge({ +// _requestId: _requestId, +// _disputeId: _disputeId, +// _pledger: _pledger, +// _token: token, +// _amount: _amount +// }); +// } +// } + +// contract BondEscalationAccounting_Unit_ClaimEscalationReward is BaseTest { +// function test_revertIfInvalidEscalation(bytes32 _disputeId) public { +// // Check: does it revert if the escalation is not valid? +// vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_NoEscalationResult.selector); + +// bondEscalationAccounting.claimEscalationReward(_disputeId, pledger); +// } + +// function test_revertIfAlreadyClaimed(bytes32 _disputeId, bytes32 _requestId) public { +// bondEscalationAccounting.forTest_setEscalationResult( +// _disputeId, _requestId, true, token, 0, IBondEscalationModule(address(this)) +// ); + +// bondEscalationAccounting.forTest_setClaimed(pledger, _requestId, true); + +// // Check: does it revert if the reward is already claimed? +// vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_AlreadyClaimed.selector); + +// bondEscalationAccounting.claimEscalationReward(_disputeId, pledger); +// } + +// function test_forVotesWon( +// bytes32 _disputeId, +// bytes32 _requestId, +// uint256 _amount, +// uint256 _pledges, +// address _bondEscalationModule +// ) public assumeFuzzable(_bondEscalationModule) { +// vm.assume(_amount > 0); +// vm.assume(_pledges > 0); +// vm.assume(_amount < type(uint256).max / _pledges); + +// bondEscalationAccounting.forTest_setEscalationResult( +// _disputeId, _requestId, true, token, _amount, IBondEscalationModule(_bondEscalationModule) +// ); + +// bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount * _pledges); + +// // Mock and expect the call to the escalation module asking for pledges +// _mockAndExpect( +// _bondEscalationModule, +// abi.encodeCall(IBondEscalationModule.pledgesForDispute, (_requestId, pledger)), +// abi.encode(_pledges) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationAccounting)); +// emit EscalationRewardClaimed(_requestId, _disputeId, pledger, token, _amount * _pledges); + +// vm.prank(_bondEscalationModule); +// bondEscalationAccounting.claimEscalationReward(_disputeId, pledger); + +// // Check: is the balance of the pledger properly updated? +// assertEq(bondEscalationAccounting.balanceOf(pledger, token), _amount * _pledges); +// // Check: is the reward marked as claimed for the pledger? +// assertTrue(bondEscalationAccounting.pledgerClaimed(_requestId, pledger)); +// // Check: are the pledges updated? +// assertEq(bondEscalationAccounting.pledges(_disputeId, token), 0); +// } + +// function test_againstVotesWon( +// bytes32 _disputeId, +// bytes32 _requestId, +// uint256 _amount, +// uint256 _pledges, +// address _bondEscalationModule +// ) public assumeFuzzable(_bondEscalationModule) { +// vm.assume(_amount > 0); +// vm.assume(_pledges > 0); + +// _amount = bound(_amount, 0, type(uint256).max / _pledges); + +// bondEscalationAccounting.forTest_setEscalationResult( +// _disputeId, _requestId, false, token, _amount, IBondEscalationModule(_bondEscalationModule) +// ); + +// bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount * _pledges); + +// // Mock and expect to call the escalation module asking for pledges +// _mockAndExpect( +// _bondEscalationModule, +// abi.encodeCall(IBondEscalationModule.pledgesAgainstDispute, (_requestId, pledger)), +// abi.encode(_pledges) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationAccounting)); +// emit EscalationRewardClaimed(_requestId, _disputeId, pledger, token, _amount * _pledges); + +// vm.prank(_bondEscalationModule); +// bondEscalationAccounting.claimEscalationReward(_disputeId, pledger); + +// // Check: is the balance of the pledger properly updated? +// assertEq(bondEscalationAccounting.balanceOf(pledger, token), _amount * _pledges); +// // Check: is the reward marked as claimed for the pledger? +// assertTrue(bondEscalationAccounting.pledgerClaimed(_requestId, pledger)); +// // Check: are the pledges updated? +// assertEq(bondEscalationAccounting.pledges(_disputeId, token), 0); +// } +// } diff --git a/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol b/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol index 75c9ad7b..bcf3c02f 100644 --- a/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol +++ b/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol @@ -1,1437 +1,1437 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {Strings} from '@openzeppelin/contracts/utils/Strings.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - BondEscalationModule, IBondEscalationModule -} from '../../../../contracts/modules/dispute/BondEscalationModule.sol'; - -import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; -import {IBondEscalationAccounting} from '../../../../interfaces/extensions/IBondEscalationAccounting.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ -contract ForTest_BondEscalationModule is BondEscalationModule { - constructor(IOracle _oracle) BondEscalationModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } - - function forTest_setBondEscalation( - bytes32 _requestId, - address[] memory _pledgersForDispute, - address[] memory _pledgersAgainstDispute - ) public { - for (uint256 _i; _i < _pledgersForDispute.length; _i++) { - pledgesForDispute[_requestId][_pledgersForDispute[_i]] += 1; - } - - for (uint256 _i; _i < _pledgersAgainstDispute.length; _i++) { - pledgesAgainstDispute[_requestId][_pledgersAgainstDispute[_i]] += 1; - } - - _escalations[_requestId].amountOfPledgesForDispute += _pledgersForDispute.length; - _escalations[_requestId].amountOfPledgesAgainstDispute += _pledgersAgainstDispute.length; - } - - function forTest_setBondEscalationStatus( - bytes32 _requestId, - BondEscalationModule.BondEscalationStatus _bondEscalationStatus - ) public { - _escalations[_requestId].status = _bondEscalationStatus; - } - - function forTest_setEscalatedDispute(bytes32 _requestId, bytes32 _disputeId) public { - _escalations[_requestId].disputeId = _disputeId; - } -} - -/** - * @title Bonded Response Module Unit tests - */ - -contract BaseTest is Test, Helpers { - // The target contract - ForTest_BondEscalationModule public bondEscalationModule; - // A mock oracle - IOracle public oracle; - // A mock accounting extension - IBondEscalationAccounting public accounting; - // A mock token - IERC20 public token; - // Mock EOA proposer - address public proposer = makeAddr('proposer'); - // Mock EOA disputer - address public disputer = makeAddr('disputer'); - // Mock bondSize - uint256 public bondSize; - // Mock max number of escalations - uint256 public maxEscalations; - // Mock bond escalation deadline - uint256 public bondEscalationDeadline; - // Mock tyingBuffer - uint256 public tyingBuffer; - // Mock dispute window - uint256 public disputeWindow; - // Mock dispute - IOracle.Dispute internal _mockDispute; - // Mock response - IOracle.Response internal _mockResponse; - - // Events - event PledgedForDispute(bytes32 indexed _disputeId, address indexed _pledger, uint256 indexed _amount); - event PledgedAgainstDispute(bytes32 indexed _disputeId, address indexed _pledger, uint256 indexed _amount); - event BondEscalationStatusUpdated( - bytes32 indexed _requestId, bytes32 indexed _disputeId, IBondEscalationModule.BondEscalationStatus _status - ); - event ResponseDisputed(bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer); - event DisputeStatusChanged( - bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer, IOracle.DisputeStatus _status - ); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - accounting = IBondEscalationAccounting(makeAddr('BondEscalationAccounting')); - vm.etch(address(accounting), hex'069420'); - - token = IERC20(makeAddr('ERC20')); - vm.etch(address(token), hex'069420'); - - // Set to an arbitrary large value to avoid unintended reverts - disputeWindow = type(uint128).max; - - // Avoid starting at 0 for time sensitive tests - vm.warp(123_456); - - _mockDispute = IOracle.Dispute({ - disputer: disputer, - responseId: bytes32('response'), - proposer: proposer, - requestId: bytes32('69'), - status: IOracle.DisputeStatus.Active, - createdAt: block.timestamp - }); - - _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - proposer: proposer, - requestId: bytes32('69'), - disputeId: 0, - response: abi.encode(bytes32('response')) - }); - - bondEscalationModule = new ForTest_BondEscalationModule(oracle); - } - - function _setRequestData( - bytes32 _requestId, - uint256 _bondSize, - uint256 _maxNumberOfEscalations, - uint256 _bondEscalationDeadline, - uint256 _tyingBuffer, - uint256 _disputeWindow - ) internal { - bytes memory _data = abi.encode( - IBondEscalationModule.RequestParameters({ - accountingExtension: accounting, - bondToken: token, - bondSize: _bondSize, - maxNumberOfEscalations: _maxNumberOfEscalations, - bondEscalationDeadline: _bondEscalationDeadline, - tyingBuffer: _tyingBuffer, - disputeWindow: _disputeWindow - }) - ); - bondEscalationModule.forTest_setRequestData(_requestId, _data); - } - - function _getRandomDispute( - bytes32 _requestId, - IOracle.DisputeStatus _status - ) internal view returns (IOracle.Dispute memory _dispute) { - _dispute = IOracle.Dispute({ - disputer: disputer, - responseId: bytes32('response'), - proposer: proposer, - requestId: _requestId, - status: _status, - createdAt: block.timestamp - }); - } - - function _setBondEscalation( - bytes32 _requestId, - uint256 _numForPledgers, - uint256 _numAgainstPledgers - ) internal returns (address[] memory _forPledgers, address[] memory _againstPledgers) { - _forPledgers = new address[](_numForPledgers); - _againstPledgers = new address[](_numAgainstPledgers); - address _forPledger; - address _againstPledger; - - for (uint256 _i; _i < _numForPledgers; _i++) { - _forPledger = makeAddr(string.concat('forPledger', Strings.toString(_i))); - _forPledgers[_i] = _forPledger; - } - - for (uint256 _j; _j < _numAgainstPledgers; _j++) { - _againstPledger = makeAddr(string.concat('againstPledger', Strings.toString(_j))); - _againstPledgers[_j] = _againstPledger; - } - - bondEscalationModule.forTest_setBondEscalation(_requestId, _forPledgers, _againstPledgers); - - return (_forPledgers, _againstPledgers); - } -} - -contract BondEscalationModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleName() public { - assertEq(bondEscalationModule.moduleName(), 'BondEscalationModule'); - } - - /** - * @notice Tests that decodeRequestData decodes the data correctly - */ - function test_decodeRequestDataReturnTheCorrectData( - bytes32 _requestId, - uint256 _bondSize, - uint256 _maxNumberOfEscalations, - uint256 _bondEscalationDeadline, - uint256 _tyingBuffer, - uint256 _disputeWindow - ) public { - _setRequestData( - _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, _disputeWindow - ); - IBondEscalationModule.RequestParameters memory _params = bondEscalationModule.decodeRequestData(_requestId); - - // Check: does the stored data match the provided one? - assertEq(address(accounting), address(_params.accountingExtension)); - assertEq(address(token), address(_params.bondToken)); - assertEq(_bondSize, _params.bondSize); - assertEq(_maxNumberOfEscalations, _params.maxNumberOfEscalations); - assertEq(_bondEscalationDeadline, _params.bondEscalationDeadline); - assertEq(_tyingBuffer, _params.tyingBuffer); - assertEq(_disputeWindow, _params.disputeWindow); - } -} - -contract BondEscalationModule_Unit_EscalateDispute is BaseTest { - /** - * @notice Tests that escalateDispute reverts if the _disputeId doesn't match any existing disputes. - */ - function test_revertOnInvalidDispute(bytes32 _disputeId) public { - _mockDispute.requestId = bytes32(0); - // Mock and expect Oracle.getDispute to be called. - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Check: does it revert if the dispute does not exist? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_DisputeDoesNotExist.selector); - vm.prank(address(oracle)); - bondEscalationModule.disputeEscalated(_disputeId); - } - - /** - * @notice Tests that escalateDispute reverts if the _disputeId doesn't match any existing disputes. - */ - function test_revertOnInvalidParameters( - bytes32 _requestId, - uint256 _maxNumberOfEscalations, - uint256 _bondSize, - uint256 _bondEscalationDeadline, - uint256 _tyingBuffer, - uint256 _disputeWindow - ) public { - bytes memory _requestData = abi.encode( - IBondEscalationModule.RequestParameters({ - accountingExtension: accounting, - bondToken: token, - bondSize: _bondSize, - maxNumberOfEscalations: _maxNumberOfEscalations, - bondEscalationDeadline: _bondEscalationDeadline, - tyingBuffer: _tyingBuffer, - disputeWindow: _disputeWindow - }) - ); - - if (_maxNumberOfEscalations == 0 || _bondSize == 0) { - // Check: does it revert if _maxNumberOfEscalations or _bondSize is 0? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidEscalationParameters.selector); - } - - vm.prank(address(oracle)); - bondEscalationModule.setupRequest(_requestId, _requestData); - } - - /** - * @notice Tests that escalateDispute reverts if a dispute is escalated before the bond escalation deadline is over. - * Conditions to reach this check: - * - The _requestId tied to the dispute tied to _disputeId must be valid (non-zero) - * - The block.timestamp has to be <= bond escalation deadline - */ - function test_revertEscalationDuringBondEscalation(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_requestId > 0); - - _mockDispute.requestId = _requestId; - - // Mock and expect Oracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Set _bondEscalationDeadline to be the current timestamp to reach the second condition. - uint256 _bondEscalationDeadline = block.timestamp; - - // Populate the requestData for the given requestId - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); - - // Setting this dispute as the one going through the bond escalation process, as the user can only - // dispute once before the bond escalation deadline is over, and that dispute goes through the escalation module. - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - // Check: does it revert if the bond escalation is not over yet? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationNotOver.selector); - vm.prank(address(oracle)); - bondEscalationModule.disputeEscalated(_disputeId); - } - - /** - * @notice Tests that escalateDispute reverts if a dispute that went through the bond escalation mechanism but isn't active - * anymore is escalated. - * Conditions to reach this check: - * - The _requestId tied to the dispute tied to _disputeId must be valid (non-zero) - * - The block.timestamp has to be > bond escalation deadline - * - The dispute has to have gone through the bond escalation process before - * - The status of the bond escalation mechanism has to be different from Active - */ - function test_revertIfEscalatingNonActiveDispute(bytes32 _disputeId, bytes32 _requestId, uint8 _status) public { - // Assume _requestId is not zero - vm.assume(_requestId > 0); - // Assume the status will be any available other but Active - vm.assume(_status != uint8(IBondEscalationModule.BondEscalationStatus.Active) && _status < 4); - - _mockDispute.requestId = _requestId; - - // Mock and expect Oracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Set a tying buffer to show that this can happen even in the tying buffer if the dispute was settled - uint256 _tyingBuffer = 1000; - - // Make the current timestamp be greater than the bond escalation deadline - uint256 _bondEscalationDeadline = block.timestamp - 1; - - // Populate the requestData for the given requestId - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); - - // Set the bond escalation status of the given requestId to something different than Active - bondEscalationModule.forTest_setBondEscalationStatus( - _requestId, IBondEscalationModule.BondEscalationStatus(_status) - ); - - // Set the dispute to be the one that went through the bond escalation process for the given requestId - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - // Check: does it revert if the dispute is not escalatable? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_NotEscalatable.selector); - vm.prank(address(oracle)); - bondEscalationModule.disputeEscalated(_disputeId); - } - - /** - * @notice Tests that escalateDispute reverts if a dispute that went through the bond escalation mechanism and is still active - * but its pledges are not tied even after the tying buffer is escalated. - * Conditions to reach this check: - * - The _requestId tied to the dispute tied to _disputeId must be valid (non-zero) - * - The block.timestamp has to be > bond escalation deadline + tying buffer - * - The dispute has to have gone or be going through the bond escalation process - * - The pledges must not be tied - */ - function test_revertIfEscalatingDisputeIsNotTied(bytes32 _disputeId, bytes32 _requestId) public { - // Assume _requestId is not zero - vm.assume(_requestId > 0); - - _mockDispute.requestId = _requestId; - - // Mock and expect Oracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Set a tying buffer to make the test more explicit - uint256 _tyingBuffer = 1000; - - // Set bond escalation deadline to be the current timestamp. We will warp this. - uint256 _bondEscalationDeadline = block.timestamp; - - // Set the number of pledgers to be different - uint256 _numForPledgers = 1; - uint256 _numAgainstPledgers = 2; - - // Warp the current timestamp so we are past the tyingBuffer - vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); - - // Populate the requestData for the given requestId - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); - - // Set the bond escalation status of the given requestId to Active - bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.Active); - - // Set the dispute to be the one that went through the bond escalation process for the given requestId - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - // Set the number of pledgers for both sides - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - - // Check: does it revert if the dispute is not escalatable? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_NotEscalatable.selector); - vm.prank(address(oracle)); - bondEscalationModule.disputeEscalated(_disputeId); - } - - /** - * @notice Tests that escalateDispute escalates the dispute going through the bond escalation mechanism correctly when the - * pledges are tied and the dispute is still active. - * Conditions for the function to succeed: - * - The _requestId tied to the dispute tied to _disputeId must be valid (non-zero) - * - The block.timestamp has to be > bond escalation deadline - * - The dispute has to have gone or be going through the bond escalation process - * - The pledges must be tied - */ - function test_escalateTiedDispute(bytes32 _disputeId, bytes32 _requestId) public { - // Assume _requestId is not zero - vm.assume(_requestId > 0); - vm.assume(_disputeId > 0); - - _mockDispute.requestId = _requestId; - - // Mock and expect Oracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {Strings} from '@openzeppelin/contracts/utils/Strings.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// BondEscalationModule, IBondEscalationModule +// } from '../../../../contracts/modules/dispute/BondEscalationModule.sol'; + +// import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; +// import {IBondEscalationAccounting} from '../../../../interfaces/extensions/IBondEscalationAccounting.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ +// contract ForTest_BondEscalationModule is BondEscalationModule { +// constructor(IOracle _oracle) BondEscalationModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } + +// function forTest_setBondEscalation( +// bytes32 _requestId, +// address[] memory _pledgersForDispute, +// address[] memory _pledgersAgainstDispute +// ) public { +// for (uint256 _i; _i < _pledgersForDispute.length; _i++) { +// pledgesForDispute[_requestId][_pledgersForDispute[_i]] += 1; +// } + +// for (uint256 _i; _i < _pledgersAgainstDispute.length; _i++) { +// pledgesAgainstDispute[_requestId][_pledgersAgainstDispute[_i]] += 1; +// } + +// _escalations[_requestId].amountOfPledgesForDispute += _pledgersForDispute.length; +// _escalations[_requestId].amountOfPledgesAgainstDispute += _pledgersAgainstDispute.length; +// } + +// function forTest_setBondEscalationStatus( +// bytes32 _requestId, +// BondEscalationModule.BondEscalationStatus _bondEscalationStatus +// ) public { +// _escalations[_requestId].status = _bondEscalationStatus; +// } + +// function forTest_setEscalatedDispute(bytes32 _requestId, bytes32 _disputeId) public { +// _escalations[_requestId].disputeId = _disputeId; +// } +// } + +// /** +// * @title Bonded Response Module Unit tests +// */ + +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_BondEscalationModule public bondEscalationModule; +// // A mock oracle +// IOracle public oracle; +// // A mock accounting extension +// IBondEscalationAccounting public accounting; +// // A mock token +// IERC20 public token; +// // Mock EOA proposer +// address public proposer = makeAddr('proposer'); +// // Mock EOA disputer +// address public disputer = makeAddr('disputer'); +// // Mock bondSize +// uint256 public bondSize; +// // Mock max number of escalations +// uint256 public maxEscalations; +// // Mock bond escalation deadline +// uint256 public bondEscalationDeadline; +// // Mock tyingBuffer +// uint256 public tyingBuffer; +// // Mock dispute window +// uint256 public disputeWindow; +// // Mock dispute +// IOracle.Dispute internal _mockDispute; +// // Mock response +// IOracle.Response internal _mockResponse; + +// // Events +// event PledgedForDispute(bytes32 indexed _disputeId, address indexed _pledger, uint256 indexed _amount); +// event PledgedAgainstDispute(bytes32 indexed _disputeId, address indexed _pledger, uint256 indexed _amount); +// event BondEscalationStatusUpdated( +// bytes32 indexed _requestId, bytes32 indexed _disputeId, IBondEscalationModule.BondEscalationStatus _status +// ); +// event ResponseDisputed(bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer); +// event DisputeStatusChanged( +// bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer, IOracle.DisputeStatus _status +// ); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// accounting = IBondEscalationAccounting(makeAddr('BondEscalationAccounting')); +// vm.etch(address(accounting), hex'069420'); + +// token = IERC20(makeAddr('ERC20')); +// vm.etch(address(token), hex'069420'); + +// // Set to an arbitrary large value to avoid unintended reverts +// disputeWindow = type(uint128).max; + +// // Avoid starting at 0 for time sensitive tests +// vm.warp(123_456); + +// _mockDispute = IOracle.Dispute({ +// disputer: disputer, +// responseId: bytes32('response'), +// proposer: proposer, +// requestId: bytes32('69'), +// status: IOracle.DisputeStatus.Active, +// createdAt: block.timestamp +// }); + +// _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// proposer: proposer, +// requestId: bytes32('69'), +// disputeId: 0, +// response: abi.encode(bytes32('response')) +// }); + +// bondEscalationModule = new ForTest_BondEscalationModule(oracle); +// } + +// function _setRequestData( +// bytes32 _requestId, +// uint256 _bondSize, +// uint256 _maxNumberOfEscalations, +// uint256 _bondEscalationDeadline, +// uint256 _tyingBuffer, +// uint256 _disputeWindow +// ) internal { +// bytes memory _data = abi.encode( +// IBondEscalationModule.RequestParameters({ +// accountingExtension: accounting, +// bondToken: token, +// bondSize: _bondSize, +// maxNumberOfEscalations: _maxNumberOfEscalations, +// bondEscalationDeadline: _bondEscalationDeadline, +// tyingBuffer: _tyingBuffer, +// disputeWindow: _disputeWindow +// }) +// ); +// bondEscalationModule.forTest_setRequestData(_requestId, _data); +// } + +// function _getRandomDispute( +// bytes32 _requestId, +// IOracle.DisputeStatus _status +// ) internal view returns (IOracle.Dispute memory _dispute) { +// _dispute = IOracle.Dispute({ +// disputer: disputer, +// responseId: bytes32('response'), +// proposer: proposer, +// requestId: _requestId, +// status: _status, +// createdAt: block.timestamp +// }); +// } + +// function _setBondEscalation( +// bytes32 _requestId, +// uint256 _numForPledgers, +// uint256 _numAgainstPledgers +// ) internal returns (address[] memory _forPledgers, address[] memory _againstPledgers) { +// _forPledgers = new address[](_numForPledgers); +// _againstPledgers = new address[](_numAgainstPledgers); +// address _forPledger; +// address _againstPledger; + +// for (uint256 _i; _i < _numForPledgers; _i++) { +// _forPledger = makeAddr(string.concat('forPledger', Strings.toString(_i))); +// _forPledgers[_i] = _forPledger; +// } + +// for (uint256 _j; _j < _numAgainstPledgers; _j++) { +// _againstPledger = makeAddr(string.concat('againstPledger', Strings.toString(_j))); +// _againstPledgers[_j] = _againstPledger; +// } + +// bondEscalationModule.forTest_setBondEscalation(_requestId, _forPledgers, _againstPledgers); + +// return (_forPledgers, _againstPledgers); +// } +// } + +// contract BondEscalationModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleName() public { +// assertEq(bondEscalationModule.moduleName(), 'BondEscalationModule'); +// } + +// /** +// * @notice Tests that decodeRequestData decodes the data correctly +// */ +// function test_decodeRequestDataReturnTheCorrectData( +// bytes32 _requestId, +// uint256 _bondSize, +// uint256 _maxNumberOfEscalations, +// uint256 _bondEscalationDeadline, +// uint256 _tyingBuffer, +// uint256 _disputeWindow +// ) public { +// _setRequestData( +// _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, _disputeWindow +// ); +// IBondEscalationModule.RequestParameters memory _params = bondEscalationModule.decodeRequestData(_requestId); + +// // Check: does the stored data match the provided one? +// assertEq(address(accounting), address(_params.accountingExtension)); +// assertEq(address(token), address(_params.bondToken)); +// assertEq(_bondSize, _params.bondSize); +// assertEq(_maxNumberOfEscalations, _params.maxNumberOfEscalations); +// assertEq(_bondEscalationDeadline, _params.bondEscalationDeadline); +// assertEq(_tyingBuffer, _params.tyingBuffer); +// assertEq(_disputeWindow, _params.disputeWindow); +// } +// } + +// contract BondEscalationModule_Unit_EscalateDispute is BaseTest { +// /** +// * @notice Tests that escalateDispute reverts if the _disputeId doesn't match any existing disputes. +// */ +// function test_revertOnInvalidDispute(bytes32 _disputeId) public { +// _mockDispute.requestId = bytes32(0); +// // Mock and expect Oracle.getDispute to be called. +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Check: does it revert if the dispute does not exist? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_DisputeDoesNotExist.selector); +// vm.prank(address(oracle)); +// bondEscalationModule.disputeEscalated(_disputeId); +// } + +// /** +// * @notice Tests that escalateDispute reverts if the _disputeId doesn't match any existing disputes. +// */ +// function test_revertOnInvalidParameters( +// bytes32 _requestId, +// uint256 _maxNumberOfEscalations, +// uint256 _bondSize, +// uint256 _bondEscalationDeadline, +// uint256 _tyingBuffer, +// uint256 _disputeWindow +// ) public { +// bytes memory _requestData = abi.encode( +// IBondEscalationModule.RequestParameters({ +// accountingExtension: accounting, +// bondToken: token, +// bondSize: _bondSize, +// maxNumberOfEscalations: _maxNumberOfEscalations, +// bondEscalationDeadline: _bondEscalationDeadline, +// tyingBuffer: _tyingBuffer, +// disputeWindow: _disputeWindow +// }) +// ); + +// if (_maxNumberOfEscalations == 0 || _bondSize == 0) { +// // Check: does it revert if _maxNumberOfEscalations or _bondSize is 0? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidEscalationParameters.selector); +// } + +// vm.prank(address(oracle)); +// bondEscalationModule.setupRequest(_requestId, _requestData); +// } + +// /** +// * @notice Tests that escalateDispute reverts if a dispute is escalated before the bond escalation deadline is over. +// * Conditions to reach this check: +// * - The _requestId tied to the dispute tied to _disputeId must be valid (non-zero) +// * - The block.timestamp has to be <= bond escalation deadline +// */ +// function test_revertEscalationDuringBondEscalation(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_requestId > 0); + +// _mockDispute.requestId = _requestId; + +// // Mock and expect Oracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Set _bondEscalationDeadline to be the current timestamp to reach the second condition. +// uint256 _bondEscalationDeadline = block.timestamp; + +// // Populate the requestData for the given requestId +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); + +// // Setting this dispute as the one going through the bond escalation process, as the user can only +// // dispute once before the bond escalation deadline is over, and that dispute goes through the escalation module. +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// // Check: does it revert if the bond escalation is not over yet? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationNotOver.selector); +// vm.prank(address(oracle)); +// bondEscalationModule.disputeEscalated(_disputeId); +// } + +// /** +// * @notice Tests that escalateDispute reverts if a dispute that went through the bond escalation mechanism but isn't active +// * anymore is escalated. +// * Conditions to reach this check: +// * - The _requestId tied to the dispute tied to _disputeId must be valid (non-zero) +// * - The block.timestamp has to be > bond escalation deadline +// * - The dispute has to have gone through the bond escalation process before +// * - The status of the bond escalation mechanism has to be different from Active +// */ +// function test_revertIfEscalatingNonActiveDispute(bytes32 _disputeId, bytes32 _requestId, uint8 _status) public { +// // Assume _requestId is not zero +// vm.assume(_requestId > 0); +// // Assume the status will be any available other but Active +// vm.assume(_status != uint8(IBondEscalationModule.BondEscalationStatus.Active) && _status < 4); + +// _mockDispute.requestId = _requestId; + +// // Mock and expect Oracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Set a tying buffer to show that this can happen even in the tying buffer if the dispute was settled +// uint256 _tyingBuffer = 1000; + +// // Make the current timestamp be greater than the bond escalation deadline +// uint256 _bondEscalationDeadline = block.timestamp - 1; + +// // Populate the requestData for the given requestId +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); + +// // Set the bond escalation status of the given requestId to something different than Active +// bondEscalationModule.forTest_setBondEscalationStatus( +// _requestId, IBondEscalationModule.BondEscalationStatus(_status) +// ); + +// // Set the dispute to be the one that went through the bond escalation process for the given requestId +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// // Check: does it revert if the dispute is not escalatable? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_NotEscalatable.selector); +// vm.prank(address(oracle)); +// bondEscalationModule.disputeEscalated(_disputeId); +// } + +// /** +// * @notice Tests that escalateDispute reverts if a dispute that went through the bond escalation mechanism and is still active +// * but its pledges are not tied even after the tying buffer is escalated. +// * Conditions to reach this check: +// * - The _requestId tied to the dispute tied to _disputeId must be valid (non-zero) +// * - The block.timestamp has to be > bond escalation deadline + tying buffer +// * - The dispute has to have gone or be going through the bond escalation process +// * - The pledges must not be tied +// */ +// function test_revertIfEscalatingDisputeIsNotTied(bytes32 _disputeId, bytes32 _requestId) public { +// // Assume _requestId is not zero +// vm.assume(_requestId > 0); + +// _mockDispute.requestId = _requestId; + +// // Mock and expect Oracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Set a tying buffer to make the test more explicit +// uint256 _tyingBuffer = 1000; + +// // Set bond escalation deadline to be the current timestamp. We will warp this. +// uint256 _bondEscalationDeadline = block.timestamp; + +// // Set the number of pledgers to be different +// uint256 _numForPledgers = 1; +// uint256 _numAgainstPledgers = 2; + +// // Warp the current timestamp so we are past the tyingBuffer +// vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); + +// // Populate the requestData for the given requestId +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); + +// // Set the bond escalation status of the given requestId to Active +// bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.Active); + +// // Set the dispute to be the one that went through the bond escalation process for the given requestId +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// // Set the number of pledgers for both sides +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); + +// // Check: does it revert if the dispute is not escalatable? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_NotEscalatable.selector); +// vm.prank(address(oracle)); +// bondEscalationModule.disputeEscalated(_disputeId); +// } + +// /** +// * @notice Tests that escalateDispute escalates the dispute going through the bond escalation mechanism correctly when the +// * pledges are tied and the dispute is still active. +// * Conditions for the function to succeed: +// * - The _requestId tied to the dispute tied to _disputeId must be valid (non-zero) +// * - The block.timestamp has to be > bond escalation deadline +// * - The dispute has to have gone or be going through the bond escalation process +// * - The pledges must be tied +// */ +// function test_escalateTiedDispute(bytes32 _disputeId, bytes32 _requestId) public { +// // Assume _requestId is not zero +// vm.assume(_requestId > 0); +// vm.assume(_disputeId > 0); + +// _mockDispute.requestId = _requestId; + +// // Mock and expect Oracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - // Set a tying buffer - uint256 _tyingBuffer = 1000; +// // Set a tying buffer +// uint256 _tyingBuffer = 1000; - // Set bond escalation deadline to be the current timestamp. We will warp this. - uint256 _bondEscalationDeadline = block.timestamp; +// // Set bond escalation deadline to be the current timestamp. We will warp this. +// uint256 _bondEscalationDeadline = block.timestamp; - // Set the number of pledgers to be the same. This means the pledges are tied. - uint256 _numForPledgers = 2; - uint256 _numAgainstPledgers = 2; - - // Warp so we are still in the tying buffer period. This is to show a dispute can be escalated during the buffer if the pledges are tied. - vm.warp(_bondEscalationDeadline + _tyingBuffer); - - // Populate the requestData for the given requestId - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); - - // Set the bond escalation status of the given requestId to Active - bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.Active); - - // Set the dispute to be the one that went through the bond escalation process for the given requestId - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - // Set the number of pledgers for both sides - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationModule)); - emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.Escalated); - - vm.prank(address(oracle)); - bondEscalationModule.disputeEscalated(_disputeId); - - IBondEscalationModule.BondEscalation memory _escalation = bondEscalationModule.getEscalation(_requestId); - // Check: is the bond escalation status properly updated? - assertEq(uint256(_escalation.status), uint256(IBondEscalationModule.BondEscalationStatus.Escalated)); - } - - /** - * @notice Tests that escalateDispute escalates a dispute not going through the bond escalation mechanism correctly after - * the bond mechanism deadline has gone by. - * Conditions for the function to succeed: - * - The _requestId tied to the dispute tied to _disputeId must be valid (non-zero) - * - The block.timestamp has to be > bond escalation deadline - */ - function test_escalateNormalDispute(bytes32 _disputeId, bytes32 _requestId) public { - // Assume _requestId and _disputeId are not zero - vm.assume(_requestId > 0); - vm.assume(_disputeId > 0); +// // Set the number of pledgers to be the same. This means the pledges are tied. +// uint256 _numForPledgers = 2; +// uint256 _numAgainstPledgers = 2; + +// // Warp so we are still in the tying buffer period. This is to show a dispute can be escalated during the buffer if the pledges are tied. +// vm.warp(_bondEscalationDeadline + _tyingBuffer); + +// // Populate the requestData for the given requestId +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); + +// // Set the bond escalation status of the given requestId to Active +// bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.Active); + +// // Set the dispute to be the one that went through the bond escalation process for the given requestId +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// // Set the number of pledgers for both sides +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationModule)); +// emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.Escalated); + +// vm.prank(address(oracle)); +// bondEscalationModule.disputeEscalated(_disputeId); + +// IBondEscalationModule.BondEscalation memory _escalation = bondEscalationModule.getEscalation(_requestId); +// // Check: is the bond escalation status properly updated? +// assertEq(uint256(_escalation.status), uint256(IBondEscalationModule.BondEscalationStatus.Escalated)); +// } + +// /** +// * @notice Tests that escalateDispute escalates a dispute not going through the bond escalation mechanism correctly after +// * the bond mechanism deadline has gone by. +// * Conditions for the function to succeed: +// * - The _requestId tied to the dispute tied to _disputeId must be valid (non-zero) +// * - The block.timestamp has to be > bond escalation deadline +// */ +// function test_escalateNormalDispute(bytes32 _disputeId, bytes32 _requestId) public { +// // Assume _requestId and _disputeId are not zero +// vm.assume(_requestId > 0); +// vm.assume(_disputeId > 0); - uint256 _tyingBuffer = 1000; +// uint256 _tyingBuffer = 1000; - _mockDispute.requestId = _requestId; +// _mockDispute.requestId = _requestId; - // Mock and expect Oracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect Oracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - // Set bond escalation deadline to be the current timestamp. We will warp this. - uint256 _bondEscalationDeadline = block.timestamp; +// // Set bond escalation deadline to be the current timestamp. We will warp this. +// uint256 _bondEscalationDeadline = block.timestamp; - // Warp so we are past the tying buffer period - vm.warp(_bondEscalationDeadline + 1); - - // Populate the requestData for the given requestId - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); - - vm.prank(address(oracle)); - bondEscalationModule.disputeEscalated(_disputeId); - } -} - -contract BondEscalationModule_Unit_DisputeResponse is BaseTest { - /** - * @notice Tests that disputeResponse reverts the caller is not the oracle address. - */ - function test_revertIfCallerIsNotOracle(bytes32 _requestId, bytes32 _responseId, address _caller) public { - vm.assume(_caller != address(oracle)); - - // Check: does it revert if not called by the Oracle? - vm.expectRevert(IModule.Module_OnlyOracle.selector); - vm.prank(_caller); - bondEscalationModule.disputeResponse(_requestId, _responseId, disputer, proposer); - } - - /** - * @notice Tests that disputeResponse reverts if the challenge period for the response is over. - */ - function test_revertIfDisputeWindowIsOver(bytes32 _requestId, bytes32 _responseId) public { - uint256 _disputeWindow = 1; +// // Warp so we are past the tying buffer period +// vm.warp(_bondEscalationDeadline + 1); + +// // Populate the requestData for the given requestId +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); + +// vm.prank(address(oracle)); +// bondEscalationModule.disputeEscalated(_disputeId); +// } +// } + +// contract BondEscalationModule_Unit_DisputeResponse is BaseTest { +// /** +// * @notice Tests that disputeResponse reverts the caller is not the oracle address. +// */ +// function test_revertIfCallerIsNotOracle(bytes32 _requestId, bytes32 _responseId, address _caller) public { +// vm.assume(_caller != address(oracle)); + +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(IModule.Module_OnlyOracle.selector); +// vm.prank(_caller); +// bondEscalationModule.disputeResponse(_requestId, _responseId, disputer, proposer); +// } + +// /** +// * @notice Tests that disputeResponse reverts if the challenge period for the response is over. +// */ +// function test_revertIfDisputeWindowIsOver(bytes32 _requestId, bytes32 _responseId) public { +// uint256 _disputeWindow = 1; - _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, _disputeWindow); +// _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, _disputeWindow); - _mockResponse.requestId = _requestId; +// _mockResponse.requestId = _requestId; - // Mock and expect Oracle.getResponse to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); +// // Mock and expect Oracle.getResponse to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - // Warp to a time after the disputeWindow is over. - vm.warp(block.timestamp + _disputeWindow + 1); +// // Warp to a time after the disputeWindow is over. +// vm.warp(block.timestamp + _disputeWindow + 1); - // Check: does it revert if the dispute window is over? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_DisputeWindowOver.selector); - vm.prank(address(oracle)); - bondEscalationModule.disputeResponse(_requestId, _responseId, disputer, proposer); - } - - /** - * @notice Tests that disputeResponse succeeds if someone dispute after the bond escalation deadline is over - */ - function test_succeedIfDisputeAfterBondingEscalationDeadline(bytes32 _requestId, bytes32 _responseId) public { - // Set deadline to timestamp so we are still in the bond escalation period - uint256 _bondEscalationDeadline = block.timestamp - 1; - - // Set the request data for the given requestId - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); - - _mockResponse.requestId = _requestId; - - // Mock and expect Oracle.getResponse to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Check: does it revert if the bond escalation is over? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); - vm.prank(address(oracle)); - bondEscalationModule.disputeResponse(_requestId, _responseId, disputer, proposer); - } - - /** - * @notice Tests that disputeResponse succeeds in starting the bond escalation mechanism when someone disputes - * the first propose before the bond escalation deadline is over. - */ - function test_firstDisputeThroughBondMechanism(bytes32 _requestId, bytes32 _responseId) public { - // Set deadline to timestamp so we are still in the bond escalation period - uint256 _bondEscalationDeadline = block.timestamp; - - // Set the request data for the given requestId - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); - - _mockResponse.requestId = _requestId; - - // Mock and expect Oracle.getResponse to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the accounting extension to be called - _mockAndExpect( - address(accounting), - abi.encodeWithSignature('bond(address,bytes32,address,uint256)', disputer, _requestId, token, bondSize), - abi.encode(true) - ); - - bytes32 _expectedDisputeId = keccak256(abi.encodePacked(disputer, _requestId, _responseId)); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationModule)); - emit BondEscalationStatusUpdated(_requestId, _expectedDisputeId, IBondEscalationModule.BondEscalationStatus.Active); - - vm.prank(address(oracle)); - bondEscalationModule.disputeResponse(_requestId, _responseId, disputer, proposer); - - // Check: is the bond escalation status now active? - assertEq( - uint256(bondEscalationModule.getEscalation(_requestId).status), - uint256(IBondEscalationModule.BondEscalationStatus.Active) - ); - - // Check: is the dispute assigned to the bond escalation process? - assertEq(bondEscalationModule.getEscalation(_requestId).disputeId, _expectedDisputeId); - } - - function test_emitsEvent(bytes32 _requestId, bytes32 _responseId) public { - // Set deadline to timestamp so we are still in the bond escalation period - uint256 _bondEscalationDeadline = block.timestamp; - - // Set the request data for the given requestId - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); - - _mockResponse.requestId = _requestId; - - // Mock and expect Oracle.getResponse to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the accounting extension to be called - _mockAndExpect( - address(accounting), - abi.encodeWithSignature('bond(address,bytes32,address,uint256)', disputer, _requestId, token, bondSize), - abi.encode(true) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationModule)); - emit ResponseDisputed(_requestId, _responseId, disputer, proposer); - - vm.prank(address(oracle)); - bondEscalationModule.disputeResponse(_requestId, _responseId, disputer, proposer); - } -} - -contract BondEscalationModule_Unit_OnDisputeStatusChange is BaseTest { - /** - * @notice Tests that onDisputeStatusChange reverts - */ - function test_revertIfCallerIsNotOracle( - bytes32 _disputeId, - bytes32 _requestId, - address _caller, - uint8 _status - ) public { - vm.assume(_caller != address(oracle)); - vm.assume(_status < 4); - - IOracle.DisputeStatus _disputeStatus = IOracle.DisputeStatus(_status); - IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _disputeStatus); - - // Check: does it revert if not called by the Oracle? - vm.expectRevert(IModule.Module_OnlyOracle.selector); - vm.prank(_caller); - bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); - } - - /** - * @notice Tests that onDisputeStatusChange pays the proposer if the disputer lost - */ - function test_callPayIfNormalDisputeLost(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0 && _requestId > 0); - - IOracle.DisputeStatus _status = IOracle.DisputeStatus.Lost; - IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); - - _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); - - // Mock and expect IAccountingExtension.pay to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.disputer, _dispute.proposer, token, bondSize)), - abi.encode(true) - ); - - vm.prank(address(oracle)); - bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); - } - - /** - * @notice Tests that onDisputeStatusChange pays the disputer if the disputer won - */ - function test_callPayIfNormalDisputeWon(bytes32 _disputeId, bytes32 _requestId) public { - IOracle.DisputeStatus _status = IOracle.DisputeStatus.Won; - IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); - - _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); - - // Mock and expect IAccountingExtension.pay to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.proposer, _dispute.disputer, token, bondSize)), - abi.encode(true) - ); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_dispute.disputer, _requestId, token, bondSize)), - abi.encode(true) - ); - - vm.prank(address(oracle)); - bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); - } - - function test_emitsEvent(bytes32 _disputeId, bytes32 _requestId) public { - IOracle.DisputeStatus _status = IOracle.DisputeStatus.Won; - IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); - - _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); - - // Mock and expect IAccountingExtension.pay to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.proposer, _dispute.disputer, token, bondSize)), - abi.encode(true) - ); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_dispute.disputer, _requestId, token, bondSize)), - abi.encode(true) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationModule)); - emit DisputeStatusChanged( - _requestId, _dispute.responseId, _dispute.disputer, _dispute.proposer, IOracle.DisputeStatus.Won - ); - - vm.prank(address(oracle)); - bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); - } - - /** - * @notice Tests that onDisputeStatusChange returns early if the dispute has gone through the bond - * escalation mechanism but no one pledged - */ - function test_earlyReturnIfBondEscalatedDisputeHashNoPledgers(bytes32 _disputeId, bytes32 _requestId) public { - IOracle.DisputeStatus _status = IOracle.DisputeStatus.Won; - IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); - - _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); - - uint256 _numForPledgers = 0; - uint256 _numAgainstPledgers = 0; - - // Set bond escalation data to have no pledgers - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - - // Set this dispute to have gone through the bond escalation process - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - // Set the bond escalation status to Escalated, which is the only possible one for this function - bondEscalationModule.forTest_setBondEscalationStatus( - _requestId, IBondEscalationModule.BondEscalationStatus.Escalated - ); - - // Mock and expect IAccountingExtension.pay to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.proposer, _dispute.disputer, token, bondSize)), - abi.encode(true) - ); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_dispute.disputer, _requestId, token, bondSize)), - abi.encode(true) - ); - - vm.prank(address(oracle)); - bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); - - // Check: is the bond escalation status properly updated? - assertEq( - uint256(bondEscalationModule.getEscalation(_requestId).status), - uint256(IBondEscalationModule.BondEscalationStatus.Escalated) - ); - } - - /** - * @notice Tests that onDisputeStatusChange changes the status of the bond escalation if the - * dispute went through the bond escalation process, as well as testing that it calls - * payPledgersWon with the correct arguments. In the Won case, this would be, passing - * the users that pledged in favor of the dispute, as they have won. - */ - function test_shouldChangeBondEscalationStatusAndCallPayPledgersWon(bytes32 _disputeId, bytes32 _requestId) public { - IOracle.DisputeStatus _status = IOracle.DisputeStatus.Won; - IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); - - _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); - - uint256 _numForPledgers = 2; - uint256 _numAgainstPledgers = 2; - - // Set bond escalation data to have pledgers and to return the winning for pledgers as in this case they won the escalation - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - - // Set this dispute to have gone through the bond escalation process - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - // Set the bond escalation status to Escalated, which is the only possible one for this function - bondEscalationModule.forTest_setBondEscalationStatus( - _requestId, IBondEscalationModule.BondEscalationStatus.Escalated - ); - - // Mock and expect IAccountingExtension.pay to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.proposer, _dispute.disputer, token, bondSize)), - abi.encode(true) - ); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_dispute.disputer, _requestId, token, bondSize)), - abi.encode(true) - ); - - // Mock and expect IBondEscalationAccounting.onSettleBondEscalation to be called - _mockAndExpect( - address(accounting), - abi.encodeCall( - IBondEscalationAccounting.onSettleBondEscalation, - (_requestId, _disputeId, true, token, bondSize << 1, _numForPledgers) - ), - abi.encode() - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationModule)); - emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.DisputerWon); - - vm.prank(address(oracle)); - bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); - - // Check: is the bond escalation status properly updated? - assertEq( - uint256(bondEscalationModule.getEscalation(_requestId).status), - uint256(IBondEscalationModule.BondEscalationStatus.DisputerWon) - ); - } - - /** - * @notice Tests that onDisputeStatusChange changes the status of the bond escalation if the - * dispute went through the bond escalation process, as well as testing that it calls - * payPledgersWon with the correct arguments. In the Lost case, this would be, passing - * the users that pledged against the dispute, as those that pledged in favor have lost . - */ - function test_shouldChangeBondEscalationStatusAndCallPayPledgersLost(bytes32 _disputeId, bytes32 _requestId) public { - // Set to Lost so the proposer and againstDisputePledgers win - IOracle.DisputeStatus _status = IOracle.DisputeStatus.Lost; - IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); - - uint256 _bondSize = 1000; - - _setRequestData(_requestId, _bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); - - uint256 _numForPledgers = 2; - uint256 _numAgainstPledgers = 2; - - // Set bond escalation data to have pledgers and to return the winning for pledgers as in this case they won the escalation - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - - // Set this dispute to have gone through the bond escalation process - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - // Set the bond escalation status to Escalated, which is the only possible one for this function - bondEscalationModule.forTest_setBondEscalationStatus( - _requestId, IBondEscalationModule.BondEscalationStatus.Escalated - ); - - // Mock and expect IAccountingExtension.pay to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.disputer, _dispute.proposer, token, _bondSize)), - abi.encode(true) - ); - - // Mock and expect IBondEscalationAccounting.onSettleBondEscalation to be called - vm.mockCall( - address(accounting), - abi.encodeCall( - IBondEscalationAccounting.onSettleBondEscalation, - (_requestId, _disputeId, false, token, _bondSize << 1, _numAgainstPledgers) - ), - abi.encode(true) - ); - - // Check: is th event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationModule)); - emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.DisputerLost); - - vm.prank(address(oracle)); - bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); - - // Check: is the bond escalation status properly updated? - assertEq( - uint256(bondEscalationModule.getEscalation(_requestId).status), - uint256(IBondEscalationModule.BondEscalationStatus.DisputerLost) - ); - } -} - -contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { - /** - * @notice Tests that pledgeForDispute reverts if the dispute does not exist. - */ - function test_revertIfDisputeIsZero() public { - bytes32 _disputeId = 0; - - // Check: does it revert if the dispute does not exist? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_DisputeDoesNotExist.selector); - bondEscalationModule.pledgeForDispute(_disputeId); - } - - /** - * @notice Tests that pledgeForDispute reverts if the dispute is not going through the bond escalation mechanism. - */ - function test_revertIfTheDisputeIsNotGoingThroughTheBondEscalationProcess( - bytes32 _disputeId, - bytes32 _requestId - ) public { - vm.assume(_disputeId > 0); - - _mockDispute.requestId = _requestId; - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Check: does it revert if the dispute is not escalated yet? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); - bondEscalationModule.pledgeForDispute(_disputeId); - } - - /** - * @notice Tests that pledgeForDispute reverts if someone tries to pledge after the tying buffer. - */ - function test_revertIfTimestampBeyondTyingBuffer(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0); - - _mockDispute.requestId = _requestId; - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - uint256 _bondSize = 1; - uint256 _maxNumberOfEscalations = 1; - uint256 _bondEscalationDeadline = block.timestamp; - uint256 _tyingBuffer = 1000; +// // Check: does it revert if the dispute window is over? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_DisputeWindowOver.selector); +// vm.prank(address(oracle)); +// bondEscalationModule.disputeResponse(_requestId, _responseId, disputer, proposer); +// } + +// /** +// * @notice Tests that disputeResponse succeeds if someone dispute after the bond escalation deadline is over +// */ +// function test_succeedIfDisputeAfterBondingEscalationDeadline(bytes32 _requestId, bytes32 _responseId) public { +// // Set deadline to timestamp so we are still in the bond escalation period +// uint256 _bondEscalationDeadline = block.timestamp - 1; + +// // Set the request data for the given requestId +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); + +// _mockResponse.requestId = _requestId; + +// // Mock and expect Oracle.getResponse to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Check: does it revert if the bond escalation is over? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); +// vm.prank(address(oracle)); +// bondEscalationModule.disputeResponse(_requestId, _responseId, disputer, proposer); +// } + +// /** +// * @notice Tests that disputeResponse succeeds in starting the bond escalation mechanism when someone disputes +// * the first propose before the bond escalation deadline is over. +// */ +// function test_firstDisputeThroughBondMechanism(bytes32 _requestId, bytes32 _responseId) public { +// // Set deadline to timestamp so we are still in the bond escalation period +// uint256 _bondEscalationDeadline = block.timestamp; + +// // Set the request data for the given requestId +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); + +// _mockResponse.requestId = _requestId; + +// // Mock and expect Oracle.getResponse to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the accounting extension to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeWithSignature('bond(address,bytes32,address,uint256)', disputer, _requestId, token, bondSize), +// abi.encode(true) +// ); + +// bytes32 _expectedDisputeId = keccak256(abi.encodePacked(disputer, _requestId, _responseId)); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationModule)); +// emit BondEscalationStatusUpdated(_requestId, _expectedDisputeId, IBondEscalationModule.BondEscalationStatus.Active); + +// vm.prank(address(oracle)); +// bondEscalationModule.disputeResponse(_requestId, _responseId, disputer, proposer); + +// // Check: is the bond escalation status now active? +// assertEq( +// uint256(bondEscalationModule.getEscalation(_requestId).status), +// uint256(IBondEscalationModule.BondEscalationStatus.Active) +// ); + +// // Check: is the dispute assigned to the bond escalation process? +// assertEq(bondEscalationModule.getEscalation(_requestId).disputeId, _expectedDisputeId); +// } + +// function test_emitsEvent(bytes32 _requestId, bytes32 _responseId) public { +// // Set deadline to timestamp so we are still in the bond escalation period +// uint256 _bondEscalationDeadline = block.timestamp; + +// // Set the request data for the given requestId +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); + +// _mockResponse.requestId = _requestId; + +// // Mock and expect Oracle.getResponse to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the accounting extension to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeWithSignature('bond(address,bytes32,address,uint256)', disputer, _requestId, token, bondSize), +// abi.encode(true) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationModule)); +// emit ResponseDisputed(_requestId, _responseId, disputer, proposer); + +// vm.prank(address(oracle)); +// bondEscalationModule.disputeResponse(_requestId, _responseId, disputer, proposer); +// } +// } + +// contract BondEscalationModule_Unit_OnDisputeStatusChange is BaseTest { +// /** +// * @notice Tests that onDisputeStatusChange reverts +// */ +// function test_revertIfCallerIsNotOracle( +// bytes32 _disputeId, +// bytes32 _requestId, +// address _caller, +// uint8 _status +// ) public { +// vm.assume(_caller != address(oracle)); +// vm.assume(_status < 4); + +// IOracle.DisputeStatus _disputeStatus = IOracle.DisputeStatus(_status); +// IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _disputeStatus); + +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(IModule.Module_OnlyOracle.selector); +// vm.prank(_caller); +// bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); +// } + +// /** +// * @notice Tests that onDisputeStatusChange pays the proposer if the disputer lost +// */ +// function test_callPayIfNormalDisputeLost(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0 && _requestId > 0); + +// IOracle.DisputeStatus _status = IOracle.DisputeStatus.Lost; +// IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); + +// _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); + +// // Mock and expect IAccountingExtension.pay to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.disputer, _dispute.proposer, token, bondSize)), +// abi.encode(true) +// ); + +// vm.prank(address(oracle)); +// bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); +// } + +// /** +// * @notice Tests that onDisputeStatusChange pays the disputer if the disputer won +// */ +// function test_callPayIfNormalDisputeWon(bytes32 _disputeId, bytes32 _requestId) public { +// IOracle.DisputeStatus _status = IOracle.DisputeStatus.Won; +// IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); + +// _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); + +// // Mock and expect IAccountingExtension.pay to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.proposer, _dispute.disputer, token, bondSize)), +// abi.encode(true) +// ); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_dispute.disputer, _requestId, token, bondSize)), +// abi.encode(true) +// ); + +// vm.prank(address(oracle)); +// bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); +// } + +// function test_emitsEvent(bytes32 _disputeId, bytes32 _requestId) public { +// IOracle.DisputeStatus _status = IOracle.DisputeStatus.Won; +// IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); + +// _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); + +// // Mock and expect IAccountingExtension.pay to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.proposer, _dispute.disputer, token, bondSize)), +// abi.encode(true) +// ); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_dispute.disputer, _requestId, token, bondSize)), +// abi.encode(true) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationModule)); +// emit DisputeStatusChanged( +// _requestId, _dispute.responseId, _dispute.disputer, _dispute.proposer, IOracle.DisputeStatus.Won +// ); + +// vm.prank(address(oracle)); +// bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); +// } + +// /** +// * @notice Tests that onDisputeStatusChange returns early if the dispute has gone through the bond +// * escalation mechanism but no one pledged +// */ +// function test_earlyReturnIfBondEscalatedDisputeHashNoPledgers(bytes32 _disputeId, bytes32 _requestId) public { +// IOracle.DisputeStatus _status = IOracle.DisputeStatus.Won; +// IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); + +// _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); + +// uint256 _numForPledgers = 0; +// uint256 _numAgainstPledgers = 0; + +// // Set bond escalation data to have no pledgers +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); + +// // Set this dispute to have gone through the bond escalation process +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// // Set the bond escalation status to Escalated, which is the only possible one for this function +// bondEscalationModule.forTest_setBondEscalationStatus( +// _requestId, IBondEscalationModule.BondEscalationStatus.Escalated +// ); + +// // Mock and expect IAccountingExtension.pay to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.proposer, _dispute.disputer, token, bondSize)), +// abi.encode(true) +// ); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_dispute.disputer, _requestId, token, bondSize)), +// abi.encode(true) +// ); + +// vm.prank(address(oracle)); +// bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); + +// // Check: is the bond escalation status properly updated? +// assertEq( +// uint256(bondEscalationModule.getEscalation(_requestId).status), +// uint256(IBondEscalationModule.BondEscalationStatus.Escalated) +// ); +// } + +// /** +// * @notice Tests that onDisputeStatusChange changes the status of the bond escalation if the +// * dispute went through the bond escalation process, as well as testing that it calls +// * payPledgersWon with the correct arguments. In the Won case, this would be, passing +// * the users that pledged in favor of the dispute, as they have won. +// */ +// function test_shouldChangeBondEscalationStatusAndCallPayPledgersWon(bytes32 _disputeId, bytes32 _requestId) public { +// IOracle.DisputeStatus _status = IOracle.DisputeStatus.Won; +// IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); + +// _setRequestData(_requestId, bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); + +// uint256 _numForPledgers = 2; +// uint256 _numAgainstPledgers = 2; + +// // Set bond escalation data to have pledgers and to return the winning for pledgers as in this case they won the escalation +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); + +// // Set this dispute to have gone through the bond escalation process +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// // Set the bond escalation status to Escalated, which is the only possible one for this function +// bondEscalationModule.forTest_setBondEscalationStatus( +// _requestId, IBondEscalationModule.BondEscalationStatus.Escalated +// ); + +// // Mock and expect IAccountingExtension.pay to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.proposer, _dispute.disputer, token, bondSize)), +// abi.encode(true) +// ); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_dispute.disputer, _requestId, token, bondSize)), +// abi.encode(true) +// ); + +// // Mock and expect IBondEscalationAccounting.onSettleBondEscalation to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall( +// IBondEscalationAccounting.onSettleBondEscalation, +// (_requestId, _disputeId, true, token, bondSize << 1, _numForPledgers) +// ), +// abi.encode() +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationModule)); +// emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.DisputerWon); + +// vm.prank(address(oracle)); +// bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); + +// // Check: is the bond escalation status properly updated? +// assertEq( +// uint256(bondEscalationModule.getEscalation(_requestId).status), +// uint256(IBondEscalationModule.BondEscalationStatus.DisputerWon) +// ); +// } + +// /** +// * @notice Tests that onDisputeStatusChange changes the status of the bond escalation if the +// * dispute went through the bond escalation process, as well as testing that it calls +// * payPledgersWon with the correct arguments. In the Lost case, this would be, passing +// * the users that pledged against the dispute, as those that pledged in favor have lost . +// */ +// function test_shouldChangeBondEscalationStatusAndCallPayPledgersLost(bytes32 _disputeId, bytes32 _requestId) public { +// // Set to Lost so the proposer and againstDisputePledgers win +// IOracle.DisputeStatus _status = IOracle.DisputeStatus.Lost; +// IOracle.Dispute memory _dispute = _getRandomDispute(_requestId, _status); + +// uint256 _bondSize = 1000; + +// _setRequestData(_requestId, _bondSize, maxEscalations, bondEscalationDeadline, tyingBuffer, disputeWindow); + +// uint256 _numForPledgers = 2; +// uint256 _numAgainstPledgers = 2; + +// // Set bond escalation data to have pledgers and to return the winning for pledgers as in this case they won the escalation +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); + +// // Set this dispute to have gone through the bond escalation process +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// // Set the bond escalation status to Escalated, which is the only possible one for this function +// bondEscalationModule.forTest_setBondEscalationStatus( +// _requestId, IBondEscalationModule.BondEscalationStatus.Escalated +// ); + +// // Mock and expect IAccountingExtension.pay to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _dispute.disputer, _dispute.proposer, token, _bondSize)), +// abi.encode(true) +// ); + +// // Mock and expect IBondEscalationAccounting.onSettleBondEscalation to be called +// vm.mockCall( +// address(accounting), +// abi.encodeCall( +// IBondEscalationAccounting.onSettleBondEscalation, +// (_requestId, _disputeId, false, token, _bondSize << 1, _numAgainstPledgers) +// ), +// abi.encode(true) +// ); + +// // Check: is th event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationModule)); +// emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.DisputerLost); + +// vm.prank(address(oracle)); +// bondEscalationModule.onDisputeStatusChange(_disputeId, _dispute); + +// // Check: is the bond escalation status properly updated? +// assertEq( +// uint256(bondEscalationModule.getEscalation(_requestId).status), +// uint256(IBondEscalationModule.BondEscalationStatus.DisputerLost) +// ); +// } +// } + +// contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { +// /** +// * @notice Tests that pledgeForDispute reverts if the dispute does not exist. +// */ +// function test_revertIfDisputeIsZero() public { +// bytes32 _disputeId = 0; + +// // Check: does it revert if the dispute does not exist? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_DisputeDoesNotExist.selector); +// bondEscalationModule.pledgeForDispute(_disputeId); +// } + +// /** +// * @notice Tests that pledgeForDispute reverts if the dispute is not going through the bond escalation mechanism. +// */ +// function test_revertIfTheDisputeIsNotGoingThroughTheBondEscalationProcess( +// bytes32 _disputeId, +// bytes32 _requestId +// ) public { +// vm.assume(_disputeId > 0); + +// _mockDispute.requestId = _requestId; + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Check: does it revert if the dispute is not escalated yet? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); +// bondEscalationModule.pledgeForDispute(_disputeId); +// } + +// /** +// * @notice Tests that pledgeForDispute reverts if someone tries to pledge after the tying buffer. +// */ +// function test_revertIfTimestampBeyondTyingBuffer(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0); + +// _mockDispute.requestId = _requestId; + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// uint256 _bondSize = 1; +// uint256 _maxNumberOfEscalations = 1; +// uint256 _bondEscalationDeadline = block.timestamp; +// uint256 _tyingBuffer = 1000; - vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); +// vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); - _setRequestData( - _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow - ); +// _setRequestData( +// _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow +// ); - // Check: does it revert if the bond escalation is over? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); - bondEscalationModule.pledgeForDispute(_disputeId); - } - - /** - * @notice Tests that pledgeForDispute reverts if the maximum number of escalations has been reached. - */ - function test_revertIfMaxNumberOfEscalationsReached(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0); - - _mockDispute.requestId = _requestId; +// // Check: does it revert if the bond escalation is over? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); +// bondEscalationModule.pledgeForDispute(_disputeId); +// } + +// /** +// * @notice Tests that pledgeForDispute reverts if the maximum number of escalations has been reached. +// */ +// function test_revertIfMaxNumberOfEscalationsReached(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0); + +// _mockDispute.requestId = _requestId; - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - uint256 _bondSize = 1; - uint256 _maxNumberOfEscalations = 2; - uint256 _bondEscalationDeadline = block.timestamp - 1; - uint256 _tyingBuffer = 1000; +// uint256 _bondSize = 1; +// uint256 _maxNumberOfEscalations = 2; +// uint256 _bondEscalationDeadline = block.timestamp - 1; +// uint256 _tyingBuffer = 1000; - _setRequestData( - _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow - ); +// _setRequestData( +// _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow +// ); - uint256 _numForPledgers = 2; - uint256 _numAgainstPledgers = _numForPledgers; +// uint256 _numForPledgers = 2; +// uint256 _numAgainstPledgers = _numForPledgers; - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - // Check: does it revert if the maximum number of escalations is reached? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); - bondEscalationModule.pledgeForDispute(_disputeId); - } +// // Check: does it revert if the maximum number of escalations is reached? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); +// bondEscalationModule.pledgeForDispute(_disputeId); +// } - /** - * @notice Tests that pledgeForDispute reverts if someone tries to pledge in favor of the dispute when there are - * more pledges in favor of the dispute than against - */ - function test_revertIfThereIsMorePledgedForForDisputeThanAgainst(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0); +// /** +// * @notice Tests that pledgeForDispute reverts if someone tries to pledge in favor of the dispute when there are +// * more pledges in favor of the dispute than against +// */ +// function test_revertIfThereIsMorePledgedForForDisputeThanAgainst(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0); - _mockDispute.requestId = _requestId; +// _mockDispute.requestId = _requestId; - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - uint256 _bondSize = 1; - uint256 _maxNumberOfEscalations = 3; - uint256 _bondEscalationDeadline = block.timestamp + 1; +// uint256 _bondSize = 1; +// uint256 _maxNumberOfEscalations = 3; +// uint256 _bondEscalationDeadline = block.timestamp + 1; - _setRequestData(_requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); +// _setRequestData(_requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); - uint256 _numForPledgers = 2; - uint256 _numAgainstPledgers = _numForPledgers - 1; +// uint256 _numForPledgers = 2; +// uint256 _numAgainstPledgers = _numForPledgers - 1; - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - // Check: does it revert if trying to pledge in a dispute that is already surpassed? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); - bondEscalationModule.pledgeForDispute(_disputeId); - } +// // Check: does it revert if trying to pledge in a dispute that is already surpassed? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); +// bondEscalationModule.pledgeForDispute(_disputeId); +// } - /** - * @notice Tests that pledgeForDispute reverts if the timestamp is within the tying buffer and someone attempts - * to pledge when the funds are tied, effectively breaking the tie - */ - function test_revertIfAttemptToBreakTieDuringTyingBuffer(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0); +// /** +// * @notice Tests that pledgeForDispute reverts if the timestamp is within the tying buffer and someone attempts +// * to pledge when the funds are tied, effectively breaking the tie +// */ +// function test_revertIfAttemptToBreakTieDuringTyingBuffer(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0); - _mockDispute.requestId = _requestId; +// _mockDispute.requestId = _requestId; - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - uint256 _bondSize = 1; - uint256 _maxNumberOfEscalations = 3; - uint256 _bondEscalationDeadline = block.timestamp - 1; - uint256 _tyingBuffer = 1000; +// uint256 _bondSize = 1; +// uint256 _maxNumberOfEscalations = 3; +// uint256 _bondEscalationDeadline = block.timestamp - 1; +// uint256 _tyingBuffer = 1000; - _setRequestData( - _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow - ); +// _setRequestData( +// _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow +// ); - uint256 _numForPledgers = 2; - uint256 _numAgainstPledgers = _numForPledgers; +// uint256 _numForPledgers = 2; +// uint256 _numAgainstPledgers = _numForPledgers; - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - // Check: does it revert if trying to tie outside of the tying buffer? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_CannotBreakTieDuringTyingBuffer.selector); - bondEscalationModule.pledgeForDispute(_disputeId); - } +// // Check: does it revert if trying to tie outside of the tying buffer? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_CannotBreakTieDuringTyingBuffer.selector); +// bondEscalationModule.pledgeForDispute(_disputeId); +// } - /** - * @notice Tests that pledgeForDispute is called successfully - */ - function test_successfulCall(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0); +// /** +// * @notice Tests that pledgeForDispute is called successfully +// */ +// function test_successfulCall(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0); - _mockDispute.requestId = _requestId; +// _mockDispute.requestId = _requestId; - // Mock and expect - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); +// // Mock and expect +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - uint256 _bondSize = 1000; - uint256 _maxNumberOfEscalations = 3; - uint256 _bondEscalationDeadline = block.timestamp - 1; - uint256 _tyingBuffer = 1000; +// uint256 _bondSize = 1000; +// uint256 _maxNumberOfEscalations = 3; +// uint256 _bondEscalationDeadline = block.timestamp - 1; +// uint256 _tyingBuffer = 1000; - _setRequestData( - _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow - ); +// _setRequestData( +// _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow +// ); - uint256 _numForPledgers = 2; - uint256 _numAgainstPledgers = _numForPledgers + 1; +// uint256 _numForPledgers = 2; +// uint256 _numAgainstPledgers = _numForPledgers + 1; - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - // Mock and expect IBondEscalationAccounting.pledge to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (address(this), _requestId, _disputeId, token, _bondSize)), - abi.encode(true) - ); +// // Mock and expect IBondEscalationAccounting.pledge to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IBondEscalationAccounting.pledge, (address(this), _requestId, _disputeId, token, _bondSize)), +// abi.encode(true) +// ); - // Check: is event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationModule)); - emit PledgedForDispute(_disputeId, address(this), _bondSize); +// // Check: is event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationModule)); +// emit PledgedForDispute(_disputeId, address(this), _bondSize); - bondEscalationModule.pledgeForDispute(_disputeId); +// bondEscalationModule.pledgeForDispute(_disputeId); - uint256 _pledgesForDispute = bondEscalationModule.getEscalation(_requestId).amountOfPledgesForDispute; - // Check: is the number of pledges for the dispute properly updated? - assertEq(_pledgesForDispute, _numForPledgers + 1); +// uint256 _pledgesForDispute = bondEscalationModule.getEscalation(_requestId).amountOfPledgesForDispute; +// // Check: is the number of pledges for the dispute properly updated? +// assertEq(_pledgesForDispute, _numForPledgers + 1); - uint256 _userPledges = bondEscalationModule.pledgesForDispute(_requestId, address(this)); - // Check: is the number of pledges for the user properly updated? - assertEq(_userPledges, 1); - } -} +// uint256 _userPledges = bondEscalationModule.pledgesForDispute(_requestId, address(this)); +// // Check: is the number of pledges for the user properly updated? +// assertEq(_userPledges, 1); +// } +// } -contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { - /** - * @notice Tests that pledgeAgainstDispute reverts if the dispute does not exist. - */ - function test_revertIfDisputeIsZero() public { - bytes32 _disputeId = 0; +// contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { +// /** +// * @notice Tests that pledgeAgainstDispute reverts if the dispute does not exist. +// */ +// function test_revertIfDisputeIsZero() public { +// bytes32 _disputeId = 0; - // Check: does it revert if the dispute does not exist? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_DisputeDoesNotExist.selector); - bondEscalationModule.pledgeAgainstDispute(_disputeId); - } +// // Check: does it revert if the dispute does not exist? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_DisputeDoesNotExist.selector); +// bondEscalationModule.pledgeAgainstDispute(_disputeId); +// } - /** - * @notice Tests that pledgeAgainstDispute reverts if the dispute is not going through the bond escalation mechanism. - */ - function test_revertIfTheDisputeIsNotGoingThroughTheBondEscalationProcess( - bytes32 _disputeId, - bytes32 _requestId - ) public { - vm.assume(_disputeId > 0); +// /** +// * @notice Tests that pledgeAgainstDispute reverts if the dispute is not going through the bond escalation mechanism. +// */ +// function test_revertIfTheDisputeIsNotGoingThroughTheBondEscalationProcess( +// bytes32 _disputeId, +// bytes32 _requestId +// ) public { +// vm.assume(_disputeId > 0); - _mockDispute.requestId = _requestId; +// _mockDispute.requestId = _requestId; - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - // Check: does it revert if the dispute is not escalated yet? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); - bondEscalationModule.pledgeAgainstDispute(_disputeId); - } +// // Check: does it revert if the dispute is not escalated yet? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); +// bondEscalationModule.pledgeAgainstDispute(_disputeId); +// } - /** - * @notice Tests that pledgeAgainstDispute reverts if someone tries to pledge after the tying buffer. - */ - function test_revertIfTimestampBeyondTyingBuffer(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0); +// /** +// * @notice Tests that pledgeAgainstDispute reverts if someone tries to pledge after the tying buffer. +// */ +// function test_revertIfTimestampBeyondTyingBuffer(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0); - _mockDispute.requestId = _requestId; +// _mockDispute.requestId = _requestId; - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - uint256 _bondSize = 1; - uint256 _maxNumberOfEscalations = 1; - uint256 _bondEscalationDeadline = block.timestamp; - uint256 _tyingBuffer = 1000; +// uint256 _bondSize = 1; +// uint256 _maxNumberOfEscalations = 1; +// uint256 _bondEscalationDeadline = block.timestamp; +// uint256 _tyingBuffer = 1000; - vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); +// vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); - _setRequestData( - _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow - ); +// _setRequestData( +// _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow +// ); - // Check: does it revert if the bond escalation is over? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); +// // Check: does it revert if the bond escalation is over? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); - bondEscalationModule.pledgeAgainstDispute(_disputeId); - } +// bondEscalationModule.pledgeAgainstDispute(_disputeId); +// } - /** - * @notice Tests that pledgeAgainstDispute reverts if the maximum number of escalations has been reached. - */ - function test_revertIfMaxNumberOfEscalationsReached(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0); +// /** +// * @notice Tests that pledgeAgainstDispute reverts if the maximum number of escalations has been reached. +// */ +// function test_revertIfMaxNumberOfEscalationsReached(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0); - _mockDispute.requestId = _requestId; +// _mockDispute.requestId = _requestId; - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - uint256 _bondSize = 1; - uint256 _maxNumberOfEscalations = 2; - uint256 _bondEscalationDeadline = block.timestamp - 1; - uint256 _tyingBuffer = 1000; +// uint256 _bondSize = 1; +// uint256 _maxNumberOfEscalations = 2; +// uint256 _bondEscalationDeadline = block.timestamp - 1; +// uint256 _tyingBuffer = 1000; - _setRequestData( - _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow - ); +// _setRequestData( +// _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow +// ); - uint256 _numForPledgers = 2; - uint256 _numAgainstPledgers = _numForPledgers; +// uint256 _numForPledgers = 2; +// uint256 _numAgainstPledgers = _numForPledgers; - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - // Check: does it revert if the maximum number of escalations is reached? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); +// // Check: does it revert if the maximum number of escalations is reached? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); - bondEscalationModule.pledgeAgainstDispute(_disputeId); - } +// bondEscalationModule.pledgeAgainstDispute(_disputeId); +// } - /** - * @notice Tests that pledgeAgainstDispute reverts if someone tries to pledge in favor of the dispute when there are - * more pledges against of the dispute than in favor of it - */ - function test_revertIfThereIsMorePledgedAgainstDisputeThanFor(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0); +// /** +// * @notice Tests that pledgeAgainstDispute reverts if someone tries to pledge in favor of the dispute when there are +// * more pledges against of the dispute than in favor of it +// */ +// function test_revertIfThereIsMorePledgedAgainstDisputeThanFor(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0); - _mockDispute.requestId = _requestId; +// _mockDispute.requestId = _requestId; - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - uint256 _bondSize = 1; - uint256 _maxNumberOfEscalations = 3; - uint256 _bondEscalationDeadline = block.timestamp + 1; +// uint256 _bondSize = 1; +// uint256 _maxNumberOfEscalations = 3; +// uint256 _bondEscalationDeadline = block.timestamp + 1; - _setRequestData(_requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); +// _setRequestData(_requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); - uint256 _numAgainstPledgers = 2; - uint256 _numForPledgers = _numAgainstPledgers - 1; +// uint256 _numAgainstPledgers = 2; +// uint256 _numForPledgers = _numAgainstPledgers - 1; - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - // Check: does it revert if trying to pledge in a dispute that is already surpassed? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); +// // Check: does it revert if trying to pledge in a dispute that is already surpassed? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); - bondEscalationModule.pledgeAgainstDispute(_disputeId); - } +// bondEscalationModule.pledgeAgainstDispute(_disputeId); +// } - /** - * @notice Tests that pledgeAgainstDispute reverts if the timestamp is within the tying buffer and someone attempts - * to pledge when the funds are tied, effectively breaking the tie - */ - function test_revertIfAttemptToBreakTieDuringTyingBuffer(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0); +// /** +// * @notice Tests that pledgeAgainstDispute reverts if the timestamp is within the tying buffer and someone attempts +// * to pledge when the funds are tied, effectively breaking the tie +// */ +// function test_revertIfAttemptToBreakTieDuringTyingBuffer(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0); - _mockDispute.requestId = _requestId; +// _mockDispute.requestId = _requestId; - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - uint256 _bondSize = 1; - uint256 _maxNumberOfEscalations = 3; - uint256 _bondEscalationDeadline = block.timestamp - 1; - uint256 _tyingBuffer = 1000; +// uint256 _bondSize = 1; +// uint256 _maxNumberOfEscalations = 3; +// uint256 _bondEscalationDeadline = block.timestamp - 1; +// uint256 _tyingBuffer = 1000; - _setRequestData( - _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow - ); +// _setRequestData( +// _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow +// ); - uint256 _numForPledgers = 2; - uint256 _numAgainstPledgers = _numForPledgers; +// uint256 _numForPledgers = 2; +// uint256 _numAgainstPledgers = _numForPledgers; - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - // Check: does it revert if trying to tie outside of the tying buffer? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_CannotBreakTieDuringTyingBuffer.selector); - bondEscalationModule.pledgeAgainstDispute(_disputeId); - } +// // Check: does it revert if trying to tie outside of the tying buffer? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_CannotBreakTieDuringTyingBuffer.selector); +// bondEscalationModule.pledgeAgainstDispute(_disputeId); +// } - /** - * @notice Tests that pledgeAgainstDispute is called successfully - */ - function test_successfulCall(bytes32 _disputeId, bytes32 _requestId) public { - vm.assume(_disputeId > 0); +// /** +// * @notice Tests that pledgeAgainstDispute is called successfully +// */ +// function test_successfulCall(bytes32 _disputeId, bytes32 _requestId) public { +// vm.assume(_disputeId > 0); - _mockDispute.requestId = _requestId; +// _mockDispute.requestId = _requestId; - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - uint256 _bondSize = 1000; - uint256 _maxNumberOfEscalations = 3; - uint256 _bondEscalationDeadline = block.timestamp - 1; - uint256 _tyingBuffer = 1000; +// uint256 _bondSize = 1000; +// uint256 _maxNumberOfEscalations = 3; +// uint256 _bondEscalationDeadline = block.timestamp - 1; +// uint256 _tyingBuffer = 1000; - _setRequestData( - _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow - ); +// _setRequestData( +// _requestId, _bondSize, _maxNumberOfEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow +// ); - uint256 _numAgainstPledgers = 2; - uint256 _numForPledgers = _numAgainstPledgers + 1; +// uint256 _numAgainstPledgers = 2; +// uint256 _numForPledgers = _numAgainstPledgers + 1; - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - _mockAndExpect( - address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (address(this), _requestId, _disputeId, token, _bondSize)), - abi.encode(true) - ); +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IBondEscalationAccounting.pledge, (address(this), _requestId, _disputeId, token, _bondSize)), +// abi.encode(true) +// ); - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationModule)); - emit PledgedAgainstDispute(_disputeId, address(this), _bondSize); +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationModule)); +// emit PledgedAgainstDispute(_disputeId, address(this), _bondSize); - bondEscalationModule.pledgeAgainstDispute(_disputeId); +// bondEscalationModule.pledgeAgainstDispute(_disputeId); - uint256 _pledgesForDispute = bondEscalationModule.getEscalation(_requestId).amountOfPledgesAgainstDispute; - // Check: is the number of pledges for the dispute properly updated? - assertEq(_pledgesForDispute, _numAgainstPledgers + 1); +// uint256 _pledgesForDispute = bondEscalationModule.getEscalation(_requestId).amountOfPledgesAgainstDispute; +// // Check: is the number of pledges for the dispute properly updated? +// assertEq(_pledgesForDispute, _numAgainstPledgers + 1); - uint256 _userPledges = bondEscalationModule.pledgesAgainstDispute(_requestId, address(this)); - // Check: is the number of pledges for the user properly updated? - assertEq(_userPledges, 1); - } -} +// uint256 _userPledges = bondEscalationModule.pledgesAgainstDispute(_requestId, address(this)); +// // Check: is the number of pledges for the user properly updated? +// assertEq(_userPledges, 1); +// } +// } -contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { - /** - * @notice Tests that settleBondEscalation reverts if someone tries to settle the escalation before the tying buffer - * has elapsed. - */ - function test_revertIfTimestampLessThanEndOfTyingBuffer(bytes32 _requestId) public { - uint256 _bondEscalationDeadline = block.timestamp; - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); +// contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { +// /** +// * @notice Tests that settleBondEscalation reverts if someone tries to settle the escalation before the tying buffer +// * has elapsed. +// */ +// function test_revertIfTimestampLessThanEndOfTyingBuffer(bytes32 _requestId) public { +// uint256 _bondEscalationDeadline = block.timestamp; +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, tyingBuffer, disputeWindow); - // Check: does it revert if the bond escalation is not over? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationNotOver.selector); - bondEscalationModule.settleBondEscalation(_requestId); - } +// // Check: does it revert if the bond escalation is not over? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationNotOver.selector); +// bondEscalationModule.settleBondEscalation(_requestId); +// } - /** - * @notice Tests that settleBondEscalation reverts if someone tries to settle a bond-escalated dispute that - * is not active. - */ - function test_revertIfStatusOfBondEscalationIsNotActive(bytes32 _requestId) public { - uint256 _bondEscalationDeadline = block.timestamp; - uint256 _tyingBuffer = 1000; - - vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); +// /** +// * @notice Tests that settleBondEscalation reverts if someone tries to settle a bond-escalated dispute that +// * is not active. +// */ +// function test_revertIfStatusOfBondEscalationIsNotActive(bytes32 _requestId) public { +// uint256 _bondEscalationDeadline = block.timestamp; +// uint256 _tyingBuffer = 1000; + +// vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); - - bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.None); - - // Check: does it revert if the bond escalation is not active? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationCantBeSettled.selector); - bondEscalationModule.settleBondEscalation(_requestId); - } - - /** - * @notice Tests that settleBondEscalation reverts if someone tries to settle a bond-escalated dispute that - * has the same number of pledgers. - */ - function test_revertIfSameNumberOfPledgers(bytes32 _requestId, bytes32 _disputeId) public { - uint256 _bondEscalationDeadline = block.timestamp; - uint256 _tyingBuffer = 1000; - - vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); - - _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); - bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.Active); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - uint256 _numForPledgers = 5; - uint256 _numAgainstPledgers = _numForPledgers; - - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - - // Check: does it revert if the number of pledgers is the same? - vm.expectRevert(IBondEscalationModule.BondEscalationModule_ShouldBeEscalated.selector); - bondEscalationModule.settleBondEscalation(_requestId); - } - - /** - * @notice Tests that settleBondEscalation is called successfully. - */ - function test_successfulCallDisputerWon(bytes32 _requestId, bytes32 _disputeId) public { - uint256 _bondSize = 1000; - uint256 _bondEscalationDeadline = block.timestamp; - uint256 _tyingBuffer = 1000; - - vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); - - _setRequestData(_requestId, _bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); - bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.Active); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - uint256 _numForPledgers = 2; - uint256 _numAgainstPledgers = _numForPledgers - 1; - - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - - _mockAndExpect( - address(oracle), - abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.Won)), - abi.encode(true) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationModule)); - emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.DisputerWon); - - bondEscalationModule.settleBondEscalation(_requestId); - // Check: is the bond escalation status properly updated? - assertEq( - uint256(bondEscalationModule.getEscalation(_requestId).status), - uint256(IBondEscalationModule.BondEscalationStatus.DisputerWon) - ); - } - - /** - * @notice Tests that settleBondEscalation is called successfully. - */ - function test_successfulCallDisputerLost(bytes32 _requestId, bytes32 _disputeId) public { - uint256 _bondSize = 1000; - uint256 _bondEscalationDeadline = block.timestamp; - uint256 _tyingBuffer = 1000; - - vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); - - _setRequestData(_requestId, _bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); - bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.Active); - bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); - - uint256 _numAgainstPledgers = 2; - uint256 _numForPledgers = _numAgainstPledgers - 1; - - _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); - - _mockAndExpect( - address(oracle), - abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.Lost)), - abi.encode(true) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondEscalationModule)); - emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.DisputerLost); - - bondEscalationModule.settleBondEscalation(_requestId); - // Check: is the bond escalation status properly updated? - assertEq( - uint256(bondEscalationModule.getEscalation(_requestId).status), - uint256(IBondEscalationModule.BondEscalationStatus.DisputerLost) - ); - } -} +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); + +// bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.None); + +// // Check: does it revert if the bond escalation is not active? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationCantBeSettled.selector); +// bondEscalationModule.settleBondEscalation(_requestId); +// } + +// /** +// * @notice Tests that settleBondEscalation reverts if someone tries to settle a bond-escalated dispute that +// * has the same number of pledgers. +// */ +// function test_revertIfSameNumberOfPledgers(bytes32 _requestId, bytes32 _disputeId) public { +// uint256 _bondEscalationDeadline = block.timestamp; +// uint256 _tyingBuffer = 1000; + +// vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); + +// _setRequestData(_requestId, bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); +// bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.Active); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// uint256 _numForPledgers = 5; +// uint256 _numAgainstPledgers = _numForPledgers; + +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); + +// // Check: does it revert if the number of pledgers is the same? +// vm.expectRevert(IBondEscalationModule.BondEscalationModule_ShouldBeEscalated.selector); +// bondEscalationModule.settleBondEscalation(_requestId); +// } + +// /** +// * @notice Tests that settleBondEscalation is called successfully. +// */ +// function test_successfulCallDisputerWon(bytes32 _requestId, bytes32 _disputeId) public { +// uint256 _bondSize = 1000; +// uint256 _bondEscalationDeadline = block.timestamp; +// uint256 _tyingBuffer = 1000; + +// vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); + +// _setRequestData(_requestId, _bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); +// bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.Active); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// uint256 _numForPledgers = 2; +// uint256 _numAgainstPledgers = _numForPledgers - 1; + +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); + +// _mockAndExpect( +// address(oracle), +// abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.Won)), +// abi.encode(true) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationModule)); +// emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.DisputerWon); + +// bondEscalationModule.settleBondEscalation(_requestId); +// // Check: is the bond escalation status properly updated? +// assertEq( +// uint256(bondEscalationModule.getEscalation(_requestId).status), +// uint256(IBondEscalationModule.BondEscalationStatus.DisputerWon) +// ); +// } + +// /** +// * @notice Tests that settleBondEscalation is called successfully. +// */ +// function test_successfulCallDisputerLost(bytes32 _requestId, bytes32 _disputeId) public { +// uint256 _bondSize = 1000; +// uint256 _bondEscalationDeadline = block.timestamp; +// uint256 _tyingBuffer = 1000; + +// vm.warp(_bondEscalationDeadline + _tyingBuffer + 1); + +// _setRequestData(_requestId, _bondSize, maxEscalations, _bondEscalationDeadline, _tyingBuffer, disputeWindow); +// bondEscalationModule.forTest_setBondEscalationStatus(_requestId, IBondEscalationModule.BondEscalationStatus.Active); +// bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + +// uint256 _numAgainstPledgers = 2; +// uint256 _numForPledgers = _numAgainstPledgers - 1; + +// _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); + +// _mockAndExpect( +// address(oracle), +// abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.Lost)), +// abi.encode(true) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondEscalationModule)); +// emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.DisputerLost); + +// bondEscalationModule.settleBondEscalation(_requestId); +// // Check: is the bond escalation status properly updated? +// assertEq( +// uint256(bondEscalationModule.getEscalation(_requestId).status), +// uint256(IBondEscalationModule.BondEscalationStatus.DisputerLost) +// ); +// } +// } diff --git a/solidity/test/unit/modules/dispute/BondedDisputeModule.t.sol b/solidity/test/unit/modules/dispute/BondedDisputeModule.t.sol index 7718281f..3ad054d0 100644 --- a/solidity/test/unit/modules/dispute/BondedDisputeModule.t.sol +++ b/solidity/test/unit/modules/dispute/BondedDisputeModule.t.sol @@ -1,407 +1,407 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - BondedDisputeModule, IBondedDisputeModule -} from '../../../../contracts/modules/dispute/BondedDisputeModule.sol'; - -import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; - -contract ForTest_BondedDisputeModule is BondedDisputeModule { - constructor(IOracle _oracle) BondedDisputeModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } -} - -/** - * @title Bonded Dispute Module Unit tests - */ -contract BaseTest is Test, Helpers { - // The target contract - ForTest_BondedDisputeModule public bondedDisputeModule; - // A mock accounting extension - IAccountingExtension public accountingExtension; - // A mock oracle - IOracle public oracle; - // Some unnoticeable dude - address public dude = makeAddr('dude'); - // 100% random sequence of bytes representing request, response, or dispute id - bytes32 public mockId = bytes32('69'); - // Create a new dummy dispute - IOracle.Dispute public mockDispute; - - event DisputeStatusChanged( - bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer, IOracle.DisputeStatus _status - ); - - /** - * @notice Deploy the target and mock oracle - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - accountingExtension = IAccountingExtension(makeAddr('AccountingExtension')); - vm.etch(address(accountingExtension), hex'069420'); - - bondedDisputeModule = new ForTest_BondedDisputeModule(oracle); - - mockDispute = IOracle.Dispute({ - createdAt: block.timestamp, - disputer: dude, - proposer: dude, - responseId: mockId, - requestId: mockId, - status: IOracle.DisputeStatus.Active - }); - } -} - -contract BondedResponseModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the decodeRequestData function returns the correct values - */ - function test_decodeRequestData_returnsCorrectData( - bytes32 _requestId, - address _accountingExtension, - address _token, - uint256 _bondSize - ) public { - // Mock data - bytes memory _requestData = abi.encode(_accountingExtension, _token, _bondSize); - - // Store the mock request - bondedDisputeModule.forTest_setRequestData(_requestId, _requestData); - - // Test: decode the given request data - IBondedDisputeModule.RequestParameters memory _storedParams = bondedDisputeModule.decodeRequestData(_requestId); - - // Check: decoded values match original values? - assertEq(address(_storedParams.accountingExtension), _accountingExtension); - assertEq(address(_storedParams.bondToken), _token); - assertEq(_storedParams.bondSize, _bondSize); - } - - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleNameReturnsName() public { - assertEq(bondedDisputeModule.moduleName(), 'BondedDisputeModule'); - } -} - -contract BondedResponseModule_Unit_OnDisputeStatusChange is BaseTest { - /** - * @notice Test if onDisputeStatusChange correctly handle proposer or disputer win - */ - function test_correctWinnerPaid(uint256 _bondSize, address _disputer, address _proposer, IERC20 _token) public { - // Mock id's (insure they are different) - bytes32 _requestId = mockId; - bytes32 _responseId = bytes32(uint256(mockId) + 1); - - // Mock request data - bytes memory _requestData = abi.encode(accountingExtension, _token, _bondSize); - - // Store the mock request - bondedDisputeModule.forTest_setRequestData(mockId, _requestData); - - // ------------------------------------ - // Scenario: dispute won by proposer - // ------------------------------------ - - mockDispute = IOracle.Dispute({ - createdAt: 1, - disputer: _disputer, - proposer: _proposer, - responseId: _responseId, - requestId: _requestId, - status: IOracle.DisputeStatus.Won - }); - - // Mock and expect the call to pay, from¨*proposer to disputer* - _mockAndExpect( - address(accountingExtension), - abi.encodeCall(accountingExtension.pay, (_requestId, _proposer, _disputer, _token, _bondSize)), - abi.encode() - ); - - // Mock and expect the call to release, to the disputer - _mockAndExpect( - address(accountingExtension), - abi.encodeCall(accountingExtension.release, (_disputer, _requestId, _token, _bondSize)), - abi.encode() - ); - - vm.prank(address(oracle)); - bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); - - // ------------------------------------ - // Scenario: dispute loss by proposer - // ------------------------------------ - - mockDispute = IOracle.Dispute({ - createdAt: 1, - disputer: _disputer, - proposer: _proposer, - responseId: _responseId, - requestId: _requestId, - status: IOracle.DisputeStatus.Lost - }); - - // Mock and expect the call to pay, from *disputer to proposer* - _mockAndExpect( - address(accountingExtension), - abi.encodeCall(accountingExtension.pay, (_requestId, _disputer, _proposer, _token, _bondSize)), - abi.encode() - ); - - // Mock and expect the call to release, for the proposer - _mockAndExpect( - address(accountingExtension), - abi.encodeCall(accountingExtension.release, (_proposer, _requestId, _token, _bondSize)), - abi.encode() - ); - - vm.prank(address(oracle)); - bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); - - // ------------------------------------ - // Scenario: dispute with no resolution - // ------------------------------------ - - mockDispute = IOracle.Dispute({ - createdAt: 1, - disputer: _disputer, - proposer: _proposer, - responseId: _responseId, - requestId: _requestId, - status: IOracle.DisputeStatus.NoResolution - }); - - // Mock and expect the call to release, for the proposer - _mockAndExpect( - address(accountingExtension), - abi.encodeCall(accountingExtension.release, (_proposer, _requestId, _token, _bondSize)), - abi.encode() - ); - - // Mock and expect the call to release, for the disputer - _mockAndExpect( - address(accountingExtension), - abi.encodeCall(accountingExtension.release, (_disputer, _requestId, _token, _bondSize)), - abi.encode() - ); - - vm.prank(address(oracle)); - bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); - } - - function test_statusWithNoChange(uint256 _bondSize, address _disputer, address _proposer, IERC20 _token) public { - // Mock id's (insure they are different) - bytes32 _requestId = mockId; - bytes32 _responseId = bytes32(uint256(mockId) + 1); - - // Mock request data - bytes memory _requestData = abi.encode(accountingExtension, _token, _bondSize); - - // Store the mock request - bondedDisputeModule.forTest_setRequestData(mockId, _requestData); - - // ------------------------------------ - // Scenario: dispute new status is None - // ------------------------------------ - - mockDispute = IOracle.Dispute({ - createdAt: 1, - disputer: _disputer, - proposer: _proposer, - responseId: _responseId, - requestId: _requestId, - status: IOracle.DisputeStatus.None - }); - - // Expect the event - vm.expectEmit(true, true, true, true, address(bondedDisputeModule)); - emit DisputeStatusChanged(_requestId, _responseId, _disputer, _proposer, IOracle.DisputeStatus.None); - - vm.prank(address(oracle)); - bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); - - // ------------------------------------ - // Scenario: dispute new status is Active - // ------------------------------------ - - mockDispute = IOracle.Dispute({ - createdAt: 1, - disputer: _disputer, - proposer: _proposer, - responseId: _responseId, - requestId: _requestId, - status: IOracle.DisputeStatus.Active - }); - - // Expect the event - vm.expectEmit(true, true, true, true, address(bondedDisputeModule)); - emit DisputeStatusChanged(_requestId, _responseId, _disputer, _proposer, IOracle.DisputeStatus.Active); - - vm.prank(address(oracle)); - bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); - // ------------------------------------ - // Scenario: dispute new status is Escalated - // ------------------------------------ - - mockDispute = IOracle.Dispute({ - createdAt: 1, - disputer: _disputer, - proposer: _proposer, - responseId: _responseId, - requestId: _requestId, - status: IOracle.DisputeStatus.Escalated - }); - - // Expect the event - vm.expectEmit(true, true, true, true, address(bondedDisputeModule)); - emit DisputeStatusChanged(_requestId, _responseId, _disputer, _proposer, IOracle.DisputeStatus.Escalated); - - vm.prank(address(oracle)); - bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); - } - - function test_emitsEvent(uint256 _bondSize, address _disputer, address _proposer, IERC20 _token) public { - // Mock id's (insure they are different) - bytes32 _requestId = mockId; - bytes32 _responseId = bytes32(uint256(mockId) + 1); - - // Mock request data - bytes memory _requestData = abi.encode(accountingExtension, _token, _bondSize); - - // Store the mock request - bondedDisputeModule.forTest_setRequestData(mockId, _requestData); - - // ------------------------------------ - // Scenario: dispute won by proposer - // ------------------------------------ - - mockDispute = IOracle.Dispute({ - createdAt: 1, - disputer: _disputer, - proposer: _proposer, - responseId: _responseId, - requestId: _requestId, - status: IOracle.DisputeStatus.Won - }); - - // Mock and expect the call to pay, from¨*proposer to disputer* - _mockAndExpect( - address(accountingExtension), - abi.encodeCall(accountingExtension.pay, (_requestId, _proposer, _disputer, _token, _bondSize)), - abi.encode() - ); - - // Mock and expect the call to release, to the disputer - _mockAndExpect( - address(accountingExtension), - abi.encodeCall(accountingExtension.release, (_disputer, _requestId, _token, _bondSize)), - abi.encode() - ); - - // Expect the event - vm.expectEmit(true, true, true, true, address(bondedDisputeModule)); - emit DisputeStatusChanged(_requestId, _responseId, _disputer, _proposer, IOracle.DisputeStatus.Won); - - vm.prank(address(oracle)); - bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); - } - - /** - * @notice Test if onDisputeStatusChange reverts when called by caller who's not the oracle - */ - function test_revertWrongCaller(address _randomCaller) public { - vm.assume(_randomCaller != address(oracle)); - - // Check: revert if wrong caller - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - // Test: call disputeResponse from non-oracle address - vm.prank(_randomCaller); - bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); - } -} - -contract BondedResponseModule_Unit_DisputeResponse is BaseTest { - /** - * @notice Test if dispute escalated do nothing - */ - function test_returnCorrectStatus() public { - // Record sstore and sload - vm.prank(address(oracle)); - vm.record(); - bondedDisputeModule.disputeEscalated(mockId); - (bytes32[] memory _reads, bytes32[] memory _writes) = vm.accesses(address(bondedDisputeModule)); - - // Check: no storage access? - assertEq(_reads.length, 0); - assertEq(_writes.length, 0); - } - - /** - * @notice Test if dispute response returns the correct status - */ - function test_createBond(uint256 _bondSize, address _disputer, address _proposer, IERC20 _token) public { - // Mock id's (insure they are different) - bytes32 _requestId = mockId; - bytes32 _responseId = bytes32(uint256(mockId) + 1); - - // Mock request data - bytes memory _requestData = abi.encode(accountingExtension, _token, _bondSize); - - // Store the mock request - bondedDisputeModule.forTest_setRequestData(mockId, _requestData); - - // Mock and expect the call to the accounting extension, initiating the bond - _mockAndExpect( - address(accountingExtension), - abi.encodeWithSignature('bond(address,bytes32,address,uint256)', _disputer, _requestId, _token, _bondSize), - abi.encode() - ); - - // Test: call disputeResponse - vm.prank(address(oracle)); - IOracle.Dispute memory _dispute = bondedDisputeModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); - - // Check: dispute is correct? - assertEq(_dispute.disputer, _disputer); - assertEq(_dispute.proposer, _proposer); - assertEq(_dispute.responseId, _responseId); - assertEq(_dispute.requestId, _requestId); - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Active)); - assertEq(_dispute.createdAt, block.timestamp); - } - - /** - * @notice Test if dispute response reverts when called by caller who's not the oracle - */ - function test_revertWrongCaller(address _randomCaller) public { - vm.assume(_randomCaller != address(oracle)); - - // Check: revert if wrong caller - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - // Test: call disputeResponse from non-oracle address - vm.prank(_randomCaller); - bondedDisputeModule.disputeResponse(mockId, mockId, dude, dude); - } -} -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// BondedDisputeModule, IBondedDisputeModule +// } from '../../../../contracts/modules/dispute/BondedDisputeModule.sol'; + +// import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; + +// contract ForTest_BondedDisputeModule is BondedDisputeModule { +// constructor(IOracle _oracle) BondedDisputeModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } +// } + +// /** +// * @title Bonded Dispute Module Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_BondedDisputeModule public bondedDisputeModule; +// // A mock accounting extension +// IAccountingExtension public accountingExtension; +// // A mock oracle +// IOracle public oracle; +// // Some unnoticeable dude +// address public dude = makeAddr('dude'); +// // 100% random sequence of bytes representing request, response, or dispute id +// bytes32 public mockId = bytes32('69'); +// // Create a new dummy dispute +// IOracle.Dispute public mockDispute; + +// event DisputeStatusChanged( +// bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer, IOracle.DisputeStatus _status +// ); + +// /** +// * @notice Deploy the target and mock oracle +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// accountingExtension = IAccountingExtension(makeAddr('AccountingExtension')); +// vm.etch(address(accountingExtension), hex'069420'); + +// bondedDisputeModule = new ForTest_BondedDisputeModule(oracle); + +// mockDispute = IOracle.Dispute({ +// createdAt: block.timestamp, +// disputer: dude, +// proposer: dude, +// responseId: mockId, +// requestId: mockId, +// status: IOracle.DisputeStatus.Active +// }); +// } +// } + +// contract BondedResponseModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the decodeRequestData function returns the correct values +// */ +// function test_decodeRequestData_returnsCorrectData( +// bytes32 _requestId, +// address _accountingExtension, +// address _token, +// uint256 _bondSize +// ) public { +// // Mock data +// bytes memory _requestData = abi.encode(_accountingExtension, _token, _bondSize); + +// // Store the mock request +// bondedDisputeModule.forTest_setRequestData(_requestId, _requestData); + +// // Test: decode the given request data +// IBondedDisputeModule.RequestParameters memory _storedParams = bondedDisputeModule.decodeRequestData(_requestId); + +// // Check: decoded values match original values? +// assertEq(address(_storedParams.accountingExtension), _accountingExtension); +// assertEq(address(_storedParams.bondToken), _token); +// assertEq(_storedParams.bondSize, _bondSize); +// } + +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleNameReturnsName() public { +// assertEq(bondedDisputeModule.moduleName(), 'BondedDisputeModule'); +// } +// } + +// contract BondedResponseModule_Unit_OnDisputeStatusChange is BaseTest { +// /** +// * @notice Test if onDisputeStatusChange correctly handle proposer or disputer win +// */ +// function test_correctWinnerPaid(uint256 _bondSize, address _disputer, address _proposer, IERC20 _token) public { +// // Mock id's (insure they are different) +// bytes32 _requestId = mockId; +// bytes32 _responseId = bytes32(uint256(mockId) + 1); + +// // Mock request data +// bytes memory _requestData = abi.encode(accountingExtension, _token, _bondSize); + +// // Store the mock request +// bondedDisputeModule.forTest_setRequestData(mockId, _requestData); + +// // ------------------------------------ +// // Scenario: dispute won by proposer +// // ------------------------------------ + +// mockDispute = IOracle.Dispute({ +// createdAt: 1, +// disputer: _disputer, +// proposer: _proposer, +// responseId: _responseId, +// requestId: _requestId, +// status: IOracle.DisputeStatus.Won +// }); + +// // Mock and expect the call to pay, from¨*proposer to disputer* +// _mockAndExpect( +// address(accountingExtension), +// abi.encodeCall(accountingExtension.pay, (_requestId, _proposer, _disputer, _token, _bondSize)), +// abi.encode() +// ); + +// // Mock and expect the call to release, to the disputer +// _mockAndExpect( +// address(accountingExtension), +// abi.encodeCall(accountingExtension.release, (_disputer, _requestId, _token, _bondSize)), +// abi.encode() +// ); + +// vm.prank(address(oracle)); +// bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); + +// // ------------------------------------ +// // Scenario: dispute loss by proposer +// // ------------------------------------ + +// mockDispute = IOracle.Dispute({ +// createdAt: 1, +// disputer: _disputer, +// proposer: _proposer, +// responseId: _responseId, +// requestId: _requestId, +// status: IOracle.DisputeStatus.Lost +// }); + +// // Mock and expect the call to pay, from *disputer to proposer* +// _mockAndExpect( +// address(accountingExtension), +// abi.encodeCall(accountingExtension.pay, (_requestId, _disputer, _proposer, _token, _bondSize)), +// abi.encode() +// ); + +// // Mock and expect the call to release, for the proposer +// _mockAndExpect( +// address(accountingExtension), +// abi.encodeCall(accountingExtension.release, (_proposer, _requestId, _token, _bondSize)), +// abi.encode() +// ); + +// vm.prank(address(oracle)); +// bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); + +// // ------------------------------------ +// // Scenario: dispute with no resolution +// // ------------------------------------ + +// mockDispute = IOracle.Dispute({ +// createdAt: 1, +// disputer: _disputer, +// proposer: _proposer, +// responseId: _responseId, +// requestId: _requestId, +// status: IOracle.DisputeStatus.NoResolution +// }); + +// // Mock and expect the call to release, for the proposer +// _mockAndExpect( +// address(accountingExtension), +// abi.encodeCall(accountingExtension.release, (_proposer, _requestId, _token, _bondSize)), +// abi.encode() +// ); + +// // Mock and expect the call to release, for the disputer +// _mockAndExpect( +// address(accountingExtension), +// abi.encodeCall(accountingExtension.release, (_disputer, _requestId, _token, _bondSize)), +// abi.encode() +// ); + +// vm.prank(address(oracle)); +// bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); +// } + +// function test_statusWithNoChange(uint256 _bondSize, address _disputer, address _proposer, IERC20 _token) public { +// // Mock id's (insure they are different) +// bytes32 _requestId = mockId; +// bytes32 _responseId = bytes32(uint256(mockId) + 1); + +// // Mock request data +// bytes memory _requestData = abi.encode(accountingExtension, _token, _bondSize); + +// // Store the mock request +// bondedDisputeModule.forTest_setRequestData(mockId, _requestData); + +// // ------------------------------------ +// // Scenario: dispute new status is None +// // ------------------------------------ + +// mockDispute = IOracle.Dispute({ +// createdAt: 1, +// disputer: _disputer, +// proposer: _proposer, +// responseId: _responseId, +// requestId: _requestId, +// status: IOracle.DisputeStatus.None +// }); + +// // Expect the event +// vm.expectEmit(true, true, true, true, address(bondedDisputeModule)); +// emit DisputeStatusChanged(_requestId, _responseId, _disputer, _proposer, IOracle.DisputeStatus.None); + +// vm.prank(address(oracle)); +// bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); + +// // ------------------------------------ +// // Scenario: dispute new status is Active +// // ------------------------------------ + +// mockDispute = IOracle.Dispute({ +// createdAt: 1, +// disputer: _disputer, +// proposer: _proposer, +// responseId: _responseId, +// requestId: _requestId, +// status: IOracle.DisputeStatus.Active +// }); + +// // Expect the event +// vm.expectEmit(true, true, true, true, address(bondedDisputeModule)); +// emit DisputeStatusChanged(_requestId, _responseId, _disputer, _proposer, IOracle.DisputeStatus.Active); + +// vm.prank(address(oracle)); +// bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); +// // ------------------------------------ +// // Scenario: dispute new status is Escalated +// // ------------------------------------ + +// mockDispute = IOracle.Dispute({ +// createdAt: 1, +// disputer: _disputer, +// proposer: _proposer, +// responseId: _responseId, +// requestId: _requestId, +// status: IOracle.DisputeStatus.Escalated +// }); + +// // Expect the event +// vm.expectEmit(true, true, true, true, address(bondedDisputeModule)); +// emit DisputeStatusChanged(_requestId, _responseId, _disputer, _proposer, IOracle.DisputeStatus.Escalated); + +// vm.prank(address(oracle)); +// bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); +// } + +// function test_emitsEvent(uint256 _bondSize, address _disputer, address _proposer, IERC20 _token) public { +// // Mock id's (insure they are different) +// bytes32 _requestId = mockId; +// bytes32 _responseId = bytes32(uint256(mockId) + 1); + +// // Mock request data +// bytes memory _requestData = abi.encode(accountingExtension, _token, _bondSize); + +// // Store the mock request +// bondedDisputeModule.forTest_setRequestData(mockId, _requestData); + +// // ------------------------------------ +// // Scenario: dispute won by proposer +// // ------------------------------------ + +// mockDispute = IOracle.Dispute({ +// createdAt: 1, +// disputer: _disputer, +// proposer: _proposer, +// responseId: _responseId, +// requestId: _requestId, +// status: IOracle.DisputeStatus.Won +// }); + +// // Mock and expect the call to pay, from¨*proposer to disputer* +// _mockAndExpect( +// address(accountingExtension), +// abi.encodeCall(accountingExtension.pay, (_requestId, _proposer, _disputer, _token, _bondSize)), +// abi.encode() +// ); + +// // Mock and expect the call to release, to the disputer +// _mockAndExpect( +// address(accountingExtension), +// abi.encodeCall(accountingExtension.release, (_disputer, _requestId, _token, _bondSize)), +// abi.encode() +// ); + +// // Expect the event +// vm.expectEmit(true, true, true, true, address(bondedDisputeModule)); +// emit DisputeStatusChanged(_requestId, _responseId, _disputer, _proposer, IOracle.DisputeStatus.Won); + +// vm.prank(address(oracle)); +// bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); +// } + +// /** +// * @notice Test if onDisputeStatusChange reverts when called by caller who's not the oracle +// */ +// function test_revertWrongCaller(address _randomCaller) public { +// vm.assume(_randomCaller != address(oracle)); + +// // Check: revert if wrong caller +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// // Test: call disputeResponse from non-oracle address +// vm.prank(_randomCaller); +// bondedDisputeModule.onDisputeStatusChange(mockId, mockDispute); +// } +// } + +// contract BondedResponseModule_Unit_DisputeResponse is BaseTest { +// /** +// * @notice Test if dispute escalated do nothing +// */ +// function test_returnCorrectStatus() public { +// // Record sstore and sload +// vm.prank(address(oracle)); +// vm.record(); +// bondedDisputeModule.disputeEscalated(mockId); +// (bytes32[] memory _reads, bytes32[] memory _writes) = vm.accesses(address(bondedDisputeModule)); + +// // Check: no storage access? +// assertEq(_reads.length, 0); +// assertEq(_writes.length, 0); +// } + +// /** +// * @notice Test if dispute response returns the correct status +// */ +// function test_createBond(uint256 _bondSize, address _disputer, address _proposer, IERC20 _token) public { +// // Mock id's (insure they are different) +// bytes32 _requestId = mockId; +// bytes32 _responseId = bytes32(uint256(mockId) + 1); + +// // Mock request data +// bytes memory _requestData = abi.encode(accountingExtension, _token, _bondSize); + +// // Store the mock request +// bondedDisputeModule.forTest_setRequestData(mockId, _requestData); + +// // Mock and expect the call to the accounting extension, initiating the bond +// _mockAndExpect( +// address(accountingExtension), +// abi.encodeWithSignature('bond(address,bytes32,address,uint256)', _disputer, _requestId, _token, _bondSize), +// abi.encode() +// ); + +// // Test: call disputeResponse +// vm.prank(address(oracle)); +// IOracle.Dispute memory _dispute = bondedDisputeModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); + +// // Check: dispute is correct? +// assertEq(_dispute.disputer, _disputer); +// assertEq(_dispute.proposer, _proposer); +// assertEq(_dispute.responseId, _responseId); +// assertEq(_dispute.requestId, _requestId); +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Active)); +// assertEq(_dispute.createdAt, block.timestamp); +// } + +// /** +// * @notice Test if dispute response reverts when called by caller who's not the oracle +// */ +// function test_revertWrongCaller(address _randomCaller) public { +// vm.assume(_randomCaller != address(oracle)); + +// // Check: revert if wrong caller +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// // Test: call disputeResponse from non-oracle address +// vm.prank(_randomCaller); +// bondedDisputeModule.disputeResponse(mockId, mockId, dude, dude); +// } +// } +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ diff --git a/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol b/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol index 51bd6787..36e325fa 100644 --- a/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol +++ b/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol @@ -1,477 +1,477 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - CircuitResolverModule, - ICircuitResolverModule -} from '../../../../contracts/modules/dispute/CircuitResolverModule.sol'; - -import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ -contract ForTest_CircuitResolverModule is CircuitResolverModule { - constructor(IOracle _oracle) CircuitResolverModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } - - function forTest_setCorrectResponse(bytes32 _requestId, bytes memory _data) public { - _correctResponses[_requestId] = _data; - } -} - -/** - * @title Bonded Dispute Module Unit tests - */ -contract BaseTest is Test, Helpers { - // The target contract - ForTest_CircuitResolverModule public circuitResolverModule; - // A mock oracle - IOracle public oracle; - // A mock accounting extension - IAccountingExtension public accountingExtension; - // Some unnoticeable dude - address public dude = makeAddr('dude'); - // 100% random sequence of bytes representing request, response, or dispute id - bytes32 public mockId = bytes32('69'); - // Create a new dummy dispute - IOracle.Dispute public mockDispute; - // A mock circuit verifier address - address public circuitVerifier; - // Mock addresses - IERC20 public _token = IERC20(makeAddr('token')); - address public _disputer = makeAddr('disputer'); - address public _proposer = makeAddr('proposer'); - bytes internal _callData = abi.encodeWithSignature('test(uint256)', 123); - - event ResponseDisputed(bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer); - event DisputeStatusChanged( - bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer, IOracle.DisputeStatus _status - ); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - accountingExtension = IAccountingExtension(makeAddr('AccountingExtension')); - vm.etch(address(accountingExtension), hex'069420'); - circuitVerifier = makeAddr('CircuitVerifier'); - vm.etch(address(circuitVerifier), hex'069420'); - - circuitResolverModule = new ForTest_CircuitResolverModule(oracle); - - mockDispute = IOracle.Dispute({ - createdAt: block.timestamp, - disputer: dude, - responseId: mockId, - proposer: dude, - requestId: mockId, - status: IOracle.DisputeStatus.Active - }); - } -} - -contract CircuitResolverModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the decodeRequestData function returns the correct values - */ - function test_decodeRequestData_returnsCorrectData( - bytes32 _requestId, - address _accountingExtension, - address _randomToken, - uint256 _bondSize - ) public { - // Mock data - bytes memory _requestData = abi.encode( - ICircuitResolverModule.RequestParameters({ - callData: _callData, - verifier: circuitVerifier, - accountingExtension: IAccountingExtension(_accountingExtension), - bondToken: IERC20(_randomToken), - bondSize: _bondSize - }) - ); - - // Store the mock request - circuitResolverModule.forTest_setRequestData(_requestId, _requestData); - - // Test: decode the given request data - ICircuitResolverModule.RequestParameters memory _params = circuitResolverModule.decodeRequestData(_requestId); - - // Check: is the request data properly stored? - assertEq(_params.callData, _callData, 'Mismatch: decoded calldata'); - assertEq(_params.verifier, circuitVerifier, 'Mismatch: decoded circuit verifier'); - assertEq(address(_params.accountingExtension), _accountingExtension, 'Mismatch: decoded accounting extension'); - assertEq(address(_params.bondToken), _randomToken, 'Mismatch: decoded token'); - assertEq(_params.bondSize, _bondSize, 'Mismatch: decoded bond size'); - } - - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleNameReturnsName() public { - assertEq(circuitResolverModule.moduleName(), 'CircuitResolverModule'); - } -} - -contract CircuitResolverModule_Unit_DisputeResponse is BaseTest { - /** - * @notice Test if dispute incorrect response returns the correct status - */ - function test_disputeIncorrectResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { - vm.assume(_requestId != _responseId); - bool _correctResponse = false; - - // Mock request data - bytes memory _requestData = abi.encode( - ICircuitResolverModule.RequestParameters({ - callData: _callData, - verifier: circuitVerifier, - accountingExtension: accountingExtension, - bondToken: IERC20(_token), - bondSize: _bondSize - }) - ); - - // Store the mock request - circuitResolverModule.forTest_setRequestData(_requestId, _requestData); - - // Create new Response memory struct with random values - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - proposer: _proposer, - requestId: _requestId, - disputeId: mockId, - response: abi.encode(true) - }); - - // Mock and expect the call to the oracle, getting the response - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the call to the verifier - _mockAndExpect(circuitVerifier, _callData, abi.encode(_correctResponse)); - - // Test: call disputeResponse - vm.prank(address(oracle)); - IOracle.Dispute memory _dispute = - circuitResolverModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); - - // Check: is the dispute data properly stored? - assertEq(_dispute.disputer, _disputer, 'Mismatch: disputer'); - assertEq(_dispute.proposer, _proposer, 'Mismatch: proposer'); - assertEq(_dispute.responseId, _responseId, 'Mismatch: responseId'); - assertEq(_dispute.requestId, _requestId, 'Mismatch: requestId'); - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won), 'Mismatch: status'); - assertEq(_dispute.createdAt, block.timestamp, 'Mismatch: createdAt'); - } - - function test_emitsEvent(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { - vm.assume(_requestId != _responseId); - - bool _correctResponse = false; - - // Mock request data - bytes memory _requestData = abi.encode( - ICircuitResolverModule.RequestParameters({ - callData: _callData, - verifier: circuitVerifier, - accountingExtension: accountingExtension, - bondToken: IERC20(_token), - bondSize: _bondSize - }) - ); - - // Store the mock request - circuitResolverModule.forTest_setRequestData(_requestId, _requestData); - - // Create new Response memory struct with random values - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - proposer: _proposer, - requestId: _requestId, - disputeId: mockId, - response: abi.encode(true) - }); - - // Mock and expect the call to the oracle, getting the response - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the call to the verifier - _mockAndExpect(circuitVerifier, _callData, abi.encode(_correctResponse)); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(circuitResolverModule)); - emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); - - vm.prank(address(oracle)); - circuitResolverModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); - } - - /** - * @notice Test if dispute correct response returns the correct status - */ - function test_disputeCorrectResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { - vm.assume(_requestId != _responseId); - - bytes memory _encodedCorrectResponse = abi.encode(true); - - // Mock request data - bytes memory _requestData = abi.encode( - ICircuitResolverModule.RequestParameters({ - callData: _callData, - verifier: circuitVerifier, - accountingExtension: accountingExtension, - bondToken: IERC20(_token), - bondSize: _bondSize - }) - ); - - // Store the mock request - circuitResolverModule.forTest_setRequestData(_requestId, _requestData); - - // Create new Response memory struct with random values - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - proposer: _proposer, - requestId: _requestId, - disputeId: mockId, - response: _encodedCorrectResponse - }); - - // Mock and expect the call to the oracle, getting the response - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the call to the verifier - _mockAndExpect(circuitVerifier, _callData, _encodedCorrectResponse); - - vm.prank(address(oracle)); - IOracle.Dispute memory _dispute = - circuitResolverModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); - - // Check: is the dispute data properly stored? - assertEq(_dispute.disputer, _disputer, 'Mismatch: disputer'); - assertEq(_dispute.proposer, _proposer, 'Mismatch: proposer'); - assertEq(_dispute.responseId, _responseId, 'Mismatch: responseId'); - assertEq(_dispute.requestId, _requestId, 'Mismatch: requestId'); - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Lost), 'Mismatch: status'); - assertEq(_dispute.createdAt, block.timestamp, 'Mismatch: createdAt'); - } - - /** - * @notice Test if dispute response reverts when called by caller who's not the oracle - */ - function test_revertWrongCaller(address _randomCaller) public { - vm.assume(_randomCaller != address(oracle)); - - // Check: does it revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(_randomCaller); - circuitResolverModule.disputeResponse(mockId, mockId, dude, dude); - } -} - -contract CircuitResolverModule_Unit_DisputeEscalation is BaseTest { - /** - * @notice Test if dispute escalated do nothing - */ - function test_returnCorrectStatus() public { - // Record sstore and sload - vm.prank(address(oracle)); - vm.record(); - circuitResolverModule.disputeEscalated(mockId); - (bytes32[] memory _reads, bytes32[] memory _writes) = vm.accesses(address(circuitResolverModule)); - - // Check: no storage access? - assertEq(_reads.length, 0); - assertEq(_writes.length, 0); - } - - /** - * @notice Test that escalateDispute finalizes the request if the original response is correct - */ - function test_correctResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { - vm.assume(_requestId != _responseId); - - bytes memory _encodedCorrectResponse = abi.encode(true); - - // Mock request data - bytes memory _requestData = abi.encode( - ICircuitResolverModule.RequestParameters({ - callData: _callData, - verifier: circuitVerifier, - accountingExtension: accountingExtension, - bondToken: IERC20(_token), - bondSize: _bondSize - }) - ); - - // Store the mock request - circuitResolverModule.forTest_setRequestData(_requestId, _requestData); - - circuitResolverModule.forTest_setCorrectResponse(_requestId, _encodedCorrectResponse); - - // Create new Response memory struct with random values - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - proposer: _proposer, - requestId: _requestId, - disputeId: mockId, - response: _encodedCorrectResponse - }); - - // Mock and expect the call to the oracle, getting the response - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the call to the oracle, finalizing the request - _mockAndExpect( - address(oracle), abi.encodeWithSignature('finalize(bytes32,bytes32)', _requestId, _responseId), abi.encode() - ); - - // Populate the mock dispute with the correct values - mockDispute.status = IOracle.DisputeStatus.Lost; - mockDispute.responseId = _responseId; - mockDispute.requestId = _requestId; - - vm.prank(address(oracle)); - circuitResolverModule.onDisputeStatusChange(bytes32(0), mockDispute); - } - - /** - * @notice Test that escalateDispute pays the disputer and proposes the new response - */ - function test_incorrectResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { - vm.assume(_requestId != _responseId); - - bytes32 _correctResponseId = bytes32(uint256(mockId) + 2); - bytes memory _encodedCorrectResponse = abi.encode(true); - - // Mock request data - bytes memory _requestData = abi.encode( - ICircuitResolverModule.RequestParameters({ - callData: _callData, - verifier: circuitVerifier, - accountingExtension: accountingExtension, - bondToken: IERC20(_token), - bondSize: _bondSize - }) - ); - - // Store the mock request and correct response - circuitResolverModule.forTest_setRequestData(_requestId, _requestData); - circuitResolverModule.forTest_setCorrectResponse(_requestId, _encodedCorrectResponse); - - // Create new Response memory struct with random values - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - proposer: _proposer, - requestId: _requestId, - disputeId: mockId, - response: abi.encode(false) - }); - - // Mock and expect the call to the oracle, getting the response - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the call to the accounting extension, paying the disputer - _mockAndExpect( - address(accountingExtension), - abi.encodeCall(accountingExtension.pay, (_requestId, _proposer, _disputer, _token, _bondSize)), - abi.encode() - ); - - // Mock and expect the call to the oracle, proposing the correct response with the disputer as the new proposer - _mockAndExpect( - address(oracle), - abi.encodeWithSignature( - 'proposeResponse(address,bytes32,bytes)', _disputer, _requestId, abi.encode(_encodedCorrectResponse) - ), - abi.encode(_correctResponseId) - ); - - // Mock and expect the call to the oracle, finalizing the request with the correct response - _mockAndExpect( - address(oracle), - abi.encodeWithSignature('finalize(bytes32,bytes32)', _requestId, _correctResponseId), - abi.encode() - ); - - // Populate the mock dispute with the correct values - mockDispute.status = IOracle.DisputeStatus.Won; - mockDispute.responseId = _responseId; - mockDispute.requestId = _requestId; - mockDispute.disputer = _disputer; - mockDispute.proposer = _proposer; - - vm.prank(address(oracle)); - circuitResolverModule.onDisputeStatusChange(bytes32(0), mockDispute); - } -} - -contract CircuitResolverModule_Unit_OnDisputeStatusChange is BaseTest { - function test_eventEmitted(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { - vm.assume(_requestId != _responseId); - - bytes memory _encodedCorrectResponse = abi.encode(true); - - // Mock request data - bytes memory _requestData = abi.encode( - ICircuitResolverModule.RequestParameters({ - callData: _callData, - verifier: circuitVerifier, - accountingExtension: accountingExtension, - bondToken: IERC20(_token), - bondSize: _bondSize - }) - ); - - // Store the mock request - circuitResolverModule.forTest_setRequestData(_requestId, _requestData); - circuitResolverModule.forTest_setCorrectResponse(_requestId, _encodedCorrectResponse); - - // Create new Response memory struct with random values - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - proposer: _proposer, - requestId: _requestId, - disputeId: mockId, - response: _encodedCorrectResponse - }); - - // Mock and expect the call to the oracle, getting the response - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the call to the oracle, finalizing the request - _mockAndExpect( - address(oracle), abi.encodeWithSignature('finalize(bytes32,bytes32)', _requestId, _responseId), abi.encode() - ); - - // Populate the mock dispute with the correct values - mockDispute.status = IOracle.DisputeStatus.Lost; - mockDispute.responseId = _responseId; - mockDispute.requestId = _requestId; - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(circuitResolverModule)); - emit DisputeStatusChanged( - _requestId, _responseId, mockDispute.disputer, mockDispute.proposer, IOracle.DisputeStatus.Lost - ); - - vm.prank(address(oracle)); - circuitResolverModule.onDisputeStatusChange(bytes32(0), mockDispute); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// CircuitResolverModule, +// ICircuitResolverModule +// } from '../../../../contracts/modules/dispute/CircuitResolverModule.sol'; + +// import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ +// contract ForTest_CircuitResolverModule is CircuitResolverModule { +// constructor(IOracle _oracle) CircuitResolverModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } + +// function forTest_setCorrectResponse(bytes32 _requestId, bytes memory _data) public { +// _correctResponses[_requestId] = _data; +// } +// } + +// /** +// * @title Bonded Dispute Module Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_CircuitResolverModule public circuitResolverModule; +// // A mock oracle +// IOracle public oracle; +// // A mock accounting extension +// IAccountingExtension public accountingExtension; +// // Some unnoticeable dude +// address public dude = makeAddr('dude'); +// // 100% random sequence of bytes representing request, response, or dispute id +// bytes32 public mockId = bytes32('69'); +// // Create a new dummy dispute +// IOracle.Dispute public mockDispute; +// // A mock circuit verifier address +// address public circuitVerifier; +// // Mock addresses +// IERC20 public _token = IERC20(makeAddr('token')); +// address public _disputer = makeAddr('disputer'); +// address public _proposer = makeAddr('proposer'); +// bytes internal _callData = abi.encodeWithSignature('test(uint256)', 123); + +// event ResponseDisputed(bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer); +// event DisputeStatusChanged( +// bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer, IOracle.DisputeStatus _status +// ); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// accountingExtension = IAccountingExtension(makeAddr('AccountingExtension')); +// vm.etch(address(accountingExtension), hex'069420'); +// circuitVerifier = makeAddr('CircuitVerifier'); +// vm.etch(address(circuitVerifier), hex'069420'); + +// circuitResolverModule = new ForTest_CircuitResolverModule(oracle); + +// mockDispute = IOracle.Dispute({ +// createdAt: block.timestamp, +// disputer: dude, +// responseId: mockId, +// proposer: dude, +// requestId: mockId, +// status: IOracle.DisputeStatus.Active +// }); +// } +// } + +// contract CircuitResolverModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the decodeRequestData function returns the correct values +// */ +// function test_decodeRequestData_returnsCorrectData( +// bytes32 _requestId, +// address _accountingExtension, +// address _randomToken, +// uint256 _bondSize +// ) public { +// // Mock data +// bytes memory _requestData = abi.encode( +// ICircuitResolverModule.RequestParameters({ +// callData: _callData, +// verifier: circuitVerifier, +// accountingExtension: IAccountingExtension(_accountingExtension), +// bondToken: IERC20(_randomToken), +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request +// circuitResolverModule.forTest_setRequestData(_requestId, _requestData); + +// // Test: decode the given request data +// ICircuitResolverModule.RequestParameters memory _params = circuitResolverModule.decodeRequestData(_requestId); + +// // Check: is the request data properly stored? +// assertEq(_params.callData, _callData, 'Mismatch: decoded calldata'); +// assertEq(_params.verifier, circuitVerifier, 'Mismatch: decoded circuit verifier'); +// assertEq(address(_params.accountingExtension), _accountingExtension, 'Mismatch: decoded accounting extension'); +// assertEq(address(_params.bondToken), _randomToken, 'Mismatch: decoded token'); +// assertEq(_params.bondSize, _bondSize, 'Mismatch: decoded bond size'); +// } + +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleNameReturnsName() public { +// assertEq(circuitResolverModule.moduleName(), 'CircuitResolverModule'); +// } +// } + +// contract CircuitResolverModule_Unit_DisputeResponse is BaseTest { +// /** +// * @notice Test if dispute incorrect response returns the correct status +// */ +// function test_disputeIncorrectResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { +// vm.assume(_requestId != _responseId); +// bool _correctResponse = false; + +// // Mock request data +// bytes memory _requestData = abi.encode( +// ICircuitResolverModule.RequestParameters({ +// callData: _callData, +// verifier: circuitVerifier, +// accountingExtension: accountingExtension, +// bondToken: IERC20(_token), +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request +// circuitResolverModule.forTest_setRequestData(_requestId, _requestData); + +// // Create new Response memory struct with random values +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// proposer: _proposer, +// requestId: _requestId, +// disputeId: mockId, +// response: abi.encode(true) +// }); + +// // Mock and expect the call to the oracle, getting the response +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the call to the verifier +// _mockAndExpect(circuitVerifier, _callData, abi.encode(_correctResponse)); + +// // Test: call disputeResponse +// vm.prank(address(oracle)); +// IOracle.Dispute memory _dispute = +// circuitResolverModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); + +// // Check: is the dispute data properly stored? +// assertEq(_dispute.disputer, _disputer, 'Mismatch: disputer'); +// assertEq(_dispute.proposer, _proposer, 'Mismatch: proposer'); +// assertEq(_dispute.responseId, _responseId, 'Mismatch: responseId'); +// assertEq(_dispute.requestId, _requestId, 'Mismatch: requestId'); +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won), 'Mismatch: status'); +// assertEq(_dispute.createdAt, block.timestamp, 'Mismatch: createdAt'); +// } + +// function test_emitsEvent(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { +// vm.assume(_requestId != _responseId); + +// bool _correctResponse = false; + +// // Mock request data +// bytes memory _requestData = abi.encode( +// ICircuitResolverModule.RequestParameters({ +// callData: _callData, +// verifier: circuitVerifier, +// accountingExtension: accountingExtension, +// bondToken: IERC20(_token), +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request +// circuitResolverModule.forTest_setRequestData(_requestId, _requestData); + +// // Create new Response memory struct with random values +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// proposer: _proposer, +// requestId: _requestId, +// disputeId: mockId, +// response: abi.encode(true) +// }); + +// // Mock and expect the call to the oracle, getting the response +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the call to the verifier +// _mockAndExpect(circuitVerifier, _callData, abi.encode(_correctResponse)); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(circuitResolverModule)); +// emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); + +// vm.prank(address(oracle)); +// circuitResolverModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); +// } + +// /** +// * @notice Test if dispute correct response returns the correct status +// */ +// function test_disputeCorrectResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { +// vm.assume(_requestId != _responseId); + +// bytes memory _encodedCorrectResponse = abi.encode(true); + +// // Mock request data +// bytes memory _requestData = abi.encode( +// ICircuitResolverModule.RequestParameters({ +// callData: _callData, +// verifier: circuitVerifier, +// accountingExtension: accountingExtension, +// bondToken: IERC20(_token), +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request +// circuitResolverModule.forTest_setRequestData(_requestId, _requestData); + +// // Create new Response memory struct with random values +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// proposer: _proposer, +// requestId: _requestId, +// disputeId: mockId, +// response: _encodedCorrectResponse +// }); + +// // Mock and expect the call to the oracle, getting the response +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the call to the verifier +// _mockAndExpect(circuitVerifier, _callData, _encodedCorrectResponse); + +// vm.prank(address(oracle)); +// IOracle.Dispute memory _dispute = +// circuitResolverModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); + +// // Check: is the dispute data properly stored? +// assertEq(_dispute.disputer, _disputer, 'Mismatch: disputer'); +// assertEq(_dispute.proposer, _proposer, 'Mismatch: proposer'); +// assertEq(_dispute.responseId, _responseId, 'Mismatch: responseId'); +// assertEq(_dispute.requestId, _requestId, 'Mismatch: requestId'); +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Lost), 'Mismatch: status'); +// assertEq(_dispute.createdAt, block.timestamp, 'Mismatch: createdAt'); +// } + +// /** +// * @notice Test if dispute response reverts when called by caller who's not the oracle +// */ +// function test_revertWrongCaller(address _randomCaller) public { +// vm.assume(_randomCaller != address(oracle)); + +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(_randomCaller); +// circuitResolverModule.disputeResponse(mockId, mockId, dude, dude); +// } +// } + +// contract CircuitResolverModule_Unit_DisputeEscalation is BaseTest { +// /** +// * @notice Test if dispute escalated do nothing +// */ +// function test_returnCorrectStatus() public { +// // Record sstore and sload +// vm.prank(address(oracle)); +// vm.record(); +// circuitResolverModule.disputeEscalated(mockId); +// (bytes32[] memory _reads, bytes32[] memory _writes) = vm.accesses(address(circuitResolverModule)); + +// // Check: no storage access? +// assertEq(_reads.length, 0); +// assertEq(_writes.length, 0); +// } + +// /** +// * @notice Test that escalateDispute finalizes the request if the original response is correct +// */ +// function test_correctResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { +// vm.assume(_requestId != _responseId); + +// bytes memory _encodedCorrectResponse = abi.encode(true); + +// // Mock request data +// bytes memory _requestData = abi.encode( +// ICircuitResolverModule.RequestParameters({ +// callData: _callData, +// verifier: circuitVerifier, +// accountingExtension: accountingExtension, +// bondToken: IERC20(_token), +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request +// circuitResolverModule.forTest_setRequestData(_requestId, _requestData); + +// circuitResolverModule.forTest_setCorrectResponse(_requestId, _encodedCorrectResponse); + +// // Create new Response memory struct with random values +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// proposer: _proposer, +// requestId: _requestId, +// disputeId: mockId, +// response: _encodedCorrectResponse +// }); + +// // Mock and expect the call to the oracle, getting the response +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the call to the oracle, finalizing the request +// _mockAndExpect( +// address(oracle), abi.encodeWithSignature('finalize(bytes32,bytes32)', _requestId, _responseId), abi.encode() +// ); + +// // Populate the mock dispute with the correct values +// mockDispute.status = IOracle.DisputeStatus.Lost; +// mockDispute.responseId = _responseId; +// mockDispute.requestId = _requestId; + +// vm.prank(address(oracle)); +// circuitResolverModule.onDisputeStatusChange(bytes32(0), mockDispute); +// } + +// /** +// * @notice Test that escalateDispute pays the disputer and proposes the new response +// */ +// function test_incorrectResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { +// vm.assume(_requestId != _responseId); + +// bytes32 _correctResponseId = bytes32(uint256(mockId) + 2); +// bytes memory _encodedCorrectResponse = abi.encode(true); + +// // Mock request data +// bytes memory _requestData = abi.encode( +// ICircuitResolverModule.RequestParameters({ +// callData: _callData, +// verifier: circuitVerifier, +// accountingExtension: accountingExtension, +// bondToken: IERC20(_token), +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request and correct response +// circuitResolverModule.forTest_setRequestData(_requestId, _requestData); +// circuitResolverModule.forTest_setCorrectResponse(_requestId, _encodedCorrectResponse); + +// // Create new Response memory struct with random values +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// proposer: _proposer, +// requestId: _requestId, +// disputeId: mockId, +// response: abi.encode(false) +// }); + +// // Mock and expect the call to the oracle, getting the response +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the call to the accounting extension, paying the disputer +// _mockAndExpect( +// address(accountingExtension), +// abi.encodeCall(accountingExtension.pay, (_requestId, _proposer, _disputer, _token, _bondSize)), +// abi.encode() +// ); + +// // Mock and expect the call to the oracle, proposing the correct response with the disputer as the new proposer +// _mockAndExpect( +// address(oracle), +// abi.encodeWithSignature( +// 'proposeResponse(address,bytes32,bytes)', _disputer, _requestId, abi.encode(_encodedCorrectResponse) +// ), +// abi.encode(_correctResponseId) +// ); + +// // Mock and expect the call to the oracle, finalizing the request with the correct response +// _mockAndExpect( +// address(oracle), +// abi.encodeWithSignature('finalize(bytes32,bytes32)', _requestId, _correctResponseId), +// abi.encode() +// ); + +// // Populate the mock dispute with the correct values +// mockDispute.status = IOracle.DisputeStatus.Won; +// mockDispute.responseId = _responseId; +// mockDispute.requestId = _requestId; +// mockDispute.disputer = _disputer; +// mockDispute.proposer = _proposer; + +// vm.prank(address(oracle)); +// circuitResolverModule.onDisputeStatusChange(bytes32(0), mockDispute); +// } +// } + +// contract CircuitResolverModule_Unit_OnDisputeStatusChange is BaseTest { +// function test_eventEmitted(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { +// vm.assume(_requestId != _responseId); + +// bytes memory _encodedCorrectResponse = abi.encode(true); + +// // Mock request data +// bytes memory _requestData = abi.encode( +// ICircuitResolverModule.RequestParameters({ +// callData: _callData, +// verifier: circuitVerifier, +// accountingExtension: accountingExtension, +// bondToken: IERC20(_token), +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request +// circuitResolverModule.forTest_setRequestData(_requestId, _requestData); +// circuitResolverModule.forTest_setCorrectResponse(_requestId, _encodedCorrectResponse); + +// // Create new Response memory struct with random values +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// proposer: _proposer, +// requestId: _requestId, +// disputeId: mockId, +// response: _encodedCorrectResponse +// }); + +// // Mock and expect the call to the oracle, getting the response +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the call to the oracle, finalizing the request +// _mockAndExpect( +// address(oracle), abi.encodeWithSignature('finalize(bytes32,bytes32)', _requestId, _responseId), abi.encode() +// ); + +// // Populate the mock dispute with the correct values +// mockDispute.status = IOracle.DisputeStatus.Lost; +// mockDispute.responseId = _responseId; +// mockDispute.requestId = _requestId; + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(circuitResolverModule)); +// emit DisputeStatusChanged( +// _requestId, _responseId, mockDispute.disputer, mockDispute.proposer, IOracle.DisputeStatus.Lost +// ); + +// vm.prank(address(oracle)); +// circuitResolverModule.onDisputeStatusChange(bytes32(0), mockDispute); +// } +// } diff --git a/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol b/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol index 44aeb027..21ec848d 100644 --- a/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol +++ b/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol @@ -1,356 +1,356 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - RootVerificationModule, - IRootVerificationModule -} from '../../../../contracts/modules/dispute/RootVerificationModule.sol'; - -import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; -import {ITreeVerifier} from '../../../../interfaces/ITreeVerifier.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ -contract ForTest_RootVerificationModule is RootVerificationModule { - constructor(IOracle _oracle) RootVerificationModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } -} - -/** - * @title Root Verification Module Unit tests - */ -contract BaseTest is Test, Helpers { - // The target contract - ForTest_RootVerificationModule public rootVerificationModule; - // A mock oracle - IOracle public oracle; - // A mock accounting extension - IAccountingExtension public accountingExtension; - // Some unnoticeable dude - address public dude = makeAddr('dude'); - // 100% random sequence of bytes representing request, response, or dispute id - bytes32 public mockId = bytes32('69'); - // Create a new dummy dispute - IOracle.Dispute public mockDispute; - // A mock tree verifier - ITreeVerifier public treeVerifier; - // Mock addresses - IERC20 public _token = IERC20(makeAddr('token')); - address public _disputer = makeAddr('disputer'); - address public _proposer = makeAddr('proposer'); - - // Mock request data - bytes32[32] internal _treeBranches = [ - bytes32('branch1'), - bytes32('branch2'), - bytes32('branch3'), - bytes32('branch4'), - bytes32('branch5'), - bytes32('branch6'), - bytes32('branch7'), - bytes32('branch8'), - bytes32('branch9'), - bytes32('branch10'), - bytes32('branch11'), - bytes32('branch12'), - bytes32('branch13'), - bytes32('branch14'), - bytes32('branch15'), - bytes32('branch16'), - bytes32('branch17'), - bytes32('branch18'), - bytes32('branch19'), - bytes32('branch20'), - bytes32('branch21'), - bytes32('branch22'), - bytes32('branch23'), - bytes32('branch24'), - bytes32('branch25'), - bytes32('branch26'), - bytes32('branch27'), - bytes32('branch28'), - bytes32('branch29'), - bytes32('branch30'), - bytes32('branch31'), - bytes32('branch32') - ]; - uint256 internal _treeCount = 1; - bytes internal _treeData = abi.encode(_treeBranches, _treeCount); - bytes32[] internal _leavesToInsert = [bytes32('leave1'), bytes32('leave2')]; - - event ResponseDisputed(bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - accountingExtension = IAccountingExtension(makeAddr('AccountingExtension')); - vm.etch(address(accountingExtension), hex'069420'); - treeVerifier = ITreeVerifier(makeAddr('TreeVerifier')); - vm.etch(address(treeVerifier), hex'069420'); - - rootVerificationModule = new ForTest_RootVerificationModule(oracle); - - mockDispute = IOracle.Dispute({ - createdAt: block.timestamp, - disputer: dude, - responseId: mockId, - proposer: dude, - requestId: mockId, - status: IOracle.DisputeStatus.Active - }); - } -} - -contract RootVerificationModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleNameReturnsName() public { - assertEq(rootVerificationModule.moduleName(), 'RootVerificationModule'); - } - - /** - * @notice Test that the decodeRequestData function returns the correct values - */ - function test_decodeRequestData_returnsCorrectData( - bytes32 _requestId, - address _accountingExtension, - address _randomToken, - uint256 _bondSize - ) public { - // Mock data - bytes memory _requestData = abi.encode( - IRootVerificationModule.RequestParameters({ - treeData: _treeData, - leavesToInsert: _leavesToInsert, - treeVerifier: treeVerifier, - accountingExtension: IAccountingExtension(_accountingExtension), - bondToken: IERC20(_randomToken), - bondSize: _bondSize - }) - ); - - // Store the mock request - rootVerificationModule.forTest_setRequestData(_requestId, _requestData); - - IRootVerificationModule.RequestParameters memory _params = rootVerificationModule.decodeRequestData(_requestId); - - bytes32[32] memory _treeBranchesStored; - uint256 _treeCountStored; - (_treeBranchesStored, _treeCountStored) = abi.decode(_params.treeData, (bytes32[32], uint256)); - - // Check: is the request data properly stored? - for (uint256 _i = 0; _i < _treeBranches.length; _i++) { - assertEq(_treeBranchesStored[_i], _treeBranches[_i], 'Mismatch: decoded tree branch'); - } - for (uint256 _i = 0; _i < _leavesToInsert.length; _i++) { - assertEq(_params.leavesToInsert[_i], _leavesToInsert[_i], 'Mismatch: decoded leave to insert'); - } - assertEq(_treeCountStored, _treeCount, 'Mismatch: decoded tree count'); - assertEq(address(_params.treeVerifier), address(treeVerifier), 'Mismatch: decoded tree verifier'); - assertEq(address(_params.accountingExtension), _accountingExtension, 'Mismatch: decoded accounting extension'); - assertEq(address(_params.bondToken), _randomToken, 'Mismatch: decoded token'); - assertEq(_params.bondSize, _bondSize, 'Mismatch: decoded bond size'); - } -} - -contract RootVerificationModule_Unit_DisputeResponse is BaseTest { - /** - * @notice Test if dispute incorrect response returns the correct status - */ - function test_disputeIncorrectResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { - vm.assume(_requestId != _responseId); - - // Mock request data - bytes memory _requestData = abi.encode( - IRootVerificationModule.RequestParameters({ - treeData: _treeData, - leavesToInsert: _leavesToInsert, - treeVerifier: treeVerifier, - accountingExtension: accountingExtension, - bondToken: _token, - bondSize: _bondSize - }) - ); - - // Store the mock request - rootVerificationModule.forTest_setRequestData(_requestId, _requestData); - - // Create new Response memory struct with random values - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - proposer: _proposer, - requestId: _requestId, - disputeId: mockId, - response: abi.encode(bytes32('randomRoot')) - }); - - // Mock and expect the call to the oracle, getting the response - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the call to the tree verifier, calculating the root - _mockAndExpect( - address(treeVerifier), - abi.encodeCall(ITreeVerifier.calculateRoot, (_treeData, _leavesToInsert)), - abi.encode(bytes32('randomRoot2')) - ); - - vm.prank(address(oracle)); - IOracle.Dispute memory _dispute = - rootVerificationModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); - - // Check: is the dispute data properly stored? - assertEq(_dispute.disputer, _disputer, 'Mismatch: disputer'); - assertEq(_dispute.proposer, _proposer, 'Mismatch: proposer'); - assertEq(_dispute.responseId, _responseId, 'Mismatch: responseId'); - assertEq(_dispute.requestId, _requestId, 'Mismatch: requestId'); - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won), 'Mismatch: status'); - assertEq(_dispute.createdAt, block.timestamp, 'Mismatch: createdAt'); - } - - function test_emitsEvent(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { - vm.assume(_requestId != _responseId); - - // Mock request data - bytes memory _requestData = abi.encode( - IRootVerificationModule.RequestParameters({ - treeData: _treeData, - leavesToInsert: _leavesToInsert, - treeVerifier: treeVerifier, - accountingExtension: accountingExtension, - bondToken: _token, - bondSize: _bondSize - }) - ); - - // Store the mock request - rootVerificationModule.forTest_setRequestData(_requestId, _requestData); - - // Create new Response memory struct with random values - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - proposer: _proposer, - requestId: _requestId, - disputeId: mockId, - response: abi.encode(bytes32('randomRoot')) - }); - - // Mock and expect the call to the oracle, getting the response - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the call to the tree verifier, calculating the root - _mockAndExpect( - address(treeVerifier), - abi.encodeCall(ITreeVerifier.calculateRoot, (_treeData, _leavesToInsert)), - abi.encode(bytes32('randomRoot2')) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(rootVerificationModule)); - emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); - - vm.prank(address(oracle)); - rootVerificationModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); - } - - /** - * @notice Test if dispute correct response returns the correct status - */ - function test_disputeCorrectResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { - vm.assume(_requestId != _responseId); - - bytes memory _encodedCorrectRoot = abi.encode(bytes32('randomRoot')); - - // Mock request data - bytes memory _requestData = abi.encode( - IRootVerificationModule.RequestParameters({ - treeData: _treeData, - leavesToInsert: _leavesToInsert, - treeVerifier: treeVerifier, - accountingExtension: accountingExtension, - bondToken: _token, - bondSize: _bondSize - }) - ); - - // Store the mock request - rootVerificationModule.forTest_setRequestData(_requestId, _requestData); - - // Create new Response memory struct with random values - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - proposer: _proposer, - requestId: _requestId, - disputeId: mockId, - response: _encodedCorrectRoot - }); - - // Mock and expect the call to the oracle, getting the response - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); - - // Mock and expect the call to the tree verifier, calculating the root - _mockAndExpect( - address(treeVerifier), - abi.encodeCall(ITreeVerifier.calculateRoot, (_treeData, _leavesToInsert)), - _encodedCorrectRoot - ); - - vm.prank(address(oracle)); - IOracle.Dispute memory _dispute = - rootVerificationModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); - - // Check: is the dispute data properly stored? - assertEq(_dispute.disputer, _disputer, 'Mismatch: disputer'); - assertEq(_dispute.proposer, _proposer, 'Mismatch: proposer'); - assertEq(_dispute.responseId, _responseId, 'Mismatch: responseId'); - assertEq(_dispute.requestId, _requestId, 'Mismatch: requestId'); - assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Lost), 'Mismatch: status'); - assertEq(_dispute.createdAt, block.timestamp, 'Mismatch: createdAt'); - } - - /** - * @notice Test if dispute response reverts when called by caller who's not the oracle - */ - function test_revertWrongCaller(address _randomCaller) public { - vm.assume(_randomCaller != address(oracle)); - - // Check: revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(_randomCaller); - rootVerificationModule.disputeResponse(mockId, mockId, dude, dude); - } -} - -contract RootVerificationModule_Unit_DisputeEscalated is BaseTest { - /** - * @notice Test if dispute escalated do nothing - */ - function test_returnCorrectStatus() public { - // Record sstore and sload - vm.prank(address(oracle)); - vm.record(); - rootVerificationModule.disputeEscalated(mockId); - (bytes32[] memory _reads, bytes32[] memory _writes) = vm.accesses(address(rootVerificationModule)); - - // Check: no storage access? - assertEq(_reads.length, 0); - assertEq(_writes.length, 0); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// RootVerificationModule, +// IRootVerificationModule +// } from '../../../../contracts/modules/dispute/RootVerificationModule.sol'; + +// import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; +// import {ITreeVerifier} from '../../../../interfaces/ITreeVerifier.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ +// contract ForTest_RootVerificationModule is RootVerificationModule { +// constructor(IOracle _oracle) RootVerificationModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } +// } + +// /** +// * @title Root Verification Module Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_RootVerificationModule public rootVerificationModule; +// // A mock oracle +// IOracle public oracle; +// // A mock accounting extension +// IAccountingExtension public accountingExtension; +// // Some unnoticeable dude +// address public dude = makeAddr('dude'); +// // 100% random sequence of bytes representing request, response, or dispute id +// bytes32 public mockId = bytes32('69'); +// // Create a new dummy dispute +// IOracle.Dispute public mockDispute; +// // A mock tree verifier +// ITreeVerifier public treeVerifier; +// // Mock addresses +// IERC20 public _token = IERC20(makeAddr('token')); +// address public _disputer = makeAddr('disputer'); +// address public _proposer = makeAddr('proposer'); + +// // Mock request data +// bytes32[32] internal _treeBranches = [ +// bytes32('branch1'), +// bytes32('branch2'), +// bytes32('branch3'), +// bytes32('branch4'), +// bytes32('branch5'), +// bytes32('branch6'), +// bytes32('branch7'), +// bytes32('branch8'), +// bytes32('branch9'), +// bytes32('branch10'), +// bytes32('branch11'), +// bytes32('branch12'), +// bytes32('branch13'), +// bytes32('branch14'), +// bytes32('branch15'), +// bytes32('branch16'), +// bytes32('branch17'), +// bytes32('branch18'), +// bytes32('branch19'), +// bytes32('branch20'), +// bytes32('branch21'), +// bytes32('branch22'), +// bytes32('branch23'), +// bytes32('branch24'), +// bytes32('branch25'), +// bytes32('branch26'), +// bytes32('branch27'), +// bytes32('branch28'), +// bytes32('branch29'), +// bytes32('branch30'), +// bytes32('branch31'), +// bytes32('branch32') +// ]; +// uint256 internal _treeCount = 1; +// bytes internal _treeData = abi.encode(_treeBranches, _treeCount); +// bytes32[] internal _leavesToInsert = [bytes32('leave1'), bytes32('leave2')]; + +// event ResponseDisputed(bytes32 indexed _requestId, bytes32 _responseId, address _disputer, address _proposer); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// accountingExtension = IAccountingExtension(makeAddr('AccountingExtension')); +// vm.etch(address(accountingExtension), hex'069420'); +// treeVerifier = ITreeVerifier(makeAddr('TreeVerifier')); +// vm.etch(address(treeVerifier), hex'069420'); + +// rootVerificationModule = new ForTest_RootVerificationModule(oracle); + +// mockDispute = IOracle.Dispute({ +// createdAt: block.timestamp, +// disputer: dude, +// responseId: mockId, +// proposer: dude, +// requestId: mockId, +// status: IOracle.DisputeStatus.Active +// }); +// } +// } + +// contract RootVerificationModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleNameReturnsName() public { +// assertEq(rootVerificationModule.moduleName(), 'RootVerificationModule'); +// } + +// /** +// * @notice Test that the decodeRequestData function returns the correct values +// */ +// function test_decodeRequestData_returnsCorrectData( +// bytes32 _requestId, +// address _accountingExtension, +// address _randomToken, +// uint256 _bondSize +// ) public { +// // Mock data +// bytes memory _requestData = abi.encode( +// IRootVerificationModule.RequestParameters({ +// treeData: _treeData, +// leavesToInsert: _leavesToInsert, +// treeVerifier: treeVerifier, +// accountingExtension: IAccountingExtension(_accountingExtension), +// bondToken: IERC20(_randomToken), +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request +// rootVerificationModule.forTest_setRequestData(_requestId, _requestData); + +// IRootVerificationModule.RequestParameters memory _params = rootVerificationModule.decodeRequestData(_requestId); + +// bytes32[32] memory _treeBranchesStored; +// uint256 _treeCountStored; +// (_treeBranchesStored, _treeCountStored) = abi.decode(_params.treeData, (bytes32[32], uint256)); + +// // Check: is the request data properly stored? +// for (uint256 _i = 0; _i < _treeBranches.length; _i++) { +// assertEq(_treeBranchesStored[_i], _treeBranches[_i], 'Mismatch: decoded tree branch'); +// } +// for (uint256 _i = 0; _i < _leavesToInsert.length; _i++) { +// assertEq(_params.leavesToInsert[_i], _leavesToInsert[_i], 'Mismatch: decoded leave to insert'); +// } +// assertEq(_treeCountStored, _treeCount, 'Mismatch: decoded tree count'); +// assertEq(address(_params.treeVerifier), address(treeVerifier), 'Mismatch: decoded tree verifier'); +// assertEq(address(_params.accountingExtension), _accountingExtension, 'Mismatch: decoded accounting extension'); +// assertEq(address(_params.bondToken), _randomToken, 'Mismatch: decoded token'); +// assertEq(_params.bondSize, _bondSize, 'Mismatch: decoded bond size'); +// } +// } + +// contract RootVerificationModule_Unit_DisputeResponse is BaseTest { +// /** +// * @notice Test if dispute incorrect response returns the correct status +// */ +// function test_disputeIncorrectResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { +// vm.assume(_requestId != _responseId); + +// // Mock request data +// bytes memory _requestData = abi.encode( +// IRootVerificationModule.RequestParameters({ +// treeData: _treeData, +// leavesToInsert: _leavesToInsert, +// treeVerifier: treeVerifier, +// accountingExtension: accountingExtension, +// bondToken: _token, +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request +// rootVerificationModule.forTest_setRequestData(_requestId, _requestData); + +// // Create new Response memory struct with random values +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// proposer: _proposer, +// requestId: _requestId, +// disputeId: mockId, +// response: abi.encode(bytes32('randomRoot')) +// }); + +// // Mock and expect the call to the oracle, getting the response +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the call to the tree verifier, calculating the root +// _mockAndExpect( +// address(treeVerifier), +// abi.encodeCall(ITreeVerifier.calculateRoot, (_treeData, _leavesToInsert)), +// abi.encode(bytes32('randomRoot2')) +// ); + +// vm.prank(address(oracle)); +// IOracle.Dispute memory _dispute = +// rootVerificationModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); + +// // Check: is the dispute data properly stored? +// assertEq(_dispute.disputer, _disputer, 'Mismatch: disputer'); +// assertEq(_dispute.proposer, _proposer, 'Mismatch: proposer'); +// assertEq(_dispute.responseId, _responseId, 'Mismatch: responseId'); +// assertEq(_dispute.requestId, _requestId, 'Mismatch: requestId'); +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Won), 'Mismatch: status'); +// assertEq(_dispute.createdAt, block.timestamp, 'Mismatch: createdAt'); +// } + +// function test_emitsEvent(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { +// vm.assume(_requestId != _responseId); + +// // Mock request data +// bytes memory _requestData = abi.encode( +// IRootVerificationModule.RequestParameters({ +// treeData: _treeData, +// leavesToInsert: _leavesToInsert, +// treeVerifier: treeVerifier, +// accountingExtension: accountingExtension, +// bondToken: _token, +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request +// rootVerificationModule.forTest_setRequestData(_requestId, _requestData); + +// // Create new Response memory struct with random values +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// proposer: _proposer, +// requestId: _requestId, +// disputeId: mockId, +// response: abi.encode(bytes32('randomRoot')) +// }); + +// // Mock and expect the call to the oracle, getting the response +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the call to the tree verifier, calculating the root +// _mockAndExpect( +// address(treeVerifier), +// abi.encodeCall(ITreeVerifier.calculateRoot, (_treeData, _leavesToInsert)), +// abi.encode(bytes32('randomRoot2')) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(rootVerificationModule)); +// emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); + +// vm.prank(address(oracle)); +// rootVerificationModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); +// } + +// /** +// * @notice Test if dispute correct response returns the correct status +// */ +// function test_disputeCorrectResponse(bytes32 _requestId, bytes32 _responseId, uint256 _bondSize) public { +// vm.assume(_requestId != _responseId); + +// bytes memory _encodedCorrectRoot = abi.encode(bytes32('randomRoot')); + +// // Mock request data +// bytes memory _requestData = abi.encode( +// IRootVerificationModule.RequestParameters({ +// treeData: _treeData, +// leavesToInsert: _leavesToInsert, +// treeVerifier: treeVerifier, +// accountingExtension: accountingExtension, +// bondToken: _token, +// bondSize: _bondSize +// }) +// ); + +// // Store the mock request +// rootVerificationModule.forTest_setRequestData(_requestId, _requestData); + +// // Create new Response memory struct with random values +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// proposer: _proposer, +// requestId: _requestId, +// disputeId: mockId, +// response: _encodedCorrectRoot +// }); + +// // Mock and expect the call to the oracle, getting the response +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponse, (_responseId)), abi.encode(_mockResponse)); + +// // Mock and expect the call to the tree verifier, calculating the root +// _mockAndExpect( +// address(treeVerifier), +// abi.encodeCall(ITreeVerifier.calculateRoot, (_treeData, _leavesToInsert)), +// _encodedCorrectRoot +// ); + +// vm.prank(address(oracle)); +// IOracle.Dispute memory _dispute = +// rootVerificationModule.disputeResponse(_requestId, _responseId, _disputer, _proposer); + +// // Check: is the dispute data properly stored? +// assertEq(_dispute.disputer, _disputer, 'Mismatch: disputer'); +// assertEq(_dispute.proposer, _proposer, 'Mismatch: proposer'); +// assertEq(_dispute.responseId, _responseId, 'Mismatch: responseId'); +// assertEq(_dispute.requestId, _requestId, 'Mismatch: requestId'); +// assertEq(uint256(_dispute.status), uint256(IOracle.DisputeStatus.Lost), 'Mismatch: status'); +// assertEq(_dispute.createdAt, block.timestamp, 'Mismatch: createdAt'); +// } + +// /** +// * @notice Test if dispute response reverts when called by caller who's not the oracle +// */ +// function test_revertWrongCaller(address _randomCaller) public { +// vm.assume(_randomCaller != address(oracle)); + +// // Check: revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(_randomCaller); +// rootVerificationModule.disputeResponse(mockId, mockId, dude, dude); +// } +// } + +// contract RootVerificationModule_Unit_DisputeEscalated is BaseTest { +// /** +// * @notice Test if dispute escalated do nothing +// */ +// function test_returnCorrectStatus() public { +// // Record sstore and sload +// vm.prank(address(oracle)); +// vm.record(); +// rootVerificationModule.disputeEscalated(mockId); +// (bytes32[] memory _reads, bytes32[] memory _writes) = vm.accesses(address(rootVerificationModule)); + +// // Check: no storage access? +// assertEq(_reads.length, 0); +// assertEq(_writes.length, 0); +// } +// } diff --git a/solidity/test/unit/modules/finality/CallbackModule.t.sol b/solidity/test/unit/modules/finality/CallbackModule.t.sol index 62793c8b..77bf4c8a 100644 --- a/solidity/test/unit/modules/finality/CallbackModule.t.sol +++ b/solidity/test/unit/modules/finality/CallbackModule.t.sol @@ -1,147 +1,147 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import {CallbackModule, ICallbackModule} from '../../../../contracts/modules/finality/CallbackModule.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ -contract ForTest_CallbackModule is CallbackModule { - constructor(IOracle _oracle) CallbackModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } -} - -/** - * @title Callback Module Unit tests - */ -contract BaseTest is Test, Helpers { - // The target contract - ForTest_CallbackModule public callbackModule; - // A mock oracle - IOracle public oracle; - - event Callback(bytes32 indexed _request, address indexed _target, bytes _data); - event RequestFinalized(bytes32 indexed _requestId, address _finalizer); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - callbackModule = new ForTest_CallbackModule(oracle); - } -} - -contract CallbackModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleNameReturnsName() public { - assertEq(callbackModule.moduleName(), 'CallbackModule'); - } - - /** - * @notice Test that the decodeRequestData function returns the correct values - */ - function test_decodeRequestData(bytes32 _requestId, address _target, bytes memory _data) public { - // Create and set some mock request data - bytes memory _requestData = abi.encode(ICallbackModule.RequestParameters({target: _target, data: _data})); - callbackModule.forTest_setRequestData(_requestId, _requestData); - - // Decode the given request data - ICallbackModule.RequestParameters memory _params = callbackModule.decodeRequestData(_requestId); - - // Check: decoded values match original values? - assertEq(_params.target, _target); - assertEq(_params.data, _data); - } -} - -contract CallbackModule_Unit_FinalizeRequest is BaseTest { - /** - * @notice Test that finalizeRequest calls the _target.callback with the correct data - */ - function test_triggersCallback( - bytes32 _requestId, - address _target, - bytes calldata _data - ) public assumeFuzzable(_target) { - vm.assume(_target != address(vm)); - - // Create and set some mock request data - bytes memory _requestData = abi.encode(ICallbackModule.RequestParameters({target: _target, data: _data})); - callbackModule.forTest_setRequestData(_requestId, _requestData); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(callbackModule)); - emit Callback(_requestId, _target, _data); - - vm.prank(address(oracle)); - callbackModule.finalizeRequest(_requestId, address(oracle)); - } - - function test_emitsEvent(bytes32 _requestId, address _target, bytes calldata _data) public assumeFuzzable(_target) { - vm.assume(_target != address(vm)); - - // Create and set some mock request data - bytes memory _requestData = abi.encode(ICallbackModule.RequestParameters({target: _target, data: _data})); - callbackModule.forTest_setRequestData(_requestId, _requestData); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(callbackModule)); - emit RequestFinalized(_requestId, address(oracle)); - - vm.prank(address(oracle)); - callbackModule.finalizeRequest(_requestId, address(oracle)); - } - - /** - * @notice Test that the finalizeRequest reverts if caller is not the oracle - */ - function test_revertsIfWrongCaller(bytes32 _requestId, address _caller) public { - vm.assume(_caller != address(oracle)); - - // Check: does it revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(_caller); - callbackModule.finalizeRequest(_requestId, address(_caller)); - } -} - -contract CallbackModule_Unit_Setup is BaseTest { - /** - * @notice Test that _afterSetupRequest checks if the target address is a contract. - */ - function test_revertIfTargetNotContract( - bytes32 _requestId, - address _target, - bool _hasCode, - bytes calldata _data - ) public assumeFuzzable(_target) { - vm.assume(_target.code.length == 0); - bytes memory _requestData = abi.encode(ICallbackModule.RequestParameters({target: _target, data: _data})); - - if (_hasCode) { - vm.etch(_target, hex'069420'); - } else { - // Check: does it revert if the target has no code? - vm.expectRevert(ICallbackModule.CallbackModule_TargetHasNoCode.selector); - } - - vm.prank(address(oracle)); - callbackModule.setupRequest(_requestId, _requestData); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import {CallbackModule, ICallbackModule} from '../../../../contracts/modules/finality/CallbackModule.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ +// contract ForTest_CallbackModule is CallbackModule { +// constructor(IOracle _oracle) CallbackModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } +// } + +// /** +// * @title Callback Module Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_CallbackModule public callbackModule; +// // A mock oracle +// IOracle public oracle; + +// event Callback(bytes32 indexed _request, address indexed _target, bytes _data); +// event RequestFinalized(bytes32 indexed _requestId, address _finalizer); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// callbackModule = new ForTest_CallbackModule(oracle); +// } +// } + +// contract CallbackModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleNameReturnsName() public { +// assertEq(callbackModule.moduleName(), 'CallbackModule'); +// } + +// /** +// * @notice Test that the decodeRequestData function returns the correct values +// */ +// function test_decodeRequestData(bytes32 _requestId, address _target, bytes memory _data) public { +// // Create and set some mock request data +// bytes memory _requestData = abi.encode(ICallbackModule.RequestParameters({target: _target, data: _data})); +// callbackModule.forTest_setRequestData(_requestId, _requestData); + +// // Decode the given request data +// ICallbackModule.RequestParameters memory _params = callbackModule.decodeRequestData(_requestId); + +// // Check: decoded values match original values? +// assertEq(_params.target, _target); +// assertEq(_params.data, _data); +// } +// } + +// contract CallbackModule_Unit_FinalizeRequest is BaseTest { +// /** +// * @notice Test that finalizeRequest calls the _target.callback with the correct data +// */ +// function test_triggersCallback( +// bytes32 _requestId, +// address _target, +// bytes calldata _data +// ) public assumeFuzzable(_target) { +// vm.assume(_target != address(vm)); + +// // Create and set some mock request data +// bytes memory _requestData = abi.encode(ICallbackModule.RequestParameters({target: _target, data: _data})); +// callbackModule.forTest_setRequestData(_requestId, _requestData); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(callbackModule)); +// emit Callback(_requestId, _target, _data); + +// vm.prank(address(oracle)); +// callbackModule.finalizeRequest(_requestId, address(oracle)); +// } + +// function test_emitsEvent(bytes32 _requestId, address _target, bytes calldata _data) public assumeFuzzable(_target) { +// vm.assume(_target != address(vm)); + +// // Create and set some mock request data +// bytes memory _requestData = abi.encode(ICallbackModule.RequestParameters({target: _target, data: _data})); +// callbackModule.forTest_setRequestData(_requestId, _requestData); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(callbackModule)); +// emit RequestFinalized(_requestId, address(oracle)); + +// vm.prank(address(oracle)); +// callbackModule.finalizeRequest(_requestId, address(oracle)); +// } + +// /** +// * @notice Test that the finalizeRequest reverts if caller is not the oracle +// */ +// function test_revertsIfWrongCaller(bytes32 _requestId, address _caller) public { +// vm.assume(_caller != address(oracle)); + +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(_caller); +// callbackModule.finalizeRequest(_requestId, address(_caller)); +// } +// } + +// contract CallbackModule_Unit_Setup is BaseTest { +// /** +// * @notice Test that _afterSetupRequest checks if the target address is a contract. +// */ +// function test_revertIfTargetNotContract( +// bytes32 _requestId, +// address _target, +// bool _hasCode, +// bytes calldata _data +// ) public assumeFuzzable(_target) { +// vm.assume(_target.code.length == 0); +// bytes memory _requestData = abi.encode(ICallbackModule.RequestParameters({target: _target, data: _data})); + +// if (_hasCode) { +// vm.etch(_target, hex'069420'); +// } else { +// // Check: does it revert if the target has no code? +// vm.expectRevert(ICallbackModule.CallbackModule_TargetHasNoCode.selector); +// } + +// vm.prank(address(oracle)); +// callbackModule.setupRequest(_requestId, _requestData); +// } +// } diff --git a/solidity/test/unit/modules/finality/MultipleCallbacksModule.t.sol b/solidity/test/unit/modules/finality/MultipleCallbacksModule.t.sol index 98e96015..3e888cf2 100644 --- a/solidity/test/unit/modules/finality/MultipleCallbacksModule.t.sol +++ b/solidity/test/unit/modules/finality/MultipleCallbacksModule.t.sol @@ -1,156 +1,156 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - MultipleCallbacksModule, - IMultipleCallbacksModule -} from '../../../../contracts/modules/finality/MultipleCallbacksModule.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ -contract ForTest_MultipleCallbacksModule is MultipleCallbacksModule { - constructor(IOracle _oracle) MultipleCallbacksModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, address[] calldata _targets, bytes[] calldata _data) public { - requestData[_requestId] = abi.encode(IMultipleCallbacksModule.RequestParameters({targets: _targets, data: _data})); - } -} - -contract BaseTest is Test, Helpers { - // The target contract - ForTest_MultipleCallbacksModule public multipleCallbackModule; - // A mock oracle - IOracle public oracle; - - event Callback(bytes32 indexed _request, address indexed _target, bytes _data); - event RequestFinalized(bytes32 indexed _requestId, address _finalizer); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - multipleCallbackModule = new ForTest_MultipleCallbacksModule(oracle); - } -} - -/** - * @title MultipleCallback Module Unit tests - */ -contract MultipleCallbacksModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleNameReturnsName() public { - assertEq(multipleCallbackModule.moduleName(), 'MultipleCallbacksModule'); - } -} - -contract MultipleCallbacksModule_Unit_FinalizeRequests is BaseTest { - /** - * @notice Test that finalizeRequests calls the _target.callback with the correct data - */ - function test_finalizeRequest(bytes32 _requestId, address[1] calldata _targets, bytes[1] calldata __data) public { - address _target = _targets[0]; - bytes calldata _data = __data[0]; - - assumeNotPrecompile(_target); - vm.assume(_target != address(vm)); - - // Create and set some mock request data - address[] memory _targetParams = new address[](1); - _targetParams[0] = _targets[0]; - bytes[] memory _dataParams = new bytes[](1); - _dataParams[0] = __data[0]; - multipleCallbackModule.forTest_setRequestData(_requestId, _targetParams, _dataParams); - - _mockAndExpect(_target, _data, abi.encode()); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(multipleCallbackModule)); - emit Callback(_requestId, _target, _data); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(multipleCallbackModule)); - emit RequestFinalized(_requestId, address(oracle)); - - vm.prank(address(oracle)); - multipleCallbackModule.finalizeRequest(_requestId, address(oracle)); - } - - /** - * @notice Test that the finalizeRequests reverts if caller is not the oracle - */ - function test_revertsIfWrongCaller(bytes32 _requestId, address _caller) public { - vm.assume(_caller != address(oracle)); - - // Check: does it revert if not called by the Oracle? - vm.expectRevert(IModule.Module_OnlyOracle.selector); - vm.prank(_caller); - multipleCallbackModule.finalizeRequest(_requestId, address(_caller)); - } - - function test_revertIfInvalidParameters(bytes32 _requestId, address[] memory _targets, bytes[] memory _data) public { - vm.assume(_targets.length != _data.length); - - bytes memory _requestData = abi.encode(IMultipleCallbacksModule.RequestParameters({targets: _targets, data: _data})); - - // Check: does it revert if arrays length mismatch? - vm.expectRevert(IMultipleCallbacksModule.MultipleCallbackModule_InvalidParameters.selector); - vm.prank(address(oracle)); - multipleCallbackModule.setupRequest(_requestId, _requestData); - } -} - -contract MultipleCallbacksModule_Unit_Setup is BaseTest { - function test_revertsIfInvalidTarget(bytes32 _requestId, address[] memory _targets, bytes memory _data) public { - vm.assume(_targets.length > 1); - - // Hardcoding data (as it is not the case tested) to avoid vm.assume issues - bytes[] memory _targetData = new bytes[](_targets.length); - for (uint256 _i = 0; _i < _targets.length; _i++) { - _targetData[_i] = abi.encodeWithSelector(bytes4(keccak256('callback(bytes32,bytes)')), _requestId, _data); - } - - bytes memory _requestData = - abi.encode(IMultipleCallbacksModule.RequestParameters({targets: _targets, data: _targetData})); - - // Check: does it revert if the target has no code? - vm.expectRevert(IMultipleCallbacksModule.MultipleCallbackModule_TargetHasNoCode.selector); - vm.prank(address(oracle)); - multipleCallbackModule.setupRequest(_requestId, _requestData); - } - - function test_setUpMultipleTargets(bytes32 _requestId, address[] memory _targets, bytes memory _data) public { - vm.assume(_targets.length > 1); - - // Hardcoding data (as it is not the case tested) to avoid vm.assume issues - bytes[] memory _targetData = new bytes[](_targets.length); - for (uint256 _i = 0; _i < _targets.length; _i++) { - _assumeFuzzable(_targets[_i]); - vm.etch(_targets[_i], hex'069420'); - _targetData[_i] = abi.encodeWithSelector(bytes4(keccak256('callback(bytes32,bytes)')), _requestId, _data); - } - - bytes memory _requestData = - abi.encode(IMultipleCallbacksModule.RequestParameters({targets: _targets, data: _targetData})); - - vm.prank(address(oracle)); - multipleCallbackModule.setupRequest(_requestId, _requestData); - - IMultipleCallbacksModule.RequestParameters memory _storedParams = - multipleCallbackModule.decodeRequestData(_requestId); - // Check: is the data properly stored? - assertEq(_storedParams.targets, _targets); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// MultipleCallbacksModule, +// IMultipleCallbacksModule +// } from '../../../../contracts/modules/finality/MultipleCallbacksModule.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ +// contract ForTest_MultipleCallbacksModule is MultipleCallbacksModule { +// constructor(IOracle _oracle) MultipleCallbacksModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, address[] calldata _targets, bytes[] calldata _data) public { +// requestData[_requestId] = abi.encode(IMultipleCallbacksModule.RequestParameters({targets: _targets, data: _data})); +// } +// } + +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_MultipleCallbacksModule public multipleCallbackModule; +// // A mock oracle +// IOracle public oracle; + +// event Callback(bytes32 indexed _request, address indexed _target, bytes _data); +// event RequestFinalized(bytes32 indexed _requestId, address _finalizer); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// multipleCallbackModule = new ForTest_MultipleCallbacksModule(oracle); +// } +// } + +// /** +// * @title MultipleCallback Module Unit tests +// */ +// contract MultipleCallbacksModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleNameReturnsName() public { +// assertEq(multipleCallbackModule.moduleName(), 'MultipleCallbacksModule'); +// } +// } + +// contract MultipleCallbacksModule_Unit_FinalizeRequests is BaseTest { +// /** +// * @notice Test that finalizeRequests calls the _target.callback with the correct data +// */ +// function test_finalizeRequest(bytes32 _requestId, address[1] calldata _targets, bytes[1] calldata __data) public { +// address _target = _targets[0]; +// bytes calldata _data = __data[0]; + +// assumeNotPrecompile(_target); +// vm.assume(_target != address(vm)); + +// // Create and set some mock request data +// address[] memory _targetParams = new address[](1); +// _targetParams[0] = _targets[0]; +// bytes[] memory _dataParams = new bytes[](1); +// _dataParams[0] = __data[0]; +// multipleCallbackModule.forTest_setRequestData(_requestId, _targetParams, _dataParams); + +// _mockAndExpect(_target, _data, abi.encode()); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(multipleCallbackModule)); +// emit Callback(_requestId, _target, _data); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(multipleCallbackModule)); +// emit RequestFinalized(_requestId, address(oracle)); + +// vm.prank(address(oracle)); +// multipleCallbackModule.finalizeRequest(_requestId, address(oracle)); +// } + +// /** +// * @notice Test that the finalizeRequests reverts if caller is not the oracle +// */ +// function test_revertsIfWrongCaller(bytes32 _requestId, address _caller) public { +// vm.assume(_caller != address(oracle)); + +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(IModule.Module_OnlyOracle.selector); +// vm.prank(_caller); +// multipleCallbackModule.finalizeRequest(_requestId, address(_caller)); +// } + +// function test_revertIfInvalidParameters(bytes32 _requestId, address[] memory _targets, bytes[] memory _data) public { +// vm.assume(_targets.length != _data.length); + +// bytes memory _requestData = abi.encode(IMultipleCallbacksModule.RequestParameters({targets: _targets, data: _data})); + +// // Check: does it revert if arrays length mismatch? +// vm.expectRevert(IMultipleCallbacksModule.MultipleCallbackModule_InvalidParameters.selector); +// vm.prank(address(oracle)); +// multipleCallbackModule.setupRequest(_requestId, _requestData); +// } +// } + +// contract MultipleCallbacksModule_Unit_Setup is BaseTest { +// function test_revertsIfInvalidTarget(bytes32 _requestId, address[] memory _targets, bytes memory _data) public { +// vm.assume(_targets.length > 1); + +// // Hardcoding data (as it is not the case tested) to avoid vm.assume issues +// bytes[] memory _targetData = new bytes[](_targets.length); +// for (uint256 _i = 0; _i < _targets.length; _i++) { +// _targetData[_i] = abi.encodeWithSelector(bytes4(keccak256('callback(bytes32,bytes)')), _requestId, _data); +// } + +// bytes memory _requestData = +// abi.encode(IMultipleCallbacksModule.RequestParameters({targets: _targets, data: _targetData})); + +// // Check: does it revert if the target has no code? +// vm.expectRevert(IMultipleCallbacksModule.MultipleCallbackModule_TargetHasNoCode.selector); +// vm.prank(address(oracle)); +// multipleCallbackModule.setupRequest(_requestId, _requestData); +// } + +// function test_setUpMultipleTargets(bytes32 _requestId, address[] memory _targets, bytes memory _data) public { +// vm.assume(_targets.length > 1); + +// // Hardcoding data (as it is not the case tested) to avoid vm.assume issues +// bytes[] memory _targetData = new bytes[](_targets.length); +// for (uint256 _i = 0; _i < _targets.length; _i++) { +// _assumeFuzzable(_targets[_i]); +// vm.etch(_targets[_i], hex'069420'); +// _targetData[_i] = abi.encodeWithSelector(bytes4(keccak256('callback(bytes32,bytes)')), _requestId, _data); +// } + +// bytes memory _requestData = +// abi.encode(IMultipleCallbacksModule.RequestParameters({targets: _targets, data: _targetData})); + +// vm.prank(address(oracle)); +// multipleCallbackModule.setupRequest(_requestId, _requestData); + +// IMultipleCallbacksModule.RequestParameters memory _storedParams = +// multipleCallbackModule.decodeRequestData(_requestId); +// // Check: is the data properly stored? +// assertEq(_storedParams.targets, _targets); +// } +// } diff --git a/solidity/test/unit/modules/request/ContractCallRequestModule.t.sol b/solidity/test/unit/modules/request/ContractCallRequestModule.t.sol index 898e8a2c..0fcf779a 100644 --- a/solidity/test/unit/modules/request/ContractCallRequestModule.t.sol +++ b/solidity/test/unit/modules/request/ContractCallRequestModule.t.sol @@ -1,310 +1,310 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - ContractCallRequestModule, - IContractCallRequestModule -} from '../../../../contracts/modules/request/ContractCallRequestModule.sol'; - -import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ - -contract ForTest_ContractCallRequestModule is ContractCallRequestModule { - constructor(IOracle _oracle) ContractCallRequestModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } -} - -/** - * @title HTTP Request Module Unit tests - */ -contract BaseTest is Test, Helpers { - // The target contract - ForTest_ContractCallRequestModule public contractCallRequestModule; - // A mock oracle - IOracle public oracle; - // A mock accounting extension - IAccountingExtension public accounting; - // A mock user for testing - address internal _user = makeAddr('user'); - // A second mock user for testing - address internal _user2 = makeAddr('user2'); - // A mock ERC20 token - IERC20 internal _token = IERC20(makeAddr('ERC20')); - // Mock data - address internal _targetContract = address(_token); - bytes4 internal _functionSelector = bytes4(abi.encodeWithSignature('allowance(address,address)')); - bytes internal _dataParams = abi.encode(_user, _user2); - - event RequestFinalized(bytes32 indexed _requestId, address _finalizer); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - accounting = IAccountingExtension(makeAddr('AccountingExtension')); - vm.etch(address(accounting), hex'069420'); - - contractCallRequestModule = new ForTest_ContractCallRequestModule(oracle); - } -} - -contract ContractCallRequestModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleNameReturnsName() public { - assertEq(contractCallRequestModule.moduleName(), 'ContractCallRequestModule', 'Wrong module name'); - } - - /** - * @notice Test that the decodeRequestData function returns the correct values - */ - function test_decodeRequestData(bytes32 _requestId, IERC20 _paymentToken, uint256 _paymentAmount) public { - bytes memory _requestData = abi.encode( - IContractCallRequestModule.RequestParameters({ - target: _targetContract, - functionSelector: _functionSelector, - data: _dataParams, - accountingExtension: accounting, - paymentToken: _paymentToken, - paymentAmount: _paymentAmount - }) - ); - - // Set the request data - contractCallRequestModule.forTest_setRequestData(_requestId, _requestData); - - // Decode the given request data - IContractCallRequestModule.RequestParameters memory _params = - contractCallRequestModule.decodeRequestData(_requestId); - - // Check: decoded values match original values? - assertEq(_params.target, _targetContract, 'Mismatch: decoded target'); - assertEq(_params.functionSelector, _functionSelector, 'Mismatch: decoded function selector'); - assertEq(_params.data, _dataParams, 'Mismatch: decoded data'); - assertEq(address(_params.accountingExtension), address(accounting), 'Mismatch: decoded accounting extension'); - assertEq(address(_params.paymentToken), address(_paymentToken), 'Mismatch: decoded payment token'); - assertEq(_params.paymentAmount, _paymentAmount, 'Mismatch: decoded payment amount'); - } -} - -contract ContractCallRequestModule_Unit_Setup is BaseTest { - /** - * @notice Test that the afterSetupRequest hook: - * - decodes the request data - * - gets the request from the oracle - * - calls the bond function on the accounting extension - */ - function test_afterSetupRequestTriggered( - bytes32 _requestId, - address _requester, - IERC20 _paymentToken, - uint256 _paymentAmount - ) public { - bytes memory _requestData = abi.encode( - IContractCallRequestModule.RequestParameters({ - target: _targetContract, - functionSelector: _functionSelector, - data: _dataParams, - accountingExtension: accounting, - paymentToken: _paymentToken, - paymentAmount: _paymentAmount - }) - ); - - IOracle.Request memory _fullRequest; - _fullRequest.requester = _requester; - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); - - // Mock and expect IAccountingExtension.bond to be called - _mockAndExpect( - address(accounting), - abi.encodeWithSignature( - 'bond(address,bytes32,address,uint256)', _requester, _requestId, _paymentToken, _paymentAmount - ), - abi.encode(true) - ); - - vm.prank(address(oracle)); - contractCallRequestModule.setupRequest(_requestId, _requestData); - - // Check: request data was set? - assertEq(contractCallRequestModule.requestData(_requestId), _requestData, 'Mismatch: Request data'); - } -} - -contract ContractCallRequestModule_Unit_FinalizeRequest is BaseTest { - /** - * @notice Test that finalizeRequest calls: - * - oracle get request - * - oracle get response - * - accounting extension pay - * - accounting extension release - */ - function test_makesCalls( - bytes32 _requestId, - address _requester, - address _proposer, - IERC20 _paymentToken, - uint256 _paymentAmount - ) public { - // Use the correct accounting parameters - bytes memory _requestData = abi.encode( - IContractCallRequestModule.RequestParameters({ - target: _targetContract, - functionSelector: _functionSelector, - data: _dataParams, - accountingExtension: accounting, - paymentToken: _paymentToken, - paymentAmount: _paymentAmount - }) - ); - - IOracle.Request memory _fullRequest; - _fullRequest.requester = _requester; - - IOracle.Response memory _fullResponse; - _fullResponse.proposer = _proposer; - _fullResponse.createdAt = block.timestamp; - - // Set the request data - contractCallRequestModule.forTest_setRequestData(_requestId, _requestData); - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); - vm.expectCall(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId))); - - // Mock and expect IOracle.getFinalizedResponse to be called - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - // Mock and expect IAccountingExtension.pay to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _paymentToken, _paymentAmount)), - abi.encode() - ); - - vm.startPrank(address(oracle)); - contractCallRequestModule.finalizeRequest(_requestId, address(oracle)); - - // Test the release flow - _fullResponse.createdAt = 0; - - // Update mock call to return the response with createdAt = 0 - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _paymentToken, _paymentAmount)), - abi.encode(true) - ); - - contractCallRequestModule.finalizeRequest(_requestId, address(this)); - } - - function test_emitsEvent( - bytes32 _requestId, - address _requester, - address _proposer, - IERC20 _paymentToken, - uint256 _paymentAmount - ) public { - // Use the correct accounting parameters - bytes memory _requestData = abi.encode( - IContractCallRequestModule.RequestParameters({ - target: _targetContract, - functionSelector: _functionSelector, - data: _dataParams, - accountingExtension: accounting, - paymentToken: _paymentToken, - paymentAmount: _paymentAmount - }) - ); - - IOracle.Request memory _fullRequest; - _fullRequest.requester = _requester; - - IOracle.Response memory _fullResponse; - _fullResponse.proposer = _proposer; - _fullResponse.createdAt = block.timestamp; - - // Set the request data - contractCallRequestModule.forTest_setRequestData(_requestId, _requestData); - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); - - // Mock and expect IAccountingExtension.pay to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _paymentToken, _paymentAmount)), - abi.encode() - ); - - // Mock and expect IOracle.getFinalizedResponse to be called - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - vm.startPrank(address(oracle)); - contractCallRequestModule.finalizeRequest(_requestId, address(oracle)); - - // Test the release flow - _fullResponse.createdAt = 0; - - // Update mock call to return the response with createdAt = 0 - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _paymentToken, _paymentAmount)), - abi.encode(true) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(contractCallRequestModule)); - emit RequestFinalized(_requestId, address(this)); - - contractCallRequestModule.finalizeRequest(_requestId, address(this)); - } - - /** - * @notice Test that the finalizeRequest reverts if caller is not the oracle - */ - function test_revertsIfWrongCaller(bytes32 _requestId, address _caller) public { - vm.assume(_caller != address(oracle)); - - // Check: does it revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(_caller); - contractCallRequestModule.finalizeRequest(_requestId, address(_caller)); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// ContractCallRequestModule, +// IContractCallRequestModule +// } from '../../../../contracts/modules/request/ContractCallRequestModule.sol'; + +// import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ + +// contract ForTest_ContractCallRequestModule is ContractCallRequestModule { +// constructor(IOracle _oracle) ContractCallRequestModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } +// } + +// /** +// * @title HTTP Request Module Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_ContractCallRequestModule public contractCallRequestModule; +// // A mock oracle +// IOracle public oracle; +// // A mock accounting extension +// IAccountingExtension public accounting; +// // A mock user for testing +// address internal _user = makeAddr('user'); +// // A second mock user for testing +// address internal _user2 = makeAddr('user2'); +// // A mock ERC20 token +// IERC20 internal _token = IERC20(makeAddr('ERC20')); +// // Mock data +// address internal _targetContract = address(_token); +// bytes4 internal _functionSelector = bytes4(abi.encodeWithSignature('allowance(address,address)')); +// bytes internal _dataParams = abi.encode(_user, _user2); + +// event RequestFinalized(bytes32 indexed _requestId, address _finalizer); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// accounting = IAccountingExtension(makeAddr('AccountingExtension')); +// vm.etch(address(accounting), hex'069420'); + +// contractCallRequestModule = new ForTest_ContractCallRequestModule(oracle); +// } +// } + +// contract ContractCallRequestModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleNameReturnsName() public { +// assertEq(contractCallRequestModule.moduleName(), 'ContractCallRequestModule', 'Wrong module name'); +// } + +// /** +// * @notice Test that the decodeRequestData function returns the correct values +// */ +// function test_decodeRequestData(bytes32 _requestId, IERC20 _paymentToken, uint256 _paymentAmount) public { +// bytes memory _requestData = abi.encode( +// IContractCallRequestModule.RequestParameters({ +// target: _targetContract, +// functionSelector: _functionSelector, +// data: _dataParams, +// accountingExtension: accounting, +// paymentToken: _paymentToken, +// paymentAmount: _paymentAmount +// }) +// ); + +// // Set the request data +// contractCallRequestModule.forTest_setRequestData(_requestId, _requestData); + +// // Decode the given request data +// IContractCallRequestModule.RequestParameters memory _params = +// contractCallRequestModule.decodeRequestData(_requestId); + +// // Check: decoded values match original values? +// assertEq(_params.target, _targetContract, 'Mismatch: decoded target'); +// assertEq(_params.functionSelector, _functionSelector, 'Mismatch: decoded function selector'); +// assertEq(_params.data, _dataParams, 'Mismatch: decoded data'); +// assertEq(address(_params.accountingExtension), address(accounting), 'Mismatch: decoded accounting extension'); +// assertEq(address(_params.paymentToken), address(_paymentToken), 'Mismatch: decoded payment token'); +// assertEq(_params.paymentAmount, _paymentAmount, 'Mismatch: decoded payment amount'); +// } +// } + +// contract ContractCallRequestModule_Unit_Setup is BaseTest { +// /** +// * @notice Test that the afterSetupRequest hook: +// * - decodes the request data +// * - gets the request from the oracle +// * - calls the bond function on the accounting extension +// */ +// function test_afterSetupRequestTriggered( +// bytes32 _requestId, +// address _requester, +// IERC20 _paymentToken, +// uint256 _paymentAmount +// ) public { +// bytes memory _requestData = abi.encode( +// IContractCallRequestModule.RequestParameters({ +// target: _targetContract, +// functionSelector: _functionSelector, +// data: _dataParams, +// accountingExtension: accounting, +// paymentToken: _paymentToken, +// paymentAmount: _paymentAmount +// }) +// ); + +// IOracle.Request memory _fullRequest; +// _fullRequest.requester = _requester; + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); + +// // Mock and expect IAccountingExtension.bond to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeWithSignature( +// 'bond(address,bytes32,address,uint256)', _requester, _requestId, _paymentToken, _paymentAmount +// ), +// abi.encode(true) +// ); + +// vm.prank(address(oracle)); +// contractCallRequestModule.setupRequest(_requestId, _requestData); + +// // Check: request data was set? +// assertEq(contractCallRequestModule.requestData(_requestId), _requestData, 'Mismatch: Request data'); +// } +// } + +// contract ContractCallRequestModule_Unit_FinalizeRequest is BaseTest { +// /** +// * @notice Test that finalizeRequest calls: +// * - oracle get request +// * - oracle get response +// * - accounting extension pay +// * - accounting extension release +// */ +// function test_makesCalls( +// bytes32 _requestId, +// address _requester, +// address _proposer, +// IERC20 _paymentToken, +// uint256 _paymentAmount +// ) public { +// // Use the correct accounting parameters +// bytes memory _requestData = abi.encode( +// IContractCallRequestModule.RequestParameters({ +// target: _targetContract, +// functionSelector: _functionSelector, +// data: _dataParams, +// accountingExtension: accounting, +// paymentToken: _paymentToken, +// paymentAmount: _paymentAmount +// }) +// ); + +// IOracle.Request memory _fullRequest; +// _fullRequest.requester = _requester; + +// IOracle.Response memory _fullResponse; +// _fullResponse.proposer = _proposer; +// _fullResponse.createdAt = block.timestamp; + +// // Set the request data +// contractCallRequestModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); +// vm.expectCall(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId))); + +// // Mock and expect IOracle.getFinalizedResponse to be called +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// // Mock and expect IAccountingExtension.pay to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _paymentToken, _paymentAmount)), +// abi.encode() +// ); + +// vm.startPrank(address(oracle)); +// contractCallRequestModule.finalizeRequest(_requestId, address(oracle)); + +// // Test the release flow +// _fullResponse.createdAt = 0; + +// // Update mock call to return the response with createdAt = 0 +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _paymentToken, _paymentAmount)), +// abi.encode(true) +// ); + +// contractCallRequestModule.finalizeRequest(_requestId, address(this)); +// } + +// function test_emitsEvent( +// bytes32 _requestId, +// address _requester, +// address _proposer, +// IERC20 _paymentToken, +// uint256 _paymentAmount +// ) public { +// // Use the correct accounting parameters +// bytes memory _requestData = abi.encode( +// IContractCallRequestModule.RequestParameters({ +// target: _targetContract, +// functionSelector: _functionSelector, +// data: _dataParams, +// accountingExtension: accounting, +// paymentToken: _paymentToken, +// paymentAmount: _paymentAmount +// }) +// ); + +// IOracle.Request memory _fullRequest; +// _fullRequest.requester = _requester; + +// IOracle.Response memory _fullResponse; +// _fullResponse.proposer = _proposer; +// _fullResponse.createdAt = block.timestamp; + +// // Set the request data +// contractCallRequestModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); + +// // Mock and expect IAccountingExtension.pay to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _paymentToken, _paymentAmount)), +// abi.encode() +// ); + +// // Mock and expect IOracle.getFinalizedResponse to be called +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// vm.startPrank(address(oracle)); +// contractCallRequestModule.finalizeRequest(_requestId, address(oracle)); + +// // Test the release flow +// _fullResponse.createdAt = 0; + +// // Update mock call to return the response with createdAt = 0 +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _paymentToken, _paymentAmount)), +// abi.encode(true) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(contractCallRequestModule)); +// emit RequestFinalized(_requestId, address(this)); + +// contractCallRequestModule.finalizeRequest(_requestId, address(this)); +// } + +// /** +// * @notice Test that the finalizeRequest reverts if caller is not the oracle +// */ +// function test_revertsIfWrongCaller(bytes32 _requestId, address _caller) public { +// vm.assume(_caller != address(oracle)); + +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(_caller); +// contractCallRequestModule.finalizeRequest(_requestId, address(_caller)); +// } +// } diff --git a/solidity/test/unit/modules/request/HttpRequestModule.t.sol b/solidity/test/unit/modules/request/HttpRequestModule.t.sol index f06349cd..a053e9fe 100644 --- a/solidity/test/unit/modules/request/HttpRequestModule.t.sol +++ b/solidity/test/unit/modules/request/HttpRequestModule.t.sol @@ -1,299 +1,299 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import {HttpRequestModule, IHttpRequestModule} from '../../../../contracts/modules/request/HttpRequestModule.sol'; - -import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ - -contract ForTest_HttpRequestModule is HttpRequestModule { - constructor(IOracle _oracle) HttpRequestModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } -} - -/** - * @title HTTP Request Module Unit tests - */ -contract BaseTest is Test, Helpers { - // Mock request data - string public constant URL = 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd'; - IHttpRequestModule.HttpMethod public constant METHOD = IHttpRequestModule.HttpMethod.GET; - string public constant BODY = '69420'; - - // Mock token - IERC20 public immutable TOKEN = IERC20(makeAddr('ERC20')); - // The target contract - ForTest_HttpRequestModule public httpRequestModule; - // A mock oracle - IOracle public oracle; - // A mock accounting extension - IAccountingExtension public accounting = IAccountingExtension(makeAddr('accounting')); - - event RequestFinalized(bytes32 indexed _requestId, address _finalizer); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - accounting = IAccountingExtension(makeAddr('AccountingExtension')); - vm.etch(address(accounting), hex'069420'); - - httpRequestModule = new ForTest_HttpRequestModule(oracle); - } -} - -contract HttpRequestModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleNameReturnsName() public { - assertEq(httpRequestModule.moduleName(), 'HttpRequestModule'); - } - - /** - * @notice Test that the decodeRequestData function returns the correct values - */ - function test_decodeRequestData(bytes32 _requestId, uint256 _amount, IERC20 _token) public { - bytes memory _requestData = abi.encode( - IHttpRequestModule.RequestParameters({ - url: URL, - method: METHOD, - body: BODY, - accountingExtension: accounting, - paymentToken: _token, - paymentAmount: _amount - }) - ); - - // Set the request data - httpRequestModule.forTest_setRequestData(_requestId, _requestData); - - // Decode the given request data - IHttpRequestModule.RequestParameters memory _params = httpRequestModule.decodeRequestData(_requestId); - - // Check: decoded values match original values? - assertEq(_params.url, URL); - assertEq(uint256(_params.method), uint256(METHOD)); - assertEq(_params.body, BODY); - assertEq(address(_params.accountingExtension), address(accounting)); - assertEq(address(_params.paymentToken), address(_token)); - assertEq(_params.paymentAmount, _amount); - } -} - -contract HttpRequestModule_Unit_Setup is BaseTest { - /** - * @notice Test that the afterSetupRequest hook: - * - decodes the request data - * - gets the request from the oracle - * - calls the bond function on the accounting extension - */ - function test_afterSetupRequestTriggered( - bytes32 _requestId, - address _requester, - uint256 _amount, - IERC20 _token - ) public { - bytes memory _requestData = abi.encode( - IHttpRequestModule.RequestParameters({ - url: URL, - method: METHOD, - body: BODY, - accountingExtension: accounting, - paymentToken: _token, - paymentAmount: _amount - }) - ); - - IOracle.Request memory _fullRequest; - _fullRequest.requester = _requester; - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); - - // Mock and expect IAccountingExtension.bond to be called - _mockAndExpect( - address(accounting), - abi.encodeWithSignature('bond(address,bytes32,address,uint256)', _requester, _requestId, _token, _amount), - abi.encode(true) - ); - - vm.prank(address(oracle)); - httpRequestModule.setupRequest(_requestId, _requestData); - } -} - -contract HttpRequestModule_Unit_FinalizeRequest is BaseTest { - /** - * @notice Test that finalizeRequest calls: - * - oracle get request - * - oracle get response - * - accounting extension pay - * - accounting extension release - */ - function test_makesCalls( - bytes32 _requestId, - address _requester, - address _proposer, - uint256 _amount, - IERC20 _token - ) public { - _amount = bound(_amount, 0, type(uint248).max); - - // Use the correct accounting parameters - bytes memory _requestData = abi.encode( - IHttpRequestModule.RequestParameters({ - url: URL, - method: METHOD, - body: BODY, - accountingExtension: accounting, - paymentToken: _token, - paymentAmount: _amount - }) - ); - - IOracle.Request memory _fullRequest; - _fullRequest.requester = _requester; - - IOracle.Response memory _fullResponse; - _fullResponse.proposer = _proposer; - _fullResponse.createdAt = block.timestamp; - - // Set the request data - httpRequestModule.forTest_setRequestData(_requestId, _requestData); - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); - - // Mock and expect IOracle.getFinalizedResponse to be called - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - // Mock and expect IAccountingExtension.pay to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _token, _amount)), - abi.encode() - ); - - vm.startPrank(address(oracle)); - httpRequestModule.finalizeRequest(_requestId, address(oracle)); - - // Test the release flow - _fullResponse.createdAt = 0; - - // Update mock call to return the response with createdAt = 0 - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _token, _amount)), - abi.encode(true) - ); - - httpRequestModule.finalizeRequest(_requestId, address(this)); - } - - function test_emitsEvent( - bytes32 _requestId, - address _requester, - address _proposer, - uint256 _amount, - IERC20 _token - ) public { - // Use the correct accounting parameters - bytes memory _requestData = abi.encode( - IHttpRequestModule.RequestParameters({ - url: URL, - method: METHOD, - body: BODY, - accountingExtension: accounting, - paymentToken: _token, - paymentAmount: _amount - }) - ); - - IOracle.Request memory _fullRequest; - _fullRequest.requester = _requester; - - IOracle.Response memory _fullResponse; - _fullResponse.proposer = _proposer; - _fullResponse.createdAt = block.timestamp; - - // Set the request data - httpRequestModule.forTest_setRequestData(_requestId, _requestData); - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); - - // Mock and expect IOracle.getFinalizedResponse to be called - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - // Mock and expect IAccountingExtension.pay to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _token, _amount)), - abi.encode() - ); - - vm.startPrank(address(oracle)); - httpRequestModule.finalizeRequest(_requestId, address(oracle)); - - // Test the release flow - _fullResponse.createdAt = 0; - - // Update mock call to return the response with createdAt = 0 - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _token, _amount)), - abi.encode(true) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(httpRequestModule)); - emit RequestFinalized(_requestId, address(this)); - - httpRequestModule.finalizeRequest(_requestId, address(this)); - } - - /** - * @notice Test that the finalizeRequest reverts if caller is not the oracle - */ - function test_revertsIfWrongCaller(bytes32 _requestId, address _caller) public { - vm.assume(_caller != address(oracle)); - - // Check: does it revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(_caller); - httpRequestModule.finalizeRequest(_requestId, address(_caller)); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import {HttpRequestModule, IHttpRequestModule} from '../../../../contracts/modules/request/HttpRequestModule.sol'; + +// import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ + +// contract ForTest_HttpRequestModule is HttpRequestModule { +// constructor(IOracle _oracle) HttpRequestModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } +// } + +// /** +// * @title HTTP Request Module Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // Mock request data +// string public constant URL = 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd'; +// IHttpRequestModule.HttpMethod public constant METHOD = IHttpRequestModule.HttpMethod.GET; +// string public constant BODY = '69420'; + +// // Mock token +// IERC20 public immutable TOKEN = IERC20(makeAddr('ERC20')); +// // The target contract +// ForTest_HttpRequestModule public httpRequestModule; +// // A mock oracle +// IOracle public oracle; +// // A mock accounting extension +// IAccountingExtension public accounting = IAccountingExtension(makeAddr('accounting')); + +// event RequestFinalized(bytes32 indexed _requestId, address _finalizer); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// accounting = IAccountingExtension(makeAddr('AccountingExtension')); +// vm.etch(address(accounting), hex'069420'); + +// httpRequestModule = new ForTest_HttpRequestModule(oracle); +// } +// } + +// contract HttpRequestModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleNameReturnsName() public { +// assertEq(httpRequestModule.moduleName(), 'HttpRequestModule'); +// } + +// /** +// * @notice Test that the decodeRequestData function returns the correct values +// */ +// function test_decodeRequestData(bytes32 _requestId, uint256 _amount, IERC20 _token) public { +// bytes memory _requestData = abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: URL, +// method: METHOD, +// body: BODY, +// accountingExtension: accounting, +// paymentToken: _token, +// paymentAmount: _amount +// }) +// ); + +// // Set the request data +// httpRequestModule.forTest_setRequestData(_requestId, _requestData); + +// // Decode the given request data +// IHttpRequestModule.RequestParameters memory _params = httpRequestModule.decodeRequestData(_requestId); + +// // Check: decoded values match original values? +// assertEq(_params.url, URL); +// assertEq(uint256(_params.method), uint256(METHOD)); +// assertEq(_params.body, BODY); +// assertEq(address(_params.accountingExtension), address(accounting)); +// assertEq(address(_params.paymentToken), address(_token)); +// assertEq(_params.paymentAmount, _amount); +// } +// } + +// contract HttpRequestModule_Unit_Setup is BaseTest { +// /** +// * @notice Test that the afterSetupRequest hook: +// * - decodes the request data +// * - gets the request from the oracle +// * - calls the bond function on the accounting extension +// */ +// function test_afterSetupRequestTriggered( +// bytes32 _requestId, +// address _requester, +// uint256 _amount, +// IERC20 _token +// ) public { +// bytes memory _requestData = abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: URL, +// method: METHOD, +// body: BODY, +// accountingExtension: accounting, +// paymentToken: _token, +// paymentAmount: _amount +// }) +// ); + +// IOracle.Request memory _fullRequest; +// _fullRequest.requester = _requester; + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); + +// // Mock and expect IAccountingExtension.bond to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeWithSignature('bond(address,bytes32,address,uint256)', _requester, _requestId, _token, _amount), +// abi.encode(true) +// ); + +// vm.prank(address(oracle)); +// httpRequestModule.setupRequest(_requestId, _requestData); +// } +// } + +// contract HttpRequestModule_Unit_FinalizeRequest is BaseTest { +// /** +// * @notice Test that finalizeRequest calls: +// * - oracle get request +// * - oracle get response +// * - accounting extension pay +// * - accounting extension release +// */ +// function test_makesCalls( +// bytes32 _requestId, +// address _requester, +// address _proposer, +// uint256 _amount, +// IERC20 _token +// ) public { +// _amount = bound(_amount, 0, type(uint248).max); + +// // Use the correct accounting parameters +// bytes memory _requestData = abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: URL, +// method: METHOD, +// body: BODY, +// accountingExtension: accounting, +// paymentToken: _token, +// paymentAmount: _amount +// }) +// ); + +// IOracle.Request memory _fullRequest; +// _fullRequest.requester = _requester; + +// IOracle.Response memory _fullResponse; +// _fullResponse.proposer = _proposer; +// _fullResponse.createdAt = block.timestamp; + +// // Set the request data +// httpRequestModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); + +// // Mock and expect IOracle.getFinalizedResponse to be called +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// // Mock and expect IAccountingExtension.pay to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _token, _amount)), +// abi.encode() +// ); + +// vm.startPrank(address(oracle)); +// httpRequestModule.finalizeRequest(_requestId, address(oracle)); + +// // Test the release flow +// _fullResponse.createdAt = 0; + +// // Update mock call to return the response with createdAt = 0 +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _token, _amount)), +// abi.encode(true) +// ); + +// httpRequestModule.finalizeRequest(_requestId, address(this)); +// } + +// function test_emitsEvent( +// bytes32 _requestId, +// address _requester, +// address _proposer, +// uint256 _amount, +// IERC20 _token +// ) public { +// // Use the correct accounting parameters +// bytes memory _requestData = abi.encode( +// IHttpRequestModule.RequestParameters({ +// url: URL, +// method: METHOD, +// body: BODY, +// accountingExtension: accounting, +// paymentToken: _token, +// paymentAmount: _amount +// }) +// ); + +// IOracle.Request memory _fullRequest; +// _fullRequest.requester = _requester; + +// IOracle.Response memory _fullResponse; +// _fullResponse.proposer = _proposer; +// _fullResponse.createdAt = block.timestamp; + +// // Set the request data +// httpRequestModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); + +// // Mock and expect IOracle.getFinalizedResponse to be called +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// // Mock and expect IAccountingExtension.pay to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _token, _amount)), +// abi.encode() +// ); + +// vm.startPrank(address(oracle)); +// httpRequestModule.finalizeRequest(_requestId, address(oracle)); + +// // Test the release flow +// _fullResponse.createdAt = 0; + +// // Update mock call to return the response with createdAt = 0 +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _token, _amount)), +// abi.encode(true) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(httpRequestModule)); +// emit RequestFinalized(_requestId, address(this)); + +// httpRequestModule.finalizeRequest(_requestId, address(this)); +// } + +// /** +// * @notice Test that the finalizeRequest reverts if caller is not the oracle +// */ +// function test_revertsIfWrongCaller(bytes32 _requestId, address _caller) public { +// vm.assume(_caller != address(oracle)); + +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(_caller); +// httpRequestModule.finalizeRequest(_requestId, address(_caller)); +// } +// } diff --git a/solidity/test/unit/modules/request/SparseMerkleTreeRequestModule.t.sol b/solidity/test/unit/modules/request/SparseMerkleTreeRequestModule.t.sol index 831e349b..7623cc70 100644 --- a/solidity/test/unit/modules/request/SparseMerkleTreeRequestModule.t.sol +++ b/solidity/test/unit/modules/request/SparseMerkleTreeRequestModule.t.sol @@ -1,360 +1,360 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - SparseMerkleTreeRequestModule, - ISparseMerkleTreeRequestModule -} from '../../../../contracts/modules/request/SparseMerkleTreeRequestModule.sol'; - -import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; -import {ITreeVerifier} from '../../../../interfaces/ITreeVerifier.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ - -contract ForTest_SparseMerkleTreeRequestModule is SparseMerkleTreeRequestModule { - constructor(IOracle _oracle) SparseMerkleTreeRequestModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } -} - -/** - * @title Sparse Merkle Tree Request Module Unit tests - */ -contract BaseTest is Test, Helpers { - // The target contract - ForTest_SparseMerkleTreeRequestModule public sparseMerkleTreeRequestModule; - // A mock oracle - IOracle public oracle; - // A mock accounting extension - IAccountingExtension public accounting; - // A mock tree verifier - ITreeVerifier public treeVerifier; - // Mock data for the request - bytes32[32] internal _treeBranches = [ - bytes32('branch1'), - bytes32('branch2'), - bytes32('branch3'), - bytes32('branch4'), - bytes32('branch5'), - bytes32('branch6'), - bytes32('branch7'), - bytes32('branch8'), - bytes32('branch9'), - bytes32('branch10'), - bytes32('branch11'), - bytes32('branch12'), - bytes32('branch13'), - bytes32('branch14'), - bytes32('branch15'), - bytes32('branch16'), - bytes32('branch17'), - bytes32('branch18'), - bytes32('branch19'), - bytes32('branch20'), - bytes32('branch21'), - bytes32('branch22'), - bytes32('branch23'), - bytes32('branch24'), - bytes32('branch25'), - bytes32('branch26'), - bytes32('branch27'), - bytes32('branch28'), - bytes32('branch29'), - bytes32('branch30'), - bytes32('branch31'), - bytes32('branch32') - ]; - uint256 internal _treeCount = 1; - bytes internal _treeData = abi.encode(_treeBranches, _treeCount); - bytes32[] internal _leavesToInsert = [bytes32('leave1'), bytes32('leave2')]; - - event RequestFinalized(bytes32 indexed _requestId, address _finalizer); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - accounting = IAccountingExtension(makeAddr('AccountingExtension')); - vm.etch(address(accounting), hex'069420'); - treeVerifier = ITreeVerifier(makeAddr('TreeVerifier')); - vm.etch(address(accounting), hex'069420'); - - sparseMerkleTreeRequestModule = new ForTest_SparseMerkleTreeRequestModule(oracle); - } -} - -contract SparseMerkleTreeRequestModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleNameReturnsName() public { - assertEq(sparseMerkleTreeRequestModule.moduleName(), 'SparseMerkleTreeRequestModule', 'Wrong module name'); - } - - /** - * @notice Test that the decodeRequestData function returns the correct values - */ - function test_decodeRequestData( - bytes32 _requestId, - IERC20 _paymentToken, - uint256 _paymentAmount, - IAccountingExtension _accounting, - ITreeVerifier _treeVerifier - ) public { - bytes memory _requestData = abi.encode( - ISparseMerkleTreeRequestModule.RequestParameters({ - treeData: _treeData, - leavesToInsert: _leavesToInsert, - treeVerifier: _treeVerifier, - accountingExtension: _accounting, - paymentToken: _paymentToken, - paymentAmount: _paymentAmount - }) - ); - - // Set the request data - sparseMerkleTreeRequestModule.forTest_setRequestData(_requestId, _requestData); - - // Decode the given request data - ISparseMerkleTreeRequestModule.RequestParameters memory _params = - sparseMerkleTreeRequestModule.decodeRequestData(_requestId); - - (bytes32[32] memory _decodedTreeBranches, uint256 _decodedTreeCount) = - abi.decode(_params.treeData, (bytes32[32], uint256)); - - // Check: decoded values match original values? - for (uint256 _i = 0; _i < _treeBranches.length; _i++) { - assertEq(_decodedTreeBranches[_i], _treeBranches[_i], 'Mismatch: decoded tree branch'); - } - for (uint256 _i = 0; _i < _leavesToInsert.length; _i++) { - assertEq(_params.leavesToInsert[_i], _leavesToInsert[_i], 'Mismatch: decoded leave to insert'); - } - assertEq(_decodedTreeCount, _treeCount, 'Mismatch: decoded tree count'); - assertEq(address(_params.treeVerifier), address(_treeVerifier), 'Mismatch: decoded tree verifier'); - assertEq(address(_params.accountingExtension), address(_accounting), 'Mismatch: decoded accounting extension'); - assertEq(address(_params.paymentToken), address(_paymentToken), 'Mismatch: decoded payment token'); - assertEq(_params.paymentAmount, _paymentAmount, 'Mismatch: decoded payment amount'); - } -} - -contract SparseMerkleTreeRequestModule_Unit_Setup is BaseTest { - /** - * @notice Test that the afterSetupRequest hook: - * - decodes the request data - * - gets the request from the oracle - * - calls the bond function on the accounting extension - */ - function test_afterSetupRequestTriggered( - bytes32 _requestId, - address _requester, - IERC20 _paymentToken, - uint256 _paymentAmount, - IAccountingExtension _accounting, - ITreeVerifier _treeVerifier - ) public assumeFuzzable(address(_accounting)) { - bytes memory _requestData = abi.encode( - ISparseMerkleTreeRequestModule.RequestParameters({ - treeData: _treeData, - leavesToInsert: _leavesToInsert, - treeVerifier: _treeVerifier, - accountingExtension: _accounting, - paymentToken: _paymentToken, - paymentAmount: _paymentAmount - }) - ); - - IOracle.Request memory _fullRequest; - _fullRequest.requester = _requester; - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); - - // Mock and expect IAccountingExtension.bond to be called - _mockAndExpect( - address(_accounting), - abi.encodeWithSignature( - 'bond(address,bytes32,address,uint256)', _requester, _requestId, _paymentToken, _paymentAmount - ), - abi.encode(true) - ); - - vm.prank(address(oracle)); - sparseMerkleTreeRequestModule.setupRequest(_requestId, _requestData); - - // Check: request data was set? - assertEq(sparseMerkleTreeRequestModule.requestData(_requestId), _requestData, 'Mismatch: Request data'); - } -} - -contract SparseMerkleTreeRequestModule_Unit_FinalizeRequest is BaseTest { - /** - * @notice Test that finalizeRequest calls: - * - oracle get request - * - oracle get response - * - accounting extension pay - * - accounting extension release - */ - function test_makesCalls( - bytes32 _requestId, - address _requester, - address _proposer, - IERC20 _paymentToken, - uint256 _paymentAmount, - IAccountingExtension _accounting, - ITreeVerifier _treeVerifier - ) public assumeFuzzable(address(_accounting)) { - // Use the correct accounting parameters - bytes memory _requestData = abi.encode( - ISparseMerkleTreeRequestModule.RequestParameters({ - treeData: _treeData, - leavesToInsert: _leavesToInsert, - treeVerifier: _treeVerifier, - accountingExtension: _accounting, - paymentToken: _paymentToken, - paymentAmount: _paymentAmount - }) - ); - - IOracle.Request memory _fullRequest; - _fullRequest.requester = _requester; - - IOracle.Response memory _fullResponse; - _fullResponse.proposer = _proposer; - _fullResponse.createdAt = block.timestamp; - - // Set the request data - sparseMerkleTreeRequestModule.forTest_setRequestData(_requestId, _requestData); - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); - - // Mock and expect IOracle.getFinalizedResponse to be called - vm.mockCall(address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse)); - - // Mock and expect IAccountingExtension.pay to be called - vm.mockCall( - address(_accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _paymentToken, _paymentAmount)), - abi.encode() - ); - - vm.startPrank(address(oracle)); - sparseMerkleTreeRequestModule.finalizeRequest(_requestId, address(oracle)); - - // Test the release flow - _fullResponse.createdAt = 0; - - // Update mock call to return the response with createdAt = 0 - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(_accounting), - abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _paymentToken, _paymentAmount)), - abi.encode(true) - ); - - sparseMerkleTreeRequestModule.finalizeRequest(_requestId, address(this)); - } - - function test_emitsEvent( - bytes32 _requestId, - address _requester, - address _proposer, - IERC20 _paymentToken, - uint256 _paymentAmount, - IAccountingExtension _accounting, - ITreeVerifier _treeVerifier - ) public assumeFuzzable(address(_accounting)) { - // Use the correct accounting parameters - bytes memory _requestData = abi.encode( - ISparseMerkleTreeRequestModule.RequestParameters({ - treeData: _treeData, - leavesToInsert: _leavesToInsert, - treeVerifier: _treeVerifier, - accountingExtension: _accounting, - paymentToken: _paymentToken, - paymentAmount: _paymentAmount - }) - ); - - IOracle.Request memory _fullRequest; - _fullRequest.requester = _requester; - - IOracle.Response memory _fullResponse; - _fullResponse.proposer = _proposer; - _fullResponse.createdAt = block.timestamp; - - // Set the request data - sparseMerkleTreeRequestModule.forTest_setRequestData(_requestId, _requestData); - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); - - // Mock and expect IOracle.getFinalizedResponse to be called - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect( - address(_accounting), - abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _paymentToken, _paymentAmount)), - abi.encode() - ); - - vm.startPrank(address(oracle)); - sparseMerkleTreeRequestModule.finalizeRequest(_requestId, address(oracle)); - - // Test the release flow - _fullResponse.createdAt = 0; - - // Update mock call to return the response with createdAt = 0 - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) - ); - - // Mock and expect IOracle.getRequest to be called - _mockAndExpect( - address(_accounting), - abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _paymentToken, _paymentAmount)), - abi.encode(true) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(sparseMerkleTreeRequestModule)); - emit RequestFinalized(_requestId, address(this)); - - sparseMerkleTreeRequestModule.finalizeRequest(_requestId, address(this)); - } - - /** - * @notice Test that the finalizeRequest reverts if caller is not the oracle - */ - function test_revertsIfWrongCaller(bytes32 _requestId, address _caller) public { - vm.assume(_caller != address(oracle)); - - // Check: does it revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(_caller); - sparseMerkleTreeRequestModule.finalizeRequest(_requestId, address(_caller)); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// SparseMerkleTreeRequestModule, +// ISparseMerkleTreeRequestModule +// } from '../../../../contracts/modules/request/SparseMerkleTreeRequestModule.sol'; + +// import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; +// import {ITreeVerifier} from '../../../../interfaces/ITreeVerifier.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ + +// contract ForTest_SparseMerkleTreeRequestModule is SparseMerkleTreeRequestModule { +// constructor(IOracle _oracle) SparseMerkleTreeRequestModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } +// } + +// /** +// * @title Sparse Merkle Tree Request Module Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_SparseMerkleTreeRequestModule public sparseMerkleTreeRequestModule; +// // A mock oracle +// IOracle public oracle; +// // A mock accounting extension +// IAccountingExtension public accounting; +// // A mock tree verifier +// ITreeVerifier public treeVerifier; +// // Mock data for the request +// bytes32[32] internal _treeBranches = [ +// bytes32('branch1'), +// bytes32('branch2'), +// bytes32('branch3'), +// bytes32('branch4'), +// bytes32('branch5'), +// bytes32('branch6'), +// bytes32('branch7'), +// bytes32('branch8'), +// bytes32('branch9'), +// bytes32('branch10'), +// bytes32('branch11'), +// bytes32('branch12'), +// bytes32('branch13'), +// bytes32('branch14'), +// bytes32('branch15'), +// bytes32('branch16'), +// bytes32('branch17'), +// bytes32('branch18'), +// bytes32('branch19'), +// bytes32('branch20'), +// bytes32('branch21'), +// bytes32('branch22'), +// bytes32('branch23'), +// bytes32('branch24'), +// bytes32('branch25'), +// bytes32('branch26'), +// bytes32('branch27'), +// bytes32('branch28'), +// bytes32('branch29'), +// bytes32('branch30'), +// bytes32('branch31'), +// bytes32('branch32') +// ]; +// uint256 internal _treeCount = 1; +// bytes internal _treeData = abi.encode(_treeBranches, _treeCount); +// bytes32[] internal _leavesToInsert = [bytes32('leave1'), bytes32('leave2')]; + +// event RequestFinalized(bytes32 indexed _requestId, address _finalizer); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// accounting = IAccountingExtension(makeAddr('AccountingExtension')); +// vm.etch(address(accounting), hex'069420'); +// treeVerifier = ITreeVerifier(makeAddr('TreeVerifier')); +// vm.etch(address(accounting), hex'069420'); + +// sparseMerkleTreeRequestModule = new ForTest_SparseMerkleTreeRequestModule(oracle); +// } +// } + +// contract SparseMerkleTreeRequestModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleNameReturnsName() public { +// assertEq(sparseMerkleTreeRequestModule.moduleName(), 'SparseMerkleTreeRequestModule', 'Wrong module name'); +// } + +// /** +// * @notice Test that the decodeRequestData function returns the correct values +// */ +// function test_decodeRequestData( +// bytes32 _requestId, +// IERC20 _paymentToken, +// uint256 _paymentAmount, +// IAccountingExtension _accounting, +// ITreeVerifier _treeVerifier +// ) public { +// bytes memory _requestData = abi.encode( +// ISparseMerkleTreeRequestModule.RequestParameters({ +// treeData: _treeData, +// leavesToInsert: _leavesToInsert, +// treeVerifier: _treeVerifier, +// accountingExtension: _accounting, +// paymentToken: _paymentToken, +// paymentAmount: _paymentAmount +// }) +// ); + +// // Set the request data +// sparseMerkleTreeRequestModule.forTest_setRequestData(_requestId, _requestData); + +// // Decode the given request data +// ISparseMerkleTreeRequestModule.RequestParameters memory _params = +// sparseMerkleTreeRequestModule.decodeRequestData(_requestId); + +// (bytes32[32] memory _decodedTreeBranches, uint256 _decodedTreeCount) = +// abi.decode(_params.treeData, (bytes32[32], uint256)); + +// // Check: decoded values match original values? +// for (uint256 _i = 0; _i < _treeBranches.length; _i++) { +// assertEq(_decodedTreeBranches[_i], _treeBranches[_i], 'Mismatch: decoded tree branch'); +// } +// for (uint256 _i = 0; _i < _leavesToInsert.length; _i++) { +// assertEq(_params.leavesToInsert[_i], _leavesToInsert[_i], 'Mismatch: decoded leave to insert'); +// } +// assertEq(_decodedTreeCount, _treeCount, 'Mismatch: decoded tree count'); +// assertEq(address(_params.treeVerifier), address(_treeVerifier), 'Mismatch: decoded tree verifier'); +// assertEq(address(_params.accountingExtension), address(_accounting), 'Mismatch: decoded accounting extension'); +// assertEq(address(_params.paymentToken), address(_paymentToken), 'Mismatch: decoded payment token'); +// assertEq(_params.paymentAmount, _paymentAmount, 'Mismatch: decoded payment amount'); +// } +// } + +// contract SparseMerkleTreeRequestModule_Unit_Setup is BaseTest { +// /** +// * @notice Test that the afterSetupRequest hook: +// * - decodes the request data +// * - gets the request from the oracle +// * - calls the bond function on the accounting extension +// */ +// function test_afterSetupRequestTriggered( +// bytes32 _requestId, +// address _requester, +// IERC20 _paymentToken, +// uint256 _paymentAmount, +// IAccountingExtension _accounting, +// ITreeVerifier _treeVerifier +// ) public assumeFuzzable(address(_accounting)) { +// bytes memory _requestData = abi.encode( +// ISparseMerkleTreeRequestModule.RequestParameters({ +// treeData: _treeData, +// leavesToInsert: _leavesToInsert, +// treeVerifier: _treeVerifier, +// accountingExtension: _accounting, +// paymentToken: _paymentToken, +// paymentAmount: _paymentAmount +// }) +// ); + +// IOracle.Request memory _fullRequest; +// _fullRequest.requester = _requester; + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); + +// // Mock and expect IAccountingExtension.bond to be called +// _mockAndExpect( +// address(_accounting), +// abi.encodeWithSignature( +// 'bond(address,bytes32,address,uint256)', _requester, _requestId, _paymentToken, _paymentAmount +// ), +// abi.encode(true) +// ); + +// vm.prank(address(oracle)); +// sparseMerkleTreeRequestModule.setupRequest(_requestId, _requestData); + +// // Check: request data was set? +// assertEq(sparseMerkleTreeRequestModule.requestData(_requestId), _requestData, 'Mismatch: Request data'); +// } +// } + +// contract SparseMerkleTreeRequestModule_Unit_FinalizeRequest is BaseTest { +// /** +// * @notice Test that finalizeRequest calls: +// * - oracle get request +// * - oracle get response +// * - accounting extension pay +// * - accounting extension release +// */ +// function test_makesCalls( +// bytes32 _requestId, +// address _requester, +// address _proposer, +// IERC20 _paymentToken, +// uint256 _paymentAmount, +// IAccountingExtension _accounting, +// ITreeVerifier _treeVerifier +// ) public assumeFuzzable(address(_accounting)) { +// // Use the correct accounting parameters +// bytes memory _requestData = abi.encode( +// ISparseMerkleTreeRequestModule.RequestParameters({ +// treeData: _treeData, +// leavesToInsert: _leavesToInsert, +// treeVerifier: _treeVerifier, +// accountingExtension: _accounting, +// paymentToken: _paymentToken, +// paymentAmount: _paymentAmount +// }) +// ); + +// IOracle.Request memory _fullRequest; +// _fullRequest.requester = _requester; + +// IOracle.Response memory _fullResponse; +// _fullResponse.proposer = _proposer; +// _fullResponse.createdAt = block.timestamp; + +// // Set the request data +// sparseMerkleTreeRequestModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); + +// // Mock and expect IOracle.getFinalizedResponse to be called +// vm.mockCall(address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse)); + +// // Mock and expect IAccountingExtension.pay to be called +// vm.mockCall( +// address(_accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _paymentToken, _paymentAmount)), +// abi.encode() +// ); + +// vm.startPrank(address(oracle)); +// sparseMerkleTreeRequestModule.finalizeRequest(_requestId, address(oracle)); + +// // Test the release flow +// _fullResponse.createdAt = 0; + +// // Update mock call to return the response with createdAt = 0 +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(_accounting), +// abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _paymentToken, _paymentAmount)), +// abi.encode(true) +// ); + +// sparseMerkleTreeRequestModule.finalizeRequest(_requestId, address(this)); +// } + +// function test_emitsEvent( +// bytes32 _requestId, +// address _requester, +// address _proposer, +// IERC20 _paymentToken, +// uint256 _paymentAmount, +// IAccountingExtension _accounting, +// ITreeVerifier _treeVerifier +// ) public assumeFuzzable(address(_accounting)) { +// // Use the correct accounting parameters +// bytes memory _requestData = abi.encode( +// ISparseMerkleTreeRequestModule.RequestParameters({ +// treeData: _treeData, +// leavesToInsert: _leavesToInsert, +// treeVerifier: _treeVerifier, +// accountingExtension: _accounting, +// paymentToken: _paymentToken, +// paymentAmount: _paymentAmount +// }) +// ); + +// IOracle.Request memory _fullRequest; +// _fullRequest.requester = _requester; + +// IOracle.Response memory _fullResponse; +// _fullResponse.proposer = _proposer; +// _fullResponse.createdAt = block.timestamp; + +// // Set the request data +// sparseMerkleTreeRequestModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getRequest, (_requestId)), abi.encode(_fullRequest)); + +// // Mock and expect IOracle.getFinalizedResponse to be called +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect( +// address(_accounting), +// abi.encodeCall(IAccountingExtension.pay, (_requestId, _requester, _proposer, _paymentToken, _paymentAmount)), +// abi.encode() +// ); + +// vm.startPrank(address(oracle)); +// sparseMerkleTreeRequestModule.finalizeRequest(_requestId, address(oracle)); + +// // Test the release flow +// _fullResponse.createdAt = 0; + +// // Update mock call to return the response with createdAt = 0 +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, (_requestId)), abi.encode(_fullResponse) +// ); + +// // Mock and expect IOracle.getRequest to be called +// _mockAndExpect( +// address(_accounting), +// abi.encodeCall(IAccountingExtension.release, (_requester, _requestId, _paymentToken, _paymentAmount)), +// abi.encode(true) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(sparseMerkleTreeRequestModule)); +// emit RequestFinalized(_requestId, address(this)); + +// sparseMerkleTreeRequestModule.finalizeRequest(_requestId, address(this)); +// } + +// /** +// * @notice Test that the finalizeRequest reverts if caller is not the oracle +// */ +// function test_revertsIfWrongCaller(bytes32 _requestId, address _caller) public { +// vm.assume(_caller != address(oracle)); + +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(_caller); +// sparseMerkleTreeRequestModule.finalizeRequest(_requestId, address(_caller)); +// } +// } diff --git a/solidity/test/unit/modules/resolution/ArbitratorModule.t.sol b/solidity/test/unit/modules/resolution/ArbitratorModule.t.sol index 91c09249..7f13db93 100644 --- a/solidity/test/unit/modules/resolution/ArbitratorModule.t.sol +++ b/solidity/test/unit/modules/resolution/ArbitratorModule.t.sol @@ -1,328 +1,328 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - ArbitratorModule, - IArbitratorModule, - IArbitrator -} from '../../../../contracts/modules/resolution/ArbitratorModule.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ -contract ForTest_ArbitratorModule is ArbitratorModule { - constructor(IOracle _oracle) ArbitratorModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } - - function forTest_setDisputeStatus(bytes32 _disputeId, IArbitratorModule.ArbitrationStatus _status) public { - _disputeData[_disputeId] = _status; - } -} - -/** - * @title Arbitrator Module Unit tests - */ -contract BaseTest is Test, Helpers { - // The target contract - ForTest_ArbitratorModule public arbitratorModule; - // A mock oracle - IOracle public oracle; - // A mock arbitrator - IArbitrator public arbitrator; - // Create a new dummy dispute - IOracle.Dispute public mockDispute; - - event ResolutionStarted(bytes32 indexed _requestId, bytes32 indexed _disputeId); - event DisputeResolved(bytes32 indexed _requestId, bytes32 indexed _disputeId, IOracle.DisputeStatus _status); - - /** - * @notice Deploy the target and mock oracle - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - arbitrator = IArbitrator(makeAddr('MockArbitrator')); - vm.etch(address(arbitrator), hex'069420'); - - arbitratorModule = new ForTest_ArbitratorModule(oracle); - - mockDispute = IOracle.Dispute({ - createdAt: block.timestamp, - disputer: makeAddr('disputer'), - proposer: makeAddr('proposer'), - responseId: bytes32('69'), - requestId: bytes32('69'), - status: IOracle.DisputeStatus.Active - }); - } -} - -contract ArbitratorModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleNameReturnsName() public { - assertEq(arbitratorModule.moduleName(), 'ArbitratorModule'); - } - /** - * @notice Test that the decodeRequestData function returns the correct values - */ - - function test_decodeRequestData(bytes32 _requestId, address _arbitrator) public { - // Mock data - bytes memory _requestData = abi.encode(address(_arbitrator)); - - // Store the mock dispute - arbitratorModule.forTest_setRequestData(_requestId, _requestData); - - // Test: decode the given request data - (address _arbitratorStored) = arbitratorModule.decodeRequestData(_requestId); - - // Check: decoded values match original values? - assertEq(_arbitratorStored, _arbitrator); - } - - /** - * @notice Test that the status is correctly retrieved - */ - function test_getStatus(uint256 _status, bytes32 _disputeId) public { - _status = bound(_status, 0, uint256(IArbitratorModule.ArbitrationStatus.Resolved)); - IArbitratorModule.ArbitrationStatus _arbitratorStatus = IArbitratorModule.ArbitrationStatus(_status); - - // Store the mock dispute - arbitratorModule.forTest_setDisputeStatus(_disputeId, _arbitratorStatus); - - // Check: The correct status is returned? - assertEq(uint256(arbitratorModule.getStatus(_disputeId)), uint256(_status)); - } -} - -contract ArbitratorModule_Unit_StartResolution is BaseTest { - /** - * @notice Test that the escalate function works as expected - */ - function test_startResolution(bytes32 _disputeId, bytes32 _requestId) public { - // Mock and expect the dummy dispute - mockDispute.requestId = _requestId; - _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); - - // Store the requestData - bytes memory _requestData = abi.encode(address(arbitrator)); - arbitratorModule.forTest_setRequestData(_requestId, _requestData); - - // Mock and expect the callback to the arbitrator - _mockAndExpect(address(arbitrator), abi.encodeCall(arbitrator.resolve, (_disputeId)), abi.encode(bytes(''))); - - vm.prank(address(oracle)); - arbitratorModule.startResolution(_disputeId); - - // Check: is status now Escalated? - assertEq(uint256(arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Active)); - } - - function test_emitsEvent(bytes32 _disputeId, bytes32 _requestId) public { - // Mock and expect the dummy dispute - mockDispute.requestId = _requestId; - _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); - - // Store the requestData - bytes memory _requestData = abi.encode(address(arbitrator)); - arbitratorModule.forTest_setRequestData(_requestId, _requestData); - - // Mock and expect the callback to the arbitrator - _mockAndExpect(address(arbitrator), abi.encodeCall(arbitrator.resolve, (_disputeId)), abi.encode(bytes(''))); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(arbitratorModule)); - emit ResolutionStarted(_requestId, _disputeId); - - vm.prank(address(oracle)); - arbitratorModule.startResolution(_disputeId); - } - - function test_revertInvalidCaller(address _caller, bytes32 _disputeId) public { - vm.assume(_caller != address(oracle)); - - // Check: does it revert if the caller is not the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(_caller); - arbitratorModule.startResolution(_disputeId); - } - - function test_revertIfEmptyArbitrator(bytes32 _disputeId, bytes32 _requestId) public { - // Mock and expect the dummy dispute - mockDispute.requestId = _requestId; - _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); - - // Store the requestData - bytes memory _requestData = abi.encode(address(0)); - arbitratorModule.forTest_setRequestData(_requestId, _requestData); - - // Check: revert? - vm.expectRevert(abi.encodeWithSelector(IArbitratorModule.ArbitratorModule_InvalidArbitrator.selector)); - - // Test: escalate the dispute - vm.prank(address(oracle)); - arbitratorModule.startResolution(_disputeId); - } -} - -contract ArbitratorModule_Unit_ResolveDispute is BaseTest { - /** - * @notice Test that the resolve function works as expected - */ - function test_resolveDispute(bytes32 _disputeId, bytes32 _requestId, uint256 _status) public { - vm.assume(_status <= uint256(IOracle.DisputeStatus.Lost)); - vm.assume(_status > uint256(IOracle.DisputeStatus.Escalated)); - IOracle.DisputeStatus _arbitratorStatus = IOracle.DisputeStatus(_status); - - // Store the mock dispute - bytes memory _requestData = abi.encode(address(arbitrator)); - arbitratorModule.forTest_setRequestData(_requestId, _requestData); - - // Mock the dummy dispute - mockDispute.requestId = _requestId; - mockDispute.status = IOracle.DisputeStatus.Escalated; - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); - - // Mock and expect getAnswer to be called on the arbitrator - _mockAndExpect( - address(arbitrator), abi.encodeCall(arbitrator.getAnswer, (_disputeId)), abi.encode(_arbitratorStatus) - ); - - // Mock and expect IOracle.updateDisputeStatus to be called - _mockAndExpect( - address(oracle), abi.encodeCall(oracle.updateDisputeStatus, (_disputeId, _arbitratorStatus)), abi.encode() - ); - - vm.prank(address(oracle)); - arbitratorModule.resolveDispute(_disputeId); - - // Check: is status now Resolved? - assertEq(uint256(arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); - } - - function test_revertsIfInvalidResolveStatus(bytes32 _disputeId, bytes32 _requestId, uint256 _status) public { - vm.assume(_status <= uint256(IOracle.DisputeStatus.Escalated)); - IOracle.DisputeStatus _arbitratorStatus = IOracle.DisputeStatus(_status); - - // Store the mock dispute - bytes memory _requestData = abi.encode(address(arbitrator)); - arbitratorModule.forTest_setRequestData(_requestId, _requestData); - - // Mock the dummy dispute - mockDispute.requestId = _requestId; - mockDispute.status = IOracle.DisputeStatus.Escalated; - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); - - // Mock and expect getAnswer to be called on the arbitrator - _mockAndExpect( - address(arbitrator), abi.encodeCall(arbitrator.getAnswer, (_disputeId)), abi.encode(_arbitratorStatus) - ); - - // Check: does it revert if the resolution status is invalid? - vm.expectRevert(abi.encodeWithSelector(IArbitratorModule.ArbitratorModule_InvalidResolutionStatus.selector)); - - vm.prank(address(oracle)); - arbitratorModule.resolveDispute(_disputeId); - } - - function test_emitsEvent(bytes32 _disputeId, bytes32 _requestId, uint256 _status) public { - vm.assume(_status <= uint256(IOracle.DisputeStatus.Lost)); - vm.assume(_status > uint256(IOracle.DisputeStatus.Escalated)); - IOracle.DisputeStatus _arbitratorStatus = IOracle.DisputeStatus(_status); - - // Store the mock dispute - bytes memory _requestData = abi.encode(address(arbitrator)); - arbitratorModule.forTest_setRequestData(_requestId, _requestData); - - // Mock the dummy dispute - mockDispute.requestId = _requestId; - mockDispute.status = IOracle.DisputeStatus.Escalated; - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); - - // Mock and expect getAnswer to be called on the arbitrator - _mockAndExpect( - address(arbitrator), abi.encodeCall(arbitrator.getAnswer, (_disputeId)), abi.encode(_arbitratorStatus) - ); - - // Mock and expect IOracle.updateDisputeStatus to be called - _mockAndExpect( - address(oracle), abi.encodeCall(oracle.updateDisputeStatus, (_disputeId, _arbitratorStatus)), abi.encode() - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(arbitratorModule)); - emit DisputeResolved(_requestId, _disputeId, _arbitratorStatus); - - vm.prank(address(oracle)); - arbitratorModule.resolveDispute(_disputeId); - } - - /** - * @notice resolve dispute reverts if the dispute status isn't Active - */ - function test_revertIfInvalidDispute(bytes32 _requestId, bytes32 _responseId, bytes32 _disputeId) public { - // Store the requestData - bytes memory _requestData = abi.encode(address(arbitrator)); - arbitratorModule.forTest_setRequestData(_requestId, _requestData); - - // Test the 3 different invalid status (None, Won, Lost) - for (uint256 _status; _status < uint256(type(IOracle.DisputeStatus).max); _status++) { - if (IOracle.DisputeStatus(_status) == IOracle.DisputeStatus.Escalated) continue; - // Create a new dummy dispute - IOracle.Dispute memory _dispute = IOracle.Dispute({ - createdAt: block.timestamp, - disputer: makeAddr('disputer'), - proposer: makeAddr('proposer'), - responseId: _responseId, - requestId: _requestId, - status: IOracle.DisputeStatus(_status) - }); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(_dispute)); - - // Check: does it revert if the dispute id is invalid? - vm.expectRevert(abi.encodeWithSelector(IArbitratorModule.ArbitratorModule_InvalidDisputeId.selector)); - - vm.prank(address(oracle)); - arbitratorModule.resolveDispute(_disputeId); - } - } - - /** - * @notice Test that the resolve function reverts if the caller isn't the arbitrator - */ - function test_revertIfWrongSender(bytes32 _disputeId, bytes32 _requestId, address _caller) public { - vm.assume(_caller != address(oracle)); - - // Store the mock dispute - bytes memory _requestData = abi.encode(address(arbitrator)); - arbitratorModule.forTest_setRequestData(_requestId, _requestData); - - // Check: does it revert if not called by the Oracle? - vm.expectRevert(IModule.Module_OnlyOracle.selector); - - vm.prank(_caller); - arbitratorModule.resolveDispute(_disputeId); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// ArbitratorModule, +// IArbitratorModule, +// IArbitrator +// } from '../../../../contracts/modules/resolution/ArbitratorModule.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ +// contract ForTest_ArbitratorModule is ArbitratorModule { +// constructor(IOracle _oracle) ArbitratorModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } + +// function forTest_setDisputeStatus(bytes32 _disputeId, IArbitratorModule.ArbitrationStatus _status) public { +// _disputeData[_disputeId] = _status; +// } +// } + +// /** +// * @title Arbitrator Module Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_ArbitratorModule public arbitratorModule; +// // A mock oracle +// IOracle public oracle; +// // A mock arbitrator +// IArbitrator public arbitrator; +// // Create a new dummy dispute +// IOracle.Dispute public mockDispute; + +// event ResolutionStarted(bytes32 indexed _requestId, bytes32 indexed _disputeId); +// event DisputeResolved(bytes32 indexed _requestId, bytes32 indexed _disputeId, IOracle.DisputeStatus _status); + +// /** +// * @notice Deploy the target and mock oracle +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// arbitrator = IArbitrator(makeAddr('MockArbitrator')); +// vm.etch(address(arbitrator), hex'069420'); + +// arbitratorModule = new ForTest_ArbitratorModule(oracle); + +// mockDispute = IOracle.Dispute({ +// createdAt: block.timestamp, +// disputer: makeAddr('disputer'), +// proposer: makeAddr('proposer'), +// responseId: bytes32('69'), +// requestId: bytes32('69'), +// status: IOracle.DisputeStatus.Active +// }); +// } +// } + +// contract ArbitratorModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleNameReturnsName() public { +// assertEq(arbitratorModule.moduleName(), 'ArbitratorModule'); +// } +// /** +// * @notice Test that the decodeRequestData function returns the correct values +// */ + +// function test_decodeRequestData(bytes32 _requestId, address _arbitrator) public { +// // Mock data +// bytes memory _requestData = abi.encode(address(_arbitrator)); + +// // Store the mock dispute +// arbitratorModule.forTest_setRequestData(_requestId, _requestData); + +// // Test: decode the given request data +// (address _arbitratorStored) = arbitratorModule.decodeRequestData(_requestId); + +// // Check: decoded values match original values? +// assertEq(_arbitratorStored, _arbitrator); +// } + +// /** +// * @notice Test that the status is correctly retrieved +// */ +// function test_getStatus(uint256 _status, bytes32 _disputeId) public { +// _status = bound(_status, 0, uint256(IArbitratorModule.ArbitrationStatus.Resolved)); +// IArbitratorModule.ArbitrationStatus _arbitratorStatus = IArbitratorModule.ArbitrationStatus(_status); + +// // Store the mock dispute +// arbitratorModule.forTest_setDisputeStatus(_disputeId, _arbitratorStatus); + +// // Check: The correct status is returned? +// assertEq(uint256(arbitratorModule.getStatus(_disputeId)), uint256(_status)); +// } +// } + +// contract ArbitratorModule_Unit_StartResolution is BaseTest { +// /** +// * @notice Test that the escalate function works as expected +// */ +// function test_startResolution(bytes32 _disputeId, bytes32 _requestId) public { +// // Mock and expect the dummy dispute +// mockDispute.requestId = _requestId; +// _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); + +// // Store the requestData +// bytes memory _requestData = abi.encode(address(arbitrator)); +// arbitratorModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock and expect the callback to the arbitrator +// _mockAndExpect(address(arbitrator), abi.encodeCall(arbitrator.resolve, (_disputeId)), abi.encode(bytes(''))); + +// vm.prank(address(oracle)); +// arbitratorModule.startResolution(_disputeId); + +// // Check: is status now Escalated? +// assertEq(uint256(arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Active)); +// } + +// function test_emitsEvent(bytes32 _disputeId, bytes32 _requestId) public { +// // Mock and expect the dummy dispute +// mockDispute.requestId = _requestId; +// _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); + +// // Store the requestData +// bytes memory _requestData = abi.encode(address(arbitrator)); +// arbitratorModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock and expect the callback to the arbitrator +// _mockAndExpect(address(arbitrator), abi.encodeCall(arbitrator.resolve, (_disputeId)), abi.encode(bytes(''))); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(arbitratorModule)); +// emit ResolutionStarted(_requestId, _disputeId); + +// vm.prank(address(oracle)); +// arbitratorModule.startResolution(_disputeId); +// } + +// function test_revertInvalidCaller(address _caller, bytes32 _disputeId) public { +// vm.assume(_caller != address(oracle)); + +// // Check: does it revert if the caller is not the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(_caller); +// arbitratorModule.startResolution(_disputeId); +// } + +// function test_revertIfEmptyArbitrator(bytes32 _disputeId, bytes32 _requestId) public { +// // Mock and expect the dummy dispute +// mockDispute.requestId = _requestId; +// _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); + +// // Store the requestData +// bytes memory _requestData = abi.encode(address(0)); +// arbitratorModule.forTest_setRequestData(_requestId, _requestData); + +// // Check: revert? +// vm.expectRevert(abi.encodeWithSelector(IArbitratorModule.ArbitratorModule_InvalidArbitrator.selector)); + +// // Test: escalate the dispute +// vm.prank(address(oracle)); +// arbitratorModule.startResolution(_disputeId); +// } +// } + +// contract ArbitratorModule_Unit_ResolveDispute is BaseTest { +// /** +// * @notice Test that the resolve function works as expected +// */ +// function test_resolveDispute(bytes32 _disputeId, bytes32 _requestId, uint256 _status) public { +// vm.assume(_status <= uint256(IOracle.DisputeStatus.Lost)); +// vm.assume(_status > uint256(IOracle.DisputeStatus.Escalated)); +// IOracle.DisputeStatus _arbitratorStatus = IOracle.DisputeStatus(_status); + +// // Store the mock dispute +// bytes memory _requestData = abi.encode(address(arbitrator)); +// arbitratorModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock the dummy dispute +// mockDispute.requestId = _requestId; +// mockDispute.status = IOracle.DisputeStatus.Escalated; + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); + +// // Mock and expect getAnswer to be called on the arbitrator +// _mockAndExpect( +// address(arbitrator), abi.encodeCall(arbitrator.getAnswer, (_disputeId)), abi.encode(_arbitratorStatus) +// ); + +// // Mock and expect IOracle.updateDisputeStatus to be called +// _mockAndExpect( +// address(oracle), abi.encodeCall(oracle.updateDisputeStatus, (_disputeId, _arbitratorStatus)), abi.encode() +// ); + +// vm.prank(address(oracle)); +// arbitratorModule.resolveDispute(_disputeId); + +// // Check: is status now Resolved? +// assertEq(uint256(arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); +// } + +// function test_revertsIfInvalidResolveStatus(bytes32 _disputeId, bytes32 _requestId, uint256 _status) public { +// vm.assume(_status <= uint256(IOracle.DisputeStatus.Escalated)); +// IOracle.DisputeStatus _arbitratorStatus = IOracle.DisputeStatus(_status); + +// // Store the mock dispute +// bytes memory _requestData = abi.encode(address(arbitrator)); +// arbitratorModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock the dummy dispute +// mockDispute.requestId = _requestId; +// mockDispute.status = IOracle.DisputeStatus.Escalated; + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); + +// // Mock and expect getAnswer to be called on the arbitrator +// _mockAndExpect( +// address(arbitrator), abi.encodeCall(arbitrator.getAnswer, (_disputeId)), abi.encode(_arbitratorStatus) +// ); + +// // Check: does it revert if the resolution status is invalid? +// vm.expectRevert(abi.encodeWithSelector(IArbitratorModule.ArbitratorModule_InvalidResolutionStatus.selector)); + +// vm.prank(address(oracle)); +// arbitratorModule.resolveDispute(_disputeId); +// } + +// function test_emitsEvent(bytes32 _disputeId, bytes32 _requestId, uint256 _status) public { +// vm.assume(_status <= uint256(IOracle.DisputeStatus.Lost)); +// vm.assume(_status > uint256(IOracle.DisputeStatus.Escalated)); +// IOracle.DisputeStatus _arbitratorStatus = IOracle.DisputeStatus(_status); + +// // Store the mock dispute +// bytes memory _requestData = abi.encode(address(arbitrator)); +// arbitratorModule.forTest_setRequestData(_requestId, _requestData); + +// // Mock the dummy dispute +// mockDispute.requestId = _requestId; +// mockDispute.status = IOracle.DisputeStatus.Escalated; + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(mockDispute)); + +// // Mock and expect getAnswer to be called on the arbitrator +// _mockAndExpect( +// address(arbitrator), abi.encodeCall(arbitrator.getAnswer, (_disputeId)), abi.encode(_arbitratorStatus) +// ); + +// // Mock and expect IOracle.updateDisputeStatus to be called +// _mockAndExpect( +// address(oracle), abi.encodeCall(oracle.updateDisputeStatus, (_disputeId, _arbitratorStatus)), abi.encode() +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(arbitratorModule)); +// emit DisputeResolved(_requestId, _disputeId, _arbitratorStatus); + +// vm.prank(address(oracle)); +// arbitratorModule.resolveDispute(_disputeId); +// } + +// /** +// * @notice resolve dispute reverts if the dispute status isn't Active +// */ +// function test_revertIfInvalidDispute(bytes32 _requestId, bytes32 _responseId, bytes32 _disputeId) public { +// // Store the requestData +// bytes memory _requestData = abi.encode(address(arbitrator)); +// arbitratorModule.forTest_setRequestData(_requestId, _requestData); + +// // Test the 3 different invalid status (None, Won, Lost) +// for (uint256 _status; _status < uint256(type(IOracle.DisputeStatus).max); _status++) { +// if (IOracle.DisputeStatus(_status) == IOracle.DisputeStatus.Escalated) continue; +// // Create a new dummy dispute +// IOracle.Dispute memory _dispute = IOracle.Dispute({ +// createdAt: block.timestamp, +// disputer: makeAddr('disputer'), +// proposer: makeAddr('proposer'), +// responseId: _responseId, +// requestId: _requestId, +// status: IOracle.DisputeStatus(_status) +// }); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(oracle.getDispute, (_disputeId)), abi.encode(_dispute)); + +// // Check: does it revert if the dispute id is invalid? +// vm.expectRevert(abi.encodeWithSelector(IArbitratorModule.ArbitratorModule_InvalidDisputeId.selector)); + +// vm.prank(address(oracle)); +// arbitratorModule.resolveDispute(_disputeId); +// } +// } + +// /** +// * @notice Test that the resolve function reverts if the caller isn't the arbitrator +// */ +// function test_revertIfWrongSender(bytes32 _disputeId, bytes32 _requestId, address _caller) public { +// vm.assume(_caller != address(oracle)); + +// // Store the mock dispute +// bytes memory _requestData = abi.encode(address(arbitrator)); +// arbitratorModule.forTest_setRequestData(_requestId, _requestData); + +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(IModule.Module_OnlyOracle.selector); + +// vm.prank(_caller); +// arbitratorModule.resolveDispute(_disputeId); +// } +// } diff --git a/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol b/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol index 000c9303..ff2a859c 100644 --- a/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol @@ -1,1191 +1,1191 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {Strings} from '@openzeppelin/contracts/utils/Strings.sol'; -import {FixedPointMathLib} from 'solmate/utils/FixedPointMathLib.sol'; - -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - BondEscalationResolutionModule, - IBondEscalationResolutionModule -} from '../../../../contracts/modules/resolution/BondEscalationResolutionModule.sol'; -import {IBondEscalationAccounting} from '../../../../interfaces/extensions/IBondEscalationAccounting.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ - -contract ForTest_BondEscalationResolutionModule is BondEscalationResolutionModule { - constructor(IOracle _oracle) BondEscalationResolutionModule(_oracle) {} - - function forTest_setRequestData( - bytes32 _requestId, - uint256 _percentageDiff, - uint256 _pledgeThreshold, - uint256 _timeUntilDeadline, - uint256 _timeToBreakInequality, - IBondEscalationAccounting _accounting, - IERC20 _token - ) public { - bytes memory _data = - abi.encode(_accounting, _token, _percentageDiff, _pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality); - requestData[_requestId] = _data; - } - - function forTest_setEscalation( - bytes32 _disputeId, - IBondEscalationResolutionModule.Resolution _resolution, - uint128 _startTime, - uint256 _pledgesFor, - uint256 _pledgesAgainst - ) public { - BondEscalationResolutionModule.Escalation memory _escalation = - IBondEscalationResolutionModule.Escalation(_resolution, _startTime, _pledgesFor, _pledgesAgainst); - escalations[_disputeId] = _escalation; - } - - function forTest_setInequalityData( - bytes32 _disputeId, - IBondEscalationResolutionModule.InequalityStatus _inequalityStatus, - uint256 _time - ) public { - BondEscalationResolutionModule.InequalityData memory _inequalityData = - IBondEscalationResolutionModule.InequalityData(_inequalityStatus, _time); - inequalityData[_disputeId] = _inequalityData; - } - - function forTest_setPledgesFor(bytes32 _disputeId, address _pledger, uint256 _pledge) public { - pledgesForDispute[_disputeId][_pledger] = _pledge; - } - - function forTest_setPledgesAgainst(bytes32 _disputeId, address _pledger, uint256 _pledge) public { - pledgesAgainstDispute[_disputeId][_pledger] = _pledge; - } -} - -/** - * @title Bonded Escalation Resolution Module Unit tests - */ - -contract BaseTest is Test, Helpers { - struct FakeDispute { - bytes32 requestId; - bytes32 test; - } - - struct FakeRequest { - address disputeModule; - } - - // The target contract - ForTest_BondEscalationResolutionModule public module; - // A mock oracle - IOracle public oracle; - // A mock accounting extension - IBondEscalationAccounting public accounting; - // A mock token - IERC20 public token; - // Mock EOA proposer - address public proposer = makeAddr('proposer'); - // Mock EOA disputer - address public disputer = makeAddr('disputer'); - // Mock EOA pledgerFor - address public pledgerFor = makeAddr('pledgerFor'); - // Mock EOA pledgerAgainst - address public pledgerAgainst = makeAddr('pledgerAgainst'); - // Mock percentageDiff - uint256 public percentageDiff; - // Mock pledge threshold - uint256 public pledgeThreshold; - // Mock time until main deadline - uint256 public timeUntilDeadline; - // Mock time to break inequality - uint256 public timeToBreakInequality; - - // Events - event DisputeResolved(bytes32 indexed _requestId, bytes32 indexed _disputeId, IOracle.DisputeStatus _status); - - event ResolutionStarted(bytes32 indexed _requestId, bytes32 indexed _disputeId); - - event PledgedForDispute( - address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, uint256 _pledgedAmount - ); - - event PledgedAgainstDispute( - address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, uint256 _pledgedAmount - ); - - event PledgeClaimed( - bytes32 indexed _requestId, - bytes32 indexed _disputeId, - address indexed _pledger, - IERC20 _token, - uint256 _pledgeReleased, - IBondEscalationResolutionModule.Resolution _resolution - ); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - accounting = IBondEscalationAccounting(makeAddr('AccountingExtension')); - vm.etch(address(accounting), hex'069420'); - - token = IERC20(makeAddr('ERC20')); - vm.etch(address(token), hex'069420'); - - // Avoid starting at 0 for time sensitive tests - vm.warp(123_456); - - module = new ForTest_BondEscalationResolutionModule(oracle); - } - - function _createPledgers( - uint256 _numOfPledgers, - uint256 _amount - ) internal returns (address[] memory _pledgers, uint256[] memory _pledgedAmounts) { - _pledgers = new address[](_numOfPledgers); - _pledgedAmounts = new uint256[](_numOfPledgers); - address _pledger; - uint256 _pledge; - - for (uint256 _i; _i < _numOfPledgers; _i++) { - _pledger = makeAddr(string.concat('pledger', Strings.toString(_i))); - _pledgers[_i] = _pledger; - } - - for (uint256 _j; _j < _numOfPledgers; _j++) { - _pledge = _amount / (_j + 100); - _pledgedAmounts[_j] = _pledge; - } - - return (_pledgers, _pledgedAmounts); - } -} - -contract BondEscalationResolutionModule_Unit_ModuleData is BaseTest { - function test_decodeRequestDataReturnTheCorrectData( - bytes32 _requestId, - uint256 _percentageDiff, - uint256 _pledgeThreshold, - uint256 _timeUntilDeadline, - uint256 _timeToBreakInequality - ) public { - // Storing fuzzed data - module.forTest_setRequestData( - _requestId, _percentageDiff, _pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token - ); - - IBondEscalationResolutionModule.RequestParameters memory _params = module.decodeRequestData(_requestId); - - // Check: do the stored values match? - assertEq(address(accounting), address(_params.accountingExtension)); - assertEq(address(token), address(_params.bondToken)); - assertEq(_percentageDiff, _params.percentageDiff); - assertEq(_pledgeThreshold, _params.pledgeThreshold); - assertEq(_timeUntilDeadline, _params.timeUntilDeadline); - assertEq(_timeToBreakInequality, _params.timeToBreakInequality); - } - - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleName() public { - assertEq(module.moduleName(), 'BondEscalationResolutionModule'); - } -} - -contract BondEscalationResolutionModule_Unit_StartResolution is BaseTest { - function test_startResolution(bytes32 _disputeId, bytes32 _requestId) public { - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Check: does it revert if the caller is not the Oracle? - vm.expectRevert(IModule.Module_OnlyOracle.selector); - module.startResolution(_disputeId); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit ResolutionStarted(_requestId, _disputeId); - - vm.prank(address(oracle)); - module.startResolution(_disputeId); - - (, uint128 _startTime,,) = module.escalations(_disputeId); - // Check: is the escalation start time set to block.timestamp? - assertEq(_startTime, uint128(block.timestamp)); - } -} - -contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { - function test_reverts(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) public { - // Mock escalation with start time 0 - module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 0, 0, 0); - - // Check: does it revert if the dispute is not escalated? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotEscalated.selector); - module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); - - // Mock escalation with start time 1 - module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, 0, 0); - - uint256 _timeUntilDeadline = block.timestamp - 1; - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, _timeUntilDeadline, timeToBreakInequality, accounting, token - ); - - // Check: does it revert if the pledging phase is over? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_PledgingPhaseOver.selector); - module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); - - IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = - IBondEscalationResolutionModule.InequalityStatus.AgainstTurnToEqualize; - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - - // Mock escalation with start time equal to current timestamp - module.forTest_setEscalation( - _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, uint128(block.timestamp), 0, 0 - ); - - _timeUntilDeadline = 10_000; - uint256 _timeToBreakInequality = 5000; - - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token - ); - - vm.warp(block.timestamp + _timeToBreakInequality); - - // Check: does it revert if inequality timer has passed? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_MustBeResolved.selector); - module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); - - vm.warp(block.timestamp - _timeToBreakInequality - 1); // Not past the deadline anymore - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - - // Mock and expect the pledge call - _mockAndExpect( - address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, token, _pledgeAmount)), - abi.encode() - ); - - // Check: does it revert if status == AgainstTurnToEqualize? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_AgainstTurnToEqualize.selector); - vm.prank(pledgerFor); - module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); - } - - function test_earlyReturnIfThresholdNotSurpassed( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _pledgeAmount - ) public { - vm.assume(_pledgeAmount < type(uint256).max - 1000); - IBondEscalationResolutionModule.Resolution _resolution = IBondEscalationResolutionModule.Resolution.Unresolved; - - // block.timestamp < _startTime + _timeUntilDeadline - uint128 _startTime = uint128(block.timestamp - 1000); - uint256 _timeUntilDeadline = 1001; - - // _pledgeThreshold > _updatedTotalVotes; - uint256 _pledgesFor = 1000; - uint256 _pledgesAgainst = 1000; - uint256 _pledgeThreshold = _pledgesFor + _pledgesAgainst + _pledgeAmount + 1; - - // block.timestamp < _inequalityData.time + _timeToBreakInequality - uint256 _timeToBreakInequality = 5000; - - // assuming the threshold has not passed, this is the only valid state - IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = - IBondEscalationResolutionModule.InequalityStatus.Equalized; - - // set all data - module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); - module.forTest_setRequestData( - _requestId, percentageDiff, _pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token - ); - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - - // Mock and expect IBondEscalationAccounting.pledge to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, token, _pledgeAmount)), - abi.encode() - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); - - vm.startPrank(pledgerFor); - module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); - - (,, uint256 _realPledgesFor,) = module.escalations(_disputeId); - (IBondEscalationResolutionModule.InequalityStatus _status,) = module.inequalityData(_disputeId); - - // Check: is the pledge amount added to the total? - assertEq(_realPledgesFor, _pledgesFor + _pledgeAmount); - // Check: is the pledges for dispute amount updated? - assertEq(module.pledgesForDispute(_disputeId, pledgerFor), _pledgeAmount); - // Check: is the status properly updated? - assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.Equalized)); - } - - function test_percentageDifferences(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) public { - ////////////////////////////////////////////////////////////////////// - // START TEST _forPercentageDifference >= _scaledPercentageDiffAsInt - ////////////////////////////////////////////////////////////////////// - - _pledgeAmount = bound(_pledgeAmount, 1, type(uint192).max); - IBondEscalationResolutionModule.Resolution _resolution = IBondEscalationResolutionModule.Resolution.Unresolved; - - // block.timestamp < _startTime + _timeUntilDeadline - uint128 _startTime = uint128(block.timestamp - 1000); - uint256 _timeUntilDeadline = 1001; - - // I'm setting the values so that the percentage diff is 20% in favor of pledgesFor. - // In this case, _pledgeAmount will be the entirety of pledgesFor, as if it were the first pledge. - // Therefore, _pledgeAmount must be 60% of total votes, _pledgesAgainst then should be 40% - // 40 = 60 * 2 / 3 -> thats why I'm multiplying by 200 and dividing by 300 - uint256 _pledgesFor = 0; - uint256 _pledgesAgainst = _pledgeAmount * 200 / 300; - uint256 _percentageDiff = 20; - - // block.timestamp < _inequalityData.time + _timeToBreakInequality - uint256 _timeToBreakInequality = 5000; - - IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = - IBondEscalationResolutionModule.InequalityStatus.Equalized; - - // Set all data - module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); - module.forTest_setRequestData( - _requestId, _percentageDiff, pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token - ); - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - - // Mock and expect IBondEscalationAccounting.pledge to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, token, _pledgeAmount)), - abi.encode() - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); - - vm.startPrank(pledgerFor); - module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); - - (,, uint256 _realPledgesFor,) = module.escalations(_disputeId); - (IBondEscalationResolutionModule.InequalityStatus _status, uint256 _timer) = module.inequalityData(_disputeId); - - // Check: is the pledge amount added to the total? - assertEq(_realPledgesFor, _pledgesFor + _pledgeAmount); - // Check: is the pledge for dispute amount updated? - assertEq(module.pledgesForDispute(_disputeId, pledgerFor), _pledgeAmount); - // Check: is the status properly updated? - assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.AgainstTurnToEqualize)); - // Check: is the timer properly updated to current timestamp? - assertEq(uint256(_timer), block.timestamp); - - //////////////////////////////////////////////////////////////////// - // END TEST _forPercentageDifference >= _scaledPercentageDiffAsInt - //////////////////////////////////////////////////////////////////// - - //----------------------------------------------------------------------// - - ////////////////////////////////////////////////////////////////////////// - // START TEST _againstPercentageDifference >= _scaledPercentageDiffAsInt - ///////////////////////////////////////////////////////////////////////// - - // Resetting status changed by previous test - _inequalityStatus = IBondEscalationResolutionModule.InequalityStatus.ForTurnToEqualize; - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - module.forTest_setPledgesFor(_disputeId, pledgerFor, 0); - - // Making the against percentage 60% of the total as percentageDiff is 20% - // Note: I'm using 301 to account for rounding down errors. I'm also setting some _pledgesFor - // to avoid the case when pledges are at 0 and someone just pledges 1 token - // which is not realistic due to the pledgeThreshold forbidding the lines tested here - // to be reached. - _pledgesFor = 100_000; - _pledgesAgainst = (_pledgeAmount + _pledgesFor) * 301 / 200; - - // Resetting the pledges values - module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); - - module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); - - (,, _realPledgesFor,) = module.escalations(_disputeId); - (_status, _timer) = module.inequalityData(_disputeId); - - // Check: is the pledge amount added to the total? - assertEq(_realPledgesFor, _pledgesFor + _pledgeAmount); - // Check: is the pledges for amount updated? - assertEq(module.pledgesForDispute(_disputeId, pledgerFor), _pledgeAmount); - // Check: is the status properly updated? - assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.ForTurnToEqualize)); - - //////////////////////////////////////////////////////////////////// - // END TEST _forPercentageDifference >= _scaledPercentageDiffAsInt - //////////////////////////////////////////////////////////////////// - - //----------------------------------------------------------------------// - - ////////////////////////////////////////////////////////////////////////// - // START TEST _status == forTurnToEqualize && both diffs < percentageDiff - ///////////////////////////////////////////////////////////////////////// - - // Resetting status changed by previous test - module.forTest_setPledgesFor(_disputeId, pledgerFor, 0); - - // Making both the same so the percentage diff is not reached - _pledgesFor = 100_000; - _pledgesAgainst = (_pledgeAmount + _pledgesFor); - - // Resetting the pledges values - module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); - - module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); - - (,, _realPledgesFor,) = module.escalations(_disputeId); - (_status, _timer) = module.inequalityData(_disputeId); - - // Check: is the pledge amount added to the total? - assertEq(_realPledgesFor, _pledgesFor + _pledgeAmount); - // Check: is the pledges for amount updated? - assertEq(module.pledgesForDispute(_disputeId, pledgerFor), _pledgeAmount); - // Check: is the status properly updated? - assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.Equalized)); - // Check: is the timer reset? - assertEq(_timer, 0); - - ////////////////////////////////////////////////////////////////////////// - // END TEST _status == forTurnToEqualize && both diffs < percentageDiff - ///////////////////////////////////////////////////////////////////////// - } -} - -contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { - function test_reverts(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) public { - // Set mock escalation with no pledges and start time 0 - module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 0, 0, 0); - - // Check: does it revert if the dispute is not escalated? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotEscalated.selector); - module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); - - // Set mock escalation with no pledges and start time 1 - module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, 0, 0); - - uint256 _timeUntilDeadline = block.timestamp - 1; - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, _timeUntilDeadline, timeToBreakInequality, accounting, token - ); - - // Check: does it revert if the pledging phase is over? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_PledgingPhaseOver.selector); - module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); - - IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = - IBondEscalationResolutionModule.InequalityStatus.ForTurnToEqualize; - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - - // Set mock escalation with no pledges and start time == block.timestamp - module.forTest_setEscalation( - _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, uint128(block.timestamp), 0, 0 - ); - - _timeUntilDeadline = 10_000; - uint256 _timeToBreakInequality = 5000; - - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token - ); - - vm.warp(block.timestamp + _timeToBreakInequality); - - // Check: does it revert if inequality timer has passed? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_MustBeResolved.selector); - module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); - - vm.warp(block.timestamp - _timeToBreakInequality - 1); // Not past the deadline anymore - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - - // Mock and expect the pledge call - _mockAndExpect( - address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, _requestId, _disputeId, token, _pledgeAmount)), - abi.encode() - ); - - // Check: does it revert if status == AgainstTurnToEqualize? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_ForTurnToEqualize.selector); - vm.prank(pledgerAgainst); - module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); - } - - function test_earlyReturnIfThresholdNotSurpassed( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _pledgeAmount - ) public { - vm.assume(_pledgeAmount < type(uint256).max - 1000); - IBondEscalationResolutionModule.Resolution _resolution = IBondEscalationResolutionModule.Resolution.Unresolved; - - // block.timestamp < _startTime + _timeUntilDeadline - uint128 _startTime = uint128(block.timestamp - 1000); - uint256 _timeUntilDeadline = 1001; - - // _pledgeThreshold > _updatedTotalVotes; - uint256 _pledgesFor = 1000; - uint256 _pledgesAgainst = 1000; - uint256 _pledgeThreshold = _pledgesFor + _pledgesAgainst + _pledgeAmount + 1; - - // block.timestamp < _inequalityData.time + _timeToBreakInequality - uint256 _timeToBreakInequality = 5000; - - // Assuming the threshold has not passed, this is the only valid state - IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = - IBondEscalationResolutionModule.InequalityStatus.Equalized; - - // Set all data - module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); - module.forTest_setRequestData( - _requestId, percentageDiff, _pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token - ); - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - - // Mock and expect IBondEscalationAccounting.pledge to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, _requestId, _disputeId, token, _pledgeAmount)), - abi.encode() - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); - - vm.startPrank(pledgerAgainst); - module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); - - (,,, uint256 _realPledgesAgainst) = module.escalations(_disputeId); - (IBondEscalationResolutionModule.InequalityStatus _status,) = module.inequalityData(_disputeId); - // asdf - - // Check: is the pledge amount added to the total? - assertEq(_realPledgesAgainst, _pledgesAgainst + _pledgeAmount); - // Check: is the pledges against amount updated? - assertEq(module.pledgesAgainstDispute(_disputeId, pledgerAgainst), _pledgeAmount); - // Check: is the status properly updated? - assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.Equalized)); - } - - function test_percentageDifferences(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) public { - _pledgeAmount = bound(_pledgeAmount, 1, type(uint192).max); - IBondEscalationResolutionModule.Resolution _resolution = IBondEscalationResolutionModule.Resolution.Unresolved; - - ////////////////////////////////////////////////////////////////////////// - // START TEST _againstPercentageDifference >= _scaledPercentageDiffAsInt - ///////////////////////////////////////////////////////////////////////// - - // block.timestamp < _startTime + _timeUntilDeadline - uint128 _startTime = uint128(block.timestamp - 1000); - uint256 _timeUntilDeadline = 1001; - - // I'm setting the values so that the percentage diff is 20% in favor of pledgesAgainst. - // In this case, _pledgeAmount will be the entirety of pledgesAgainst, as if it were the first pledge. - // Therefore, _pledgeAmount must be 60% of total votes, _pledgesFor then should be 40% - // 40 = 60 * 2 / 3 -> thats why I'm multiplying by 200 and dividing by 300 - uint256 _pledgesAgainst = 0; - uint256 _pledgesFor = _pledgeAmount * 200 / 300; - uint256 _percentageDiff = 20; - - // block.timestamp < _inequalityData.time + _timeToBreakInequality - uint256 _timeToBreakInequality = 5000; - - IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = - IBondEscalationResolutionModule.InequalityStatus.Equalized; - - // Set all data - module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); - module.forTest_setRequestData( - _requestId, _percentageDiff, pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token - ); - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - - // Mock and expect IBondEscalationAccounting.pledge to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, _requestId, _disputeId, token, _pledgeAmount)), - abi.encode() - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); - - vm.startPrank(pledgerAgainst); - module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); - - (,,, uint256 _realPledgesAgainst) = module.escalations(_disputeId); - (IBondEscalationResolutionModule.InequalityStatus _status, uint256 _timer) = module.inequalityData(_disputeId); - - // Check: is the pledge amount added to the total? - assertEq(_realPledgesAgainst, _pledgesAgainst + _pledgeAmount); - // Check: is the pledges against amount updated? - assertEq(module.pledgesAgainstDispute(_disputeId, pledgerAgainst), _pledgeAmount); - // Check: is the status properly updated? - assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.ForTurnToEqualize)); - // Check: is the timer properly updated? - assertEq(uint256(_timer), block.timestamp); - - /////////////////////////////////////////////////////////////////////// - // END TEST _againstPercentageDifference >= _scaledPercentageDiffAsInt - /////////////////////////////////////////////////////////////////////// - - //----------------------------------------------------------------------// - - ////////////////////////////////////////////////////////////////////////// - // START TEST _forPercentageDifference >= _scaledPercentageDiffAsInt - ///////////////////////////////////////////////////////////////////////// - - // Resetting status changed by previous test - _inequalityStatus = IBondEscalationResolutionModule.InequalityStatus.AgainstTurnToEqualize; - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - module.forTest_setPledgesAgainst(_disputeId, pledgerAgainst, 0); - - // Making the for percentage 60% of the total as percentageDiff is 20% - // Note: I'm using 301 to account for rounding down errors. I'm also setting some _pledgesAgainst - // to avoid the case when pledges are at 0 and someone just pledges 1 token - // which is not realistic due to the pledgeThreshold forbidding the lines tested here - // to be reached. - _pledgesAgainst = 100_000; - _pledgesFor = (_pledgeAmount + _pledgesAgainst) * 301 / 200; - - // Resetting the pledges values - module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); - - module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); - - (,,, _realPledgesAgainst) = module.escalations(_disputeId); - (_status, _timer) = module.inequalityData(_disputeId); - - // Check: is the pledge amount added to the total? - assertEq(_realPledgesAgainst, _pledgesAgainst + _pledgeAmount); - // Check: is the pledges against amount updated? - assertEq(module.pledgesAgainstDispute(_disputeId, pledgerAgainst), _pledgeAmount); - // Check: is the status properly updated? - assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.AgainstTurnToEqualize)); - - //////////////////////////////////////////////////////////////////// - // END TEST _forPercentageDifference >= _scaledPercentageDiffAsInt - //////////////////////////////////////////////////////////////////// - - //----------------------------------------------------------------------// - - ////////////////////////////////////////////////////////////////////////// - // START TEST _status == forTurnToEqualize && both diffs < percentageDiff - ///////////////////////////////////////////////////////////////////////// - - // Resetting status changed by previous test - module.forTest_setPledgesAgainst(_disputeId, pledgerAgainst, 0); - - // Making both the same so the percentage diff is not reached - _pledgesAgainst = 100_000; - _pledgesFor = (_pledgeAmount + _pledgesAgainst); - - // Resetting the pledges values - module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); - - module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); - - (,,, _realPledgesAgainst) = module.escalations(_disputeId); - (_status, _timer) = module.inequalityData(_disputeId); - - // Check: is the pledge amount added to the total? - assertEq(_realPledgesAgainst, _pledgesAgainst + _pledgeAmount); - // Check: is the pledges against amount updated? - assertEq(module.pledgesAgainstDispute(_disputeId, pledgerAgainst), _pledgeAmount); - // Check: is the status properly updated? - assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.Equalized)); - // Check: is the timer properly reset? - assertEq(_timer, 0); - - ////////////////////////////////////////////////////////////////////////// - // END TEST _status == forTurnToEqualize && both diffs < percentageDiff - ///////////////////////////////////////////////////////////////////////// - } -} - -contract BondEscalationResolutionModule_Unit_ResolveDispute is BaseTest { - /* - Specs: - 0. Should revert if the resolution status is different than Unresolved - done - 1. Should revert if the dispute is not escalated (startTime == 0) - done - 2. Should revert if the main deadline has not be reached and the inequality timer has not culminated - done - - 3. After resolve, if the pledges from both sides never reached the threshold, or if the pledges of both sides end up tied - it should set the resolution status to NoResolution. TODO: and do the appropriate calls. - 4. After resolve, if the pledges for the disputer were more than the pledges against him, then it should - set the resolution state to DisputerWon and call the oracle to update the status with Won. Also emit event. - 5. Same as 4 but with DisputerLost, and Lost when the pledges against the disputer were more than the pledges in favor of - the disputer. - */ - - function test_reverts(bytes32 _requestId, bytes32 _disputeId) public { - // Set mock escalation with resolution == DisputerWon - module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.DisputerWon, 0, 0, 0); - - // Check: does it revert if the status is different than resolved? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_AlreadyResolved.selector); - - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - - // Set mock escalation with resolution == Unresolved - module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 0, 0, 0); - - // Check: does it revert if the dispute is not escalated? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotEscalated.selector); - - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {Strings} from '@openzeppelin/contracts/utils/Strings.sol'; +// import {FixedPointMathLib} from 'solmate/utils/FixedPointMathLib.sol'; + +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// BondEscalationResolutionModule, +// IBondEscalationResolutionModule +// } from '../../../../contracts/modules/resolution/BondEscalationResolutionModule.sol'; +// import {IBondEscalationAccounting} from '../../../../interfaces/extensions/IBondEscalationAccounting.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ + +// contract ForTest_BondEscalationResolutionModule is BondEscalationResolutionModule { +// constructor(IOracle _oracle) BondEscalationResolutionModule(_oracle) {} + +// function forTest_setRequestData( +// bytes32 _requestId, +// uint256 _percentageDiff, +// uint256 _pledgeThreshold, +// uint256 _timeUntilDeadline, +// uint256 _timeToBreakInequality, +// IBondEscalationAccounting _accounting, +// IERC20 _token +// ) public { +// bytes memory _data = +// abi.encode(_accounting, _token, _percentageDiff, _pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality); +// requestData[_requestId] = _data; +// } + +// function forTest_setEscalation( +// bytes32 _disputeId, +// IBondEscalationResolutionModule.Resolution _resolution, +// uint128 _startTime, +// uint256 _pledgesFor, +// uint256 _pledgesAgainst +// ) public { +// BondEscalationResolutionModule.Escalation memory _escalation = +// IBondEscalationResolutionModule.Escalation(_resolution, _startTime, _pledgesFor, _pledgesAgainst); +// escalations[_disputeId] = _escalation; +// } + +// function forTest_setInequalityData( +// bytes32 _disputeId, +// IBondEscalationResolutionModule.InequalityStatus _inequalityStatus, +// uint256 _time +// ) public { +// BondEscalationResolutionModule.InequalityData memory _inequalityData = +// IBondEscalationResolutionModule.InequalityData(_inequalityStatus, _time); +// inequalityData[_disputeId] = _inequalityData; +// } + +// function forTest_setPledgesFor(bytes32 _disputeId, address _pledger, uint256 _pledge) public { +// pledgesForDispute[_disputeId][_pledger] = _pledge; +// } + +// function forTest_setPledgesAgainst(bytes32 _disputeId, address _pledger, uint256 _pledge) public { +// pledgesAgainstDispute[_disputeId][_pledger] = _pledge; +// } +// } + +// /** +// * @title Bonded Escalation Resolution Module Unit tests +// */ + +// contract BaseTest is Test, Helpers { +// struct FakeDispute { +// bytes32 requestId; +// bytes32 test; +// } + +// struct FakeRequest { +// address disputeModule; +// } + +// // The target contract +// ForTest_BondEscalationResolutionModule public module; +// // A mock oracle +// IOracle public oracle; +// // A mock accounting extension +// IBondEscalationAccounting public accounting; +// // A mock token +// IERC20 public token; +// // Mock EOA proposer +// address public proposer = makeAddr('proposer'); +// // Mock EOA disputer +// address public disputer = makeAddr('disputer'); +// // Mock EOA pledgerFor +// address public pledgerFor = makeAddr('pledgerFor'); +// // Mock EOA pledgerAgainst +// address public pledgerAgainst = makeAddr('pledgerAgainst'); +// // Mock percentageDiff +// uint256 public percentageDiff; +// // Mock pledge threshold +// uint256 public pledgeThreshold; +// // Mock time until main deadline +// uint256 public timeUntilDeadline; +// // Mock time to break inequality +// uint256 public timeToBreakInequality; + +// // Events +// event DisputeResolved(bytes32 indexed _requestId, bytes32 indexed _disputeId, IOracle.DisputeStatus _status); + +// event ResolutionStarted(bytes32 indexed _requestId, bytes32 indexed _disputeId); + +// event PledgedForDispute( +// address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, uint256 _pledgedAmount +// ); + +// event PledgedAgainstDispute( +// address indexed _pledger, bytes32 indexed _requestId, bytes32 indexed _disputeId, uint256 _pledgedAmount +// ); + +// event PledgeClaimed( +// bytes32 indexed _requestId, +// bytes32 indexed _disputeId, +// address indexed _pledger, +// IERC20 _token, +// uint256 _pledgeReleased, +// IBondEscalationResolutionModule.Resolution _resolution +// ); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// accounting = IBondEscalationAccounting(makeAddr('AccountingExtension')); +// vm.etch(address(accounting), hex'069420'); + +// token = IERC20(makeAddr('ERC20')); +// vm.etch(address(token), hex'069420'); + +// // Avoid starting at 0 for time sensitive tests +// vm.warp(123_456); + +// module = new ForTest_BondEscalationResolutionModule(oracle); +// } + +// function _createPledgers( +// uint256 _numOfPledgers, +// uint256 _amount +// ) internal returns (address[] memory _pledgers, uint256[] memory _pledgedAmounts) { +// _pledgers = new address[](_numOfPledgers); +// _pledgedAmounts = new uint256[](_numOfPledgers); +// address _pledger; +// uint256 _pledge; + +// for (uint256 _i; _i < _numOfPledgers; _i++) { +// _pledger = makeAddr(string.concat('pledger', Strings.toString(_i))); +// _pledgers[_i] = _pledger; +// } + +// for (uint256 _j; _j < _numOfPledgers; _j++) { +// _pledge = _amount / (_j + 100); +// _pledgedAmounts[_j] = _pledge; +// } + +// return (_pledgers, _pledgedAmounts); +// } +// } + +// contract BondEscalationResolutionModule_Unit_ModuleData is BaseTest { +// function test_decodeRequestDataReturnTheCorrectData( +// bytes32 _requestId, +// uint256 _percentageDiff, +// uint256 _pledgeThreshold, +// uint256 _timeUntilDeadline, +// uint256 _timeToBreakInequality +// ) public { +// // Storing fuzzed data +// module.forTest_setRequestData( +// _requestId, _percentageDiff, _pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token +// ); + +// IBondEscalationResolutionModule.RequestParameters memory _params = module.decodeRequestData(_requestId); + +// // Check: do the stored values match? +// assertEq(address(accounting), address(_params.accountingExtension)); +// assertEq(address(token), address(_params.bondToken)); +// assertEq(_percentageDiff, _params.percentageDiff); +// assertEq(_pledgeThreshold, _params.pledgeThreshold); +// assertEq(_timeUntilDeadline, _params.timeUntilDeadline); +// assertEq(_timeToBreakInequality, _params.timeToBreakInequality); +// } + +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleName() public { +// assertEq(module.moduleName(), 'BondEscalationResolutionModule'); +// } +// } + +// contract BondEscalationResolutionModule_Unit_StartResolution is BaseTest { +// function test_startResolution(bytes32 _disputeId, bytes32 _requestId) public { +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Check: does it revert if the caller is not the Oracle? +// vm.expectRevert(IModule.Module_OnlyOracle.selector); +// module.startResolution(_disputeId); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit ResolutionStarted(_requestId, _disputeId); + +// vm.prank(address(oracle)); +// module.startResolution(_disputeId); + +// (, uint128 _startTime,,) = module.escalations(_disputeId); +// // Check: is the escalation start time set to block.timestamp? +// assertEq(_startTime, uint128(block.timestamp)); +// } +// } + +// contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { +// function test_reverts(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) public { +// // Mock escalation with start time 0 +// module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 0, 0, 0); + +// // Check: does it revert if the dispute is not escalated? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotEscalated.selector); +// module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); + +// // Mock escalation with start time 1 +// module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, 0, 0); + +// uint256 _timeUntilDeadline = block.timestamp - 1; +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, _timeUntilDeadline, timeToBreakInequality, accounting, token +// ); + +// // Check: does it revert if the pledging phase is over? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_PledgingPhaseOver.selector); +// module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); + +// IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = +// IBondEscalationResolutionModule.InequalityStatus.AgainstTurnToEqualize; +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); + +// // Mock escalation with start time equal to current timestamp +// module.forTest_setEscalation( +// _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, uint128(block.timestamp), 0, 0 +// ); + +// _timeUntilDeadline = 10_000; +// uint256 _timeToBreakInequality = 5000; + +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token +// ); + +// vm.warp(block.timestamp + _timeToBreakInequality); + +// // Check: does it revert if inequality timer has passed? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_MustBeResolved.selector); +// module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); + +// vm.warp(block.timestamp - _timeToBreakInequality - 1); // Not past the deadline anymore +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); + +// // Mock and expect the pledge call +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, token, _pledgeAmount)), +// abi.encode() +// ); + +// // Check: does it revert if status == AgainstTurnToEqualize? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_AgainstTurnToEqualize.selector); +// vm.prank(pledgerFor); +// module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); +// } + +// function test_earlyReturnIfThresholdNotSurpassed( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _pledgeAmount +// ) public { +// vm.assume(_pledgeAmount < type(uint256).max - 1000); +// IBondEscalationResolutionModule.Resolution _resolution = IBondEscalationResolutionModule.Resolution.Unresolved; + +// // block.timestamp < _startTime + _timeUntilDeadline +// uint128 _startTime = uint128(block.timestamp - 1000); +// uint256 _timeUntilDeadline = 1001; + +// // _pledgeThreshold > _updatedTotalVotes; +// uint256 _pledgesFor = 1000; +// uint256 _pledgesAgainst = 1000; +// uint256 _pledgeThreshold = _pledgesFor + _pledgesAgainst + _pledgeAmount + 1; + +// // block.timestamp < _inequalityData.time + _timeToBreakInequality +// uint256 _timeToBreakInequality = 5000; + +// // assuming the threshold has not passed, this is the only valid state +// IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = +// IBondEscalationResolutionModule.InequalityStatus.Equalized; + +// // set all data +// module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); +// module.forTest_setRequestData( +// _requestId, percentageDiff, _pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token +// ); +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); + +// // Mock and expect IBondEscalationAccounting.pledge to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, token, _pledgeAmount)), +// abi.encode() +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); + +// vm.startPrank(pledgerFor); +// module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); + +// (,, uint256 _realPledgesFor,) = module.escalations(_disputeId); +// (IBondEscalationResolutionModule.InequalityStatus _status,) = module.inequalityData(_disputeId); + +// // Check: is the pledge amount added to the total? +// assertEq(_realPledgesFor, _pledgesFor + _pledgeAmount); +// // Check: is the pledges for dispute amount updated? +// assertEq(module.pledgesForDispute(_disputeId, pledgerFor), _pledgeAmount); +// // Check: is the status properly updated? +// assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.Equalized)); +// } + +// function test_percentageDifferences(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) public { +// ////////////////////////////////////////////////////////////////////// +// // START TEST _forPercentageDifference >= _scaledPercentageDiffAsInt +// ////////////////////////////////////////////////////////////////////// + +// _pledgeAmount = bound(_pledgeAmount, 1, type(uint192).max); +// IBondEscalationResolutionModule.Resolution _resolution = IBondEscalationResolutionModule.Resolution.Unresolved; + +// // block.timestamp < _startTime + _timeUntilDeadline +// uint128 _startTime = uint128(block.timestamp - 1000); +// uint256 _timeUntilDeadline = 1001; + +// // I'm setting the values so that the percentage diff is 20% in favor of pledgesFor. +// // In this case, _pledgeAmount will be the entirety of pledgesFor, as if it were the first pledge. +// // Therefore, _pledgeAmount must be 60% of total votes, _pledgesAgainst then should be 40% +// // 40 = 60 * 2 / 3 -> thats why I'm multiplying by 200 and dividing by 300 +// uint256 _pledgesFor = 0; +// uint256 _pledgesAgainst = _pledgeAmount * 200 / 300; +// uint256 _percentageDiff = 20; + +// // block.timestamp < _inequalityData.time + _timeToBreakInequality +// uint256 _timeToBreakInequality = 5000; + +// IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = +// IBondEscalationResolutionModule.InequalityStatus.Equalized; + +// // Set all data +// module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); +// module.forTest_setRequestData( +// _requestId, _percentageDiff, pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token +// ); +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); + +// // Mock and expect IBondEscalationAccounting.pledge to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, token, _pledgeAmount)), +// abi.encode() +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); + +// vm.startPrank(pledgerFor); +// module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); + +// (,, uint256 _realPledgesFor,) = module.escalations(_disputeId); +// (IBondEscalationResolutionModule.InequalityStatus _status, uint256 _timer) = module.inequalityData(_disputeId); + +// // Check: is the pledge amount added to the total? +// assertEq(_realPledgesFor, _pledgesFor + _pledgeAmount); +// // Check: is the pledge for dispute amount updated? +// assertEq(module.pledgesForDispute(_disputeId, pledgerFor), _pledgeAmount); +// // Check: is the status properly updated? +// assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.AgainstTurnToEqualize)); +// // Check: is the timer properly updated to current timestamp? +// assertEq(uint256(_timer), block.timestamp); + +// //////////////////////////////////////////////////////////////////// +// // END TEST _forPercentageDifference >= _scaledPercentageDiffAsInt +// //////////////////////////////////////////////////////////////////// + +// //----------------------------------------------------------------------// + +// ////////////////////////////////////////////////////////////////////////// +// // START TEST _againstPercentageDifference >= _scaledPercentageDiffAsInt +// ///////////////////////////////////////////////////////////////////////// + +// // Resetting status changed by previous test +// _inequalityStatus = IBondEscalationResolutionModule.InequalityStatus.ForTurnToEqualize; +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); +// module.forTest_setPledgesFor(_disputeId, pledgerFor, 0); + +// // Making the against percentage 60% of the total as percentageDiff is 20% +// // Note: I'm using 301 to account for rounding down errors. I'm also setting some _pledgesFor +// // to avoid the case when pledges are at 0 and someone just pledges 1 token +// // which is not realistic due to the pledgeThreshold forbidding the lines tested here +// // to be reached. +// _pledgesFor = 100_000; +// _pledgesAgainst = (_pledgeAmount + _pledgesFor) * 301 / 200; + +// // Resetting the pledges values +// module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); + +// module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); + +// (,, _realPledgesFor,) = module.escalations(_disputeId); +// (_status, _timer) = module.inequalityData(_disputeId); + +// // Check: is the pledge amount added to the total? +// assertEq(_realPledgesFor, _pledgesFor + _pledgeAmount); +// // Check: is the pledges for amount updated? +// assertEq(module.pledgesForDispute(_disputeId, pledgerFor), _pledgeAmount); +// // Check: is the status properly updated? +// assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.ForTurnToEqualize)); + +// //////////////////////////////////////////////////////////////////// +// // END TEST _forPercentageDifference >= _scaledPercentageDiffAsInt +// //////////////////////////////////////////////////////////////////// + +// //----------------------------------------------------------------------// + +// ////////////////////////////////////////////////////////////////////////// +// // START TEST _status == forTurnToEqualize && both diffs < percentageDiff +// ///////////////////////////////////////////////////////////////////////// + +// // Resetting status changed by previous test +// module.forTest_setPledgesFor(_disputeId, pledgerFor, 0); + +// // Making both the same so the percentage diff is not reached +// _pledgesFor = 100_000; +// _pledgesAgainst = (_pledgeAmount + _pledgesFor); + +// // Resetting the pledges values +// module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); + +// module.pledgeForDispute(_requestId, _disputeId, _pledgeAmount); + +// (,, _realPledgesFor,) = module.escalations(_disputeId); +// (_status, _timer) = module.inequalityData(_disputeId); + +// // Check: is the pledge amount added to the total? +// assertEq(_realPledgesFor, _pledgesFor + _pledgeAmount); +// // Check: is the pledges for amount updated? +// assertEq(module.pledgesForDispute(_disputeId, pledgerFor), _pledgeAmount); +// // Check: is the status properly updated? +// assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.Equalized)); +// // Check: is the timer reset? +// assertEq(_timer, 0); + +// ////////////////////////////////////////////////////////////////////////// +// // END TEST _status == forTurnToEqualize && both diffs < percentageDiff +// ///////////////////////////////////////////////////////////////////////// +// } +// } + +// contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { +// function test_reverts(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) public { +// // Set mock escalation with no pledges and start time 0 +// module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 0, 0, 0); + +// // Check: does it revert if the dispute is not escalated? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotEscalated.selector); +// module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); + +// // Set mock escalation with no pledges and start time 1 +// module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, 0, 0); + +// uint256 _timeUntilDeadline = block.timestamp - 1; +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, _timeUntilDeadline, timeToBreakInequality, accounting, token +// ); + +// // Check: does it revert if the pledging phase is over? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_PledgingPhaseOver.selector); +// module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); + +// IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = +// IBondEscalationResolutionModule.InequalityStatus.ForTurnToEqualize; +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); + +// // Set mock escalation with no pledges and start time == block.timestamp +// module.forTest_setEscalation( +// _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, uint128(block.timestamp), 0, 0 +// ); + +// _timeUntilDeadline = 10_000; +// uint256 _timeToBreakInequality = 5000; + +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token +// ); + +// vm.warp(block.timestamp + _timeToBreakInequality); + +// // Check: does it revert if inequality timer has passed? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_MustBeResolved.selector); +// module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); + +// vm.warp(block.timestamp - _timeToBreakInequality - 1); // Not past the deadline anymore +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); + +// // Mock and expect the pledge call +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, _requestId, _disputeId, token, _pledgeAmount)), +// abi.encode() +// ); + +// // Check: does it revert if status == AgainstTurnToEqualize? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_ForTurnToEqualize.selector); +// vm.prank(pledgerAgainst); +// module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); +// } + +// function test_earlyReturnIfThresholdNotSurpassed( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _pledgeAmount +// ) public { +// vm.assume(_pledgeAmount < type(uint256).max - 1000); +// IBondEscalationResolutionModule.Resolution _resolution = IBondEscalationResolutionModule.Resolution.Unresolved; + +// // block.timestamp < _startTime + _timeUntilDeadline +// uint128 _startTime = uint128(block.timestamp - 1000); +// uint256 _timeUntilDeadline = 1001; + +// // _pledgeThreshold > _updatedTotalVotes; +// uint256 _pledgesFor = 1000; +// uint256 _pledgesAgainst = 1000; +// uint256 _pledgeThreshold = _pledgesFor + _pledgesAgainst + _pledgeAmount + 1; + +// // block.timestamp < _inequalityData.time + _timeToBreakInequality +// uint256 _timeToBreakInequality = 5000; + +// // Assuming the threshold has not passed, this is the only valid state +// IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = +// IBondEscalationResolutionModule.InequalityStatus.Equalized; + +// // Set all data +// module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); +// module.forTest_setRequestData( +// _requestId, percentageDiff, _pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token +// ); +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); + +// // Mock and expect IBondEscalationAccounting.pledge to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, _requestId, _disputeId, token, _pledgeAmount)), +// abi.encode() +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); + +// vm.startPrank(pledgerAgainst); +// module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); + +// (,,, uint256 _realPledgesAgainst) = module.escalations(_disputeId); +// (IBondEscalationResolutionModule.InequalityStatus _status,) = module.inequalityData(_disputeId); +// // asdf + +// // Check: is the pledge amount added to the total? +// assertEq(_realPledgesAgainst, _pledgesAgainst + _pledgeAmount); +// // Check: is the pledges against amount updated? +// assertEq(module.pledgesAgainstDispute(_disputeId, pledgerAgainst), _pledgeAmount); +// // Check: is the status properly updated? +// assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.Equalized)); +// } + +// function test_percentageDifferences(bytes32 _requestId, bytes32 _disputeId, uint256 _pledgeAmount) public { +// _pledgeAmount = bound(_pledgeAmount, 1, type(uint192).max); +// IBondEscalationResolutionModule.Resolution _resolution = IBondEscalationResolutionModule.Resolution.Unresolved; + +// ////////////////////////////////////////////////////////////////////////// +// // START TEST _againstPercentageDifference >= _scaledPercentageDiffAsInt +// ///////////////////////////////////////////////////////////////////////// + +// // block.timestamp < _startTime + _timeUntilDeadline +// uint128 _startTime = uint128(block.timestamp - 1000); +// uint256 _timeUntilDeadline = 1001; + +// // I'm setting the values so that the percentage diff is 20% in favor of pledgesAgainst. +// // In this case, _pledgeAmount will be the entirety of pledgesAgainst, as if it were the first pledge. +// // Therefore, _pledgeAmount must be 60% of total votes, _pledgesFor then should be 40% +// // 40 = 60 * 2 / 3 -> thats why I'm multiplying by 200 and dividing by 300 +// uint256 _pledgesAgainst = 0; +// uint256 _pledgesFor = _pledgeAmount * 200 / 300; +// uint256 _percentageDiff = 20; + +// // block.timestamp < _inequalityData.time + _timeToBreakInequality +// uint256 _timeToBreakInequality = 5000; + +// IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = +// IBondEscalationResolutionModule.InequalityStatus.Equalized; + +// // Set all data +// module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); +// module.forTest_setRequestData( +// _requestId, _percentageDiff, pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token +// ); +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); + +// // Mock and expect IBondEscalationAccounting.pledge to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, _requestId, _disputeId, token, _pledgeAmount)), +// abi.encode() +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); + +// vm.startPrank(pledgerAgainst); +// module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); + +// (,,, uint256 _realPledgesAgainst) = module.escalations(_disputeId); +// (IBondEscalationResolutionModule.InequalityStatus _status, uint256 _timer) = module.inequalityData(_disputeId); + +// // Check: is the pledge amount added to the total? +// assertEq(_realPledgesAgainst, _pledgesAgainst + _pledgeAmount); +// // Check: is the pledges against amount updated? +// assertEq(module.pledgesAgainstDispute(_disputeId, pledgerAgainst), _pledgeAmount); +// // Check: is the status properly updated? +// assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.ForTurnToEqualize)); +// // Check: is the timer properly updated? +// assertEq(uint256(_timer), block.timestamp); + +// /////////////////////////////////////////////////////////////////////// +// // END TEST _againstPercentageDifference >= _scaledPercentageDiffAsInt +// /////////////////////////////////////////////////////////////////////// + +// //----------------------------------------------------------------------// + +// ////////////////////////////////////////////////////////////////////////// +// // START TEST _forPercentageDifference >= _scaledPercentageDiffAsInt +// ///////////////////////////////////////////////////////////////////////// + +// // Resetting status changed by previous test +// _inequalityStatus = IBondEscalationResolutionModule.InequalityStatus.AgainstTurnToEqualize; +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); +// module.forTest_setPledgesAgainst(_disputeId, pledgerAgainst, 0); + +// // Making the for percentage 60% of the total as percentageDiff is 20% +// // Note: I'm using 301 to account for rounding down errors. I'm also setting some _pledgesAgainst +// // to avoid the case when pledges are at 0 and someone just pledges 1 token +// // which is not realistic due to the pledgeThreshold forbidding the lines tested here +// // to be reached. +// _pledgesAgainst = 100_000; +// _pledgesFor = (_pledgeAmount + _pledgesAgainst) * 301 / 200; + +// // Resetting the pledges values +// module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); + +// module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); + +// (,,, _realPledgesAgainst) = module.escalations(_disputeId); +// (_status, _timer) = module.inequalityData(_disputeId); + +// // Check: is the pledge amount added to the total? +// assertEq(_realPledgesAgainst, _pledgesAgainst + _pledgeAmount); +// // Check: is the pledges against amount updated? +// assertEq(module.pledgesAgainstDispute(_disputeId, pledgerAgainst), _pledgeAmount); +// // Check: is the status properly updated? +// assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.AgainstTurnToEqualize)); + +// //////////////////////////////////////////////////////////////////// +// // END TEST _forPercentageDifference >= _scaledPercentageDiffAsInt +// //////////////////////////////////////////////////////////////////// + +// //----------------------------------------------------------------------// + +// ////////////////////////////////////////////////////////////////////////// +// // START TEST _status == forTurnToEqualize && both diffs < percentageDiff +// ///////////////////////////////////////////////////////////////////////// + +// // Resetting status changed by previous test +// module.forTest_setPledgesAgainst(_disputeId, pledgerAgainst, 0); + +// // Making both the same so the percentage diff is not reached +// _pledgesAgainst = 100_000; +// _pledgesFor = (_pledgeAmount + _pledgesAgainst); + +// // Resetting the pledges values +// module.forTest_setEscalation(_disputeId, _resolution, _startTime, _pledgesFor, _pledgesAgainst); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); + +// module.pledgeAgainstDispute(_requestId, _disputeId, _pledgeAmount); + +// (,,, _realPledgesAgainst) = module.escalations(_disputeId); +// (_status, _timer) = module.inequalityData(_disputeId); + +// // Check: is the pledge amount added to the total? +// assertEq(_realPledgesAgainst, _pledgesAgainst + _pledgeAmount); +// // Check: is the pledges against amount updated? +// assertEq(module.pledgesAgainstDispute(_disputeId, pledgerAgainst), _pledgeAmount); +// // Check: is the status properly updated? +// assertEq(uint256(_status), uint256(IBondEscalationResolutionModule.InequalityStatus.Equalized)); +// // Check: is the timer properly reset? +// assertEq(_timer, 0); + +// ////////////////////////////////////////////////////////////////////////// +// // END TEST _status == forTurnToEqualize && both diffs < percentageDiff +// ///////////////////////////////////////////////////////////////////////// +// } +// } + +// contract BondEscalationResolutionModule_Unit_ResolveDispute is BaseTest { +// /* +// Specs: +// 0. Should revert if the resolution status is different than Unresolved - done +// 1. Should revert if the dispute is not escalated (startTime == 0) - done +// 2. Should revert if the main deadline has not be reached and the inequality timer has not culminated - done + +// 3. After resolve, if the pledges from both sides never reached the threshold, or if the pledges of both sides end up tied +// it should set the resolution status to NoResolution. TODO: and do the appropriate calls. +// 4. After resolve, if the pledges for the disputer were more than the pledges against him, then it should +// set the resolution state to DisputerWon and call the oracle to update the status with Won. Also emit event. +// 5. Same as 4 but with DisputerLost, and Lost when the pledges against the disputer were more than the pledges in favor of +// the disputer. +// */ + +// function test_reverts(bytes32 _requestId, bytes32 _disputeId) public { +// // Set mock escalation with resolution == DisputerWon +// module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.DisputerWon, 0, 0, 0); + +// // Check: does it revert if the status is different than resolved? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_AlreadyResolved.selector); + +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); + +// // Set mock escalation with resolution == Unresolved +// module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 0, 0, 0); + +// // Check: does it revert if the dispute is not escalated? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotEscalated.selector); + +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); - // Revert if we have not yet reached the deadline and the timer has not passed - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); +// // Revert if we have not yet reached the deadline and the timer has not passed +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - uint256 _timeUntilDeadline = 100_000; - uint256 _timeToBreakInequality = 100_000; - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token - ); +// uint256 _timeUntilDeadline = 100_000; +// uint256 _timeToBreakInequality = 100_000; +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, _timeUntilDeadline, _timeToBreakInequality, accounting, token +// ); - IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = - IBondEscalationResolutionModule.InequalityStatus.AgainstTurnToEqualize; - module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); - - // Set mock escalation with resolution == Unresolved and start time == block.timestamp - module.forTest_setEscalation( - _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, uint128(block.timestamp), 0, 0 - ); +// IBondEscalationResolutionModule.InequalityStatus _inequalityStatus = +// IBondEscalationResolutionModule.InequalityStatus.AgainstTurnToEqualize; +// module.forTest_setInequalityData(_disputeId, _inequalityStatus, block.timestamp); + +// // Set mock escalation with resolution == Unresolved and start time == block.timestamp +// module.forTest_setEscalation( +// _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, uint128(block.timestamp), 0, 0 +// ); - // Check: does it revert if the dispute must be resolved? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_PledgingPhaseNotOver.selector); +// // Check: does it revert if the dispute must be resolved? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_PledgingPhaseNotOver.selector); - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - } +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); +// } - function test_thresholdNotReached(bytes32 _requestId, bytes32 _disputeId) public { - // START OF SETUP TO AVOID REVERTS - // Set a mock escalation with resolution == Unresolved and start time == 1 - module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, 0, 0); +// function test_thresholdNotReached(bytes32 _requestId, bytes32 _disputeId) public { +// // START OF SETUP TO AVOID REVERTS +// // Set a mock escalation with resolution == Unresolved and start time == 1 +// module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, 0, 0); - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Mock and expect IOracle.updateDisputeStatus to be called - _mockAndExpect( - address(oracle), - abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.NoResolution)), - abi.encode() - ); - // END OF SETUP TO AVOID REVERTS - - // START OF TEST THRESHOLD NOT REACHED - uint256 _pledgeThreshold = 1000; - module.forTest_setRequestData( - _requestId, percentageDiff, _pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit DisputeResolved(_requestId, _disputeId, IOracle.DisputeStatus.NoResolution); - - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - - (IBondEscalationResolutionModule.Resolution _trueResStatus,,,) = module.escalations(_disputeId); - - // Check: is the resolution status updated to NoResolution? - assertEq(uint256(_trueResStatus), uint256(IBondEscalationResolutionModule.Resolution.NoResolution)); - - // END OF TEST THRESHOLD NOT REACHED - } - - function test_tiedPledges(bytes32 _requestId, bytes32 _disputeId) public { - // START OF SETUP TO AVOID REVERTS - // Set mock escalation with tied pledges - module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, 2000, 2000); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Mock and expect IOracle.updateDisputeStatus to be called +// _mockAndExpect( +// address(oracle), +// abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.NoResolution)), +// abi.encode() +// ); +// // END OF SETUP TO AVOID REVERTS + +// // START OF TEST THRESHOLD NOT REACHED +// uint256 _pledgeThreshold = 1000; +// module.forTest_setRequestData( +// _requestId, percentageDiff, _pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit DisputeResolved(_requestId, _disputeId, IOracle.DisputeStatus.NoResolution); + +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); + +// (IBondEscalationResolutionModule.Resolution _trueResStatus,,,) = module.escalations(_disputeId); + +// // Check: is the resolution status updated to NoResolution? +// assertEq(uint256(_trueResStatus), uint256(IBondEscalationResolutionModule.Resolution.NoResolution)); + +// // END OF TEST THRESHOLD NOT REACHED +// } + +// function test_tiedPledges(bytes32 _requestId, bytes32 _disputeId) public { +// // START OF SETUP TO AVOID REVERTS +// // Set mock escalation with tied pledges +// module.forTest_setEscalation(_disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, 2000, 2000); - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - // Mock and expect IOracle.updateDisputeStatus to be called - _mockAndExpect( - address(oracle), - abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.NoResolution)), - abi.encode() - ); +// // Mock and expect IOracle.updateDisputeStatus to be called +// _mockAndExpect( +// address(oracle), +// abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.NoResolution)), +// abi.encode() +// ); - // END OF SETUP TO AVOID REVERTS +// // END OF SETUP TO AVOID REVERTS - // START OF TIED PLEDGES - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token - ); +// // START OF TIED PLEDGES +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token +// ); - // Events - vm.expectEmit(true, true, true, true, address(module)); - emit DisputeResolved(_requestId, _disputeId, IOracle.DisputeStatus.NoResolution); +// // Events +// vm.expectEmit(true, true, true, true, address(module)); +// emit DisputeResolved(_requestId, _disputeId, IOracle.DisputeStatus.NoResolution); - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - - (IBondEscalationResolutionModule.Resolution _trueResStatus,,,) = module.escalations(_disputeId); +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); + +// (IBondEscalationResolutionModule.Resolution _trueResStatus,,,) = module.escalations(_disputeId); - // Check: is the escalation status updated to NoResolution? - assertEq(uint256(_trueResStatus), uint256(IBondEscalationResolutionModule.Resolution.NoResolution)); +// // Check: is the escalation status updated to NoResolution? +// assertEq(uint256(_trueResStatus), uint256(IBondEscalationResolutionModule.Resolution.NoResolution)); - // END OF TIED PLEDGES - } - - function test_forPledgesWon( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _pledgesAgainst, - uint256 _pledgesFor - ) public { - vm.assume(_pledgesAgainst < _pledgesFor); - vm.assume(_pledgesFor < type(uint128).max); - // START OF SETUP TO AVOID REVERTS - - // Set mock escalation with pledgers for dispute winning - module.forTest_setEscalation( - _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, _pledgesFor, _pledgesAgainst - ); - - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // END OF SETUP TO AVOID REVERTS - - // START OF FOR PLEDGES WON - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token - ); - - // Mock and expect IOracle.updateDisputeStatus to be called - _mockAndExpect( - address(oracle), - abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.Won)), - abi.encode() - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit DisputeResolved(_requestId, _disputeId, IOracle.DisputeStatus.Won); - - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - - (IBondEscalationResolutionModule.Resolution _trueResStatus,,,) = module.escalations(_disputeId); - // Check: is the status of the escalation == DisputerWon? - assertEq(uint256(_trueResStatus), uint256(IBondEscalationResolutionModule.Resolution.DisputerWon)); - - // END OF FOR PLEDGES WON - } - - function test_againstPledgesWon( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _pledgesFor, - uint256 _pledgesAgainst - ) public { - vm.assume(_pledgesAgainst > _pledgesFor); - vm.assume(_pledgesAgainst < type(uint128).max); - // START OF SETUP TO AVOID REVERTS - - // Set mock escalation with pledgers against dispute winning - module.forTest_setEscalation( - _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, _pledgesFor, _pledgesAgainst - ); - - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // END OF SETUP TO AVOID REVERTS - - // START OF FOR PLEDGES LOST - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token - ); - - // Mock and expect IOracle.updateDisputeStatus to be called - _mockAndExpect( - address(oracle), - abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.Lost)), - abi.encode() - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit DisputeResolved(_requestId, _disputeId, IOracle.DisputeStatus.Lost); - - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - - (IBondEscalationResolutionModule.Resolution _trueResStatus,,,) = module.escalations(_disputeId); - // Check: is the status of the escalation == DisputerLost? - assertEq(uint256(_trueResStatus), uint256(IBondEscalationResolutionModule.Resolution.DisputerLost)); - - // END OF FOR PLEDGES LOST - } -} - -contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { - function test_reverts( - bytes32 _disputeId, - bytes32 _requestId, - uint256 _pledgesFor, - uint256 _pledgesAgainst, - uint128 _startTime, - address _randomPledger - ) public { - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token - ); - // Set a mock escalation with resolution == Unresolved - module.forTest_setEscalation( - _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, _startTime, _pledgesFor, _pledgesAgainst - ); - - module.forTest_setPledgesFor(_disputeId, _randomPledger, _pledgesFor); - module.forTest_setPledgesAgainst(_disputeId, _randomPledger, _pledgesAgainst); - - // Check: does it revert if trying to claim a pledge of a not resolved escalation? - vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotResolved.selector); - module.claimPledge(_requestId, _disputeId); - } - - function test_disputerWon( - bytes32 _disputeId, - bytes32 _requestId, - uint256 _totalPledgesFor, - uint256 _totalPledgesAgainst, - uint256 _userForPledge, - address _randomPledger - ) public { - // Im bounding to type(uint192).max because it has 58 digits and base has 18, so multiplying results in - // 77 digits, which is slightly less than uint256 max, which has 78 digits. Seems fair? Unless it's a very stupid token - // no single pledger should surpass a balance of type(uint192).max - _userForPledge = bound(_userForPledge, 0, type(uint192).max); - vm.assume(_totalPledgesFor > _totalPledgesAgainst); - vm.assume(_totalPledgesFor >= _userForPledge); - - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token - ); - - // Set mock escalation with resolution == DisputerWon - module.forTest_setEscalation( - _disputeId, IBondEscalationResolutionModule.Resolution.DisputerWon, 0, _totalPledgesFor, _totalPledgesAgainst - ); - - module.forTest_setPledgesFor(_disputeId, _randomPledger, _userForPledge); - - uint256 _pledgerProportion = FixedPointMathLib.mulDivDown(_userForPledge, module.BASE(), (_totalPledgesFor)); - uint256 _amountToRelease = - _userForPledge + (FixedPointMathLib.mulDivDown(_totalPledgesAgainst, _pledgerProportion, (module.BASE()))); - - // Mock and expect IBondEscalationAccounting.releasePledge to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(accounting.releasePledge, (_requestId, _disputeId, _randomPledger, token, _amountToRelease)), - abi.encode(true) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgeClaimed( - _requestId, - _disputeId, - _randomPledger, - token, - _amountToRelease, - IBondEscalationResolutionModule.Resolution.DisputerWon - ); - - vm.prank(_randomPledger); - module.claimPledge(_requestId, _disputeId); - - // Check: are the pledges for dispute for the dispute and pledger set to 0? - assertEq(module.pledgesForDispute(_disputeId, _randomPledger), 0); - } - - function test_disputerLost( - bytes32 _disputeId, - bytes32 _requestId, - uint256 _totalPledgesFor, - uint256 _totalPledgesAgainst, - uint256 _userAgainstPledge, - address _randomPledger - ) public { - // Im bounding to type(uint192).max because it has 58 digits and base has 18, so multiplying results in - // 77 digits, which is slightly less than uint256 max, which has 78 digits. Seems fair? Unless it's a very stupid token - // no single pledger should surpass a balance of type(uint192).max - _userAgainstPledge = bound(_userAgainstPledge, 0, type(uint192).max); - vm.assume(_totalPledgesAgainst > _totalPledgesFor); - vm.assume(_totalPledgesAgainst >= _userAgainstPledge); - - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token - ); - - // Set mock escalation with resolution == DisputerLost - module.forTest_setEscalation( - _disputeId, IBondEscalationResolutionModule.Resolution.DisputerLost, 0, _totalPledgesFor, _totalPledgesAgainst - ); - - module.forTest_setPledgesAgainst(_disputeId, _randomPledger, _userAgainstPledge); - - uint256 _pledgerProportion = FixedPointMathLib.mulDivDown(_userAgainstPledge, module.BASE(), _totalPledgesAgainst); - uint256 _amountToRelease = - _userAgainstPledge + (FixedPointMathLib.mulDivDown(_totalPledgesFor, _pledgerProportion, module.BASE())); - - // Mock and expect IBondEscalationAccounting.releasePledge to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(accounting.releasePledge, (_requestId, _disputeId, _randomPledger, token, _amountToRelease)), - abi.encode(true) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgeClaimed( - _requestId, - _disputeId, - _randomPledger, - token, - _amountToRelease, - IBondEscalationResolutionModule.Resolution.DisputerLost - ); - - vm.prank(_randomPledger); - module.claimPledge(_requestId, _disputeId); - - // Check: is the pledges against dispute for this dispute and pledger set to 0? - assertEq(module.pledgesAgainstDispute(_disputeId, _randomPledger), 0); - } - - function test_noResolution( - bytes32 _disputeId, - bytes32 _requestId, - uint256 _userForPledge, - uint256 _userAgainstPledge, - address _randomPledger - ) public { - vm.assume(_userForPledge > 0); - vm.assume(_userAgainstPledge > 0); - - module.forTest_setRequestData( - _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token - ); - - // Set mock escalation with resolution == NoResolution - module.forTest_setEscalation( - _disputeId, IBondEscalationResolutionModule.Resolution.NoResolution, 0, _userForPledge, _userAgainstPledge - ); - - module.forTest_setPledgesFor(_disputeId, _randomPledger, _userForPledge); - module.forTest_setPledgesAgainst(_disputeId, _randomPledger, _userAgainstPledge); - - // Mock and expect IBondEscalationAccounting.releasePledge to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(accounting.releasePledge, (_requestId, _disputeId, _randomPledger, token, _userForPledge)), - abi.encode(true) - ); - - // Mock and expect IBondEscalationAccounting.releasePledge to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(accounting.releasePledge, (_requestId, _disputeId, _randomPledger, token, _userAgainstPledge)), - abi.encode(true) - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgeClaimed( - _requestId, - _disputeId, - _randomPledger, - token, - _userForPledge, - IBondEscalationResolutionModule.Resolution.NoResolution - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit PledgeClaimed( - _requestId, - _disputeId, - _randomPledger, - token, - _userAgainstPledge, - IBondEscalationResolutionModule.Resolution.NoResolution - ); - - vm.prank(_randomPledger); - module.claimPledge(_requestId, _disputeId); - - // Check: is the pledges against dispute for this dispute and pledger set to 0? - assertEq(module.pledgesAgainstDispute(_disputeId, _randomPledger), 0); - // Check: is the pledges for dispute for this dispute and pledger set to 0? - assertEq(module.pledgesForDispute(_disputeId, _randomPledger), 0); - } -} +// // END OF TIED PLEDGES +// } + +// function test_forPledgesWon( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _pledgesAgainst, +// uint256 _pledgesFor +// ) public { +// vm.assume(_pledgesAgainst < _pledgesFor); +// vm.assume(_pledgesFor < type(uint128).max); +// // START OF SETUP TO AVOID REVERTS + +// // Set mock escalation with pledgers for dispute winning +// module.forTest_setEscalation( +// _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, _pledgesFor, _pledgesAgainst +// ); + +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // END OF SETUP TO AVOID REVERTS + +// // START OF FOR PLEDGES WON +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token +// ); + +// // Mock and expect IOracle.updateDisputeStatus to be called +// _mockAndExpect( +// address(oracle), +// abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.Won)), +// abi.encode() +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit DisputeResolved(_requestId, _disputeId, IOracle.DisputeStatus.Won); + +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); + +// (IBondEscalationResolutionModule.Resolution _trueResStatus,,,) = module.escalations(_disputeId); +// // Check: is the status of the escalation == DisputerWon? +// assertEq(uint256(_trueResStatus), uint256(IBondEscalationResolutionModule.Resolution.DisputerWon)); + +// // END OF FOR PLEDGES WON +// } + +// function test_againstPledgesWon( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _pledgesFor, +// uint256 _pledgesAgainst +// ) public { +// vm.assume(_pledgesAgainst > _pledgesFor); +// vm.assume(_pledgesAgainst < type(uint128).max); +// // START OF SETUP TO AVOID REVERTS + +// // Set mock escalation with pledgers against dispute winning +// module.forTest_setEscalation( +// _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, 1, _pledgesFor, _pledgesAgainst +// ); + +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // END OF SETUP TO AVOID REVERTS + +// // START OF FOR PLEDGES LOST +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token +// ); + +// // Mock and expect IOracle.updateDisputeStatus to be called +// _mockAndExpect( +// address(oracle), +// abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, IOracle.DisputeStatus.Lost)), +// abi.encode() +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit DisputeResolved(_requestId, _disputeId, IOracle.DisputeStatus.Lost); + +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); + +// (IBondEscalationResolutionModule.Resolution _trueResStatus,,,) = module.escalations(_disputeId); +// // Check: is the status of the escalation == DisputerLost? +// assertEq(uint256(_trueResStatus), uint256(IBondEscalationResolutionModule.Resolution.DisputerLost)); + +// // END OF FOR PLEDGES LOST +// } +// } + +// contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { +// function test_reverts( +// bytes32 _disputeId, +// bytes32 _requestId, +// uint256 _pledgesFor, +// uint256 _pledgesAgainst, +// uint128 _startTime, +// address _randomPledger +// ) public { +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token +// ); +// // Set a mock escalation with resolution == Unresolved +// module.forTest_setEscalation( +// _disputeId, IBondEscalationResolutionModule.Resolution.Unresolved, _startTime, _pledgesFor, _pledgesAgainst +// ); + +// module.forTest_setPledgesFor(_disputeId, _randomPledger, _pledgesFor); +// module.forTest_setPledgesAgainst(_disputeId, _randomPledger, _pledgesAgainst); + +// // Check: does it revert if trying to claim a pledge of a not resolved escalation? +// vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotResolved.selector); +// module.claimPledge(_requestId, _disputeId); +// } + +// function test_disputerWon( +// bytes32 _disputeId, +// bytes32 _requestId, +// uint256 _totalPledgesFor, +// uint256 _totalPledgesAgainst, +// uint256 _userForPledge, +// address _randomPledger +// ) public { +// // Im bounding to type(uint192).max because it has 58 digits and base has 18, so multiplying results in +// // 77 digits, which is slightly less than uint256 max, which has 78 digits. Seems fair? Unless it's a very stupid token +// // no single pledger should surpass a balance of type(uint192).max +// _userForPledge = bound(_userForPledge, 0, type(uint192).max); +// vm.assume(_totalPledgesFor > _totalPledgesAgainst); +// vm.assume(_totalPledgesFor >= _userForPledge); + +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token +// ); + +// // Set mock escalation with resolution == DisputerWon +// module.forTest_setEscalation( +// _disputeId, IBondEscalationResolutionModule.Resolution.DisputerWon, 0, _totalPledgesFor, _totalPledgesAgainst +// ); + +// module.forTest_setPledgesFor(_disputeId, _randomPledger, _userForPledge); + +// uint256 _pledgerProportion = FixedPointMathLib.mulDivDown(_userForPledge, module.BASE(), (_totalPledgesFor)); +// uint256 _amountToRelease = +// _userForPledge + (FixedPointMathLib.mulDivDown(_totalPledgesAgainst, _pledgerProportion, (module.BASE()))); + +// // Mock and expect IBondEscalationAccounting.releasePledge to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(accounting.releasePledge, (_requestId, _disputeId, _randomPledger, token, _amountToRelease)), +// abi.encode(true) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgeClaimed( +// _requestId, +// _disputeId, +// _randomPledger, +// token, +// _amountToRelease, +// IBondEscalationResolutionModule.Resolution.DisputerWon +// ); + +// vm.prank(_randomPledger); +// module.claimPledge(_requestId, _disputeId); + +// // Check: are the pledges for dispute for the dispute and pledger set to 0? +// assertEq(module.pledgesForDispute(_disputeId, _randomPledger), 0); +// } + +// function test_disputerLost( +// bytes32 _disputeId, +// bytes32 _requestId, +// uint256 _totalPledgesFor, +// uint256 _totalPledgesAgainst, +// uint256 _userAgainstPledge, +// address _randomPledger +// ) public { +// // Im bounding to type(uint192).max because it has 58 digits and base has 18, so multiplying results in +// // 77 digits, which is slightly less than uint256 max, which has 78 digits. Seems fair? Unless it's a very stupid token +// // no single pledger should surpass a balance of type(uint192).max +// _userAgainstPledge = bound(_userAgainstPledge, 0, type(uint192).max); +// vm.assume(_totalPledgesAgainst > _totalPledgesFor); +// vm.assume(_totalPledgesAgainst >= _userAgainstPledge); + +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token +// ); + +// // Set mock escalation with resolution == DisputerLost +// module.forTest_setEscalation( +// _disputeId, IBondEscalationResolutionModule.Resolution.DisputerLost, 0, _totalPledgesFor, _totalPledgesAgainst +// ); + +// module.forTest_setPledgesAgainst(_disputeId, _randomPledger, _userAgainstPledge); + +// uint256 _pledgerProportion = FixedPointMathLib.mulDivDown(_userAgainstPledge, module.BASE(), _totalPledgesAgainst); +// uint256 _amountToRelease = +// _userAgainstPledge + (FixedPointMathLib.mulDivDown(_totalPledgesFor, _pledgerProportion, module.BASE())); + +// // Mock and expect IBondEscalationAccounting.releasePledge to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(accounting.releasePledge, (_requestId, _disputeId, _randomPledger, token, _amountToRelease)), +// abi.encode(true) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgeClaimed( +// _requestId, +// _disputeId, +// _randomPledger, +// token, +// _amountToRelease, +// IBondEscalationResolutionModule.Resolution.DisputerLost +// ); + +// vm.prank(_randomPledger); +// module.claimPledge(_requestId, _disputeId); + +// // Check: is the pledges against dispute for this dispute and pledger set to 0? +// assertEq(module.pledgesAgainstDispute(_disputeId, _randomPledger), 0); +// } + +// function test_noResolution( +// bytes32 _disputeId, +// bytes32 _requestId, +// uint256 _userForPledge, +// uint256 _userAgainstPledge, +// address _randomPledger +// ) public { +// vm.assume(_userForPledge > 0); +// vm.assume(_userAgainstPledge > 0); + +// module.forTest_setRequestData( +// _requestId, percentageDiff, pledgeThreshold, timeUntilDeadline, timeToBreakInequality, accounting, token +// ); + +// // Set mock escalation with resolution == NoResolution +// module.forTest_setEscalation( +// _disputeId, IBondEscalationResolutionModule.Resolution.NoResolution, 0, _userForPledge, _userAgainstPledge +// ); + +// module.forTest_setPledgesFor(_disputeId, _randomPledger, _userForPledge); +// module.forTest_setPledgesAgainst(_disputeId, _randomPledger, _userAgainstPledge); + +// // Mock and expect IBondEscalationAccounting.releasePledge to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(accounting.releasePledge, (_requestId, _disputeId, _randomPledger, token, _userForPledge)), +// abi.encode(true) +// ); + +// // Mock and expect IBondEscalationAccounting.releasePledge to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(accounting.releasePledge, (_requestId, _disputeId, _randomPledger, token, _userAgainstPledge)), +// abi.encode(true) +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgeClaimed( +// _requestId, +// _disputeId, +// _randomPledger, +// token, +// _userForPledge, +// IBondEscalationResolutionModule.Resolution.NoResolution +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit PledgeClaimed( +// _requestId, +// _disputeId, +// _randomPledger, +// token, +// _userAgainstPledge, +// IBondEscalationResolutionModule.Resolution.NoResolution +// ); + +// vm.prank(_randomPledger); +// module.claimPledge(_requestId, _disputeId); + +// // Check: is the pledges against dispute for this dispute and pledger set to 0? +// assertEq(module.pledgesAgainstDispute(_disputeId, _randomPledger), 0); +// // Check: is the pledges for dispute for this dispute and pledger set to 0? +// assertEq(module.pledgesForDispute(_disputeId, _randomPledger), 0); +// } +// } diff --git a/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol b/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol index c3d5be46..da6dde87 100644 --- a/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol @@ -1,409 +1,409 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - ERC20ResolutionModule, - IERC20ResolutionModule -} from '../../../../contracts/modules/resolution/ERC20ResolutionModule.sol'; - -contract ForTest_ERC20ResolutionModule is ERC20ResolutionModule { - constructor(IOracle _oracle) ERC20ResolutionModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } - - function forTest_setEscalation(bytes32 _disputeId, ERC20ResolutionModule.Escalation calldata __escalation) public { - escalations[_disputeId] = __escalation; - } - - function forTest_setVotes(bytes32 _disputeId, address _voter, uint256 _amountOfVotes) public { - votes[_disputeId][_voter] = _amountOfVotes; - } -} - -contract BaseTest is Test, Helpers { - // The target contract - ForTest_ERC20ResolutionModule public module; - // A mock oracle - IOracle public oracle; - // A mock token - IERC20 public token; - // Mock EOA proposer - address public proposer = makeAddr('proposer'); - // Mock EOA disputer - address public disputer = makeAddr('disputer'); - - // Mocking module events - event VoteCast(address _voter, bytes32 _disputeId, uint256 _numberOfVotes); - event VotingPhaseStarted(uint256 _startTime, bytes32 _disputeId); - event DisputeResolved(bytes32 indexed _requestId, bytes32 indexed _disputeId, IOracle.DisputeStatus _status); - - /** - * @notice Deploy the target and mock oracle extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - token = IERC20(makeAddr('ERC20')); - vm.etch(address(token), hex'069420'); - - module = new ForTest_ERC20ResolutionModule(oracle); - } - - /** - * @dev Helper function to cast votes. - */ - function _populateVoters( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amountOfVoters, - uint256 _amountOfVotes - ) internal returns (uint256 _totalVotesCast) { - for (uint256 _i = 1; _i <= _amountOfVoters;) { - vm.warp(120_000); - vm.startPrank(vm.addr(_i)); - vm.mockCall( - address(token), - abi.encodeCall(IERC20.transferFrom, (vm.addr(_i), address(module), _amountOfVotes)), - abi.encode() - ); - module.castVote(_requestId, _disputeId, _amountOfVotes); - vm.stopPrank(); - _totalVotesCast += _amountOfVotes; - unchecked { - ++_i; - } - } - } -} - -contract ERC20ResolutionModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleName() public { - assertEq(module.moduleName(), 'ERC20ResolutionModule'); - } - - /** - * @notice Test that the decodeRequestData function returns the correct values - */ - function test_decodeRequestData_returnsCorrectData( - bytes32 _requestId, - address _token, - uint256 _minVotesForQuorum, - uint256 _votingTimeWindow - ) public { - // Mock data - bytes memory _requestData = abi.encode(_token, _minVotesForQuorum, _votingTimeWindow); - - // Store the mock request - module.forTest_setRequestData(_requestId, _requestData); - - // Test: decode the given request data - IERC20ResolutionModule.RequestParameters memory _params = module.decodeRequestData(_requestId); - - // Check: decoded values match original values? - assertEq(address(_params.votingToken), _token); - assertEq(_params.minVotesForQuorum, _minVotesForQuorum); - assertEq(_params.timeUntilDeadline, _votingTimeWindow); - } -} - -contract ERC20ResolutionModule_Unit_StartResolution is BaseTest { - /** - * @notice Test that the `startResolution` is correctly called and the voting phase is started - */ - function test_startResolution(bytes32 _disputeId) public { - // Check: does revert if called by address != oracle? - vm.expectRevert(IModule.Module_OnlyOracle.selector); - module.startResolution(_disputeId); - - // Check: emits VotingPhaseStarted event? - vm.expectEmit(true, true, true, true); - emit VotingPhaseStarted(block.timestamp, _disputeId); - - vm.prank(address(oracle)); - module.startResolution(_disputeId); - - (uint256 _startTime,) = module.escalations(_disputeId); - - // Check: `startTime` is set to block.timestamp? - assertEq(_startTime, block.timestamp); - } -} - -contract ERC20ResolutionModule_Unit_CastVote is BaseTest { - /** - * @notice Test casting votes in valid voting time window. - */ - function test_castVote(bytes32 _requestId, bytes32 _disputeId, uint256 _amountOfVotes, address _voter) public { - // Store mock dispute - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Store mock escalation data with startTime 100_000 - module.forTest_setEscalation( - _disputeId, - IERC20ResolutionModule.Escalation({ - startTime: 100_000, - totalVotes: 0 // Initial amount of votes - }) - ); - - uint256 _minVotesForQuorum = 1; - uint256 _votingTimeWindow = 40_000; - - // Store mock request data with 40_000 voting time window - module.forTest_setRequestData(_requestId, abi.encode(token, _minVotesForQuorum, _votingTimeWindow)); - - // Mock and expect IERC20.transferFrom to be called - _mockAndExpect( - address(token), abi.encodeCall(IERC20.transferFrom, (_voter, address(module), _amountOfVotes)), abi.encode() - ); - - // Warp to voting phase - vm.warp(130_000); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true); - emit VoteCast(_voter, _disputeId, _amountOfVotes); - - vm.prank(_voter); - module.castVote(_requestId, _disputeId, _amountOfVotes); - - (, uint256 _totalVotes) = module.escalations(_disputeId); - // Check: totalVotes is updated? - assertEq(_totalVotes, _amountOfVotes); - - // Check: voter data is updated? - assertEq(module.votes(_disputeId, _voter), _amountOfVotes); - } - - /** - * @notice Test that `castVote` reverts if there is no dispute with the given`_disputeId` - */ - function test_revertIfNonExistentDispute(bytes32 _requestId, bytes32 _disputeId, uint256 _amountOfVotes) public { - // Default non-existent dispute - IOracle.Dispute memory _mockDispute = IOracle.Dispute({ - disputer: address(0), - responseId: bytes32(0), - proposer: address(0), - requestId: bytes32(0), - status: IOracle.DisputeStatus.None, - createdAt: 0 - }); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Check: reverts if called with `_disputeId` of a non-existent dispute? - vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_NonExistentDispute.selector); - module.castVote(_requestId, _disputeId, _amountOfVotes); - } - - /** - * @notice Test that `castVote` reverts if called with `_disputeId` of a non-escalated dispute. - */ - function test_revertIfNotEscalated(bytes32 _requestId, bytes32 _disputeId, uint256 _numberOfVotes) public { - // Mock the oracle response for looking up a dispute - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Check: reverts if called with `_disputeId` of a non-escalated dispute? - vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_DisputeNotEscalated.selector); - module.castVote(_requestId, _disputeId, _numberOfVotes); - } - - /** - * @notice Test that `castVote` reverts if called with `_disputeId` of an already resolved dispute. - */ - function test_revertIfAlreadyResolved(bytes32 _requestId, bytes32 _disputeId, uint256 _amountOfVotes) public { - // Mock dispute already resolved => DisputeStatus.Lost - IOracle.Dispute memory _mockDispute = IOracle.Dispute({ - disputer: disputer, - responseId: bytes32('response'), - proposer: proposer, - requestId: _requestId, - status: IOracle.DisputeStatus.Lost, - createdAt: block.timestamp - }); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Check: reverts if dispute is already resolved? - vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_AlreadyResolved.selector); - module.castVote(_requestId, _disputeId, _amountOfVotes); - } - - /** - * @notice Test that `castVote` reverts if called outside the voting time window. - */ - function test_revertIfVotingPhaseOver( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _numberOfVotes, - uint256 _timestamp - ) public { - vm.assume(_timestamp > 140_000); - - // Mock the oracle response for looking up a dispute - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - vm.mockCall(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - module.forTest_setEscalation(_disputeId, IERC20ResolutionModule.Escalation({startTime: 100_000, totalVotes: 0})); - - // Store request data - uint256 _minVotesForQuorum = 1; - uint256 _votingTimeWindow = 40_000; - - module.forTest_setRequestData(_requestId, abi.encode(token, _minVotesForQuorum, _votingTimeWindow)); - - // Jump to timestamp - vm.warp(_timestamp); - - // Check: reverts if trying to cast vote after voting phase? - vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_VotingPhaseOver.selector); - module.castVote(_requestId, _disputeId, _numberOfVotes); - } -} - -contract ERC20ResolutionModule_Unit_ResolveDispute is BaseTest { - /** - * @notice Test that a dispute is resolved, the tokens are transferred back to the voters and the dispute status updated. - */ - function test_resolveDispute(bytes32 _requestId, bytes32 _disputeId, uint16 _minVotesForQuorum) public { - // Store mock dispute and mock calls - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - vm.mockCall(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Store request data - uint256 _votingTimeWindow = 40_000; - - module.forTest_setRequestData(_requestId, abi.encode(token, _minVotesForQuorum, _votingTimeWindow)); - - // Store escalation data with `startTime` 100_000 and votes 0 - module.forTest_setEscalation(_disputeId, IERC20ResolutionModule.Escalation({startTime: 100_000, totalVotes: 0})); - - uint256 _votersAmount = 5; - - // Make 5 addresses cast 100 votes each - uint256 _totalVotesCast = _populateVoters(_requestId, _disputeId, _votersAmount, 100); - - // Warp to resolving phase - vm.warp(150_000); - - // Mock and expect token transfers (should happen always) - for (uint256 _i = 1; _i <= _votersAmount;) { - _mockAndExpect(address(token), abi.encodeCall(IERC20.transfer, (vm.addr(_i), 100)), abi.encode()); - unchecked { - ++_i; - } - } - - // If quorum reached, check for dispute status update and event emission - IOracle.DisputeStatus _newStatus = - _totalVotesCast >= _minVotesForQuorum ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost; - - // Mock and expect IOracle.updateDisputeStatus to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, _newStatus)), abi.encode()); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true); - emit DisputeResolved(_requestId, _disputeId, _newStatus); - - // Check: does revert if called by address != oracle? - vm.expectRevert(IModule.Module_OnlyOracle.selector); - module.resolveDispute(_disputeId); - - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - } - - /** - * @notice Test that `resolveDispute` reverts if called during voting phase. - */ - function test_revertIfOnGoingVotePhase(bytes32 _requestId, bytes32 _disputeId, uint256 _timestamp) public { - _timestamp = bound(_timestamp, 500_000, 999_999); +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// ERC20ResolutionModule, +// IERC20ResolutionModule +// } from '../../../../contracts/modules/resolution/ERC20ResolutionModule.sol'; + +// contract ForTest_ERC20ResolutionModule is ERC20ResolutionModule { +// constructor(IOracle _oracle) ERC20ResolutionModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } + +// function forTest_setEscalation(bytes32 _disputeId, ERC20ResolutionModule.Escalation calldata __escalation) public { +// escalations[_disputeId] = __escalation; +// } + +// function forTest_setVotes(bytes32 _disputeId, address _voter, uint256 _amountOfVotes) public { +// votes[_disputeId][_voter] = _amountOfVotes; +// } +// } + +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_ERC20ResolutionModule public module; +// // A mock oracle +// IOracle public oracle; +// // A mock token +// IERC20 public token; +// // Mock EOA proposer +// address public proposer = makeAddr('proposer'); +// // Mock EOA disputer +// address public disputer = makeAddr('disputer'); + +// // Mocking module events +// event VoteCast(address _voter, bytes32 _disputeId, uint256 _numberOfVotes); +// event VotingPhaseStarted(uint256 _startTime, bytes32 _disputeId); +// event DisputeResolved(bytes32 indexed _requestId, bytes32 indexed _disputeId, IOracle.DisputeStatus _status); + +// /** +// * @notice Deploy the target and mock oracle extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// token = IERC20(makeAddr('ERC20')); +// vm.etch(address(token), hex'069420'); + +// module = new ForTest_ERC20ResolutionModule(oracle); +// } + +// /** +// * @dev Helper function to cast votes. +// */ +// function _populateVoters( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _amountOfVoters, +// uint256 _amountOfVotes +// ) internal returns (uint256 _totalVotesCast) { +// for (uint256 _i = 1; _i <= _amountOfVoters;) { +// vm.warp(120_000); +// vm.startPrank(vm.addr(_i)); +// vm.mockCall( +// address(token), +// abi.encodeCall(IERC20.transferFrom, (vm.addr(_i), address(module), _amountOfVotes)), +// abi.encode() +// ); +// module.castVote(_requestId, _disputeId, _amountOfVotes); +// vm.stopPrank(); +// _totalVotesCast += _amountOfVotes; +// unchecked { +// ++_i; +// } +// } +// } +// } + +// contract ERC20ResolutionModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleName() public { +// assertEq(module.moduleName(), 'ERC20ResolutionModule'); +// } + +// /** +// * @notice Test that the decodeRequestData function returns the correct values +// */ +// function test_decodeRequestData_returnsCorrectData( +// bytes32 _requestId, +// address _token, +// uint256 _minVotesForQuorum, +// uint256 _votingTimeWindow +// ) public { +// // Mock data +// bytes memory _requestData = abi.encode(_token, _minVotesForQuorum, _votingTimeWindow); + +// // Store the mock request +// module.forTest_setRequestData(_requestId, _requestData); + +// // Test: decode the given request data +// IERC20ResolutionModule.RequestParameters memory _params = module.decodeRequestData(_requestId); + +// // Check: decoded values match original values? +// assertEq(address(_params.votingToken), _token); +// assertEq(_params.minVotesForQuorum, _minVotesForQuorum); +// assertEq(_params.timeUntilDeadline, _votingTimeWindow); +// } +// } + +// contract ERC20ResolutionModule_Unit_StartResolution is BaseTest { +// /** +// * @notice Test that the `startResolution` is correctly called and the voting phase is started +// */ +// function test_startResolution(bytes32 _disputeId) public { +// // Check: does revert if called by address != oracle? +// vm.expectRevert(IModule.Module_OnlyOracle.selector); +// module.startResolution(_disputeId); + +// // Check: emits VotingPhaseStarted event? +// vm.expectEmit(true, true, true, true); +// emit VotingPhaseStarted(block.timestamp, _disputeId); + +// vm.prank(address(oracle)); +// module.startResolution(_disputeId); + +// (uint256 _startTime,) = module.escalations(_disputeId); + +// // Check: `startTime` is set to block.timestamp? +// assertEq(_startTime, block.timestamp); +// } +// } + +// contract ERC20ResolutionModule_Unit_CastVote is BaseTest { +// /** +// * @notice Test casting votes in valid voting time window. +// */ +// function test_castVote(bytes32 _requestId, bytes32 _disputeId, uint256 _amountOfVotes, address _voter) public { +// // Store mock dispute +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Store mock escalation data with startTime 100_000 +// module.forTest_setEscalation( +// _disputeId, +// IERC20ResolutionModule.Escalation({ +// startTime: 100_000, +// totalVotes: 0 // Initial amount of votes +// }) +// ); + +// uint256 _minVotesForQuorum = 1; +// uint256 _votingTimeWindow = 40_000; + +// // Store mock request data with 40_000 voting time window +// module.forTest_setRequestData(_requestId, abi.encode(token, _minVotesForQuorum, _votingTimeWindow)); + +// // Mock and expect IERC20.transferFrom to be called +// _mockAndExpect( +// address(token), abi.encodeCall(IERC20.transferFrom, (_voter, address(module), _amountOfVotes)), abi.encode() +// ); + +// // Warp to voting phase +// vm.warp(130_000); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true); +// emit VoteCast(_voter, _disputeId, _amountOfVotes); + +// vm.prank(_voter); +// module.castVote(_requestId, _disputeId, _amountOfVotes); + +// (, uint256 _totalVotes) = module.escalations(_disputeId); +// // Check: totalVotes is updated? +// assertEq(_totalVotes, _amountOfVotes); + +// // Check: voter data is updated? +// assertEq(module.votes(_disputeId, _voter), _amountOfVotes); +// } + +// /** +// * @notice Test that `castVote` reverts if there is no dispute with the given`_disputeId` +// */ +// function test_revertIfNonExistentDispute(bytes32 _requestId, bytes32 _disputeId, uint256 _amountOfVotes) public { +// // Default non-existent dispute +// IOracle.Dispute memory _mockDispute = IOracle.Dispute({ +// disputer: address(0), +// responseId: bytes32(0), +// proposer: address(0), +// requestId: bytes32(0), +// status: IOracle.DisputeStatus.None, +// createdAt: 0 +// }); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Check: reverts if called with `_disputeId` of a non-existent dispute? +// vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_NonExistentDispute.selector); +// module.castVote(_requestId, _disputeId, _amountOfVotes); +// } + +// /** +// * @notice Test that `castVote` reverts if called with `_disputeId` of a non-escalated dispute. +// */ +// function test_revertIfNotEscalated(bytes32 _requestId, bytes32 _disputeId, uint256 _numberOfVotes) public { +// // Mock the oracle response for looking up a dispute +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Check: reverts if called with `_disputeId` of a non-escalated dispute? +// vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_DisputeNotEscalated.selector); +// module.castVote(_requestId, _disputeId, _numberOfVotes); +// } + +// /** +// * @notice Test that `castVote` reverts if called with `_disputeId` of an already resolved dispute. +// */ +// function test_revertIfAlreadyResolved(bytes32 _requestId, bytes32 _disputeId, uint256 _amountOfVotes) public { +// // Mock dispute already resolved => DisputeStatus.Lost +// IOracle.Dispute memory _mockDispute = IOracle.Dispute({ +// disputer: disputer, +// responseId: bytes32('response'), +// proposer: proposer, +// requestId: _requestId, +// status: IOracle.DisputeStatus.Lost, +// createdAt: block.timestamp +// }); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Check: reverts if dispute is already resolved? +// vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_AlreadyResolved.selector); +// module.castVote(_requestId, _disputeId, _amountOfVotes); +// } + +// /** +// * @notice Test that `castVote` reverts if called outside the voting time window. +// */ +// function test_revertIfVotingPhaseOver( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _numberOfVotes, +// uint256 _timestamp +// ) public { +// vm.assume(_timestamp > 140_000); + +// // Mock the oracle response for looking up a dispute +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// vm.mockCall(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// module.forTest_setEscalation(_disputeId, IERC20ResolutionModule.Escalation({startTime: 100_000, totalVotes: 0})); + +// // Store request data +// uint256 _minVotesForQuorum = 1; +// uint256 _votingTimeWindow = 40_000; + +// module.forTest_setRequestData(_requestId, abi.encode(token, _minVotesForQuorum, _votingTimeWindow)); + +// // Jump to timestamp +// vm.warp(_timestamp); + +// // Check: reverts if trying to cast vote after voting phase? +// vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_VotingPhaseOver.selector); +// module.castVote(_requestId, _disputeId, _numberOfVotes); +// } +// } + +// contract ERC20ResolutionModule_Unit_ResolveDispute is BaseTest { +// /** +// * @notice Test that a dispute is resolved, the tokens are transferred back to the voters and the dispute status updated. +// */ +// function test_resolveDispute(bytes32 _requestId, bytes32 _disputeId, uint16 _minVotesForQuorum) public { +// // Store mock dispute and mock calls +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// vm.mockCall(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Store request data +// uint256 _votingTimeWindow = 40_000; + +// module.forTest_setRequestData(_requestId, abi.encode(token, _minVotesForQuorum, _votingTimeWindow)); + +// // Store escalation data with `startTime` 100_000 and votes 0 +// module.forTest_setEscalation(_disputeId, IERC20ResolutionModule.Escalation({startTime: 100_000, totalVotes: 0})); + +// uint256 _votersAmount = 5; + +// // Make 5 addresses cast 100 votes each +// uint256 _totalVotesCast = _populateVoters(_requestId, _disputeId, _votersAmount, 100); + +// // Warp to resolving phase +// vm.warp(150_000); + +// // Mock and expect token transfers (should happen always) +// for (uint256 _i = 1; _i <= _votersAmount;) { +// _mockAndExpect(address(token), abi.encodeCall(IERC20.transfer, (vm.addr(_i), 100)), abi.encode()); +// unchecked { +// ++_i; +// } +// } + +// // If quorum reached, check for dispute status update and event emission +// IOracle.DisputeStatus _newStatus = +// _totalVotesCast >= _minVotesForQuorum ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost; + +// // Mock and expect IOracle.updateDisputeStatus to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, _newStatus)), abi.encode()); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true); +// emit DisputeResolved(_requestId, _disputeId, _newStatus); + +// // Check: does revert if called by address != oracle? +// vm.expectRevert(IModule.Module_OnlyOracle.selector); +// module.resolveDispute(_disputeId); + +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); +// } + +// /** +// * @notice Test that `resolveDispute` reverts if called during voting phase. +// */ +// function test_revertIfOnGoingVotePhase(bytes32 _requestId, bytes32 _disputeId, uint256 _timestamp) public { +// _timestamp = bound(_timestamp, 500_000, 999_999); - // Store mock dispute and mock calls - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Store mock dispute and mock calls +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - module.forTest_setEscalation( - _disputeId, - IERC20ResolutionModule.Escalation({ - startTime: 500_000, - totalVotes: 0 // Initial amount of votes - }) - ); +// module.forTest_setEscalation( +// _disputeId, +// IERC20ResolutionModule.Escalation({ +// startTime: 500_000, +// totalVotes: 0 // Initial amount of votes +// }) +// ); - // Store request data - uint256 _minVotesForQuorum = 1; - uint256 _votingTimeWindow = 500_000; +// // Store request data +// uint256 _minVotesForQuorum = 1; +// uint256 _votingTimeWindow = 500_000; - module.forTest_setRequestData(_requestId, abi.encode(token, _minVotesForQuorum, _votingTimeWindow)); +// module.forTest_setRequestData(_requestId, abi.encode(token, _minVotesForQuorum, _votingTimeWindow)); - // Jump to timestamp - vm.warp(_timestamp); +// // Jump to timestamp +// vm.warp(_timestamp); - // Check: reverts if trying to resolve during voting phase? - vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_OnGoingVotingPhase.selector); - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - } -} +// // Check: reverts if trying to resolve during voting phase? +// vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_OnGoingVotingPhase.selector); +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); +// } +// } -contract ERC20ResolutionModule_Unit_GetVoters is BaseTest { - /** - * @notice Test that `getVoters` returns an array of addresses of users that have voted. - */ - function test_getVoters(bytes32 _requestId, bytes32 _disputeId) public { - // Store mock dispute and mock calls - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); +// contract ERC20ResolutionModule_Unit_GetVoters is BaseTest { +// /** +// * @notice Test that `getVoters` returns an array of addresses of users that have voted. +// */ +// function test_getVoters(bytes32 _requestId, bytes32 _disputeId) public { +// // Store mock dispute and mock calls +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - // Store request data - uint256 _votingTimeWindow = 40_000; - uint256 _minVotesForQuorum = 1; +// // Store request data +// uint256 _votingTimeWindow = 40_000; +// uint256 _minVotesForQuorum = 1; - module.forTest_setRequestData(_requestId, abi.encode(token, _minVotesForQuorum, _votingTimeWindow)); +// module.forTest_setRequestData(_requestId, abi.encode(token, _minVotesForQuorum, _votingTimeWindow)); - // Store escalation data with `startTime` 100_000 and votes 0 - module.forTest_setEscalation(_disputeId, IERC20ResolutionModule.Escalation({startTime: 100_000, totalVotes: 0})); +// // Store escalation data with `startTime` 100_000 and votes 0 +// module.forTest_setEscalation(_disputeId, IERC20ResolutionModule.Escalation({startTime: 100_000, totalVotes: 0})); - uint256 _votersAmount = 3; +// uint256 _votersAmount = 3; - // Make 3 addresses cast 100 votes each - _populateVoters(_requestId, _disputeId, _votersAmount, 100); +// // Make 3 addresses cast 100 votes each +// _populateVoters(_requestId, _disputeId, _votersAmount, 100); - address[] memory _votersArray = module.getVoters(_disputeId); +// address[] memory _votersArray = module.getVoters(_disputeId); - for (uint256 _i = 1; _i <= _votersAmount; _i++) { - assertEq(_votersArray[_i - 1], vm.addr(_i)); - } - } -} +// for (uint256 _i = 1; _i <= _votersAmount; _i++) { +// assertEq(_votersArray[_i - 1], vm.addr(_i)); +// } +// } +// } diff --git a/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol b/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol index 31167536..769a9d86 100644 --- a/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol @@ -1,595 +1,595 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; - -import { - PrivateERC20ResolutionModule, - IPrivateERC20ResolutionModule -} from '../../../../contracts/modules/resolution/PrivateERC20ResolutionModule.sol'; -import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; - -contract ForTest_PrivateERC20ResolutionModule is PrivateERC20ResolutionModule { - constructor(IOracle _oracle) PrivateERC20ResolutionModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } - - function forTest_setEscalation( - bytes32 _disputeId, - PrivateERC20ResolutionModule.Escalation calldata __escalation - ) public { - escalations[_disputeId] = __escalation; - } - - function forTest_setVoterData( - bytes32 _disputeId, - address _voter, - IPrivateERC20ResolutionModule.VoterData memory _data - ) public { - _votersData[_disputeId][_voter] = _data; - } - - function forTest_getVoterData( - bytes32 _disputeId, - address _voter - ) public view returns (IPrivateERC20ResolutionModule.VoterData memory _data) { - _data = _votersData[_disputeId][_voter]; - } -} - -contract BaseTest is Test, Helpers { - // The target contract - ForTest_PrivateERC20ResolutionModule public module; - // A mock oracle - IOracle public oracle; - // A mock accounting extension - IAccountingExtension public accounting; - // A mock token - IERC20 public token; - // Mock EOA proposer - address public proposer = makeAddr('proposer'); - // Mock EOA disputer - address public disputer = makeAddr('disputer'); - - // Mocking module events - event CommittingPhaseStarted(uint256 _startTime, bytes32 _disputeId); - event VoteCommitted(address _voter, bytes32 _disputeId, bytes32 _commitment); - event VoteRevealed(address _voter, bytes32 _disputeId, uint256 _numberOfVotes); - event DisputeResolved(bytes32 indexed _requestId, bytes32 indexed _disputeId, IOracle.DisputeStatus _status); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - accounting = IAccountingExtension(makeAddr('AccountingExtension')); - vm.etch(address(accounting), hex'069420'); - - token = IERC20(makeAddr('ERC20')); - vm.etch(address(token), hex'069420'); - - proposer = makeAddr('proposer'); - disputer = makeAddr('disputer'); - - module = new ForTest_PrivateERC20ResolutionModule(oracle); - } - - /** - * @dev Helper function to store commitments and reveal votes. - */ - function _populateVoters( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amountOfVoters, - uint256 _amountOfVotes - ) internal returns (uint256 _totalVotesCast) { - for (uint256 _i = 1; _i <= _amountOfVoters;) { - vm.warp(120_000); - vm.startPrank(vm.addr(_i)); - bytes32 _commitment = module.computeCommitment(_disputeId, _amountOfVotes, bytes32(_i)); // index as salt - module.commitVote(_requestId, _disputeId, _commitment); - vm.warp(140_001); - vm.mockCall( - address(token), - abi.encodeCall(IERC20.transferFrom, (vm.addr(_i), address(module), _amountOfVotes)), - abi.encode() - ); - module.revealVote(_requestId, _disputeId, _amountOfVotes, bytes32(_i)); - vm.stopPrank(); - _totalVotesCast += _amountOfVotes; - unchecked { - ++_i; - } - } - } -} - -contract PrivateERC20ResolutionModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleName() public { - assertEq(module.moduleName(), 'PrivateERC20ResolutionModule'); - } -} - -contract PrivateERC20ResolutionModule_Unit_StartResolution is BaseTest { - /** - * @notice Test that the startResolution is correctly called and the committing phase is started - */ - function test_startResolution(bytes32 _disputeId) public { - module.forTest_setEscalation(_disputeId, IPrivateERC20ResolutionModule.Escalation({startTime: 0, totalVotes: 0})); - - // Check: does revert if called by address != oracle? - vm.expectRevert(IModule.Module_OnlyOracle.selector); - module.startResolution(_disputeId); - - // Check: emits CommittingPhaseStarted event? - vm.expectEmit(true, true, true, true); - emit CommittingPhaseStarted(block.timestamp, _disputeId); - - vm.prank(address(oracle)); - module.startResolution(_disputeId); - - (uint256 _startTime,) = module.escalations(_disputeId); - - // Check: startTime is set to block.timestamp? - assertEq(_startTime, block.timestamp); - } -} - -contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { - /** - * @notice Test that a user can store a vote commitment for a dispute - */ - function test_commitVote( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amountOfVotes, - bytes32 _salt, - address _voter - ) public { - // Mock the dispute - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Store mock escalation data with startTime 100_000 - module.forTest_setEscalation( - _disputeId, - IPrivateERC20ResolutionModule.Escalation({ - startTime: 100_000, - totalVotes: 0 // Initial amount of votes - }) - ); - - // Store mock request data with 40_000 committing time window - uint256 _minVotesForQuorum = 1; - uint256 _committingTimeWindow = 40_000; - uint256 _revealingTimeWindow = 40_000; - - module.forTest_setRequestData( - _requestId, - abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) - ); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Set timestamp for valid committingTimeWindow - vm.warp(123_456); - - // Compute commitment - vm.startPrank(_voter); - bytes32 _commitment = module.computeCommitment(_disputeId, _amountOfVotes, _salt); - - // Check: is event emitted? - vm.expectEmit(true, true, true, true); - emit VoteCommitted(_voter, _disputeId, _commitment); - - // Check: does it revert if no commitment is given? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_EmptyCommitment.selector); - module.commitVote(_requestId, _disputeId, bytes32('')); - - // Compute and store commitment - module.commitVote(_requestId, _disputeId, _commitment); - - // Check: reverts if empty commitment is given? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_EmptyCommitment.selector); - module.commitVote(_requestId, _disputeId, bytes32('')); - - // Check: is the commitment stored? - IPrivateERC20ResolutionModule.VoterData memory _voterData = module.forTest_getVoterData(_disputeId, _voter); - assertEq(_voterData.commitment, _commitment); - - bytes32 _newCommitment = module.computeCommitment(_disputeId, uint256(_salt), bytes32(_amountOfVotes)); - module.commitVote(_requestId, _disputeId, _newCommitment); - vm.stopPrank(); - - // Check: is voters data updated with new commitment? - IPrivateERC20ResolutionModule.VoterData memory _newVoterData = module.forTest_getVoterData(_disputeId, _voter); - assertEq(_newVoterData.commitment, _newCommitment); - } - - /** - * @notice Test that `commitVote` reverts if there is no dispute with the given`_disputeId` - */ - function test_revertIfNonExistentDispute(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) public { - IOracle.Dispute memory _mockDispute = IOracle.Dispute({ - disputer: address(0), - responseId: bytes32(0), - proposer: address(0), - requestId: bytes32(0), - status: IOracle.DisputeStatus.None, - createdAt: 0 - }); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Check: does it revert if no dispute exists? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_NonExistentDispute.selector); - module.commitVote(_requestId, _disputeId, _commitment); - } - - /** - * @notice Test that `commitVote` reverts if called with `_disputeId` of an already resolved dispute. - */ - function test_revertIfAlreadyResolved(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) public { - // Mock dispute already resolved => DisputeStatus.Lost - IOracle.Dispute memory _mockDispute = IOracle.Dispute({ - disputer: disputer, - responseId: bytes32('response'), - proposer: proposer, - requestId: _requestId, - status: IOracle.DisputeStatus.Lost, - createdAt: block.timestamp - }); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Check: does it revert if the dispute is already resolved? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_AlreadyResolved.selector); - module.commitVote(_requestId, _disputeId, _commitment); - } - - /** - * @notice Test that `commitVote` reverts if called with `_disputeId` of a non-escalated dispute. - */ - function test_revertIfNotEscalated(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) public { - // Mock the oracle response for looking up a dispute - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Check: reverts if dispute is not escalated? == no escalation data - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_DisputeNotEscalated.selector); - module.commitVote(_requestId, _disputeId, _commitment); - } - - /** - * @notice Test that `commitVote` reverts if called outside of the committing time window. - */ - function test_revertIfCommittingPhaseOver(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) public { - // Mock the oracle response for looking up a dispute - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - module.forTest_setEscalation( - _disputeId, - IPrivateERC20ResolutionModule.Escalation({ - startTime: 100_000, - totalVotes: 0 // Initial amount of votes - }) - ); - - uint256 _minVotesForQuorum = 1; - uint256 _committingTimeWindow = 40_000; - uint256 _revealingTimeWindow = 40_000; - - module.forTest_setRequestData( - _requestId, - abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) - ); - - // Warp to invalid timestamp for commitment - vm.warp(150_000); - - // Check: does it revert if the committing phase is over? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_CommittingPhaseOver.selector); - module.commitVote(_requestId, _disputeId, _commitment); - } -} - -contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { - /** - * @notice Test revealing votes with proper timestamp, dispute status and commitment data. - */ - function test_revealVote( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amountOfVotes, - bytes32 _salt, - address _voter - ) public { - // Store mock escalation data with startTime 100_000 - module.forTest_setEscalation( - _disputeId, - IPrivateERC20ResolutionModule.Escalation({ - startTime: 100_000, - totalVotes: 0 // Initial amount of votes - }) - ); - - // Store mock request data with 40_000 committing time window - module.forTest_setRequestData( - _requestId, abi.encode(address(accounting), token, uint256(1), uint256(40_000), uint256(40_000)) - ); - - // Store commitment - vm.prank(_voter); - bytes32 _commitment = module.computeCommitment(_disputeId, _amountOfVotes, _salt); - module.forTest_setVoterData( - _disputeId, _voter, IPrivateERC20ResolutionModule.VoterData({numOfVotes: 0, commitment: _commitment}) - ); - - // Mock and expect IERC20.transferFrom to be called - _mockAndExpect( - address(token), abi.encodeCall(IERC20.transferFrom, (_voter, address(module), _amountOfVotes)), abi.encode() - ); - - // Warp to revealing phase - vm.warp(150_000); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true); - emit VoteRevealed(_voter, _disputeId, _amountOfVotes); - - vm.prank(_voter); - module.revealVote(_requestId, _disputeId, _amountOfVotes, _salt); - - (, uint256 _totalVotes) = module.escalations(_disputeId); - // Check: is totalVotes updated? - assertEq(_totalVotes, _amountOfVotes); - - // Check: is voter data proplerly updated? - IPrivateERC20ResolutionModule.VoterData memory _voterData = module.forTest_getVoterData(_disputeId, _voter); - assertEq(_voterData.numOfVotes, _amountOfVotes); - } - - /** - * @notice Test that `revealVote` reverts if called with `_disputeId` of a non-escalated dispute. - */ - function test_revertIfNotEscalated( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _numberOfVotes, - bytes32 _salt - ) public { - // Check: does it revert if the dispute is not escalated? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_DisputeNotEscalated.selector); - module.revealVote(_requestId, _disputeId, _numberOfVotes, _salt); - } - - /** - * @notice Test that `revealVote` reverts if called outside the revealing time window. - */ - function test_revertIfInvalidPhase( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _numberOfVotes, - bytes32 _salt, - uint256 _timestamp - ) public { - vm.assume(_timestamp >= 100_000 && (_timestamp <= 140_000 || _timestamp > 180_000)); - - module.forTest_setEscalation( - _disputeId, - IPrivateERC20ResolutionModule.Escalation({ - startTime: 100_000, - totalVotes: 0 // Initial amount of votes - }) - ); - - // Store request data - uint256 _minVotesForQuorum = 1; - uint256 _committingTimeWindow = 40_000; - uint256 _revealingTimeWindow = 40_000; - - module.forTest_setRequestData( - _requestId, - abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) - ); - - // Jump to timestamp - vm.warp(_timestamp); - - if (_timestamp <= 140_000) { - // Check: does it revert if trying to reveal during the committing phase? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_OnGoingCommittingPhase.selector); - module.revealVote(_requestId, _disputeId, _numberOfVotes, _salt); - } else { - // Check: does it revert if trying to reveal after the revealing phase? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_RevealingPhaseOver.selector); - module.revealVote(_requestId, _disputeId, _numberOfVotes, _salt); - } - } - - /** - * @notice Test that `revealVote` reverts if called with revealing parameters (`_disputeId`, `_numberOfVotes`, `_salt`) - * that do not compute to the stored commitment. - */ - function test_revertIfFalseCommitment( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amountOfVotes, - uint256 _wrongAmountOfVotes, - bytes32 _salt, - bytes32 _wrongSalt, - address _voter, - address _wrongVoter - ) public { - vm.assume(_amountOfVotes != _wrongAmountOfVotes); - vm.assume(_salt != _wrongSalt); - vm.assume(_voter != _wrongVoter); - - module.forTest_setEscalation( - _disputeId, - IPrivateERC20ResolutionModule.Escalation({ - startTime: 100_000, - totalVotes: 0 // Initial amount of votes - }) - ); - - // Store request data - uint256 _minVotesForQuorum = 1; - uint256 _committingTimeWindow = 40_000; - uint256 _revealingTimeWindow = 40_000; - - module.forTest_setRequestData( - _requestId, - abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) - ); - vm.warp(150_000); - - vm.startPrank(_voter); - bytes32 _commitment = module.computeCommitment(_disputeId, _amountOfVotes, _salt); - module.forTest_setVoterData( - _disputeId, _voter, IPrivateERC20ResolutionModule.VoterData({numOfVotes: 0, commitment: _commitment}) - ); - - // Check: does it revert if the commitment is not valid? (wrong salt) - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); - module.revealVote(_requestId, _disputeId, _amountOfVotes, _wrongSalt); - - // Check: does it revert if the commitment is not valid? (wrong amount of votes) - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); - module.revealVote(_requestId, _disputeId, _wrongAmountOfVotes, _salt); - - vm.stopPrank(); - - // Check: does it revert if the commitment is not valid? (wrong voter) - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); - vm.prank(_wrongVoter); - module.revealVote(_requestId, _disputeId, _amountOfVotes, _salt); - } -} - -contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { - /** - * @notice Test that a dispute is resolved, the tokens are transferred back to the voters and the dispute status updated. - */ - function test_resolveDispute(bytes32 _requestId, bytes32 _disputeId, uint16 _minVotesForQuorum) public { - // Store mock dispute and mock calls - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - // Store request data - uint256 _committingTimeWindow = 40_000; - uint256 _revealingTimeWindow = 40_000; - - module.forTest_setRequestData( - _requestId, - abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) - ); - - // Store escalation data with startTime 100_000 and votes 0 - module.forTest_setEscalation( - _disputeId, IPrivateERC20ResolutionModule.Escalation({startTime: 100_000, totalVotes: 0}) - ); - - uint256 _votersAmount = 5; - - // Make 5 addresses cast 100 votes each - uint256 _totalVotesCast = _populateVoters(_requestId, _disputeId, _votersAmount, 100); - - // Warp to resolving phase - vm.warp(190_000); - - // Mock and expect token transfers (should happen always) - for (uint256 _i = 1; _i <= _votersAmount;) { - _mockAndExpect(address(token), abi.encodeCall(IERC20.transfer, (vm.addr(_i), 100)), abi.encode()); - unchecked { - ++_i; - } - } - - // If quorum reached, check for dispute status update and event emission - IOracle.DisputeStatus _newStatus = - _totalVotesCast >= _minVotesForQuorum ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost; - - // Mock and expect IOracle.updateDisputeStatus to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, _newStatus)), abi.encode()); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true); - emit DisputeResolved(_requestId, _disputeId, _newStatus); - - // Check: does it revert if called by address != oracle? - vm.expectRevert(IModule.Module_OnlyOracle.selector); - module.resolveDispute(_disputeId); - - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - } - - /** - * @notice Test that `resolveDispute` reverts if called during committing or revealing time window. - */ - function test_revertIfWrongPhase(bytes32 _requestId, bytes32 _disputeId, uint256 _timestamp) public { - _timestamp = bound(_timestamp, 1, 1_000_000); - - // Store mock dispute and mock calls - IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); - - // Mock and expect IOracle.getDispute to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); - - module.forTest_setEscalation( - _disputeId, - IPrivateERC20ResolutionModule.Escalation({ - startTime: 1, - totalVotes: 0 // Initial amount of votes - }) - ); - - // Store request data - uint256 _minVotesForQuorum = 1; - uint256 _committingTimeWindow = 500_000; - uint256 _revealingTimeWindow = 1_000_000; - - module.forTest_setRequestData( - _requestId, - abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) - ); - - // Jump to timestamp - vm.warp(_timestamp); - - if (_timestamp <= 500_000) { - // Check: does it revert if trying to resolve during the committing phase? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_OnGoingCommittingPhase.selector); - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - } else { - // Check: does it revert if trying to resolve during the revealing phase? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_OnGoingRevealingPhase.selector); - vm.prank(address(oracle)); - module.resolveDispute(_disputeId); - } - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; + +// import { +// PrivateERC20ResolutionModule, +// IPrivateERC20ResolutionModule +// } from '../../../../contracts/modules/resolution/PrivateERC20ResolutionModule.sol'; +// import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; + +// contract ForTest_PrivateERC20ResolutionModule is PrivateERC20ResolutionModule { +// constructor(IOracle _oracle) PrivateERC20ResolutionModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } + +// function forTest_setEscalation( +// bytes32 _disputeId, +// PrivateERC20ResolutionModule.Escalation calldata __escalation +// ) public { +// escalations[_disputeId] = __escalation; +// } + +// function forTest_setVoterData( +// bytes32 _disputeId, +// address _voter, +// IPrivateERC20ResolutionModule.VoterData memory _data +// ) public { +// _votersData[_disputeId][_voter] = _data; +// } + +// function forTest_getVoterData( +// bytes32 _disputeId, +// address _voter +// ) public view returns (IPrivateERC20ResolutionModule.VoterData memory _data) { +// _data = _votersData[_disputeId][_voter]; +// } +// } + +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_PrivateERC20ResolutionModule public module; +// // A mock oracle +// IOracle public oracle; +// // A mock accounting extension +// IAccountingExtension public accounting; +// // A mock token +// IERC20 public token; +// // Mock EOA proposer +// address public proposer = makeAddr('proposer'); +// // Mock EOA disputer +// address public disputer = makeAddr('disputer'); + +// // Mocking module events +// event CommittingPhaseStarted(uint256 _startTime, bytes32 _disputeId); +// event VoteCommitted(address _voter, bytes32 _disputeId, bytes32 _commitment); +// event VoteRevealed(address _voter, bytes32 _disputeId, uint256 _numberOfVotes); +// event DisputeResolved(bytes32 indexed _requestId, bytes32 indexed _disputeId, IOracle.DisputeStatus _status); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// accounting = IAccountingExtension(makeAddr('AccountingExtension')); +// vm.etch(address(accounting), hex'069420'); + +// token = IERC20(makeAddr('ERC20')); +// vm.etch(address(token), hex'069420'); + +// proposer = makeAddr('proposer'); +// disputer = makeAddr('disputer'); + +// module = new ForTest_PrivateERC20ResolutionModule(oracle); +// } + +// /** +// * @dev Helper function to store commitments and reveal votes. +// */ +// function _populateVoters( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _amountOfVoters, +// uint256 _amountOfVotes +// ) internal returns (uint256 _totalVotesCast) { +// for (uint256 _i = 1; _i <= _amountOfVoters;) { +// vm.warp(120_000); +// vm.startPrank(vm.addr(_i)); +// bytes32 _commitment = module.computeCommitment(_disputeId, _amountOfVotes, bytes32(_i)); // index as salt +// module.commitVote(_requestId, _disputeId, _commitment); +// vm.warp(140_001); +// vm.mockCall( +// address(token), +// abi.encodeCall(IERC20.transferFrom, (vm.addr(_i), address(module), _amountOfVotes)), +// abi.encode() +// ); +// module.revealVote(_requestId, _disputeId, _amountOfVotes, bytes32(_i)); +// vm.stopPrank(); +// _totalVotesCast += _amountOfVotes; +// unchecked { +// ++_i; +// } +// } +// } +// } + +// contract PrivateERC20ResolutionModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleName() public { +// assertEq(module.moduleName(), 'PrivateERC20ResolutionModule'); +// } +// } + +// contract PrivateERC20ResolutionModule_Unit_StartResolution is BaseTest { +// /** +// * @notice Test that the startResolution is correctly called and the committing phase is started +// */ +// function test_startResolution(bytes32 _disputeId) public { +// module.forTest_setEscalation(_disputeId, IPrivateERC20ResolutionModule.Escalation({startTime: 0, totalVotes: 0})); + +// // Check: does revert if called by address != oracle? +// vm.expectRevert(IModule.Module_OnlyOracle.selector); +// module.startResolution(_disputeId); + +// // Check: emits CommittingPhaseStarted event? +// vm.expectEmit(true, true, true, true); +// emit CommittingPhaseStarted(block.timestamp, _disputeId); + +// vm.prank(address(oracle)); +// module.startResolution(_disputeId); + +// (uint256 _startTime,) = module.escalations(_disputeId); + +// // Check: startTime is set to block.timestamp? +// assertEq(_startTime, block.timestamp); +// } +// } + +// contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { +// /** +// * @notice Test that a user can store a vote commitment for a dispute +// */ +// function test_commitVote( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _amountOfVotes, +// bytes32 _salt, +// address _voter +// ) public { +// // Mock the dispute +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Store mock escalation data with startTime 100_000 +// module.forTest_setEscalation( +// _disputeId, +// IPrivateERC20ResolutionModule.Escalation({ +// startTime: 100_000, +// totalVotes: 0 // Initial amount of votes +// }) +// ); + +// // Store mock request data with 40_000 committing time window +// uint256 _minVotesForQuorum = 1; +// uint256 _committingTimeWindow = 40_000; +// uint256 _revealingTimeWindow = 40_000; + +// module.forTest_setRequestData( +// _requestId, +// abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) +// ); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Set timestamp for valid committingTimeWindow +// vm.warp(123_456); + +// // Compute commitment +// vm.startPrank(_voter); +// bytes32 _commitment = module.computeCommitment(_disputeId, _amountOfVotes, _salt); + +// // Check: is event emitted? +// vm.expectEmit(true, true, true, true); +// emit VoteCommitted(_voter, _disputeId, _commitment); + +// // Check: does it revert if no commitment is given? +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_EmptyCommitment.selector); +// module.commitVote(_requestId, _disputeId, bytes32('')); + +// // Compute and store commitment +// module.commitVote(_requestId, _disputeId, _commitment); + +// // Check: reverts if empty commitment is given? +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_EmptyCommitment.selector); +// module.commitVote(_requestId, _disputeId, bytes32('')); + +// // Check: is the commitment stored? +// IPrivateERC20ResolutionModule.VoterData memory _voterData = module.forTest_getVoterData(_disputeId, _voter); +// assertEq(_voterData.commitment, _commitment); + +// bytes32 _newCommitment = module.computeCommitment(_disputeId, uint256(_salt), bytes32(_amountOfVotes)); +// module.commitVote(_requestId, _disputeId, _newCommitment); +// vm.stopPrank(); + +// // Check: is voters data updated with new commitment? +// IPrivateERC20ResolutionModule.VoterData memory _newVoterData = module.forTest_getVoterData(_disputeId, _voter); +// assertEq(_newVoterData.commitment, _newCommitment); +// } + +// /** +// * @notice Test that `commitVote` reverts if there is no dispute with the given`_disputeId` +// */ +// function test_revertIfNonExistentDispute(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) public { +// IOracle.Dispute memory _mockDispute = IOracle.Dispute({ +// disputer: address(0), +// responseId: bytes32(0), +// proposer: address(0), +// requestId: bytes32(0), +// status: IOracle.DisputeStatus.None, +// createdAt: 0 +// }); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Check: does it revert if no dispute exists? +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_NonExistentDispute.selector); +// module.commitVote(_requestId, _disputeId, _commitment); +// } + +// /** +// * @notice Test that `commitVote` reverts if called with `_disputeId` of an already resolved dispute. +// */ +// function test_revertIfAlreadyResolved(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) public { +// // Mock dispute already resolved => DisputeStatus.Lost +// IOracle.Dispute memory _mockDispute = IOracle.Dispute({ +// disputer: disputer, +// responseId: bytes32('response'), +// proposer: proposer, +// requestId: _requestId, +// status: IOracle.DisputeStatus.Lost, +// createdAt: block.timestamp +// }); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Check: does it revert if the dispute is already resolved? +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_AlreadyResolved.selector); +// module.commitVote(_requestId, _disputeId, _commitment); +// } + +// /** +// * @notice Test that `commitVote` reverts if called with `_disputeId` of a non-escalated dispute. +// */ +// function test_revertIfNotEscalated(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) public { +// // Mock the oracle response for looking up a dispute +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Check: reverts if dispute is not escalated? == no escalation data +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_DisputeNotEscalated.selector); +// module.commitVote(_requestId, _disputeId, _commitment); +// } + +// /** +// * @notice Test that `commitVote` reverts if called outside of the committing time window. +// */ +// function test_revertIfCommittingPhaseOver(bytes32 _requestId, bytes32 _disputeId, bytes32 _commitment) public { +// // Mock the oracle response for looking up a dispute +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// module.forTest_setEscalation( +// _disputeId, +// IPrivateERC20ResolutionModule.Escalation({ +// startTime: 100_000, +// totalVotes: 0 // Initial amount of votes +// }) +// ); + +// uint256 _minVotesForQuorum = 1; +// uint256 _committingTimeWindow = 40_000; +// uint256 _revealingTimeWindow = 40_000; + +// module.forTest_setRequestData( +// _requestId, +// abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) +// ); + +// // Warp to invalid timestamp for commitment +// vm.warp(150_000); + +// // Check: does it revert if the committing phase is over? +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_CommittingPhaseOver.selector); +// module.commitVote(_requestId, _disputeId, _commitment); +// } +// } + +// contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { +// /** +// * @notice Test revealing votes with proper timestamp, dispute status and commitment data. +// */ +// function test_revealVote( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _amountOfVotes, +// bytes32 _salt, +// address _voter +// ) public { +// // Store mock escalation data with startTime 100_000 +// module.forTest_setEscalation( +// _disputeId, +// IPrivateERC20ResolutionModule.Escalation({ +// startTime: 100_000, +// totalVotes: 0 // Initial amount of votes +// }) +// ); + +// // Store mock request data with 40_000 committing time window +// module.forTest_setRequestData( +// _requestId, abi.encode(address(accounting), token, uint256(1), uint256(40_000), uint256(40_000)) +// ); + +// // Store commitment +// vm.prank(_voter); +// bytes32 _commitment = module.computeCommitment(_disputeId, _amountOfVotes, _salt); +// module.forTest_setVoterData( +// _disputeId, _voter, IPrivateERC20ResolutionModule.VoterData({numOfVotes: 0, commitment: _commitment}) +// ); + +// // Mock and expect IERC20.transferFrom to be called +// _mockAndExpect( +// address(token), abi.encodeCall(IERC20.transferFrom, (_voter, address(module), _amountOfVotes)), abi.encode() +// ); + +// // Warp to revealing phase +// vm.warp(150_000); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true); +// emit VoteRevealed(_voter, _disputeId, _amountOfVotes); + +// vm.prank(_voter); +// module.revealVote(_requestId, _disputeId, _amountOfVotes, _salt); + +// (, uint256 _totalVotes) = module.escalations(_disputeId); +// // Check: is totalVotes updated? +// assertEq(_totalVotes, _amountOfVotes); + +// // Check: is voter data proplerly updated? +// IPrivateERC20ResolutionModule.VoterData memory _voterData = module.forTest_getVoterData(_disputeId, _voter); +// assertEq(_voterData.numOfVotes, _amountOfVotes); +// } + +// /** +// * @notice Test that `revealVote` reverts if called with `_disputeId` of a non-escalated dispute. +// */ +// function test_revertIfNotEscalated( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _numberOfVotes, +// bytes32 _salt +// ) public { +// // Check: does it revert if the dispute is not escalated? +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_DisputeNotEscalated.selector); +// module.revealVote(_requestId, _disputeId, _numberOfVotes, _salt); +// } + +// /** +// * @notice Test that `revealVote` reverts if called outside the revealing time window. +// */ +// function test_revertIfInvalidPhase( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _numberOfVotes, +// bytes32 _salt, +// uint256 _timestamp +// ) public { +// vm.assume(_timestamp >= 100_000 && (_timestamp <= 140_000 || _timestamp > 180_000)); + +// module.forTest_setEscalation( +// _disputeId, +// IPrivateERC20ResolutionModule.Escalation({ +// startTime: 100_000, +// totalVotes: 0 // Initial amount of votes +// }) +// ); + +// // Store request data +// uint256 _minVotesForQuorum = 1; +// uint256 _committingTimeWindow = 40_000; +// uint256 _revealingTimeWindow = 40_000; + +// module.forTest_setRequestData( +// _requestId, +// abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) +// ); + +// // Jump to timestamp +// vm.warp(_timestamp); + +// if (_timestamp <= 140_000) { +// // Check: does it revert if trying to reveal during the committing phase? +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_OnGoingCommittingPhase.selector); +// module.revealVote(_requestId, _disputeId, _numberOfVotes, _salt); +// } else { +// // Check: does it revert if trying to reveal after the revealing phase? +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_RevealingPhaseOver.selector); +// module.revealVote(_requestId, _disputeId, _numberOfVotes, _salt); +// } +// } + +// /** +// * @notice Test that `revealVote` reverts if called with revealing parameters (`_disputeId`, `_numberOfVotes`, `_salt`) +// * that do not compute to the stored commitment. +// */ +// function test_revertIfFalseCommitment( +// bytes32 _requestId, +// bytes32 _disputeId, +// uint256 _amountOfVotes, +// uint256 _wrongAmountOfVotes, +// bytes32 _salt, +// bytes32 _wrongSalt, +// address _voter, +// address _wrongVoter +// ) public { +// vm.assume(_amountOfVotes != _wrongAmountOfVotes); +// vm.assume(_salt != _wrongSalt); +// vm.assume(_voter != _wrongVoter); + +// module.forTest_setEscalation( +// _disputeId, +// IPrivateERC20ResolutionModule.Escalation({ +// startTime: 100_000, +// totalVotes: 0 // Initial amount of votes +// }) +// ); + +// // Store request data +// uint256 _minVotesForQuorum = 1; +// uint256 _committingTimeWindow = 40_000; +// uint256 _revealingTimeWindow = 40_000; + +// module.forTest_setRequestData( +// _requestId, +// abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) +// ); +// vm.warp(150_000); + +// vm.startPrank(_voter); +// bytes32 _commitment = module.computeCommitment(_disputeId, _amountOfVotes, _salt); +// module.forTest_setVoterData( +// _disputeId, _voter, IPrivateERC20ResolutionModule.VoterData({numOfVotes: 0, commitment: _commitment}) +// ); + +// // Check: does it revert if the commitment is not valid? (wrong salt) +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); +// module.revealVote(_requestId, _disputeId, _amountOfVotes, _wrongSalt); + +// // Check: does it revert if the commitment is not valid? (wrong amount of votes) +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); +// module.revealVote(_requestId, _disputeId, _wrongAmountOfVotes, _salt); + +// vm.stopPrank(); + +// // Check: does it revert if the commitment is not valid? (wrong voter) +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); +// vm.prank(_wrongVoter); +// module.revealVote(_requestId, _disputeId, _amountOfVotes, _salt); +// } +// } + +// contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { +// /** +// * @notice Test that a dispute is resolved, the tokens are transferred back to the voters and the dispute status updated. +// */ +// function test_resolveDispute(bytes32 _requestId, bytes32 _disputeId, uint16 _minVotesForQuorum) public { +// // Store mock dispute and mock calls +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// // Store request data +// uint256 _committingTimeWindow = 40_000; +// uint256 _revealingTimeWindow = 40_000; + +// module.forTest_setRequestData( +// _requestId, +// abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) +// ); + +// // Store escalation data with startTime 100_000 and votes 0 +// module.forTest_setEscalation( +// _disputeId, IPrivateERC20ResolutionModule.Escalation({startTime: 100_000, totalVotes: 0}) +// ); + +// uint256 _votersAmount = 5; + +// // Make 5 addresses cast 100 votes each +// uint256 _totalVotesCast = _populateVoters(_requestId, _disputeId, _votersAmount, 100); + +// // Warp to resolving phase +// vm.warp(190_000); + +// // Mock and expect token transfers (should happen always) +// for (uint256 _i = 1; _i <= _votersAmount;) { +// _mockAndExpect(address(token), abi.encodeCall(IERC20.transfer, (vm.addr(_i), 100)), abi.encode()); +// unchecked { +// ++_i; +// } +// } + +// // If quorum reached, check for dispute status update and event emission +// IOracle.DisputeStatus _newStatus = +// _totalVotesCast >= _minVotesForQuorum ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost; + +// // Mock and expect IOracle.updateDisputeStatus to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.updateDisputeStatus, (_disputeId, _newStatus)), abi.encode()); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true); +// emit DisputeResolved(_requestId, _disputeId, _newStatus); + +// // Check: does it revert if called by address != oracle? +// vm.expectRevert(IModule.Module_OnlyOracle.selector); +// module.resolveDispute(_disputeId); + +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); +// } + +// /** +// * @notice Test that `resolveDispute` reverts if called during committing or revealing time window. +// */ +// function test_revertIfWrongPhase(bytes32 _requestId, bytes32 _disputeId, uint256 _timestamp) public { +// _timestamp = bound(_timestamp, 1, 1_000_000); + +// // Store mock dispute and mock calls +// IOracle.Dispute memory _mockDispute = _getMockDispute(_requestId, disputer, proposer); + +// // Mock and expect IOracle.getDispute to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getDispute, (_disputeId)), abi.encode(_mockDispute)); + +// module.forTest_setEscalation( +// _disputeId, +// IPrivateERC20ResolutionModule.Escalation({ +// startTime: 1, +// totalVotes: 0 // Initial amount of votes +// }) +// ); + +// // Store request data +// uint256 _minVotesForQuorum = 1; +// uint256 _committingTimeWindow = 500_000; +// uint256 _revealingTimeWindow = 1_000_000; + +// module.forTest_setRequestData( +// _requestId, +// abi.encode(address(accounting), token, _minVotesForQuorum, _committingTimeWindow, _revealingTimeWindow) +// ); + +// // Jump to timestamp +// vm.warp(_timestamp); + +// if (_timestamp <= 500_000) { +// // Check: does it revert if trying to resolve during the committing phase? +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_OnGoingCommittingPhase.selector); +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); +// } else { +// // Check: does it revert if trying to resolve during the revealing phase? +// vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_OnGoingRevealingPhase.selector); +// vm.prank(address(oracle)); +// module.resolveDispute(_disputeId); +// } +// } +// } diff --git a/solidity/test/unit/modules/resolution/SequentialResolutionModule.t.sol b/solidity/test/unit/modules/resolution/SequentialResolutionModule.t.sol index 3312e122..e46f5d55 100644 --- a/solidity/test/unit/modules/resolution/SequentialResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/SequentialResolutionModule.t.sol @@ -1,760 +1,760 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; - -import { - SequentialResolutionModule, - IResolutionModule, - ISequentialResolutionModule -} from '../../../../contracts/modules/resolution/SequentialResolutionModule.sol'; - -contract ForTest_ResolutionModule is Module { - string public name; - IOracle.DisputeStatus internal _responseStatus; - - constructor(IOracle _oracle, string memory _name) payable Module(_oracle) { - name = _name; - } - - function resolveDispute(bytes32 _disputeId) external { - ORACLE.updateDisputeStatus(_disputeId, _responseStatus); - } - - function startResolution(bytes32 _disputeId) external {} - - function moduleName() external view returns (string memory _moduleName) { - return name; - } - - function forTest_setResponseStatus(IOracle.DisputeStatus _status) external { - _responseStatus = _status; - } -} - -contract BaseTest is Test, Helpers { - SequentialResolutionModule public module; - IOracle public oracle; - bytes32 public disputeId = bytes32(uint256(1)); - bytes32 public responseId = bytes32(uint256(2)); - bytes32 public requestId = bytes32(uint256(3)); - - bytes32 public disputeId2 = bytes32(uint256(4)); - bytes32 public requestId2 = bytes32(uint256(5)); - - address public proposer = makeAddr('proposer'); - address public disputer = makeAddr('disputer'); - bytes public responseData = abi.encode('responseData'); - - ForTest_ResolutionModule public submodule1; - ForTest_ResolutionModule public submodule2; - ForTest_ResolutionModule public submodule3; - IResolutionModule[] public resolutionModules; - IResolutionModule[] public resolutionModules2; - uint256 public sequenceId; - uint256 public sequenceId2; - - event ResolutionSequenceAdded(uint256 _sequenceId, IResolutionModule[] _modules); - - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - vm.mockCall( - address(oracle), - abi.encodeWithSelector(IOracle.getDispute.selector, disputeId), - abi.encode( - IOracle.Dispute(block.timestamp, disputer, proposer, responseId, requestId, IOracle.DisputeStatus.Escalated) - ) - ); - - vm.mockCall( - address(oracle), - abi.encodeWithSelector(IOracle.getDispute.selector, disputeId2), - abi.encode( - IOracle.Dispute(block.timestamp, disputer, proposer, responseId, requestId2, IOracle.DisputeStatus.Escalated) - ) - ); - - vm.mockCall(address(oracle), abi.encodeWithSelector(IOracle.updateDisputeStatus.selector), abi.encode()); - - module = new SequentialResolutionModule(oracle); - - submodule1 = new ForTest_ResolutionModule(module, 'module1'); - submodule2 = new ForTest_ResolutionModule(module, 'module2'); - submodule3 = new ForTest_ResolutionModule(module, 'module3'); - - vm.mockCall(address(submodule1), abi.encodeWithSelector(IModule.setupRequest.selector), abi.encode()); - vm.mockCall(address(submodule2), abi.encodeWithSelector(IModule.setupRequest.selector), abi.encode()); - vm.mockCall(address(submodule3), abi.encodeWithSelector(IModule.setupRequest.selector), abi.encode()); - - resolutionModules.push(IResolutionModule(address(submodule1))); - resolutionModules.push(IResolutionModule(address(submodule2))); - resolutionModules.push(IResolutionModule(address(submodule3))); - - sequenceId = module.addResolutionModuleSequence(resolutionModules); - - bytes[] memory _submoduleData = new bytes[](3); - _submoduleData[0] = abi.encode('submodule1Data'); - _submoduleData[1] = abi.encode('submodule2Data'); - _submoduleData[2] = abi.encode('submodule3Data'); - - vm.prank(address(oracle)); - module.setupRequest( - requestId, - abi.encode(ISequentialResolutionModule.RequestParameters({sequenceId: sequenceId, submoduleData: _submoduleData})) - ); - - resolutionModules2.push(IResolutionModule(address(submodule2))); - resolutionModules2.push(IResolutionModule(address(submodule3))); - resolutionModules2.push(IResolutionModule(address(submodule1))); - - sequenceId2 = module.addResolutionModuleSequence(resolutionModules2); - - vm.prank(address(oracle)); - module.setupRequest( - requestId2, - abi.encode( - ISequentialResolutionModule.RequestParameters({sequenceId: sequenceId2, submoduleData: _submoduleData}) - ) - ); - } -} - -/** - * @title SequentialResolutionModule Unit tests - */ -contract SequentialResolutionModule_Unit_ModuleData is BaseTest { - function test_decodeRequestParameters() public { - ISequentialResolutionModule.RequestParameters memory _params = module.decodeRequestData(requestId); - - // Check: are all request parameters properly stored? - assertEq(_params.sequenceId, sequenceId); - assertEq(_params.submoduleData[0], abi.encode('submodule1Data')); - assertEq(_params.submoduleData[1], abi.encode('submodule2Data')); - assertEq(_params.submoduleData[2], abi.encode('submodule3Data')); - } - - function test_moduleName() public { - assertEq(module.moduleName(), 'SequentialResolutionModule'); - } -} - -contract SequentialResolutionModule_Unit_Setup is BaseTest { - function test_setupRequestCallsAllSubmodules(bytes32 _requestId) public { - bytes memory _submodule1Data = abi.encode('submodule1Data'); - bytes memory _submodule2Data = abi.encode('submodule2Data'); - bytes memory _submodule3Data = abi.encode('submodule3Data'); - - bytes[] memory _submoduleData = new bytes[](3); - _submoduleData[0] = _submodule1Data; - _submoduleData[1] = _submodule2Data; - _submoduleData[2] = _submodule3Data; - - // Check: is the submodule 1 called with the proper data? - vm.expectCall( - address(submodule1), abi.encodeWithSelector(IModule.setupRequest.selector, _requestId, _submodule1Data) - ); - // Check: is the submodule 2 called with the proper data? - vm.expectCall( - address(submodule2), abi.encodeWithSelector(IModule.setupRequest.selector, _requestId, _submodule2Data) - ); - // Check: is the submodule 3 called with the proper data? - vm.expectCall( - address(submodule3), abi.encodeWithSelector(IModule.setupRequest.selector, _requestId, _submodule3Data) - ); - - vm.prank(address(oracle)); - module.setupRequest( - _requestId, - abi.encode(ISequentialResolutionModule.RequestParameters({sequenceId: sequenceId, submoduleData: _submoduleData})) - ); - } - - function test_addResolutionModuleSequence(IResolutionModule[] memory _testModules) public { - uint256 _beforeSequenceId = module.currentSequenceId(); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(module)); - emit ResolutionSequenceAdded(_beforeSequenceId + 1, _testModules); - - uint256 _afterSequenceId = module.addResolutionModuleSequence(_testModules); - // Check: is the sequence id updated? - assertEq(_beforeSequenceId + 1, _afterSequenceId); - } - - function test_setupRequestRevertsIfNotOracle() public { - // Check: does it revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(makeAddr('other_sender')); - module.setupRequest(requestId, abi.encode()); - } -} - -contract SequentialResolutionModule_Unit_OracleProxy is BaseTest { - function test_allowedModuleCallsOracle() public { - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.allowedModule.selector), abi.encode(true)); - module.allowedModule(requestId, address(module)); - } - - function test_getDisputeCallsOracle() public { - IOracle.Dispute memory _dispute; - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getDispute.selector), abi.encode(_dispute)); - module.getDispute(disputeId); - } - - function test_getResponseCallsOracle() public { - IOracle.Response memory _response; - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getResponse.selector), abi.encode(_response)); - module.getResponse(responseId); - } - - function test_getRequestCallsOracle() public { - IOracle.Request memory _request; - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getRequest.selector), abi.encode(_request)); - module.getRequest(requestId); - } - - function test_getFullRequestCallsOracle() public { - IOracle.FullRequest memory _request; - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getFullRequest.selector), abi.encode(_request)); - module.getFullRequest(requestId); - } - - function test_disputeOfCallsOracle() public { - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.disputeOf.selector), abi.encode(disputeId)); - module.disputeOf(requestId); - } - - function test_getFinalizedResponseCallsOracle() public { - IOracle.Response memory _response; - _mockAndExpect( - address(oracle), abi.encodeWithSelector(IOracle.getFinalizedResponse.selector), abi.encode(_response) - ); - module.getFinalizedResponse(requestId); - } - - function test_getResponseIdsCallsOracle() public { - bytes32[] memory _ids; - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getResponseIds.selector), abi.encode(_ids)); - module.getResponseIds(requestId); - } - - function test_listRequestsCallsOracle() public { - IOracle.FullRequest[] memory _list; - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.listRequests.selector), abi.encode(_list)); - module.listRequests(0, 10); - } - - function test_listRequestIdsCallsOracle() public { - bytes32[] memory _list; - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.listRequestIds.selector), abi.encode(_list)); - module.listRequestIds(0, 10); - } - - function test_getRequestIdCallsOracle(uint256 _nonce) public { - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getRequestId.selector), abi.encode(bytes32(0))); - module.getRequestId(_nonce); - } - - function test_getRequestByNonceCallsOracle(uint256 _nonce) public { - IOracle.Request memory _request; - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getRequestByNonce.selector), abi.encode(_request)); - module.getRequestByNonce(_nonce); - } - - function test_finalizeCallsOracle() public { - _mockAndExpect(address(oracle), abi.encodeWithSignature('finalize(bytes32,bytes32)'), abi.encode()); - vm.prank(address(submodule1)); - module.finalize(requestId, responseId); - } - - function test_escalateDisputeCallsOracle() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.escalateDispute.selector), abi.encode()); - - vm.prank(address(submodule1)); - module.escalateDispute(disputeId); - } - - function test_isParticipantCallsOracle(bytes32 _requestId, address _user) public { - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.isParticipant.selector), abi.encode(true)); - module.isParticipant(_requestId, _user); - } - - function test_getFinalizedResponseIdCallsOracle(bytes32 _requestId) public { - _mockAndExpect( - address(oracle), abi.encodeWithSelector(IOracle.getFinalizedResponseId.selector), abi.encode(bytes32('69')) - ); - module.getFinalizedResponseId(_requestId); - } - - function test_totalRequestCountCallsOracle() public { - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.totalRequestCount.selector), abi.encode(uint256(69))); - module.totalRequestCount(); - } - - function test_finalizeWithoutResponseCallsOracle() public { - _mockAndExpect(address(oracle), abi.encodeWithSignature('finalize(bytes32)'), abi.encode()); - vm.prank(address(submodule1)); - module.finalize(requestId); - } - - function test_getDisputeCallsManager(bytes32 _disputeId) public { - IOracle.Dispute memory _dispute; - _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getDispute.selector), abi.encode(_dispute)); - module.getDispute(_disputeId); - } -} - -contract SequentialResolutionModule_Unit_ResolveDispute is BaseTest { - function test_revertIfNotOracle() public { - // Check: does it revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(makeAddr('other_sender')); - module.resolveDispute(disputeId); - } - - function test_callsFirstModuleAndResolvesIfWon() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - submodule1.forTest_setResponseStatus(IOracle.DisputeStatus.Won); - - // Check: is the module called with IOracle.updateDisputeStatus and DisputeStatus.Won? - vm.expectCall( - address(module), - abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.Won) - ); - - // Check: is the oracle called with IOracle.updateDisputeStatus and DisputeStatus.Won? - vm.expectCall( - address(oracle), - abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.Won) - ); - - vm.prank(address(oracle)); - module.resolveDispute(disputeId); - } - - function test_callsFirstModuleAndResolvesIfLost() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - submodule1.forTest_setResponseStatus(IOracle.DisputeStatus.Lost); - - // Check: is the module called with IOracle.updateDisputeStatus and DisputeStatus.Lost? - vm.expectCall( - address(module), - abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.Lost) - ); - - // Check: is the oracle called with IOracle.updateDisputeStatus and DisputeStatus.Lost? - vm.expectCall( - address(oracle), - abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.Lost) - ); - - vm.prank(address(oracle)); - module.resolveDispute(disputeId); - } - - function test_goesToTheNextResolutionModule() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - submodule1.forTest_setResponseStatus(IOracle.DisputeStatus.NoResolution); - - // Check: is the submodule 2 called with IResolutionModule.startResolution? - vm.expectCall(address(submodule2), abi.encodeWithSelector(IResolutionModule.startResolution.selector, disputeId)); - - // Check: is the current resolution module the submodule 1? - assertEq(address(module.getCurrentResolutionModule(disputeId)), address(submodule1)); - - vm.prank(address(oracle)); - module.resolveDispute(disputeId); - - // Check: is the current resolution module the submodule 2? - assertEq(address(module.getCurrentResolutionModule(disputeId)), address(submodule2)); - - // Check: is the submodule 2 called with IResolutionModule.resolveDispute? - vm.expectCall(address(submodule2), abi.encodeWithSelector(IResolutionModule.resolveDispute.selector, disputeId)); - - vm.prank(address(oracle)); - module.resolveDispute(disputeId); - } - - function test_callsTheManagerWhenThereAreNoMoreSubmodulesLeft() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - - submodule1.forTest_setResponseStatus(IOracle.DisputeStatus.NoResolution); - - vm.prank(address(oracle)); - module.resolveDispute(disputeId); - - submodule2.forTest_setResponseStatus(IOracle.DisputeStatus.NoResolution); - - vm.prank(address(oracle)); - module.resolveDispute(disputeId); - - // Check: is the oracle called with IOracle.updateDisputeStatus and DisputeStatus.NoResolution? - vm.expectCall( - address(oracle), - abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.NoResolution) - ); - - submodule3.forTest_setResponseStatus(IOracle.DisputeStatus.NoResolution); - vm.prank(address(oracle)); - module.resolveDispute(disputeId); - } -} - -contract SequentialResolutionModule_Unit_StartResolution is BaseTest { - function test_revertsIfNotOracle() public { - // Check: does it revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(makeAddr('other_sender')); - module.startResolution(disputeId); - } - - function test_callsFirstModule() public { - // Check: is the submodule 1 called with IResolutionModule.startResolution? - vm.expectCall(address(submodule1), abi.encodeWithSelector(IResolutionModule.startResolution.selector, disputeId)); - - vm.prank(address(oracle)); - module.startResolution(disputeId); - } - - function test_callsFirstModuleSequence2() public { - // Check: is the submodule 2 called with IResolutionModule.startResolution? - vm.expectCall(address(submodule2), abi.encodeWithSelector(IResolutionModule.startResolution.selector, disputeId2)); +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; + +// import { +// SequentialResolutionModule, +// IResolutionModule, +// ISequentialResolutionModule +// } from '../../../../contracts/modules/resolution/SequentialResolutionModule.sol'; + +// contract ForTest_ResolutionModule is Module { +// string public name; +// IOracle.DisputeStatus internal _responseStatus; + +// constructor(IOracle _oracle, string memory _name) payable Module(_oracle) { +// name = _name; +// } + +// function resolveDispute(bytes32 _disputeId) external { +// ORACLE.updateDisputeStatus(_disputeId, _responseStatus); +// } + +// function startResolution(bytes32 _disputeId) external {} + +// function moduleName() external view returns (string memory _moduleName) { +// return name; +// } + +// function forTest_setResponseStatus(IOracle.DisputeStatus _status) external { +// _responseStatus = _status; +// } +// } + +// contract BaseTest is Test, Helpers { +// SequentialResolutionModule public module; +// IOracle public oracle; +// bytes32 public disputeId = bytes32(uint256(1)); +// bytes32 public responseId = bytes32(uint256(2)); +// bytes32 public requestId = bytes32(uint256(3)); + +// bytes32 public disputeId2 = bytes32(uint256(4)); +// bytes32 public requestId2 = bytes32(uint256(5)); + +// address public proposer = makeAddr('proposer'); +// address public disputer = makeAddr('disputer'); +// bytes public responseData = abi.encode('responseData'); + +// ForTest_ResolutionModule public submodule1; +// ForTest_ResolutionModule public submodule2; +// ForTest_ResolutionModule public submodule3; +// IResolutionModule[] public resolutionModules; +// IResolutionModule[] public resolutionModules2; +// uint256 public sequenceId; +// uint256 public sequenceId2; + +// event ResolutionSequenceAdded(uint256 _sequenceId, IResolutionModule[] _modules); + +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// vm.mockCall( +// address(oracle), +// abi.encodeWithSelector(IOracle.getDispute.selector, disputeId), +// abi.encode( +// IOracle.Dispute(block.timestamp, disputer, proposer, responseId, requestId, IOracle.DisputeStatus.Escalated) +// ) +// ); + +// vm.mockCall( +// address(oracle), +// abi.encodeWithSelector(IOracle.getDispute.selector, disputeId2), +// abi.encode( +// IOracle.Dispute(block.timestamp, disputer, proposer, responseId, requestId2, IOracle.DisputeStatus.Escalated) +// ) +// ); + +// vm.mockCall(address(oracle), abi.encodeWithSelector(IOracle.updateDisputeStatus.selector), abi.encode()); + +// module = new SequentialResolutionModule(oracle); + +// submodule1 = new ForTest_ResolutionModule(module, 'module1'); +// submodule2 = new ForTest_ResolutionModule(module, 'module2'); +// submodule3 = new ForTest_ResolutionModule(module, 'module3'); + +// vm.mockCall(address(submodule1), abi.encodeWithSelector(IModule.setupRequest.selector), abi.encode()); +// vm.mockCall(address(submodule2), abi.encodeWithSelector(IModule.setupRequest.selector), abi.encode()); +// vm.mockCall(address(submodule3), abi.encodeWithSelector(IModule.setupRequest.selector), abi.encode()); + +// resolutionModules.push(IResolutionModule(address(submodule1))); +// resolutionModules.push(IResolutionModule(address(submodule2))); +// resolutionModules.push(IResolutionModule(address(submodule3))); + +// sequenceId = module.addResolutionModuleSequence(resolutionModules); + +// bytes[] memory _submoduleData = new bytes[](3); +// _submoduleData[0] = abi.encode('submodule1Data'); +// _submoduleData[1] = abi.encode('submodule2Data'); +// _submoduleData[2] = abi.encode('submodule3Data'); + +// vm.prank(address(oracle)); +// module.setupRequest( +// requestId, +// abi.encode(ISequentialResolutionModule.RequestParameters({sequenceId: sequenceId, submoduleData: _submoduleData})) +// ); + +// resolutionModules2.push(IResolutionModule(address(submodule2))); +// resolutionModules2.push(IResolutionModule(address(submodule3))); +// resolutionModules2.push(IResolutionModule(address(submodule1))); + +// sequenceId2 = module.addResolutionModuleSequence(resolutionModules2); + +// vm.prank(address(oracle)); +// module.setupRequest( +// requestId2, +// abi.encode( +// ISequentialResolutionModule.RequestParameters({sequenceId: sequenceId2, submoduleData: _submoduleData}) +// ) +// ); +// } +// } + +// /** +// * @title SequentialResolutionModule Unit tests +// */ +// contract SequentialResolutionModule_Unit_ModuleData is BaseTest { +// function test_decodeRequestParameters() public { +// ISequentialResolutionModule.RequestParameters memory _params = module.decodeRequestData(requestId); + +// // Check: are all request parameters properly stored? +// assertEq(_params.sequenceId, sequenceId); +// assertEq(_params.submoduleData[0], abi.encode('submodule1Data')); +// assertEq(_params.submoduleData[1], abi.encode('submodule2Data')); +// assertEq(_params.submoduleData[2], abi.encode('submodule3Data')); +// } + +// function test_moduleName() public { +// assertEq(module.moduleName(), 'SequentialResolutionModule'); +// } +// } + +// contract SequentialResolutionModule_Unit_Setup is BaseTest { +// function test_setupRequestCallsAllSubmodules(bytes32 _requestId) public { +// bytes memory _submodule1Data = abi.encode('submodule1Data'); +// bytes memory _submodule2Data = abi.encode('submodule2Data'); +// bytes memory _submodule3Data = abi.encode('submodule3Data'); + +// bytes[] memory _submoduleData = new bytes[](3); +// _submoduleData[0] = _submodule1Data; +// _submoduleData[1] = _submodule2Data; +// _submoduleData[2] = _submodule3Data; + +// // Check: is the submodule 1 called with the proper data? +// vm.expectCall( +// address(submodule1), abi.encodeWithSelector(IModule.setupRequest.selector, _requestId, _submodule1Data) +// ); +// // Check: is the submodule 2 called with the proper data? +// vm.expectCall( +// address(submodule2), abi.encodeWithSelector(IModule.setupRequest.selector, _requestId, _submodule2Data) +// ); +// // Check: is the submodule 3 called with the proper data? +// vm.expectCall( +// address(submodule3), abi.encodeWithSelector(IModule.setupRequest.selector, _requestId, _submodule3Data) +// ); + +// vm.prank(address(oracle)); +// module.setupRequest( +// _requestId, +// abi.encode(ISequentialResolutionModule.RequestParameters({sequenceId: sequenceId, submoduleData: _submoduleData})) +// ); +// } + +// function test_addResolutionModuleSequence(IResolutionModule[] memory _testModules) public { +// uint256 _beforeSequenceId = module.currentSequenceId(); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(module)); +// emit ResolutionSequenceAdded(_beforeSequenceId + 1, _testModules); + +// uint256 _afterSequenceId = module.addResolutionModuleSequence(_testModules); +// // Check: is the sequence id updated? +// assertEq(_beforeSequenceId + 1, _afterSequenceId); +// } + +// function test_setupRequestRevertsIfNotOracle() public { +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(makeAddr('other_sender')); +// module.setupRequest(requestId, abi.encode()); +// } +// } + +// contract SequentialResolutionModule_Unit_OracleProxy is BaseTest { +// function test_allowedModuleCallsOracle() public { +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.allowedModule.selector), abi.encode(true)); +// module.allowedModule(requestId, address(module)); +// } + +// function test_getDisputeCallsOracle() public { +// IOracle.Dispute memory _dispute; +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getDispute.selector), abi.encode(_dispute)); +// module.getDispute(disputeId); +// } + +// function test_getResponseCallsOracle() public { +// IOracle.Response memory _response; +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getResponse.selector), abi.encode(_response)); +// module.getResponse(responseId); +// } + +// function test_getRequestCallsOracle() public { +// IOracle.Request memory _request; +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getRequest.selector), abi.encode(_request)); +// module.getRequest(requestId); +// } + +// function test_getFullRequestCallsOracle() public { +// IOracle.FullRequest memory _request; +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getFullRequest.selector), abi.encode(_request)); +// module.getFullRequest(requestId); +// } + +// function test_disputeOfCallsOracle() public { +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.disputeOf.selector), abi.encode(disputeId)); +// module.disputeOf(requestId); +// } + +// function test_getFinalizedResponseCallsOracle() public { +// IOracle.Response memory _response; +// _mockAndExpect( +// address(oracle), abi.encodeWithSelector(IOracle.getFinalizedResponse.selector), abi.encode(_response) +// ); +// module.getFinalizedResponse(requestId); +// } + +// function test_getResponseIdsCallsOracle() public { +// bytes32[] memory _ids; +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getResponseIds.selector), abi.encode(_ids)); +// module.getResponseIds(requestId); +// } + +// function test_listRequestsCallsOracle() public { +// IOracle.FullRequest[] memory _list; +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.listRequests.selector), abi.encode(_list)); +// module.listRequests(0, 10); +// } + +// function test_listRequestIdsCallsOracle() public { +// bytes32[] memory _list; +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.listRequestIds.selector), abi.encode(_list)); +// module.listRequestIds(0, 10); +// } + +// function test_getRequestIdCallsOracle(uint256 _nonce) public { +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getRequestId.selector), abi.encode(bytes32(0))); +// module.getRequestId(_nonce); +// } + +// function test_getRequestByNonceCallsOracle(uint256 _nonce) public { +// IOracle.Request memory _request; +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getRequestByNonce.selector), abi.encode(_request)); +// module.getRequestByNonce(_nonce); +// } + +// function test_finalizeCallsOracle() public { +// _mockAndExpect(address(oracle), abi.encodeWithSignature('finalize(bytes32,bytes32)'), abi.encode()); +// vm.prank(address(submodule1)); +// module.finalize(requestId, responseId); +// } + +// function test_escalateDisputeCallsOracle() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); + +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.escalateDispute.selector), abi.encode()); + +// vm.prank(address(submodule1)); +// module.escalateDispute(disputeId); +// } + +// function test_isParticipantCallsOracle(bytes32 _requestId, address _user) public { +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.isParticipant.selector), abi.encode(true)); +// module.isParticipant(_requestId, _user); +// } + +// function test_getFinalizedResponseIdCallsOracle(bytes32 _requestId) public { +// _mockAndExpect( +// address(oracle), abi.encodeWithSelector(IOracle.getFinalizedResponseId.selector), abi.encode(bytes32('69')) +// ); +// module.getFinalizedResponseId(_requestId); +// } + +// function test_totalRequestCountCallsOracle() public { +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.totalRequestCount.selector), abi.encode(uint256(69))); +// module.totalRequestCount(); +// } + +// function test_finalizeWithoutResponseCallsOracle() public { +// _mockAndExpect(address(oracle), abi.encodeWithSignature('finalize(bytes32)'), abi.encode()); +// vm.prank(address(submodule1)); +// module.finalize(requestId); +// } + +// function test_getDisputeCallsManager(bytes32 _disputeId) public { +// IOracle.Dispute memory _dispute; +// _mockAndExpect(address(oracle), abi.encodeWithSelector(IOracle.getDispute.selector), abi.encode(_dispute)); +// module.getDispute(_disputeId); +// } +// } + +// contract SequentialResolutionModule_Unit_ResolveDispute is BaseTest { +// function test_revertIfNotOracle() public { +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(makeAddr('other_sender')); +// module.resolveDispute(disputeId); +// } + +// function test_callsFirstModuleAndResolvesIfWon() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); +// submodule1.forTest_setResponseStatus(IOracle.DisputeStatus.Won); + +// // Check: is the module called with IOracle.updateDisputeStatus and DisputeStatus.Won? +// vm.expectCall( +// address(module), +// abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.Won) +// ); + +// // Check: is the oracle called with IOracle.updateDisputeStatus and DisputeStatus.Won? +// vm.expectCall( +// address(oracle), +// abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.Won) +// ); + +// vm.prank(address(oracle)); +// module.resolveDispute(disputeId); +// } + +// function test_callsFirstModuleAndResolvesIfLost() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); +// submodule1.forTest_setResponseStatus(IOracle.DisputeStatus.Lost); + +// // Check: is the module called with IOracle.updateDisputeStatus and DisputeStatus.Lost? +// vm.expectCall( +// address(module), +// abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.Lost) +// ); + +// // Check: is the oracle called with IOracle.updateDisputeStatus and DisputeStatus.Lost? +// vm.expectCall( +// address(oracle), +// abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.Lost) +// ); + +// vm.prank(address(oracle)); +// module.resolveDispute(disputeId); +// } + +// function test_goesToTheNextResolutionModule() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); +// submodule1.forTest_setResponseStatus(IOracle.DisputeStatus.NoResolution); + +// // Check: is the submodule 2 called with IResolutionModule.startResolution? +// vm.expectCall(address(submodule2), abi.encodeWithSelector(IResolutionModule.startResolution.selector, disputeId)); + +// // Check: is the current resolution module the submodule 1? +// assertEq(address(module.getCurrentResolutionModule(disputeId)), address(submodule1)); + +// vm.prank(address(oracle)); +// module.resolveDispute(disputeId); + +// // Check: is the current resolution module the submodule 2? +// assertEq(address(module.getCurrentResolutionModule(disputeId)), address(submodule2)); + +// // Check: is the submodule 2 called with IResolutionModule.resolveDispute? +// vm.expectCall(address(submodule2), abi.encodeWithSelector(IResolutionModule.resolveDispute.selector, disputeId)); + +// vm.prank(address(oracle)); +// module.resolveDispute(disputeId); +// } + +// function test_callsTheManagerWhenThereAreNoMoreSubmodulesLeft() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); + +// submodule1.forTest_setResponseStatus(IOracle.DisputeStatus.NoResolution); + +// vm.prank(address(oracle)); +// module.resolveDispute(disputeId); + +// submodule2.forTest_setResponseStatus(IOracle.DisputeStatus.NoResolution); + +// vm.prank(address(oracle)); +// module.resolveDispute(disputeId); + +// // Check: is the oracle called with IOracle.updateDisputeStatus and DisputeStatus.NoResolution? +// vm.expectCall( +// address(oracle), +// abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.NoResolution) +// ); + +// submodule3.forTest_setResponseStatus(IOracle.DisputeStatus.NoResolution); +// vm.prank(address(oracle)); +// module.resolveDispute(disputeId); +// } +// } + +// contract SequentialResolutionModule_Unit_StartResolution is BaseTest { +// function test_revertsIfNotOracle() public { +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(makeAddr('other_sender')); +// module.startResolution(disputeId); +// } + +// function test_callsFirstModule() public { +// // Check: is the submodule 1 called with IResolutionModule.startResolution? +// vm.expectCall(address(submodule1), abi.encodeWithSelector(IResolutionModule.startResolution.selector, disputeId)); + +// vm.prank(address(oracle)); +// module.startResolution(disputeId); +// } + +// function test_callsFirstModuleSequence2() public { +// // Check: is the submodule 2 called with IResolutionModule.startResolution? +// vm.expectCall(address(submodule2), abi.encodeWithSelector(IResolutionModule.startResolution.selector, disputeId2)); - vm.prank(address(oracle)); - module.startResolution(disputeId2); - } +// vm.prank(address(oracle)); +// module.startResolution(disputeId2); +// } - function test_newDispute() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); +// function test_newDispute() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); - vm.prank(address(submodule1)); - module.updateDisputeStatus(disputeId, IOracle.DisputeStatus.NoResolution); +// vm.prank(address(submodule1)); +// module.updateDisputeStatus(disputeId, IOracle.DisputeStatus.NoResolution); - // Check: is the submodule 2 stored as the current resolution module for the dispute? - assertEq(address(module.getCurrentResolutionModule(disputeId)), address(submodule2)); +// // Check: is the submodule 2 stored as the current resolution module for the dispute? +// assertEq(address(module.getCurrentResolutionModule(disputeId)), address(submodule2)); - bytes32 _dispute3 = bytes32(uint256(6969)); +// bytes32 _dispute3 = bytes32(uint256(6969)); - _mockAndExpect( - address(oracle), - abi.encodeWithSelector(IOracle.getDispute.selector, _dispute3), - abi.encode( - IOracle.Dispute(block.timestamp, disputer, proposer, responseId, requestId, IOracle.DisputeStatus.Escalated) - ) - ); +// _mockAndExpect( +// address(oracle), +// abi.encodeWithSelector(IOracle.getDispute.selector, _dispute3), +// abi.encode( +// IOracle.Dispute(block.timestamp, disputer, proposer, responseId, requestId, IOracle.DisputeStatus.Escalated) +// ) +// ); - vm.prank(address(oracle)); - module.startResolution(_dispute3); +// vm.prank(address(oracle)); +// module.startResolution(_dispute3); - // Check: is the submodule 1 stored as the current resolution module for the dispute 3? - assertEq(address(module.getCurrentResolutionModule(_dispute3)), address(submodule1)); - } -} +// // Check: is the submodule 1 stored as the current resolution module for the dispute 3? +// assertEq(address(module.getCurrentResolutionModule(_dispute3)), address(submodule1)); +// } +// } -contract SequentialResolutionModule_Unit_UpdateDisputeStatus is BaseTest { - function test_revertsIfNotValidSubmodule() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - // Check: does it revert if not called by a submodule? +// contract SequentialResolutionModule_Unit_UpdateDisputeStatus is BaseTest { +// function test_revertsIfNotValidSubmodule() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); +// // Check: does it revert if not called by a submodule? - // Check: does it revert if not called by a submodule? - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_OnlySubmodule.selector) - ); +// // Check: does it revert if not called by a submodule? +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_OnlySubmodule.selector) +// ); - vm.prank(makeAddr('other_sender')); - module.updateDisputeStatus(disputeId, IOracle.DisputeStatus.NoResolution); - } - - function test_revertsIfNotSubmodule() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - - // Check: does it revert if not called by a submodule? - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_OnlySubmodule.selector) - ); - - vm.prank(makeAddr('caller')); - module.updateDisputeStatus(disputeId, IOracle.DisputeStatus.NoResolution); - } - - function test_revertsIfNotSubmoduleSequence2() public { - vm.prank(address(oracle)); - module.startResolution(disputeId2); - - // Check: does it revert if not called by a submodule? - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_OnlySubmodule.selector) - ); - - vm.prank(makeAddr('caller')); - module.updateDisputeStatus(disputeId2, IOracle.DisputeStatus.NoResolution); - } - - function test_changesCurrentIndex() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - - // Check: is the submodule 2 called with IResolutionModule.startResolution? - vm.expectCall(address(submodule2), abi.encodeWithSelector(IResolutionModule.startResolution.selector, disputeId)); - - // Check: is the submodule 1 stored as the current resolution module for the dispute? - assertEq(address(module.getCurrentResolutionModule(disputeId)), address(submodule1)); - - vm.prank(address(submodule1)); - module.updateDisputeStatus(disputeId, IOracle.DisputeStatus.NoResolution); - - // Check: is the submodule 2 stored as the current resolution module for the dispute? - assertEq(address(module.getCurrentResolutionModule(disputeId)), address(submodule2)); - } - - function test_changesCurrentIndexSequence2() public { - vm.prank(address(oracle)); - module.startResolution(disputeId2); - - // Check: is the submodule 3 called with IResolutionModule.startResolution? - vm.expectCall(address(submodule3), abi.encodeWithSelector(IResolutionModule.startResolution.selector, disputeId2)); - - // Check: is the submodule 2 stored as the current resolution module for the dispute? - assertEq(address(module.getCurrentResolutionModule(disputeId2)), address(submodule2)); - - vm.prank(address(submodule2)); - module.updateDisputeStatus(disputeId2, IOracle.DisputeStatus.NoResolution); - - // Check: is the submodule 3 stored as the current resolution module for the dispute? - assertEq(address(module.getCurrentResolutionModule(disputeId2)), address(submodule3)); - } - - function test_callsManagerWhenResolved() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - - // Check: is the Oracle called with IOracle.updateDisputeStatus? - vm.expectCall( - address(oracle), - abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.Won) - ); - - vm.prank(address(submodule1)); - module.updateDisputeStatus(disputeId, IOracle.DisputeStatus.Won); - } - - function test_callsManagerWhenResolvedSequence2() public { - vm.prank(address(oracle)); - module.startResolution(disputeId2); - - // Check: is the Oracle called with IOracle.updateDisputeStatus? - vm.expectCall( - address(oracle), - abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId2, IOracle.DisputeStatus.Won) - ); - - vm.prank(address(submodule2)); - module.updateDisputeStatus(disputeId2, IOracle.DisputeStatus.Won); - } -} - -contract SequentialResolutionModule_Unit_EscalateDispute is BaseTest { - function test_revertsIfNotSubmodule() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - - // Check: does it revert if not called by a submodule? - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_OnlySubmodule.selector) - ); - module.escalateDispute(disputeId); - } -} - -contract SequentialResolutionModule_Unit_FinalizeRequest is BaseTest { - function test_finalizesAllSubmodules() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - - // Check: are the submodules called with IModule.finalizeRequest? - vm.expectCall(address(submodule1), abi.encodeWithSelector(IModule.finalizeRequest.selector, requestId)); - vm.expectCall(address(submodule2), abi.encodeWithSelector(IModule.finalizeRequest.selector, requestId)); - vm.expectCall(address(submodule3), abi.encodeWithSelector(IModule.finalizeRequest.selector, requestId)); - - vm.prank(address(oracle)); - module.finalizeRequest(requestId, address(oracle)); - } - - function test_revertsIfNotOracle() public { - // Check: does it revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(makeAddr('caller')); - module.finalizeRequest(requestId, makeAddr('caller')); - } - - function test_revertsIfNotSubmodule() public { - vm.prank(address(oracle)); - module.startResolution(disputeId); - - // Check: does it revert if not called by a submodule? - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_OnlySubmodule.selector) - ); - module.finalize(requestId, responseId); - } -} - -contract SequentialResolutionModule_Unit_ListSubmodules is BaseTest { - function test_fullList() public { - IResolutionModule[] memory _submodules = module.listSubmodules(0, 3, 1); - - // Check: do the stored submodules match? - assertEq(_submodules.length, 3); - assertEq(address(_submodules[0]), address(submodule1)); - assertEq(address(_submodules[1]), address(submodule2)); - assertEq(address(_submodules[2]), address(submodule3)); - } - - function test_fullListSequence2() public { - IResolutionModule[] memory _submodules = module.listSubmodules(0, 3, sequenceId2); - - // Check: do the stored submodules match? - assertEq(_submodules.length, 3); - assertEq(address(_submodules[0]), address(submodule2)); - assertEq(address(_submodules[1]), address(submodule3)); - assertEq(address(_submodules[2]), address(submodule1)); - } - - function test_moreThanExist() public { - IResolutionModule[] memory _submodules = module.listSubmodules(0, 200, 1); - - // Check: do the stored submodules match? - assertEq(_submodules.length, 3); - assertEq(address(_submodules[0]), address(submodule1)); - assertEq(address(_submodules[1]), address(submodule2)); - assertEq(address(_submodules[2]), address(submodule3)); - } - - function test_partialListMiddle() public { - IResolutionModule[] memory _submodules = module.listSubmodules(1, 2, 1); - - // Check: do the stored submodules match? - assertEq(_submodules.length, 2); - assertEq(address(_submodules[0]), address(submodule2)); - assertEq(address(_submodules[1]), address(submodule3)); - } - - function test_partialListStart() public { - IResolutionModule[] memory _submodules = module.listSubmodules(0, 2, sequenceId); - - // Check: do the stored submodules match? - assertEq(_submodules.length, 2); - assertEq(address(_submodules[0]), address(submodule1)); - assertEq(address(_submodules[1]), address(submodule2)); - } -} - -contract SequentialResolutionModule_Unit_NotImplemented is BaseTest { - function testReverts_disputeResponseNotSubmodule() public { - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - module.disputeResponse(requestId, responseId); - } - - function testReverts_proposeResponseNotSubmodule() public { - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - module.proposeResponse(requestId, responseData); - } - - function testReverts_proposeResponseWithProposerNotSubmodule() public { - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - module.proposeResponse(proposer, requestId, responseData); - } - - function testReverts_disputeResponseNotImplemented() public { - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - vm.prank(address(submodule1)); - module.disputeResponse(requestId, responseId); - } - - function testReverts_proposeResponseNotImplemented() public { - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - vm.prank(address(submodule1)); - module.proposeResponse(requestId, responseData); - } - - function testReverts_proposeResponseWithProposerNotImplemented() public { - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - vm.prank(address(submodule1)); - module.proposeResponse(proposer, requestId, responseData); - } - - function testReverts_createRequestNotImplemented() public { - IOracle.NewRequest memory _request; - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - vm.prank(address(submodule1)); - module.createRequest(_request); - } - - function testReverts_createRequestsNotImplemented() public { - IOracle.NewRequest[] memory _requests; - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - vm.prank(address(submodule1)); - module.createRequests(_requests); - } - - function testReverts_deleteResponseNotImplemented() public { - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - vm.prank(address(submodule1)); - module.deleteResponse(requestId); - } - - function testReverts_createRequestNotSubmodule() public { - IOracle.NewRequest memory _request; - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - module.createRequest(_request); - } - - function testReverts_createRequestsNotSubmodule() public { - IOracle.NewRequest[] memory _requests; - vm.expectRevert( - abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) - ); - module.createRequests(_requests); - } -} +// vm.prank(makeAddr('other_sender')); +// module.updateDisputeStatus(disputeId, IOracle.DisputeStatus.NoResolution); +// } + +// function test_revertsIfNotSubmodule() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); + +// // Check: does it revert if not called by a submodule? +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_OnlySubmodule.selector) +// ); + +// vm.prank(makeAddr('caller')); +// module.updateDisputeStatus(disputeId, IOracle.DisputeStatus.NoResolution); +// } + +// function test_revertsIfNotSubmoduleSequence2() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId2); + +// // Check: does it revert if not called by a submodule? +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_OnlySubmodule.selector) +// ); + +// vm.prank(makeAddr('caller')); +// module.updateDisputeStatus(disputeId2, IOracle.DisputeStatus.NoResolution); +// } + +// function test_changesCurrentIndex() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); + +// // Check: is the submodule 2 called with IResolutionModule.startResolution? +// vm.expectCall(address(submodule2), abi.encodeWithSelector(IResolutionModule.startResolution.selector, disputeId)); + +// // Check: is the submodule 1 stored as the current resolution module for the dispute? +// assertEq(address(module.getCurrentResolutionModule(disputeId)), address(submodule1)); + +// vm.prank(address(submodule1)); +// module.updateDisputeStatus(disputeId, IOracle.DisputeStatus.NoResolution); + +// // Check: is the submodule 2 stored as the current resolution module for the dispute? +// assertEq(address(module.getCurrentResolutionModule(disputeId)), address(submodule2)); +// } + +// function test_changesCurrentIndexSequence2() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId2); + +// // Check: is the submodule 3 called with IResolutionModule.startResolution? +// vm.expectCall(address(submodule3), abi.encodeWithSelector(IResolutionModule.startResolution.selector, disputeId2)); + +// // Check: is the submodule 2 stored as the current resolution module for the dispute? +// assertEq(address(module.getCurrentResolutionModule(disputeId2)), address(submodule2)); + +// vm.prank(address(submodule2)); +// module.updateDisputeStatus(disputeId2, IOracle.DisputeStatus.NoResolution); + +// // Check: is the submodule 3 stored as the current resolution module for the dispute? +// assertEq(address(module.getCurrentResolutionModule(disputeId2)), address(submodule3)); +// } + +// function test_callsManagerWhenResolved() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); + +// // Check: is the Oracle called with IOracle.updateDisputeStatus? +// vm.expectCall( +// address(oracle), +// abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId, IOracle.DisputeStatus.Won) +// ); + +// vm.prank(address(submodule1)); +// module.updateDisputeStatus(disputeId, IOracle.DisputeStatus.Won); +// } + +// function test_callsManagerWhenResolvedSequence2() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId2); + +// // Check: is the Oracle called with IOracle.updateDisputeStatus? +// vm.expectCall( +// address(oracle), +// abi.encodeWithSelector(IOracle.updateDisputeStatus.selector, disputeId2, IOracle.DisputeStatus.Won) +// ); + +// vm.prank(address(submodule2)); +// module.updateDisputeStatus(disputeId2, IOracle.DisputeStatus.Won); +// } +// } + +// contract SequentialResolutionModule_Unit_EscalateDispute is BaseTest { +// function test_revertsIfNotSubmodule() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); + +// // Check: does it revert if not called by a submodule? +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_OnlySubmodule.selector) +// ); +// module.escalateDispute(disputeId); +// } +// } + +// contract SequentialResolutionModule_Unit_FinalizeRequest is BaseTest { +// function test_finalizesAllSubmodules() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); + +// // Check: are the submodules called with IModule.finalizeRequest? +// vm.expectCall(address(submodule1), abi.encodeWithSelector(IModule.finalizeRequest.selector, requestId)); +// vm.expectCall(address(submodule2), abi.encodeWithSelector(IModule.finalizeRequest.selector, requestId)); +// vm.expectCall(address(submodule3), abi.encodeWithSelector(IModule.finalizeRequest.selector, requestId)); + +// vm.prank(address(oracle)); +// module.finalizeRequest(requestId, address(oracle)); +// } + +// function test_revertsIfNotOracle() public { +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(makeAddr('caller')); +// module.finalizeRequest(requestId, makeAddr('caller')); +// } + +// function test_revertsIfNotSubmodule() public { +// vm.prank(address(oracle)); +// module.startResolution(disputeId); + +// // Check: does it revert if not called by a submodule? +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_OnlySubmodule.selector) +// ); +// module.finalize(requestId, responseId); +// } +// } + +// contract SequentialResolutionModule_Unit_ListSubmodules is BaseTest { +// function test_fullList() public { +// IResolutionModule[] memory _submodules = module.listSubmodules(0, 3, 1); + +// // Check: do the stored submodules match? +// assertEq(_submodules.length, 3); +// assertEq(address(_submodules[0]), address(submodule1)); +// assertEq(address(_submodules[1]), address(submodule2)); +// assertEq(address(_submodules[2]), address(submodule3)); +// } + +// function test_fullListSequence2() public { +// IResolutionModule[] memory _submodules = module.listSubmodules(0, 3, sequenceId2); + +// // Check: do the stored submodules match? +// assertEq(_submodules.length, 3); +// assertEq(address(_submodules[0]), address(submodule2)); +// assertEq(address(_submodules[1]), address(submodule3)); +// assertEq(address(_submodules[2]), address(submodule1)); +// } + +// function test_moreThanExist() public { +// IResolutionModule[] memory _submodules = module.listSubmodules(0, 200, 1); + +// // Check: do the stored submodules match? +// assertEq(_submodules.length, 3); +// assertEq(address(_submodules[0]), address(submodule1)); +// assertEq(address(_submodules[1]), address(submodule2)); +// assertEq(address(_submodules[2]), address(submodule3)); +// } + +// function test_partialListMiddle() public { +// IResolutionModule[] memory _submodules = module.listSubmodules(1, 2, 1); + +// // Check: do the stored submodules match? +// assertEq(_submodules.length, 2); +// assertEq(address(_submodules[0]), address(submodule2)); +// assertEq(address(_submodules[1]), address(submodule3)); +// } + +// function test_partialListStart() public { +// IResolutionModule[] memory _submodules = module.listSubmodules(0, 2, sequenceId); + +// // Check: do the stored submodules match? +// assertEq(_submodules.length, 2); +// assertEq(address(_submodules[0]), address(submodule1)); +// assertEq(address(_submodules[1]), address(submodule2)); +// } +// } + +// contract SequentialResolutionModule_Unit_NotImplemented is BaseTest { +// function testReverts_disputeResponseNotSubmodule() public { +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// module.disputeResponse(requestId, responseId); +// } + +// function testReverts_proposeResponseNotSubmodule() public { +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// module.proposeResponse(requestId, responseData); +// } + +// function testReverts_proposeResponseWithProposerNotSubmodule() public { +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// module.proposeResponse(proposer, requestId, responseData); +// } + +// function testReverts_disputeResponseNotImplemented() public { +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// vm.prank(address(submodule1)); +// module.disputeResponse(requestId, responseId); +// } + +// function testReverts_proposeResponseNotImplemented() public { +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// vm.prank(address(submodule1)); +// module.proposeResponse(requestId, responseData); +// } + +// function testReverts_proposeResponseWithProposerNotImplemented() public { +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// vm.prank(address(submodule1)); +// module.proposeResponse(proposer, requestId, responseData); +// } + +// function testReverts_createRequestNotImplemented() public { +// IOracle.NewRequest memory _request; +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// vm.prank(address(submodule1)); +// module.createRequest(_request); +// } + +// function testReverts_createRequestsNotImplemented() public { +// IOracle.NewRequest[] memory _requests; +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// vm.prank(address(submodule1)); +// module.createRequests(_requests); +// } + +// function testReverts_deleteResponseNotImplemented() public { +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// vm.prank(address(submodule1)); +// module.deleteResponse(requestId); +// } + +// function testReverts_createRequestNotSubmodule() public { +// IOracle.NewRequest memory _request; +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// module.createRequest(_request); +// } + +// function testReverts_createRequestsNotSubmodule() public { +// IOracle.NewRequest[] memory _requests; +// vm.expectRevert( +// abi.encodeWithSelector(ISequentialResolutionModule.SequentialResolutionModule_NotImplemented.selector) +// ); +// module.createRequests(_requests); +// } +// } diff --git a/solidity/test/unit/modules/response/BondedResponseModule.t.sol b/solidity/test/unit/modules/response/BondedResponseModule.t.sol index de5ff122..9d16f581 100644 --- a/solidity/test/unit/modules/response/BondedResponseModule.t.sol +++ b/solidity/test/unit/modules/response/BondedResponseModule.t.sol @@ -1,461 +1,461 @@ -// SPDX-License-Identifier: AGPL-3.0-only -pragma solidity ^0.8.19; - -import 'forge-std/Test.sol'; - -import {Helpers} from '../../../utils/Helpers.sol'; - -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -import { - BondedResponseModule, - IBondedResponseModule, - IModule, - IOracle -} from '../../../../contracts/modules/response/BondedResponseModule.sol'; - -import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; - -/** - * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks - */ -contract ForTest_BondedResponseModule is BondedResponseModule { - constructor(IOracle _oracle) BondedResponseModule(_oracle) {} - - function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { - requestData[_requestId] = _data; - } -} - -/** - * @title Bonded Response Module Unit tests - */ -contract BaseTest is Test, Helpers { - // The target contract - ForTest_BondedResponseModule public bondedResponseModule; - // A mock oracle - IOracle public oracle; - // A mock accounting extension - IAccountingExtension public accounting = IAccountingExtension(makeAddr('accounting')); - // Base dispute window - uint256 internal _baseDisputeWindow = 12 hours; - - event ProposeResponse(bytes32 indexed _requestId, address _proposer, bytes _responseData); - event RequestFinalized(bytes32 indexed _requestId, address _finalizer); - - /** - * @notice Deploy the target and mock oracle+accounting extension - */ - function setUp() public { - oracle = IOracle(makeAddr('Oracle')); - vm.etch(address(oracle), hex'069420'); - - // vm.etch(address(token), hex'069420'); - - // Avoid starting at 0 for time sensitive tests - vm.warp(123_456); - - bondedResponseModule = new ForTest_BondedResponseModule(oracle); - } -} - -contract BondedResponseModule_Unit_ModuleData is BaseTest { - /** - * @notice Test that the moduleName function returns the correct name - */ - function test_moduleNameReturnsName() public { - assertEq(bondedResponseModule.moduleName(), 'BondedResponseModule'); - } - - /** - * @notice Test that the decodeRequestData function returns the correct values - */ - function test_decodeRequestData( - bytes32 _requestId, - uint256 _bondSize, - uint256 _deadline, - uint256 _disputeWindow, - IERC20 _token - ) public { - // Create and set some mock request data - bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); - bondedResponseModule.forTest_setRequestData(_requestId, _data); - - // Get the returned values - IBondedResponseModule.RequestParameters memory _params = bondedResponseModule.decodeRequestData(_requestId); - - // Check: correct values returned? - assertEq(address(_params.accountingExtension), address(accounting), 'Mismatch: accounting extension address'); - assertEq(address(_params.bondToken), address(_token), 'Mismatch: token address'); - assertEq(_params.bondSize, _bondSize, 'Mismatch: bond size'); - assertEq(_params.deadline, _deadline, 'Mismatch: deadline'); - assertEq(_params.disputeWindow, _disputeWindow, 'Mismatch: dispute window'); - } -} - -contract BondedResponseModule_Unit_Setup is BaseTest { - function test_setupRequestRevertsIfInvalidRequest( - IAccountingExtension _accounting, - IERC20 _token, - uint256 _deadline, - uint256 _bondSize - ) public { - _deadline = bound(_deadline, 0, block.timestamp); - - IBondedResponseModule.RequestParameters memory _requestParams = IBondedResponseModule.RequestParameters({ - accountingExtension: _accounting, - bondToken: _token, - bondSize: _bondSize, - deadline: _deadline, - disputeWindow: _baseDisputeWindow - }); - - // Check: does it revert if the provided deadline is invalid? - vm.expectRevert(IBondedResponseModule.BondedResponseModule_InvalidRequest.selector); - vm.prank(address(oracle)); - - bondedResponseModule.setupRequest(bytes32(0), abi.encode(_requestParams)); - } -} - -contract BondedResponseModule_Unit_Propose is BaseTest { - /** - * @notice Test that the propose function is only callable by the oracle - */ - function test_revertIfNotOracle( - bytes32 _requestId, - address _sender, - address _proposer, - bytes calldata _responseData - ) public { - vm.assume(_sender != address(oracle)); - - // Check: does it revert if not called by the Oracle? - vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); - - vm.prank(address(_sender)); - bondedResponseModule.propose(_requestId, _proposer, _responseData, _sender); - } - - /** - * @notice Test that the propose function works correctly and triggers _afterPropose (which bonds) - */ - function test_propose( - bytes32 _requestId, - uint256 _bondSize, - uint256 _deadline, - uint256 _disputeWindow, - bytes calldata _responseData, - address _sender, - IERC20 _token, - address _proposer - ) public { - _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); - _disputeWindow = bound(_disputeWindow, 61, 365 days); - _bondSize = bound(_bondSize, 0, type(uint248).max); - - // Create and set some mock request data - bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); - bondedResponseModule.forTest_setRequestData(_requestId, _data); - - // Mock and expect IOracle.getResponseIds to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponseIds, _requestId), abi.encode(new bytes32[](0))); - - // Mock and expect IAccountingExtension.bond to be called - _mockAndExpect( - address(accounting), - abi.encodeWithSignature( - 'bond(address,bytes32,address,uint256,address)', _proposer, _requestId, _token, _bondSize, _sender - ), - abi.encode() - ); - - vm.prank(address(oracle)); - IOracle.Response memory _responseReturned = - bondedResponseModule.propose(_requestId, _proposer, _responseData, _sender); - - IOracle.Response memory _responseExpected = IOracle.Response({ - createdAt: block.timestamp, - requestId: _requestId, - disputeId: bytes32(''), - proposer: _proposer, - response: _responseData - }); - - // Check: correct response struct returned? - assertEq(_responseReturned.requestId, _responseExpected.requestId, 'Mismatch: request ID'); - assertEq(_responseReturned.disputeId, _responseExpected.disputeId, 'Mismatch: dispute ID'); - assertEq(_responseReturned.proposer, _responseExpected.proposer, 'Mismatch: proposer address'); - assertEq(_responseReturned.response, _responseExpected.response, 'Mismatch: response object'); - } - - function test_emitsEvent( - bytes32 _requestId, - uint256 _bondSize, - uint256 _deadline, - uint256 _disputeWindow, - bytes calldata _responseData, - address _sender, - IERC20 _token, - address _proposer - ) public { - _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); - _disputeWindow = bound(_disputeWindow, 61, 365 days); - - // Create and set some mock request data - bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); - bondedResponseModule.forTest_setRequestData(_requestId, _data); - - // Mock and expect IOracle.getResponseIds to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponseIds, _requestId), abi.encode(new bytes32[](0))); - - // Mock and expect IOracle.getResponseIds to be called - _mockAndExpect( - address(accounting), - abi.encodeWithSignature( - 'bond(address,bytes32,address,uint256,address)', _proposer, _requestId, _token, _bondSize, _sender - ), - abi.encode() - ); - - // Check: is the event emitted? - vm.expectEmit(true, true, true, true, address(bondedResponseModule)); - emit ProposeResponse(_requestId, _proposer, _responseData); - - vm.prank(address(oracle)); - bondedResponseModule.propose(_requestId, _proposer, _responseData, _sender); - } -} - -contract BondedResponseModule_Unit_FinalizeRequest is BaseTest { - /** - * @notice Test that the propose function is only callable by the oracle - */ - function test_calls( - bytes32 _requestId, - uint256 _bondSize, - uint256 _deadline, - uint256 _disputeWindow, - IERC20 _token, - address _proposer - ) public { - _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); - _disputeWindow = bound(_disputeWindow, 61, 365 days); - - // Check revert if deadline has not passed - bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); - bondedResponseModule.forTest_setRequestData(_requestId, _data); - - // Mock and expect IOracle.allowedModule to be called - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(false) - ); - - // Check: does it revert if it's too early to finalize? - vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooEarlyToFinalize.selector); - - vm.prank(address(oracle)); - bondedResponseModule.finalizeRequest(_requestId, address(this)); - - // Check correct calls are made if deadline has passed - _deadline = block.timestamp; - - _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); - bondedResponseModule.forTest_setRequestData(_requestId, _data); - - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - requestId: _requestId, - disputeId: bytes32(''), - proposer: _proposer, - response: bytes('bleh') - }); - - // Mock and expect IOracle.getFinalizedResponse to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, _requestId), abi.encode(_mockResponse)); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_proposer, _requestId, _token, _bondSize)), - abi.encode(true) - ); - - vm.warp(block.timestamp + _disputeWindow); - - vm.prank(address(oracle)); - bondedResponseModule.finalizeRequest(_requestId, address(this)); - } - - function test_emitsEvent( - bytes32 _requestId, - uint256 _bondSize, - uint256 _deadline, - uint256 _disputeWindow, - IERC20 _token, - address _proposer - ) public { - _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); - _disputeWindow = bound(_disputeWindow, 61, 365 days); - - // Check revert if deadline has not passed - bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); - bondedResponseModule.forTest_setRequestData(_requestId, _data); - - // Mock and expect IOracle.allowedModule to be called - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(false) - ); - - // Check correct calls are made if deadline has passed - _deadline = block.timestamp; - - _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); - bondedResponseModule.forTest_setRequestData(_requestId, _data); - - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - requestId: _requestId, - disputeId: bytes32(''), - proposer: _proposer, - response: bytes('bleh') - }); - - // Mock and expect IOracle.getFinalizedResponse to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, _requestId), abi.encode(_mockResponse)); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_proposer, _requestId, _token, _bondSize)), - abi.encode(true) - ); - - // Check: is event emitted? - vm.expectEmit(true, true, true, true, address(bondedResponseModule)); - emit RequestFinalized(_requestId, address(this)); - - vm.warp(block.timestamp + _disputeWindow); - - vm.prank(address(oracle)); - bondedResponseModule.finalizeRequest(_requestId, address(this)); - } - - /** - * @notice Test that the finalize function can be called by an allowed module before the time window. - */ - function test_earlyByModule( - bytes32 _requestId, - uint256 _bondSize, - uint256 _deadline, - IERC20 _token, - address _proposer - ) public { - _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); - - address _allowedModule = makeAddr('allowed module'); - bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _baseDisputeWindow); - bondedResponseModule.forTest_setRequestData(_requestId, _data); - - // Mock and expect IOracle.allowedModule to be called - _mockAndExpect( - address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _allowedModule)), abi.encode(true) - ); - - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: block.timestamp, - requestId: _requestId, - disputeId: bytes32(''), - proposer: _proposer, - response: bytes('bleh') - }); - - // Mock and expect IOracle.getFinalizedResponse to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, _requestId), abi.encode(_mockResponse)); - - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_proposer, _requestId, _token, _bondSize)), - abi.encode(true) - ); - - vm.prank(address(oracle)); - bondedResponseModule.finalizeRequest(_requestId, _allowedModule); - } - - /** - * @notice Test that the finalizing a request during a response dispute window will revert. - */ - function test_revertDuringDisputeWindow( - bytes32 _requestId, - uint256 _bondSize, - uint256 _deadline, - IERC20 _token, - address _proposer - ) public { - _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); - - address _finalizer = makeAddr('finalizer'); - bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _baseDisputeWindow); - bondedResponseModule.forTest_setRequestData(_requestId, _data); - - // Mock and expect IOracle.allowedModule to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _finalizer)), abi.encode(false)); - - IOracle.Response memory _mockResponse = IOracle.Response({ - createdAt: _deadline - 1, - requestId: _requestId, - disputeId: bytes32(''), - proposer: _proposer, - response: bytes('bleh') - }); - - // Mock and expect IOracle.getFinalizedResponse to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, _requestId), abi.encode(_mockResponse)); - - vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooEarlyToFinalize.selector); - - vm.warp(_deadline + 1); - vm.prank(address(oracle)); - bondedResponseModule.finalizeRequest(_requestId, _finalizer); - } -} - -contract BondedResponseModule_Unit_DeleteResponse is BaseTest { - /** - * @notice Test that the delete response function triggers bond release. - */ - function test_deleteResponse( - bytes32 _requestId, - bytes32 _responseId, - uint256 _bondSize, - uint256 _deadline, - uint256 _timestamp, - IERC20 _token, - address _proposer - ) public { - _timestamp = bound(_timestamp, 1, type(uint248).max); - - // Create and set some mock request data - bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _baseDisputeWindow); - bondedResponseModule.forTest_setRequestData(_requestId, _data); - - vm.warp(_timestamp); - - if (_deadline >= _timestamp) { - // Mock and expect IAccountingExtension.release to be called - _mockAndExpect( - address(accounting), - abi.encodeCall(IAccountingExtension.release, (_proposer, _requestId, _token, _bondSize)), - abi.encode() - ); - } else { - // Check: does it revert if the deadline has passed? - vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooLateToDelete.selector); - } - - vm.prank(address(oracle)); - bondedResponseModule.deleteResponse(_requestId, _responseId, _proposer); - } -} +// // SPDX-License-Identifier: AGPL-3.0-only +// pragma solidity ^0.8.19; + +// import 'forge-std/Test.sol'; + +// import {Helpers} from '../../../utils/Helpers.sol'; + +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +// import { +// BondedResponseModule, +// IBondedResponseModule, +// IModule, +// IOracle +// } from '../../../../contracts/modules/response/BondedResponseModule.sol'; + +// import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; + +// /** +// * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks +// */ +// contract ForTest_BondedResponseModule is BondedResponseModule { +// constructor(IOracle _oracle) BondedResponseModule(_oracle) {} + +// function forTest_setRequestData(bytes32 _requestId, bytes memory _data) public { +// requestData[_requestId] = _data; +// } +// } + +// /** +// * @title Bonded Response Module Unit tests +// */ +// contract BaseTest is Test, Helpers { +// // The target contract +// ForTest_BondedResponseModule public bondedResponseModule; +// // A mock oracle +// IOracle public oracle; +// // A mock accounting extension +// IAccountingExtension public accounting = IAccountingExtension(makeAddr('accounting')); +// // Base dispute window +// uint256 internal _baseDisputeWindow = 12 hours; + +// event ProposeResponse(bytes32 indexed _requestId, address _proposer, bytes _responseData); +// event RequestFinalized(bytes32 indexed _requestId, address _finalizer); + +// /** +// * @notice Deploy the target and mock oracle+accounting extension +// */ +// function setUp() public { +// oracle = IOracle(makeAddr('Oracle')); +// vm.etch(address(oracle), hex'069420'); + +// // vm.etch(address(token), hex'069420'); + +// // Avoid starting at 0 for time sensitive tests +// vm.warp(123_456); + +// bondedResponseModule = new ForTest_BondedResponseModule(oracle); +// } +// } + +// contract BondedResponseModule_Unit_ModuleData is BaseTest { +// /** +// * @notice Test that the moduleName function returns the correct name +// */ +// function test_moduleNameReturnsName() public { +// assertEq(bondedResponseModule.moduleName(), 'BondedResponseModule'); +// } + +// /** +// * @notice Test that the decodeRequestData function returns the correct values +// */ +// function test_decodeRequestData( +// bytes32 _requestId, +// uint256 _bondSize, +// uint256 _deadline, +// uint256 _disputeWindow, +// IERC20 _token +// ) public { +// // Create and set some mock request data +// bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); +// bondedResponseModule.forTest_setRequestData(_requestId, _data); + +// // Get the returned values +// IBondedResponseModule.RequestParameters memory _params = bondedResponseModule.decodeRequestData(_requestId); + +// // Check: correct values returned? +// assertEq(address(_params.accountingExtension), address(accounting), 'Mismatch: accounting extension address'); +// assertEq(address(_params.bondToken), address(_token), 'Mismatch: token address'); +// assertEq(_params.bondSize, _bondSize, 'Mismatch: bond size'); +// assertEq(_params.deadline, _deadline, 'Mismatch: deadline'); +// assertEq(_params.disputeWindow, _disputeWindow, 'Mismatch: dispute window'); +// } +// } + +// contract BondedResponseModule_Unit_Setup is BaseTest { +// function test_setupRequestRevertsIfInvalidRequest( +// IAccountingExtension _accounting, +// IERC20 _token, +// uint256 _deadline, +// uint256 _bondSize +// ) public { +// _deadline = bound(_deadline, 0, block.timestamp); + +// IBondedResponseModule.RequestParameters memory _requestParams = IBondedResponseModule.RequestParameters({ +// accountingExtension: _accounting, +// bondToken: _token, +// bondSize: _bondSize, +// deadline: _deadline, +// disputeWindow: _baseDisputeWindow +// }); + +// // Check: does it revert if the provided deadline is invalid? +// vm.expectRevert(IBondedResponseModule.BondedResponseModule_InvalidRequest.selector); +// vm.prank(address(oracle)); + +// bondedResponseModule.setupRequest(bytes32(0), abi.encode(_requestParams)); +// } +// } + +// contract BondedResponseModule_Unit_Propose is BaseTest { +// /** +// * @notice Test that the propose function is only callable by the oracle +// */ +// function test_revertIfNotOracle( +// bytes32 _requestId, +// address _sender, +// address _proposer, +// bytes calldata _responseData +// ) public { +// vm.assume(_sender != address(oracle)); + +// // Check: does it revert if not called by the Oracle? +// vm.expectRevert(abi.encodeWithSelector(IModule.Module_OnlyOracle.selector)); + +// vm.prank(address(_sender)); +// bondedResponseModule.propose(_requestId, _proposer, _responseData, _sender); +// } + +// /** +// * @notice Test that the propose function works correctly and triggers _afterPropose (which bonds) +// */ +// function test_propose( +// bytes32 _requestId, +// uint256 _bondSize, +// uint256 _deadline, +// uint256 _disputeWindow, +// bytes calldata _responseData, +// address _sender, +// IERC20 _token, +// address _proposer +// ) public { +// _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); +// _disputeWindow = bound(_disputeWindow, 61, 365 days); +// _bondSize = bound(_bondSize, 0, type(uint248).max); + +// // Create and set some mock request data +// bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); +// bondedResponseModule.forTest_setRequestData(_requestId, _data); + +// // Mock and expect IOracle.getResponseIds to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponseIds, _requestId), abi.encode(new bytes32[](0))); + +// // Mock and expect IAccountingExtension.bond to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeWithSignature( +// 'bond(address,bytes32,address,uint256,address)', _proposer, _requestId, _token, _bondSize, _sender +// ), +// abi.encode() +// ); + +// vm.prank(address(oracle)); +// IOracle.Response memory _responseReturned = +// bondedResponseModule.propose(_requestId, _proposer, _responseData, _sender); + +// IOracle.Response memory _responseExpected = IOracle.Response({ +// createdAt: block.timestamp, +// requestId: _requestId, +// disputeId: bytes32(''), +// proposer: _proposer, +// response: _responseData +// }); + +// // Check: correct response struct returned? +// assertEq(_responseReturned.requestId, _responseExpected.requestId, 'Mismatch: request ID'); +// assertEq(_responseReturned.disputeId, _responseExpected.disputeId, 'Mismatch: dispute ID'); +// assertEq(_responseReturned.proposer, _responseExpected.proposer, 'Mismatch: proposer address'); +// assertEq(_responseReturned.response, _responseExpected.response, 'Mismatch: response object'); +// } + +// function test_emitsEvent( +// bytes32 _requestId, +// uint256 _bondSize, +// uint256 _deadline, +// uint256 _disputeWindow, +// bytes calldata _responseData, +// address _sender, +// IERC20 _token, +// address _proposer +// ) public { +// _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); +// _disputeWindow = bound(_disputeWindow, 61, 365 days); + +// // Create and set some mock request data +// bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); +// bondedResponseModule.forTest_setRequestData(_requestId, _data); + +// // Mock and expect IOracle.getResponseIds to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getResponseIds, _requestId), abi.encode(new bytes32[](0))); + +// // Mock and expect IOracle.getResponseIds to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeWithSignature( +// 'bond(address,bytes32,address,uint256,address)', _proposer, _requestId, _token, _bondSize, _sender +// ), +// abi.encode() +// ); + +// // Check: is the event emitted? +// vm.expectEmit(true, true, true, true, address(bondedResponseModule)); +// emit ProposeResponse(_requestId, _proposer, _responseData); + +// vm.prank(address(oracle)); +// bondedResponseModule.propose(_requestId, _proposer, _responseData, _sender); +// } +// } + +// contract BondedResponseModule_Unit_FinalizeRequest is BaseTest { +// /** +// * @notice Test that the propose function is only callable by the oracle +// */ +// function test_calls( +// bytes32 _requestId, +// uint256 _bondSize, +// uint256 _deadline, +// uint256 _disputeWindow, +// IERC20 _token, +// address _proposer +// ) public { +// _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); +// _disputeWindow = bound(_disputeWindow, 61, 365 days); + +// // Check revert if deadline has not passed +// bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); +// bondedResponseModule.forTest_setRequestData(_requestId, _data); + +// // Mock and expect IOracle.allowedModule to be called +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(false) +// ); + +// // Check: does it revert if it's too early to finalize? +// vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooEarlyToFinalize.selector); + +// vm.prank(address(oracle)); +// bondedResponseModule.finalizeRequest(_requestId, address(this)); + +// // Check correct calls are made if deadline has passed +// _deadline = block.timestamp; + +// _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); +// bondedResponseModule.forTest_setRequestData(_requestId, _data); + +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// requestId: _requestId, +// disputeId: bytes32(''), +// proposer: _proposer, +// response: bytes('bleh') +// }); + +// // Mock and expect IOracle.getFinalizedResponse to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, _requestId), abi.encode(_mockResponse)); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_proposer, _requestId, _token, _bondSize)), +// abi.encode(true) +// ); + +// vm.warp(block.timestamp + _disputeWindow); + +// vm.prank(address(oracle)); +// bondedResponseModule.finalizeRequest(_requestId, address(this)); +// } + +// function test_emitsEvent( +// bytes32 _requestId, +// uint256 _bondSize, +// uint256 _deadline, +// uint256 _disputeWindow, +// IERC20 _token, +// address _proposer +// ) public { +// _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); +// _disputeWindow = bound(_disputeWindow, 61, 365 days); + +// // Check revert if deadline has not passed +// bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); +// bondedResponseModule.forTest_setRequestData(_requestId, _data); + +// // Mock and expect IOracle.allowedModule to be called +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(false) +// ); + +// // Check correct calls are made if deadline has passed +// _deadline = block.timestamp; + +// _data = abi.encode(accounting, _token, _bondSize, _deadline, _disputeWindow); +// bondedResponseModule.forTest_setRequestData(_requestId, _data); + +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// requestId: _requestId, +// disputeId: bytes32(''), +// proposer: _proposer, +// response: bytes('bleh') +// }); + +// // Mock and expect IOracle.getFinalizedResponse to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, _requestId), abi.encode(_mockResponse)); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_proposer, _requestId, _token, _bondSize)), +// abi.encode(true) +// ); + +// // Check: is event emitted? +// vm.expectEmit(true, true, true, true, address(bondedResponseModule)); +// emit RequestFinalized(_requestId, address(this)); + +// vm.warp(block.timestamp + _disputeWindow); + +// vm.prank(address(oracle)); +// bondedResponseModule.finalizeRequest(_requestId, address(this)); +// } + +// /** +// * @notice Test that the finalize function can be called by an allowed module before the time window. +// */ +// function test_earlyByModule( +// bytes32 _requestId, +// uint256 _bondSize, +// uint256 _deadline, +// IERC20 _token, +// address _proposer +// ) public { +// _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); + +// address _allowedModule = makeAddr('allowed module'); +// bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _baseDisputeWindow); +// bondedResponseModule.forTest_setRequestData(_requestId, _data); + +// // Mock and expect IOracle.allowedModule to be called +// _mockAndExpect( +// address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _allowedModule)), abi.encode(true) +// ); + +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: block.timestamp, +// requestId: _requestId, +// disputeId: bytes32(''), +// proposer: _proposer, +// response: bytes('bleh') +// }); + +// // Mock and expect IOracle.getFinalizedResponse to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, _requestId), abi.encode(_mockResponse)); + +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_proposer, _requestId, _token, _bondSize)), +// abi.encode(true) +// ); + +// vm.prank(address(oracle)); +// bondedResponseModule.finalizeRequest(_requestId, _allowedModule); +// } + +// /** +// * @notice Test that the finalizing a request during a response dispute window will revert. +// */ +// function test_revertDuringDisputeWindow( +// bytes32 _requestId, +// uint256 _bondSize, +// uint256 _deadline, +// IERC20 _token, +// address _proposer +// ) public { +// _deadline = bound(_deadline, block.timestamp + 1, type(uint248).max); + +// address _finalizer = makeAddr('finalizer'); +// bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _baseDisputeWindow); +// bondedResponseModule.forTest_setRequestData(_requestId, _data); + +// // Mock and expect IOracle.allowedModule to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, _finalizer)), abi.encode(false)); + +// IOracle.Response memory _mockResponse = IOracle.Response({ +// createdAt: _deadline - 1, +// requestId: _requestId, +// disputeId: bytes32(''), +// proposer: _proposer, +// response: bytes('bleh') +// }); + +// // Mock and expect IOracle.getFinalizedResponse to be called +// _mockAndExpect(address(oracle), abi.encodeCall(IOracle.getFinalizedResponse, _requestId), abi.encode(_mockResponse)); + +// vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooEarlyToFinalize.selector); + +// vm.warp(_deadline + 1); +// vm.prank(address(oracle)); +// bondedResponseModule.finalizeRequest(_requestId, _finalizer); +// } +// } + +// contract BondedResponseModule_Unit_DeleteResponse is BaseTest { +// /** +// * @notice Test that the delete response function triggers bond release. +// */ +// function test_deleteResponse( +// bytes32 _requestId, +// bytes32 _responseId, +// uint256 _bondSize, +// uint256 _deadline, +// uint256 _timestamp, +// IERC20 _token, +// address _proposer +// ) public { +// _timestamp = bound(_timestamp, 1, type(uint248).max); + +// // Create and set some mock request data +// bytes memory _data = abi.encode(accounting, _token, _bondSize, _deadline, _baseDisputeWindow); +// bondedResponseModule.forTest_setRequestData(_requestId, _data); + +// vm.warp(_timestamp); + +// if (_deadline >= _timestamp) { +// // Mock and expect IAccountingExtension.release to be called +// _mockAndExpect( +// address(accounting), +// abi.encodeCall(IAccountingExtension.release, (_proposer, _requestId, _token, _bondSize)), +// abi.encode() +// ); +// } else { +// // Check: does it revert if the deadline has passed? +// vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooLateToDelete.selector); +// } + +// vm.prank(address(oracle)); +// bondedResponseModule.deleteResponse(_requestId, _responseId, _proposer); +// } +// } diff --git a/solidity/test/utils/Helpers.sol b/solidity/test/utils/Helpers.sol index cd60ad9c..46874489 100644 --- a/solidity/test/utils/Helpers.sol +++ b/solidity/test/utils/Helpers.sol @@ -1,56 +1,56 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.19; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {DSTestPlus} from '@defi-wonderland/solidity-utils/solidity/test/DSTestPlus.sol'; -import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; +// import {DSTestPlus} from '@defi-wonderland/solidity-utils/solidity/test/DSTestPlus.sol'; +// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; -import {IAccountingExtension} from '../../interfaces/extensions/IAccountingExtension.sol'; +// import {IAccountingExtension} from '../../interfaces/extensions/IAccountingExtension.sol'; -contract Helpers is DSTestPlus { - modifier assumeFuzzable(address _address) { - _assumeFuzzable(_address); - _; - } +// contract Helpers is DSTestPlus { +// modifier assumeFuzzable(address _address) { +// _assumeFuzzable(_address); +// _; +// } - function _assumeFuzzable(address _address) internal pure { - assumeNotForgeAddress(_address); - assumeNotZeroAddress(_address); - assumeNotPrecompile(_address); - } +// function _assumeFuzzable(address _address) internal pure { +// assumeNotForgeAddress(_address); +// assumeNotZeroAddress(_address); +// assumeNotPrecompile(_address); +// } - function _mockAndExpect(address _receiver, bytes memory _calldata, bytes memory _returned) internal { - vm.mockCall(_receiver, _calldata, _returned); - vm.expectCall(_receiver, _calldata); - } +// function _mockAndExpect(address _receiver, bytes memory _calldata, bytes memory _returned) internal { +// vm.mockCall(_receiver, _calldata, _returned); +// vm.expectCall(_receiver, _calldata); +// } - function _getMockDispute( - bytes32 _requestId, - address _disputer, - address _proposer - ) internal view returns (IOracle.Dispute memory _dispute) { - _dispute = IOracle.Dispute({ - disputer: _disputer, - responseId: bytes32('response'), - proposer: _proposer, - requestId: _requestId, - status: IOracle.DisputeStatus.None, - createdAt: block.timestamp - }); - } +// function _getMockDispute( +// bytes32 _requestId, +// address _disputer, +// address _proposer +// ) internal view returns (IOracle.Dispute memory _dispute) { +// _dispute = IOracle.Dispute({ +// disputer: _disputer, +// responseId: bytes32('response'), +// proposer: _proposer, +// requestId: _requestId, +// status: IOracle.DisputeStatus.None, +// createdAt: block.timestamp +// }); +// } - function _forBondDepositERC20( - IAccountingExtension _accountingExtension, - address _depositor, - IERC20 _token, - uint256 _depositAmount, - uint256 _balanceIncrease - ) internal { - vm.assume(_balanceIncrease >= _depositAmount); - deal(address(_token), _depositor, _balanceIncrease); - vm.startPrank(_depositor); - _token.approve(address(_accountingExtension), _depositAmount); - _accountingExtension.deposit(_token, _depositAmount); - vm.stopPrank(); - } -} +// function _forBondDepositERC20( +// IAccountingExtension _accountingExtension, +// address _depositor, +// IERC20 _token, +// uint256 _depositAmount, +// uint256 _balanceIncrease +// ) internal { +// vm.assume(_balanceIncrease >= _depositAmount); +// deal(address(_token), _depositor, _balanceIncrease); +// vm.startPrank(_depositor); +// _token.approve(address(_accountingExtension), _depositAmount); +// _accountingExtension.deposit(_token, _depositAmount); +// vm.stopPrank(); +// } +// }