diff --git a/package.json b/package.json index 1e1f39c8..5a5af24d 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "package.json": "sort-package-json" }, "dependencies": { - "@defi-wonderland/prophet-core-contracts": "0.0.0-c25103ea", + "@defi-wonderland/prophet-core-contracts": "0.0.0-d01bc1a0", "@openzeppelin/contracts": "4.9.5", "solmate": "https://github.com/transmissions11/solmate.git#bfc9c25865a274a7827fea5abf6e4fb64fc64e6c" }, diff --git a/solidity/contracts/extensions/AccountingExtension.sol b/solidity/contracts/extensions/AccountingExtension.sol index 790b507b..97384f31 100644 --- a/solidity/contracts/extensions/AccountingExtension.sol +++ b/solidity/contracts/extensions/AccountingExtension.sol @@ -6,15 +6,14 @@ 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 {Validator} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Validator.sol'; + import {IAccountingExtension} from '../../interfaces/extensions/IAccountingExtension.sol'; -contract AccountingExtension is IAccountingExtension { +contract AccountingExtension is Validator, 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; @@ -27,9 +26,7 @@ contract AccountingExtension is IAccountingExtension { */ mapping(address _bonder => EnumerableSet.AddressSet _modules) internal _approvals; - constructor(IOracle _oracle) { - ORACLE = _oracle; - } + constructor(IOracle _oracle) Validator(_oracle) {} /** * @notice Checks that the caller is an allowed module used in the request. diff --git a/solidity/contracts/extensions/BondEscalationAccounting.sol b/solidity/contracts/extensions/BondEscalationAccounting.sol index 851ce760..4bca276a 100644 --- a/solidity/contracts/extensions/BondEscalationAccounting.sol +++ b/solidity/contracts/extensions/BondEscalationAccounting.sol @@ -24,11 +24,15 @@ contract BondEscalationAccounting is AccountingExtension, IBondEscalationAccount /// @inheritdoc IBondEscalationAccounting function pledge( address _pledger, - bytes32 _requestId, - bytes32 _disputeId, + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, IERC20 _token, uint256 _amount - ) external onlyAllowedModule(_requestId) { + ) external { + bytes32 _requestId = _getId(_request); + bytes32 _disputeId = _validateDispute(_request, _dispute); + + if (!ORACLE.allowedModule(_requestId, msg.sender)) revert AccountingExtension_UnauthorizedModule(); if (balanceOf[_pledger][_token] < _amount) revert BondEscalationAccounting_InsufficientFunds(); pledges[_disputeId][_token] += _amount; @@ -42,12 +46,17 @@ contract BondEscalationAccounting is AccountingExtension, IBondEscalationAccount /// @inheritdoc IBondEscalationAccounting function onSettleBondEscalation( - bytes32 _requestId, - bytes32 _disputeId, + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, IERC20 _token, uint256 _amountPerPledger, uint256 _winningPledgersLength - ) external onlyAllowedModule(_requestId) { + ) external { + bytes32 _requestId = _getId(_request); + bytes32 _disputeId = _validateDispute(_request, _dispute); + + if (!ORACLE.allowedModule(_requestId, msg.sender)) revert AccountingExtension_UnauthorizedModule(); + if (pledges[_disputeId][_token] < _amountPerPledger * _winningPledgersLength) { revert BondEscalationAccounting_InsufficientFunds(); } @@ -113,12 +122,17 @@ contract BondEscalationAccounting is AccountingExtension, IBondEscalationAccount /// @inheritdoc IBondEscalationAccounting function releasePledge( - bytes32 _requestId, - bytes32 _disputeId, + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, address _pledger, IERC20 _token, uint256 _amount - ) external onlyAllowedModule(_requestId) { + ) external { + bytes32 _requestId = _getId(_request); + bytes32 _disputeId = _validateDispute(_request, _dispute); + + if (!ORACLE.allowedModule(_requestId, msg.sender)) revert AccountingExtension_UnauthorizedModule(); + if (pledges[_disputeId][_token] < _amount) revert BondEscalationAccounting_InsufficientFunds(); balanceOf[_pledger][_token] += _amount; diff --git a/solidity/contracts/modules/dispute/BondEscalationModule.sol b/solidity/contracts/modules/dispute/BondEscalationModule.sol index 0d56983b..d33ce09b 100644 --- a/solidity/contracts/modules/dispute/BondEscalationModule.sol +++ b/solidity/contracts/modules/dispute/BondEscalationModule.sol @@ -102,8 +102,8 @@ contract BondEscalationModule is Module, IBondEscalationModule { if (_escalation.amountOfPledgesForDispute + _escalation.amountOfPledgesAgainstDispute > 0) { _params.accountingExtension.onSettleBondEscalation({ - _requestId: _dispute.requestId, - _disputeId: _disputeId, + _request: _request, + _dispute: _dispute, _token: _params.bondToken, _amountPerPledger: _params.bondSize, _winningPledgersLength: _escalation.amountOfPledgesForDispute + _escalation.amountOfPledgesAgainstDispute @@ -133,8 +133,8 @@ contract BondEscalationModule is Module, IBondEscalationModule { + FixedPointMathLib.mulDivDown(_pledgesForDispute, _params.bondSize, _pledgesAgainstDispute); _params.accountingExtension.onSettleBondEscalation({ - _requestId: _dispute.requestId, - _disputeId: _escalation.disputeId, + _request: _request, + _dispute: _dispute, _token: _params.bondToken, _amountPerPledger: _amountToPay, _winningPledgersLength: _won ? _pledgesForDispute : _pledgesAgainstDispute @@ -217,8 +217,8 @@ contract BondEscalationModule is Module, IBondEscalationModule { pledgesForDispute[_dispute.requestId][msg.sender] += 1; _params.accountingExtension.pledge({ _pledger: msg.sender, - _requestId: _dispute.requestId, - _disputeId: _disputeId, + _request: _request, + _dispute: _dispute, _token: _params.bondToken, _amount: _params.bondSize }); @@ -235,8 +235,8 @@ contract BondEscalationModule is Module, IBondEscalationModule { pledgesAgainstDispute[_dispute.requestId][msg.sender] += 1; _params.accountingExtension.pledge({ _pledger: msg.sender, - _requestId: _dispute.requestId, - _disputeId: _disputeId, + _request: _request, + _dispute: _dispute, _token: _params.bondToken, _amount: _params.bondSize }); diff --git a/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol b/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol index 1246b792..a1e3392f 100644 --- a/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol +++ b/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol @@ -140,8 +140,8 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu _reward = FixedPointMathLib.mulDivDown(_escalation.pledgesAgainst, _pledgerProportion, BASE); _amountToRelease = _reward + _pledgerBalanceBefore; _claimPledge({ - _requestId: _dispute.requestId, - _disputeId: _disputeId, + _request: _request, + _dispute: _dispute, _amountToRelease: _amountToRelease, _resolution: _escalation.resolution, _params: _params @@ -153,8 +153,8 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu _reward = FixedPointMathLib.mulDivDown(_escalation.pledgesFor, _pledgerProportion, BASE); _amountToRelease = _reward + _pledgerBalanceBefore; _claimPledge({ - _requestId: _dispute.requestId, - _disputeId: _disputeId, + _request: _request, + _dispute: _dispute, _amountToRelease: _amountToRelease, _resolution: _escalation.resolution, _params: _params @@ -166,8 +166,8 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu if (_pledgerBalanceFor > 0) { pledgesForDispute[_disputeId][msg.sender] -= _pledgerBalanceFor; _claimPledge({ - _requestId: _dispute.requestId, - _disputeId: _disputeId, + _request: _request, + _dispute: _dispute, _amountToRelease: _pledgerBalanceFor, _resolution: _escalation.resolution, _params: _params @@ -177,8 +177,8 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu if (_pledgerBalanceAgainst > 0) { pledgesAgainstDispute[_disputeId][msg.sender] -= _pledgerBalanceAgainst; _claimPledge({ - _requestId: _dispute.requestId, - _disputeId: _disputeId, + _request: _request, + _dispute: _dispute, _amountToRelease: _pledgerBalanceAgainst, _resolution: _escalation.resolution, _params: _params @@ -220,8 +220,8 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu _params.accountingExtension.pledge({ _pledger: msg.sender, - _requestId: _dispute.requestId, - _disputeId: _disputeId, + _request: _request, + _dispute: _dispute, _token: _params.bondToken, _amount: _pledgeAmount }); @@ -308,30 +308,30 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu /** * @notice Releases the pledged funds to the pledger * - * @param _requestId The ID of the request - * @param _disputeId The ID of the dispute + * @param _request The request + * @param _dispute The dispute * @param _amountToRelease The amount to release * @param _resolution The resolution of the dispute * @param _params The request parameters */ function _claimPledge( - bytes32 _requestId, - bytes32 _disputeId, + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, uint256 _amountToRelease, Resolution _resolution, RequestParameters memory _params ) internal { _params.accountingExtension.releasePledge({ - _requestId: _requestId, - _disputeId: _disputeId, + _request: _request, + _dispute: _dispute, _pledger: msg.sender, _token: _params.bondToken, _amount: _amountToRelease }); emit PledgeClaimed({ - _requestId: _requestId, - _disputeId: _disputeId, + _requestId: _getId(_request), + _disputeId: _getId(_dispute), _pledger: msg.sender, _token: _params.bondToken, _pledgeReleased: _amountToRelease, diff --git a/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol b/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol index c71eed1b..bb2fe905 100644 --- a/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol +++ b/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol @@ -53,7 +53,6 @@ contract PrivateERC20ResolutionModule is Module, IPrivateERC20ResolutionModule { /// @inheritdoc IPrivateERC20ResolutionModule function commitVote(IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, bytes32 _commitment) public { bytes32 _disputeId = _validateDispute(_request, _dispute); - if (ORACLE.disputeCreatedAt(_disputeId) == 0) revert PrivateERC20ResolutionModule_NonExistentDispute(); if (ORACLE.disputeStatus(_disputeId) != IOracle.DisputeStatus.Escalated) { revert PrivateERC20ResolutionModule_AlreadyResolved(); } @@ -113,7 +112,6 @@ contract PrivateERC20ResolutionModule is Module, IPrivateERC20ResolutionModule { IOracle.Response calldata _response, IOracle.Dispute calldata _dispute ) external onlyOracle { - if (ORACLE.disputeCreatedAt(_disputeId) == 0) revert PrivateERC20ResolutionModule_NonExistentDispute(); if (ORACLE.disputeStatus(_disputeId) != IOracle.DisputeStatus.Escalated) { revert PrivateERC20ResolutionModule_AlreadyResolved(); } diff --git a/solidity/interfaces/extensions/IAccountingExtension.sol b/solidity/interfaces/extensions/IAccountingExtension.sol index 20fe9f62..d1f0ba1a 100644 --- a/solidity/interfaces/extensions/IAccountingExtension.sol +++ b/solidity/interfaces/extensions/IAccountingExtension.sol @@ -96,12 +96,6 @@ interface IAccountingExtension { VARIABLES //////////////////////////////////////////////////////////////*/ - /** - * @notice Returns the interface for the Oracle contract - * @return _oracle The Oracle address - */ - 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 diff --git a/solidity/interfaces/extensions/IBondEscalationAccounting.sol b/solidity/interfaces/extensions/IBondEscalationAccounting.sol index dead0586..840f84e4 100644 --- a/solidity/interfaces/extensions/IBondEscalationAccounting.sol +++ b/solidity/interfaces/extensions/IBondEscalationAccounting.sol @@ -3,6 +3,8 @@ pragma solidity ^0.8.19; import {IBondEscalationModule} from '../modules/dispute/IBondEscalationModule.sol'; import {IAccountingExtension} from './IAccountingExtension.sol'; + +import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; /** @@ -170,26 +172,32 @@ interface IBondEscalationAccounting is IAccountingExtension { * @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 _request The bond-escalated request + * @param _dispute The bond-escalated dispute * @param _token Address of the token being paid as a reward for winning the bond escalation * @param _amount Amount of token to pledge */ - function pledge(address _pledger, bytes32 _requestId, bytes32 _disputeId, IERC20 _token, uint256 _amount) external; + function pledge( + address _pledger, + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, + 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 _request The bond-escalated request + * @param _dispute The bond-escalated dispute * @param _token Address of the token being paid as a reward for winning the bond escalation * @param _amountPerPledger Amount of `_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, + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, IERC20 _token, uint256 _amountPerPledger, uint256 _winningPledgersLength @@ -200,15 +208,15 @@ interface IBondEscalationAccounting is IAccountingExtension { * * @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 _request The bond-escalated request + * @param _dispute The bond-escalated dispute * @param _pledger Address of the pledger * @param _token Address of the token to be released * @param _amount Amount of `_token` to be released to the pledger */ function releasePledge( - bytes32 _requestId, - bytes32 _disputeId, + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, address _pledger, IERC20 _token, uint256 _amount diff --git a/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol b/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol index 27c3389c..fccddc87 100644 --- a/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol +++ b/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol @@ -70,11 +70,6 @@ interface IPrivateERC20ResolutionModule is IResolutionModule { */ 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 */ diff --git a/solidity/test/integration/BondEscalation.t.sol b/solidity/test/integration/BondEscalation.t.sol index 26cbdc9b..3ce1e13b 100644 --- a/solidity/test/integration/BondEscalation.t.sol +++ b/solidity/test/integration/BondEscalation.t.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.19; import './IntegrationBase.sol'; +import {IValidator} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IValidator.sol'; contract Integration_BondEscalation is IntegrationBase { address internal _secondDisputer = makeAddr('secondDisputer'); @@ -441,4 +442,60 @@ contract Integration_BondEscalation is IntegrationBase { _bondEscalationAccounting.balanceOf(_thirdDisputer, usdc), _pledgeSize * 2, 'Mismatch: Third Disputer balance' ); } + + function test_attackerAllowedModules() public { + ////////////////// DISPUTE ESCALATION //////////////////////// + // Step 1: Proposer pledges against the dispute + _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); + vm.prank(proposer); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + + // Step 2: Disputer doubles down + _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); + vm.prank(disputer); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + + // Step 3: Proposer doubles down + _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); + vm.prank(proposer); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + + // 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 + _deposit(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize); + vm.prank(_secondDisputer); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + + ////////////////// NEW MALICIOUS REQUEST //////////////////////// + + address _attacker = makeAddr('attacker'); + + mockRequest.nonce += 1; + mockRequest.requester = _attacker; + mockRequest.disputeModule = _attacker; + mockRequest.requestModuleData = abi.encode( + IHttpRequestModule.RequestParameters({ + url: _expectedUrl, + body: _expectedBody, + method: _expectedMethod, + accountingExtension: _bondEscalationAccounting, + paymentToken: usdc, + paymentAmount: 0 + }) + ); + + uint256 _attackerBalance = _bondEscalationAccounting.balanceOf(_attacker, usdc); + assertEq(_attackerBalance, 0); + + vm.startPrank(_attacker); + // Create a new proposal with another dispute module + _bondEscalationAccounting.approveModule(mockRequest.requestModule); + + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); + _bondEscalationAccounting.releasePledge(mockRequest, mockDispute, _attacker, usdc, _pledgeSize * 4); + vm.stopPrank(); + } } diff --git a/solidity/test/unit/modules/dispute/BondEscalationAccounting.t.sol b/solidity/test/unit/modules/dispute/BondEscalationAccounting.t.sol index 3c71e321..d76ace9c 100644 --- a/solidity/test/unit/modules/dispute/BondEscalationAccounting.t.sol +++ b/solidity/test/unit/modules/dispute/BondEscalationAccounting.t.sol @@ -110,15 +110,12 @@ contract BaseTest is Test, Helpers { } contract BondEscalationAccounting_Unit_Pledge is BaseTest { - function test_revertIfDisallowedModule( - address _pledger, - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amount - ) public { + function test_revertIfDisallowedModule(address _pledger, uint256 _amount) public { + (, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + // 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) + address(oracle), abi.encodeCall(IOracle.allowedModule, (_getId(mockRequest), address(this))), abi.encode(false) ); // Check: does it revert if called by an unauthorized module? @@ -126,22 +123,19 @@ contract BondEscalationAccounting_Unit_Pledge is BaseTest { bondEscalationAccounting.pledge({ _pledger: _pledger, - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: _dispute, _token: token, _amount: _amount }); } - function test_revertIfNotEnoughDeposited( - address _pledger, - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amount - ) public { + function test_revertIfNotEnoughDeposited(address _pledger, uint256 _amount) public { vm.assume(_amount > 0); - // Mock and expect the call to oracle checking if the module is allowed + (, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + _mockAndExpect( address(oracle), abi.encodeCall(IOracle.allowedModule, (_requestId, address(this))), abi.encode(true) ); @@ -151,14 +145,18 @@ contract BondEscalationAccounting_Unit_Pledge is BaseTest { bondEscalationAccounting.pledge({ _pledger: _pledger, - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: _dispute, _token: token, _amount: _amount }); } - function test_successfulCall(address _pledger, bytes32 _requestId, bytes32 _disputeId, uint256 _amount) public { + function test_successfulCall(address _pledger, uint256 _amount) public { + (, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); + // 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) @@ -175,8 +173,8 @@ contract BondEscalationAccounting_Unit_Pledge is BaseTest { bondEscalationAccounting.pledge({ _pledger: _pledger, - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: _dispute, _token: token, _amount: _amount }); @@ -192,12 +190,10 @@ contract BondEscalationAccounting_Unit_Pledge is BaseTest { } contract BondEscalationAccounting_Unit_OnSettleBondEscalation is BaseTest { - function test_revertIfDisallowedModule( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _numOfWinningPledgers, - uint256 _amountPerPledger - ) public { + function test_revertIfDisallowedModule(uint256 _numOfWinningPledgers, uint256 _amountPerPledger) public { + (, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + // 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) @@ -207,30 +203,30 @@ contract BondEscalationAccounting_Unit_OnSettleBondEscalation is BaseTest { vm.expectRevert(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector); bondEscalationAccounting.onSettleBondEscalation({ - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: _dispute, _token: token, _amountPerPledger: _amountPerPledger, _winningPledgersLength: _numOfWinningPledgers }); } - function test_revertIfAlreadySettled( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _numOfWinningPledgers, - uint256 _amountPerPledger - ) public { + function test_revertIfAlreadySettled(uint256 _numOfWinningPledgers, uint256 _amountPerPledger) public { + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(mockDispute); + 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) ); + // Mock and expect the call to oracle checking if the dispute exists + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); + bondEscalationAccounting.forTest_setEscalationResult( _disputeId, _requestId, token, _amountPerPledger, IBondEscalationModule(address(this)) ); @@ -241,20 +237,19 @@ contract BondEscalationAccounting_Unit_OnSettleBondEscalation is BaseTest { vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_AlreadySettled.selector); bondEscalationAccounting.onSettleBondEscalation({ - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: mockDispute, _token: token, _amountPerPledger: _amountPerPledger, _winningPledgersLength: _numOfWinningPledgers }); } - function test_revertIfInsufficientFunds( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amountPerPledger, - uint256 _numOfWinningPledgers - ) public { + function test_revertIfInsufficientFunds(uint256 _amountPerPledger, uint256 _numOfWinningPledgers) public { + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); + // 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); @@ -275,20 +270,19 @@ contract BondEscalationAccounting_Unit_OnSettleBondEscalation is BaseTest { vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_InsufficientFunds.selector); bondEscalationAccounting.onSettleBondEscalation({ - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: _dispute, _token: token, _amountPerPledger: _amountPerPledger, _winningPledgersLength: _numOfWinningPledgers }); } - function test_successfulCall( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _numOfWinningPledgers, - uint256 _amountPerPledger - ) public { + function test_successfulCall(uint256 _numOfWinningPledgers, uint256 _amountPerPledger) public { + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); + // 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); @@ -308,8 +302,8 @@ contract BondEscalationAccounting_Unit_OnSettleBondEscalation is BaseTest { emit BondEscalationSettled(_requestId, _disputeId, token, _amountPerPledger, _numOfWinningPledgers); bondEscalationAccounting.onSettleBondEscalation({ - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: _dispute, _token: token, _amountPerPledger: _amountPerPledger, _winningPledgersLength: _numOfWinningPledgers @@ -331,12 +325,11 @@ contract BondEscalationAccounting_Unit_OnSettleBondEscalation is BaseTest { } contract BondEscalationAccounting_Unit_ReleasePledge is BaseTest { - function test_revertIfDisallowedModule( - bytes32 _requestId, - bytes32 _disputeId, - address _pledger, - uint256 _amount - ) public { + function test_revertIfDisallowedModule(address _pledger, uint256 _amount) public { + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); + // 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) @@ -346,22 +339,21 @@ contract BondEscalationAccounting_Unit_ReleasePledge is BaseTest { vm.expectRevert(IAccountingExtension.AccountingExtension_UnauthorizedModule.selector); bondEscalationAccounting.releasePledge({ - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: _dispute, _pledger: _pledger, _token: token, _amount: _amount }); } - function test_revertIfInsufficientFunds( - bytes32 _requestId, - bytes32 _disputeId, - uint256 _amount, - address _pledger - ) public { + function test_revertIfInsufficientFunds(uint256 _amount, address _pledger) public { vm.assume(_amount < type(uint256).max); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); + // 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) @@ -374,15 +366,19 @@ contract BondEscalationAccounting_Unit_ReleasePledge is BaseTest { vm.expectRevert(IBondEscalationAccounting.BondEscalationAccounting_InsufficientFunds.selector); bondEscalationAccounting.releasePledge({ - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: _dispute, _pledger: _pledger, _token: token, _amount: _underflowAmount }); } - function test_successfulCall(bytes32 _requestId, bytes32 _disputeId, uint256 _amount, address _pledger) public { + function test_successfulCall(uint256 _amount, address _pledger) public { + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); + // 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) @@ -391,8 +387,8 @@ contract BondEscalationAccounting_Unit_ReleasePledge is BaseTest { bondEscalationAccounting.forTest_setPledge(_disputeId, token, _amount); bondEscalationAccounting.releasePledge({ - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: _dispute, _pledger: _pledger, _token: token, _amount: _amount @@ -402,7 +398,11 @@ contract BondEscalationAccounting_Unit_ReleasePledge is BaseTest { assertEq(bondEscalationAccounting.balanceOf(_pledger, token), _amount); } - function test_emitsEvent(bytes32 _requestId, bytes32 _disputeId, uint256 _amount, address _pledger) public { + function test_emitsEvent(uint256 _amount, address _pledger) public { + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); + // 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) @@ -415,8 +415,8 @@ contract BondEscalationAccounting_Unit_ReleasePledge is BaseTest { emit PledgeReleased(_requestId, _disputeId, _pledger, token, _amount); bondEscalationAccounting.releasePledge({ - _requestId: _requestId, - _disputeId: _disputeId, + _request: mockRequest, + _dispute: _dispute, _pledger: _pledger, _token: token, _amount: _amount diff --git a/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol b/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol index 21df0cb0..0b8bdcbd 100644 --- a/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol +++ b/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol @@ -7,6 +7,7 @@ import {Helpers} from '../../../utils/Helpers.sol'; import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +import {IValidator} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IValidator.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {Strings} from '@openzeppelin/contracts/utils/Strings.sol'; @@ -839,7 +840,7 @@ contract BondEscalationModule_Unit_OnDisputeStatusChange is BaseTest { address(_params.accountingExtension), abi.encodeCall( IBondEscalationAccounting.onSettleBondEscalation, - (_requestId, _disputeId, _params.bondToken, _params.bondSize << 1, _numPledgers) + (mockRequest, mockDispute, _params.bondToken, _params.bondSize << 1, _numPledgers) ), abi.encode() ); @@ -909,7 +910,7 @@ contract BondEscalationModule_Unit_OnDisputeStatusChange is BaseTest { address(_params.accountingExtension), abi.encodeCall( IBondEscalationAccounting.onSettleBondEscalation, - (_requestId, _disputeId, _params.bondToken, _params.bondSize << 1, _numPledgers) + (mockRequest, mockDispute, _params.bondToken, _params.bondSize << 1, _numPledgers) ), abi.encode() ); @@ -935,7 +936,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { */ function test_revertIfInvalidDisputeBody() public { // Check: does it revert if the dispute body is invalid? - vm.expectRevert(IModule.Module_InvalidDisputeBody.selector); + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); } @@ -943,12 +944,11 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { * @notice Tests that pledgeForDispute reverts if the dispute is not going through the bond escalation mechanism. */ function test_revertIfTheDisputeIsNotGoingThroughTheBondEscalationProcess() public { - bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; + (, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); // Check: does it revert if the dispute is not escalated yet? vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); - bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute); } /** @@ -964,9 +964,9 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); + (, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + bytes32 _disputeId = _getId(_dispute); bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); @@ -974,7 +974,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if the bond escalation is over? vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); - bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute); } /** @@ -990,9 +990,9 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); + (, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + bytes32 _disputeId = _getId(_dispute); bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); @@ -1003,7 +1003,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if the maximum number of escalations is reached? vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); - bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute); } /** @@ -1019,10 +1019,9 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { _params.bondEscalationDeadline = block.timestamp + 1; mockRequest.disputeModuleData = abi.encode(_params); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); - + bytes32 _disputeId = _getId(_dispute); bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); uint256 _numForPledgers = 2; @@ -1032,7 +1031,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if trying to pledge in a dispute that is already surpassed? vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); - bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute); } /** @@ -1049,9 +1048,9 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + bytes32 _disputeId = _getId(_dispute); bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); @@ -1062,7 +1061,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if trying to tie outside of the tying buffer? vm.expectRevert(IBondEscalationModule.BondEscalationModule_CannotBreakTieDuringTyingBuffer.selector); - bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute); } /** @@ -1078,9 +1077,9 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + bytes32 _disputeId = _getId(_dispute); // Mock and expect bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); @@ -1094,7 +1093,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { _mockAndExpect( address(_params.accountingExtension), abi.encodeCall( - IBondEscalationAccounting.pledge, (address(this), _requestId, _disputeId, _params.bondToken, _params.bondSize) + IBondEscalationAccounting.pledge, (address(this), mockRequest, _dispute, _params.bondToken, _params.bondSize) ), abi.encode(true) ); @@ -1103,7 +1102,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { vm.expectEmit(true, true, true, true, address(bondEscalationModule)); emit PledgedForDispute(_disputeId, address(this), _params.bondSize); - bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute); uint256 _pledgesForDispute = bondEscalationModule.getEscalation(_requestId).amountOfPledgesForDispute; // Check: is the number of pledges for the dispute properly updated? @@ -1121,7 +1120,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { */ function test_revertIfInvalidDisputeBody() public { // Check: does it revert if the dispute body is invalid? - vm.expectRevert(IModule.Module_InvalidDisputeBody.selector); + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); } @@ -1129,12 +1128,13 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { * @notice Tests that pledgeAgainstDispute reverts if the dispute is not going through the bond escalation mechanism. */ function test_revertIfTheDisputeIsNotGoingThroughTheBondEscalationProcess() public { + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; + bytes32 _disputeId = _getId(_dispute); // Check: does it revert if the dispute is not escalated yet? vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); } /** @@ -1150,9 +1150,9 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + bytes32 _disputeId = _getId(_dispute); bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); @@ -1161,7 +1161,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if the bond escalation is over? vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); } /** @@ -1177,9 +1177,9 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + bytes32 _disputeId = _getId(_dispute); bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); @@ -1191,7 +1191,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if the maximum number of escalations is reached? vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); } /** @@ -1208,9 +1208,9 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { _params.bondEscalationDeadline = block.timestamp + 1; mockRequest.disputeModuleData = abi.encode(_params); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + bytes32 _disputeId = _getId(_dispute); bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); @@ -1222,7 +1222,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if trying to pledge in a dispute that is already surpassed? vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); } /** @@ -1240,10 +1240,9 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); - // Compute proper IDs + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + bytes32 _disputeId = _getId(_dispute); bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); @@ -1254,7 +1253,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if trying to tie outside of the tying buffer? vm.expectRevert(IBondEscalationModule.BondEscalationModule_CannotBreakTieDuringTyingBuffer.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); } /** @@ -1270,9 +1269,9 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + bytes32 _disputeId = _getId(_dispute); bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); @@ -1284,7 +1283,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { _mockAndExpect( address(_params.accountingExtension), abi.encodeCall( - IBondEscalationAccounting.pledge, (address(this), _requestId, _disputeId, _params.bondToken, _params.bondSize) + IBondEscalationAccounting.pledge, (address(this), mockRequest, _dispute, _params.bondToken, _params.bondSize) ), abi.encode(true) ); @@ -1293,7 +1292,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { vm.expectEmit(true, true, true, true, address(bondEscalationModule)); emit PledgedAgainstDispute(_disputeId, address(this), _params.bondSize); - bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); uint256 _pledgesForDispute = bondEscalationModule.getEscalation(_requestId).amountOfPledgesAgainstDispute; // Check: is the number of pledges for the dispute properly updated? @@ -1311,7 +1310,7 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { */ function test_revertIfInvalidResponseBody() public { // Check: does it revert if the response body is invalid? - vm.expectRevert(IModule.Module_InvalidResponseBody.selector); + vm.expectRevert(IValidator.Validator_InvalidResponseBody.selector); bondEscalationModule.settleBondEscalation(mockRequest, mockResponse, mockDispute); } @@ -1323,7 +1322,7 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { mockResponse.requestId = _requestId; // Check: does it revert if the dispute body is invalid? - vm.expectRevert(IModule.Module_InvalidDisputeBody.selector); + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); bondEscalationModule.settleBondEscalation(mockRequest, mockResponse, mockDispute); } @@ -1338,17 +1337,14 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { _params.tyingBuffer = bound(_params.tyingBuffer, 0, type(uint128).max); _params.bondEscalationDeadline = block.timestamp; mockRequest.disputeModuleData = abi.encode(_params); - bytes32 _requestId = _getId(mockRequest); - - mockResponse.requestId = _requestId; - bytes32 _responseId = _getId(mockResponse); - mockDispute.requestId = _requestId; - mockDispute.responseId = _responseId; + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); // Check: does it revert if the bond escalation is not over? vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationNotOver.selector); - bondEscalationModule.settleBondEscalation(mockRequest, mockResponse, mockDispute); + bondEscalationModule.settleBondEscalation(mockRequest, _response, _dispute); } /** @@ -1362,13 +1358,10 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { _params.bondEscalationDeadline = block.timestamp; _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); - bytes32 _requestId = _getId(mockRequest); - mockResponse.requestId = _requestId; - bytes32 _responseId = _getId(mockResponse); - - mockDispute.requestId = _requestId; - mockDispute.responseId = _responseId; + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); vm.warp(_params.bondEscalationDeadline + _params.tyingBuffer + 1); @@ -1376,7 +1369,7 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { // Check: does it revert if the bond escalation is not active? vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationCantBeSettled.selector); - bondEscalationModule.settleBondEscalation(mockRequest, mockResponse, mockDispute); + bondEscalationModule.settleBondEscalation(mockRequest, _response, _dispute); } /** @@ -1390,14 +1383,10 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { _params.bondEscalationDeadline = block.timestamp; _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); - bytes32 _requestId = _getId(mockRequest); - - mockResponse.requestId = _requestId; - bytes32 _responseId = _getId(mockResponse); - mockDispute.requestId = _requestId; - mockDispute.responseId = _responseId; - bytes32 _disputeId = _getId(mockDispute); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); vm.warp(_params.bondEscalationDeadline + _params.tyingBuffer + 1); @@ -1411,7 +1400,7 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { // Check: does it revert if the number of pledgers is the same? vm.expectRevert(IBondEscalationModule.BondEscalationModule_ShouldBeEscalated.selector); - bondEscalationModule.settleBondEscalation(mockRequest, mockResponse, mockDispute); + bondEscalationModule.settleBondEscalation(mockRequest, _response, _dispute); } /** @@ -1425,14 +1414,10 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { _params.bondEscalationDeadline = block.timestamp; _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); - bytes32 _requestId = _getId(mockRequest); - - mockResponse.requestId = _requestId; - bytes32 _responseId = _getId(mockResponse); - mockDispute.requestId = _requestId; - mockDispute.responseId = _responseId; - bytes32 _disputeId = _getId(mockDispute); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); vm.warp(_params.bondEscalationDeadline + _params.tyingBuffer + 1); @@ -1446,7 +1431,7 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { _mockAndExpect( address(oracle), - abi.encodeCall(IOracle.updateDisputeStatus, (mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Won)), + abi.encodeCall(IOracle.updateDisputeStatus, (mockRequest, _response, _dispute, IOracle.DisputeStatus.Won)), abi.encode(true) ); @@ -1454,7 +1439,7 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { vm.expectEmit(true, true, true, true, address(bondEscalationModule)); emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.DisputerWon); - bondEscalationModule.settleBondEscalation(mockRequest, mockResponse, mockDispute); + bondEscalationModule.settleBondEscalation(mockRequest, _response, _dispute); // Check: is the bond escalation status properly updated? assertEq( uint256(bondEscalationModule.getEscalation(_requestId).status), @@ -1473,14 +1458,10 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { _params.bondEscalationDeadline = block.timestamp; _params.tyingBuffer = 1000; mockRequest.disputeModuleData = abi.encode(_params); - bytes32 _requestId = _getId(mockRequest); - - mockResponse.requestId = _requestId; - bytes32 _responseId = _getId(mockResponse); - mockDispute.requestId = _requestId; - mockDispute.responseId = _responseId; - bytes32 _disputeId = _getId(mockDispute); + (IOracle.Response memory _response, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); vm.warp(_params.bondEscalationDeadline + _params.tyingBuffer + 1); @@ -1494,7 +1475,7 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { _mockAndExpect( address(oracle), - abi.encodeCall(IOracle.updateDisputeStatus, (mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Lost)), + abi.encodeCall(IOracle.updateDisputeStatus, (mockRequest, _response, _dispute, IOracle.DisputeStatus.Lost)), abi.encode(true) ); @@ -1502,7 +1483,7 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { vm.expectEmit(true, true, true, true, address(bondEscalationModule)); emit BondEscalationStatusUpdated(_requestId, _disputeId, IBondEscalationModule.BondEscalationStatus.DisputerLost); - bondEscalationModule.settleBondEscalation(mockRequest, mockResponse, mockDispute); + bondEscalationModule.settleBondEscalation(mockRequest, _response, _dispute); // Check: is the bond escalation status properly updated? assertEq( uint256(bondEscalationModule.getEscalation(_requestId).status), diff --git a/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol b/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol index 7eb0e1ac..38d693f5 100644 --- a/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol @@ -11,6 +11,7 @@ import {FixedPointMathLib} from 'solmate/utils/FixedPointMathLib.sol'; import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +import {IValidator} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IValidator.sol'; import { BondEscalationResolutionModule, @@ -155,12 +156,24 @@ contract BaseTest is Test, Helpers { mockRequest.resolutionModuleData = abi.encode(_params); _requestId = _getId(mockRequest); - mockResponse.requestId = _requestId; + mockResponse = _getResponse(mockRequest, proposer); _responseId = _getId(mockResponse); - mockDispute.requestId = _requestId; - mockDispute.responseId = _responseId; + mockDispute = _getDispute(mockRequest, mockResponse); _disputeId = _getId(mockDispute); + + vm.mockCall(address(oracle), abi.encodeCall(IOracle.responseCreatedAt, (_responseId)), abi.encode(block.timestamp)); + vm.mockCall(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(block.timestamp)); + } + + function _getRequestResponseDispute(IBondEscalationResolutionModule.RequestParameters memory _params) + internal + returns (IOracle.Request memory _request, IOracle.Response memory _response, IOracle.Dispute memory _dispute) + { + _request = mockRequest; + _request.resolutionModuleData = abi.encode(_params); + _response = _getResponse(mockRequest, proposer); + _dispute = _getDispute(mockRequest, mockResponse); } } @@ -256,7 +269,8 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { IBondEscalationResolutionModule.RequestParameters memory _params ) public assumeFuzzable(address(_params.accountingExtension)) { // Check: does it revert if the dispute body is invalid? - vm.expectRevert(IModule.Module_InvalidDisputeBody.selector); + mockDispute.requestId = bytes32(0); + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount); // 1. BondEscalationResolutionModule_NotEscalated @@ -308,7 +322,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { _mockAndExpect( address(_params.accountingExtension), abi.encodeCall( - IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, _params.bondToken, _pledgeAmount) + IBondEscalationAccounting.pledge, (pledgerFor, mockRequest, mockDispute, _params.bondToken, _pledgeAmount) ), abi.encode() ); @@ -348,7 +362,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { _mockAndExpect( address(_params.accountingExtension), abi.encodeCall( - IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, _params.bondToken, _pledgeAmount) + IBondEscalationAccounting.pledge, (pledgerFor, mockRequest, mockDispute, _params.bondToken, _pledgeAmount) ), abi.encode() ); @@ -397,7 +411,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { // Mock and expect IBondEscalationAccounting.pledge to be called _mockAndExpect( address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, token, _pledgeAmount)), + abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, mockRequest, mockDispute, token, _pledgeAmount)), abi.encode() ); @@ -448,7 +462,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { // Mock and expect IBondEscalationAccounting.pledge to be called _mockAndExpect( address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, token, _pledgeAmount)), + abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, mockRequest, mockDispute, token, _pledgeAmount)), abi.encode() ); @@ -496,7 +510,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { // Mock and expect IBondEscalationAccounting.pledge to be called _mockAndExpect( address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, _requestId, _disputeId, token, _pledgeAmount)), + abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerFor, mockRequest, mockDispute, token, _pledgeAmount)), abi.encode() ); @@ -541,7 +555,8 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { IBondEscalationResolutionModule.RequestParameters memory _params ) public assumeFuzzable(address(_params.accountingExtension)) { // Check: does it revert if the dispute body is invalid? - vm.expectRevert(IModule.Module_InvalidDisputeBody.selector); + mockDispute.requestId = bytes32(0); + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount); // 1. BondEscalationResolutionModule_NotEscalated @@ -593,7 +608,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { _mockAndExpect( address(_params.accountingExtension), abi.encodeCall( - IBondEscalationAccounting.pledge, (pledgerAgainst, _requestId, _disputeId, _params.bondToken, _pledgeAmount) + IBondEscalationAccounting.pledge, (pledgerAgainst, mockRequest, mockDispute, _params.bondToken, _pledgeAmount) ), abi.encode() ); @@ -632,7 +647,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { address(requestParameters.accountingExtension), abi.encodeCall( IBondEscalationAccounting.pledge, - (pledgerAgainst, _requestId, _disputeId, requestParameters.bondToken, _pledgeAmount) + (pledgerAgainst, mockRequest, mockDispute, requestParameters.bondToken, _pledgeAmount) ), abi.encode() ); @@ -681,7 +696,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { // Mock and expect IBondEscalationAccounting.pledge to be called _mockAndExpect( address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, _requestId, _disputeId, token, _pledgeAmount)), + abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, mockRequest, mockDispute, token, _pledgeAmount)), abi.encode() ); @@ -732,7 +747,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { // Mock and expect IBondEscalationAccounting.pledge to be called _mockAndExpect( address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, _requestId, _disputeId, token, _pledgeAmount)), + abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, mockRequest, mockDispute, token, _pledgeAmount)), abi.encode() ); @@ -780,7 +795,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { // Mock and expect IBondEscalationAccounting.pledge to be called _mockAndExpect( address(accounting), - abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, _requestId, _disputeId, token, _pledgeAmount)), + abi.encodeCall(IBondEscalationAccounting.pledge, (pledgerAgainst, mockRequest, mockDispute, token, _pledgeAmount)), abi.encode() ); @@ -1014,7 +1029,8 @@ contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { IBondEscalationResolutionModule.RequestParameters memory _params ) public assumeFuzzable(address(_params.accountingExtension)) { // Check: does it revert if the dispute body is invalid? - vm.expectRevert(IModule.Module_InvalidDisputeBody.selector); + mockDispute.requestId = bytes32(0); + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); module.claimPledge(mockRequest, mockDispute); (,, bytes32 _disputeId) = _setResolutionModuleData(_params); @@ -1063,7 +1079,7 @@ contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { _mockAndExpect( address(_params.accountingExtension), abi.encodeCall( - accounting.releasePledge, (_requestId, _disputeId, _randomPledger, _params.bondToken, _amountToRelease) + accounting.releasePledge, (mockRequest, mockDispute, _randomPledger, _params.bondToken, _amountToRelease) ), abi.encode(true) ); @@ -1117,7 +1133,7 @@ contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { _mockAndExpect( address(_params.accountingExtension), abi.encodeCall( - accounting.releasePledge, (_requestId, _disputeId, _randomPledger, _params.bondToken, _amountToRelease) + accounting.releasePledge, (mockRequest, mockDispute, _randomPledger, _params.bondToken, _amountToRelease) ), abi.encode(true) ); @@ -1163,7 +1179,7 @@ contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { _mockAndExpect( address(_params.accountingExtension), abi.encodeCall( - accounting.releasePledge, (_requestId, _disputeId, _randomPledger, _params.bondToken, _userForPledge) + accounting.releasePledge, (mockRequest, mockDispute, _randomPledger, _params.bondToken, _userForPledge) ), abi.encode(true) ); @@ -1172,7 +1188,7 @@ contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { _mockAndExpect( address(_params.accountingExtension), abi.encodeCall( - accounting.releasePledge, (_requestId, _disputeId, _randomPledger, _params.bondToken, _userAgainstPledge) + accounting.releasePledge, (mockRequest, mockDispute, _randomPledger, _params.bondToken, _userAgainstPledge) ), abi.encode(true) ); diff --git a/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol b/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol index ebbe6419..7eb76aea 100644 --- a/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol @@ -10,6 +10,7 @@ import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +import {IValidator} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IValidator.sol'; import { ERC20ResolutionModule, @@ -165,8 +166,15 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { timeUntilDeadline: votingTimeWindow }) ); - mockDispute.requestId = _getId(mockRequest); - bytes32 _disputeId = _getId(mockDispute); + + // Compute proper IDs + bytes32 _requestId = _getId(mockRequest); + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + // Mock and expect IOracle.disputeCreatedAt to be called + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); // Store mock escalation data with startTime 100_000 module.forTest_setStartTime(_disputeId, 100_000); @@ -175,7 +183,7 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { _mockAndExpect( address(accountingExtension), abi.encodeWithSignature( - 'bond(address,bytes32,address,uint256)', _voter, mockDispute.requestId, token, _amountOfVotes + 'bond(address,bytes32,address,uint256)', _voter, _dispute.requestId, token, _amountOfVotes ), abi.encode() ); @@ -192,7 +200,7 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { emit VoteCast(_voter, _disputeId, _amountOfVotes); vm.prank(_voter); - module.castVote(mockRequest, mockDispute, _amountOfVotes); + module.castVote(mockRequest, _dispute, _amountOfVotes); (, uint256 _totalVotes) = module.escalations(_disputeId); // Check: totalVotes is updated? @@ -207,7 +215,8 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { */ function test_revertIfInvalidDisputeBody(uint256 _numberOfVotes) public { // Check: does it revert if the dispute body is invalid? - vm.expectRevert(IModule.Module_InvalidDisputeBody.selector); + mockDispute.requestId = bytes32(0); + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); module.castVote(mockRequest, mockDispute, _numberOfVotes); } @@ -215,12 +224,18 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { * @notice Test that `castVote` reverts if called with `_disputeId` of a non-escalated dispute. */ function test_revertIfNotEscalated(uint256 _numberOfVotes) public { + // Compute proper IDs bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + // Mock and expect IOracle.disputeCreatedAt to be called + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); // Check: reverts if called with `_disputeId` of a non-escalated dispute? vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_DisputeNotEscalated.selector); - module.castVote(mockRequest, mockDispute, _numberOfVotes); + module.castVote(mockRequest, _dispute, _numberOfVotes); } /** @@ -235,9 +250,15 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { timeUntilDeadline: _votingTimeWindow }) ); + + // Compute proper IDs bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + // Mock and expect IOracle.disputeCreatedAt to be called + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); _mockAndExpect( address(oracle), abi.encodeCall(IOracle.disputeStatus, (_disputeId)), abi.encode(IOracle.DisputeStatus.Won) @@ -247,7 +268,7 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { // Check: reverts if dispute is already resolved? vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_AlreadyResolved.selector); - module.castVote(mockRequest, mockDispute, _amountOfVotes); + module.castVote(mockRequest, _dispute, _amountOfVotes); } /** @@ -265,9 +286,15 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { timeUntilDeadline: votingTimeWindow }) ); + + // Compute proper IDs bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + // Mock and expect IOracle.disputeCreatedAt to be called + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); _mockAndExpect( address(oracle), abi.encodeCall(IOracle.disputeStatus, (_disputeId)), abi.encode(IOracle.DisputeStatus.Escalated) @@ -280,7 +307,7 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { // Check: reverts if trying to cast vote after voting phase? vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_VotingPhaseOver.selector); - module.castVote(mockRequest, mockDispute, _numberOfVotes); + module.castVote(mockRequest, _dispute, _numberOfVotes); } } @@ -392,7 +419,8 @@ contract ERC20ResolutionModule_Unit_ClaimVote is BaseTest { */ function test_revertIfInvalidDisputeBody() public { // Check: does it revert if the dispute body is invalid? - vm.expectRevert(IModule.Module_InvalidDisputeBody.selector); + mockDispute.requestId = bytes32(0); + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); module.claimVote(mockRequest, mockDispute); } @@ -408,7 +436,15 @@ contract ERC20ResolutionModule_Unit_ClaimVote is BaseTest { timeUntilDeadline: 1000 }) ); - mockDispute.requestId = _getId(mockRequest); + + // Compute proper IDs + bytes32 _requestId = _getId(mockRequest); + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + // Mock and expect IOracle.disputeCreatedAt to be called + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); module.forTest_setStartTime(_getId(mockDispute), block.timestamp); // Expect an error to be thrown @@ -416,7 +452,7 @@ contract ERC20ResolutionModule_Unit_ClaimVote is BaseTest { // Claim the refund vm.prank(_voter); - module.claimVote(mockRequest, mockDispute); + module.claimVote(mockRequest, _dispute); } /** @@ -432,21 +468,24 @@ contract ERC20ResolutionModule_Unit_ClaimVote is BaseTest { }) ); - // Prepare the dispute - mockDispute.requestId = _getId(mockRequest); - module.forTest_setStartTime(_getId(mockDispute), block.timestamp); - module.forTest_setVotes(_getId(mockDispute), _voter, _amount); + // Compute proper IDs + bytes32 _requestId = _getId(mockRequest); + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + // Mock and expect IOracle.disputeCreatedAt to be called + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); // Expect the bond to be released _mockAndExpect( address(accountingExtension), - abi.encodeCall(accountingExtension.release, (_voter, mockDispute.requestId, token, _amount)), + abi.encodeCall(accountingExtension.release, (_voter, _dispute.requestId, token, _amount)), abi.encode() ); vm.warp(block.timestamp + 1000); - bytes32 _disputeId = _getId(mockDispute); module.forTest_setVotes(_disputeId, _voter, _amount); // Expect the event to be emitted @@ -455,7 +494,7 @@ contract ERC20ResolutionModule_Unit_ClaimVote is BaseTest { // Claim the refund vm.prank(_voter); - module.claimVote(mockRequest, mockDispute); + module.claimVote(mockRequest, _dispute); } } diff --git a/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol b/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol index 2e8ba6c6..5b4d6264 100644 --- a/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol @@ -7,6 +7,7 @@ import {Helpers} from '../../../utils/Helpers.sol'; import {IModule} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IModule.sol'; import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; +import {IValidator} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IValidator.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import { @@ -230,7 +231,8 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { */ function test_revertIfInvalidDisputeBody(bytes32 _commitment) public { // Check: does it revert if the dispute body is invalid? - vm.expectRevert(IModule.Module_InvalidDisputeBody.selector); + mockDispute.requestId = bytes32(0); + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); module.commitVote(mockRequest, mockDispute, _commitment); } @@ -240,15 +242,16 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { function test_revertIfNonExistentDispute(bytes32 _commitment) public { // Compute proper IDs bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); // Mock and expect IOracle.disputeCreatedAt to be called _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(0)); // Check: does it revert if no dispute exists? - vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_NonExistentDispute.selector); - module.commitVote(mockRequest, mockDispute, _commitment); + vm.expectRevert(IValidator.Validator_InvalidDispute.selector); + module.commitVote(mockRequest, _dispute, _commitment); } /** @@ -343,8 +346,9 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { function test_revertIfNotEscalated(bytes32 _commitment) public { // Compute proper IDs bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); // Mock and expect IOracle.disputeCreatedAt to be called _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); @@ -355,7 +359,7 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { // Check: reverts if dispute is not escalated? == no escalation data vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_DisputeNotEscalated.selector); - module.commitVote(mockRequest, mockDispute, _commitment); + module.commitVote(mockRequest, _dispute, _commitment); } /** @@ -415,10 +419,14 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { }) ); - // Compute proper ids + // Compute proper IDs bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + // Mock and expect IOracle.disputeCreatedAt to be called + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); // Store mock escalation data with startTime 100_000 module.forTest_setStartTime(_disputeId, 100_000); @@ -443,7 +451,7 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { emit VoteRevealed(_voter, _disputeId, _amountOfVotes); vm.prank(_voter); - module.revealVote(mockRequest, mockDispute, _amountOfVotes, _salt); + module.revealVote(mockRequest, _dispute, _amountOfVotes, _salt); (, uint256 _totalVotes) = module.escalations(_disputeId); // Check: is totalVotes updated? @@ -459,7 +467,8 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { */ function test_revertIfInvalidDisputeBody(uint256 _numberOfVotes, bytes32 _salt) public { // Check: does it revert if the dispute body is invalid? - vm.expectRevert(IModule.Module_InvalidDisputeBody.selector); + mockDispute.requestId = bytes32(0); + vm.expectRevert(IValidator.Validator_InvalidDisputeBody.selector); module.revealVote(mockRequest, mockDispute, _numberOfVotes, _salt); } @@ -467,9 +476,14 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { * @notice Test that `revealVote` reverts if called with `_disputeId` of a non-escalated dispute. */ function test_revertIfNotEscalated(uint256 _numberOfVotes, bytes32 _salt) public { - // Compute proper id + // Compute proper IDs bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + // Mock and expect IOracle.disputeCreatedAt to be called + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); // Check: does it revert if the dispute is not escalated? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_DisputeNotEscalated.selector); @@ -493,10 +507,14 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { }) ); - // Compute proper ids + // Compute proper IDs bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, _disputeId), abi.encode(1)); + module.forTest_setStartTime(_disputeId, 100_000); // Jump to timestamp @@ -505,11 +523,11 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { if (_timestamp <= 140_000) { // Check: does it revert if trying to reveal during the committing phase? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_OnGoingCommittingPhase.selector); - module.revealVote(mockRequest, mockDispute, _numberOfVotes, _salt); + module.revealVote(mockRequest, _dispute, _numberOfVotes, _salt); } else { // Check: does it revert if trying to reveal after the revealing phase? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_RevealingPhaseOver.selector); - module.revealVote(mockRequest, mockDispute, _numberOfVotes, _salt); + module.revealVote(mockRequest, _dispute, _numberOfVotes, _salt); } } @@ -540,10 +558,14 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { }) ); - // Compute proper ids + // Compute proper IDs bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + // Mock and expect IOracle.disputeCreatedAt to be called + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); module.forTest_setStartTime(_disputeId, 100_000); @@ -557,18 +579,18 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { // Check: does it revert if the commitment is not valid? (wrong salt) vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); - module.revealVote(mockRequest, mockDispute, _amountOfVotes, _wrongSalt); + module.revealVote(mockRequest, _dispute, _amountOfVotes, _wrongSalt); // Check: does it revert if the commitment is not valid? (wrong amount of votes) vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); - module.revealVote(mockRequest, mockDispute, _wrongAmountOfVotes, _salt); + module.revealVote(mockRequest, _dispute, _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(mockRequest, mockDispute, _amountOfVotes, _salt); + module.revealVote(mockRequest, _dispute, _amountOfVotes, _salt); } } @@ -669,15 +691,13 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { }) ); - // Compute proper ids - bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + // Compute proper IDs + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); module.forTest_setStartTime(_disputeId, 1); - // Mock and expect IOracle.disputeCreatedAt to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); // Mock and expect IOracle.disputeStatus to be called _mockAndExpect( address(oracle), abi.encodeCall(IOracle.disputeStatus, (_disputeId)), abi.encode(IOracle.DisputeStatus.Escalated) @@ -690,12 +710,12 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { // 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, mockRequest, mockResponse, mockDispute); + module.resolveDispute(_disputeId, mockRequest, _response, _dispute); } 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, mockRequest, mockResponse, mockDispute); + module.resolveDispute(_disputeId, mockRequest, _response, _dispute); } } @@ -711,15 +731,13 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { }) ); - // Compute proper ids - bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + // Compute proper IDs + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); module.forTest_setStartTime(_disputeId, 1); - // Mock and expect IOracle.disputeCreatedAt to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); // Mock and expect IOracle.disputeStatus to be called _mockAndExpect( address(oracle), abi.encodeCall(IOracle.disputeStatus, (_disputeId)), abi.encode(IOracle.DisputeStatus.Active) @@ -728,7 +746,7 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { // Check: does it revert if the dispute is already resolved? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_AlreadyResolved.selector); vm.prank(address(oracle)); - module.resolveDispute(_disputeId, mockRequest, mockResponse, mockDispute); + module.resolveDispute(_disputeId, mockRequest, _response, _dispute); } function test_revertIfWon() public { @@ -743,15 +761,13 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { }) ); - // Compute proper ids - bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + // Compute proper IDs + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); module.forTest_setStartTime(_disputeId, 1); - // Mock and expect IOracle.disputeCreatedAt to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); // Mock and expect IOracle.disputeStatus to be called _mockAndExpect( address(oracle), abi.encodeCall(IOracle.disputeStatus, (_disputeId)), abi.encode(IOracle.DisputeStatus.Won) @@ -760,7 +776,7 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { // Check: does it revert if the dispute is already resolved? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_AlreadyResolved.selector); vm.prank(address(oracle)); - module.resolveDispute(_disputeId, mockRequest, mockResponse, mockDispute); + module.resolveDispute(_disputeId, mockRequest, _response, _dispute); } function test_revertIfLost() public { @@ -775,15 +791,13 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { }) ); - // Compute proper ids - bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + // Compute proper IDs + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); module.forTest_setStartTime(_disputeId, 1); - // Mock and expect IOracle.disputeCreatedAt to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); // Mock and expect IOracle.disputeStatus to be called _mockAndExpect( address(oracle), abi.encodeCall(IOracle.disputeStatus, (_disputeId)), abi.encode(IOracle.DisputeStatus.Lost) @@ -792,7 +806,7 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { // Check: does it revert if the dispute is already resolved? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_AlreadyResolved.selector); vm.prank(address(oracle)); - module.resolveDispute(_disputeId, mockRequest, mockResponse, mockDispute); + module.resolveDispute(_disputeId, mockRequest, _response, _dispute); } function test_revertIfNonResolve() public { @@ -807,15 +821,13 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { }) ); - // Compute proper ids - bytes32 _requestId = _getId(mockRequest); - mockDispute.requestId = _requestId; - bytes32 _disputeId = _getId(mockDispute); + // Compute proper IDs + IOracle.Response memory _response = _getResponse(mockRequest, proposer); + IOracle.Dispute memory _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); module.forTest_setStartTime(_disputeId, 1); - // Mock and expect IOracle.disputeCreatedAt to be called - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); // Mock and expect IOracle.disputeStatus to be called _mockAndExpect( address(oracle), @@ -826,6 +838,6 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { // Check: does it revert if the dispute is already resolved? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_AlreadyResolved.selector); vm.prank(address(oracle)); - module.resolveDispute(_disputeId, mockRequest, mockResponse, mockDispute); + module.resolveDispute(_disputeId, mockRequest, _response, _dispute); } } diff --git a/solidity/test/unit/modules/response/BondedResponseModule.t.sol b/solidity/test/unit/modules/response/BondedResponseModule.t.sol index 71d74ea0..bb299960 100644 --- a/solidity/test/unit/modules/response/BondedResponseModule.t.sol +++ b/solidity/test/unit/modules/response/BondedResponseModule.t.sol @@ -432,7 +432,6 @@ contract BondedResponseModule_Unit_ReleaseUnutilizedResponse is BaseTest { IERC20 _token, uint256 _bondSize, uint256 _deadline, - address _proposer, bytes32 _finalizedResponseId ) public { // Setting the response module data @@ -441,7 +440,7 @@ contract BondedResponseModule_Unit_ReleaseUnutilizedResponse is BaseTest { // Updating IDs bytes32 _requestId = _getId(mockRequest); mockResponse.requestId = _requestId; - mockResponse.proposer = _proposer; + mockResponse.proposer = proposer; bytes32 _responseId = _getId(mockResponse); // Can't claim back the bond of the response that was finalized @@ -456,10 +455,12 @@ contract BondedResponseModule_Unit_ReleaseUnutilizedResponse is BaseTest { address(oracle), abi.encodeCall(IOracle.finalizedResponseId, (_requestId)), abi.encode(_finalizedResponseId) ); + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.responseCreatedAt, (_responseId)), abi.encode(block.number)); + // Mock and expect IAccountingExtension.release to be called _mockAndExpect( address(accounting), - abi.encodeCall(IAccountingExtension.release, (_proposer, _getId(mockRequest), _token, _bondSize)), + abi.encodeCall(IAccountingExtension.release, (proposer, _getId(mockRequest), _token, _bondSize)), abi.encode(true) ); @@ -485,9 +486,8 @@ contract BondedResponseModule_Unit_ReleaseUnutilizedResponse is BaseTest { // Updating IDs bytes32 _requestId = _getId(mockRequest); - mockResponse.requestId = _requestId; - mockResponse.proposer = _proposer; - bytes32 _responseId = _getId(mockResponse); + IOracle.Response memory _response = _getResponse(mockRequest, _proposer); + bytes32 _responseId = _getId(_response); // Mock and expect IOracle.disputeOf to be called _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeOf, (_responseId)), abi.encode(bytes32(0))); @@ -495,10 +495,12 @@ contract BondedResponseModule_Unit_ReleaseUnutilizedResponse is BaseTest { // Mock and expect IOracle.finalizedResponseId to be called _mockAndExpect(address(oracle), abi.encodeCall(IOracle.finalizedResponseId, (_requestId)), abi.encode(0)); + _mockAndExpect(address(oracle), abi.encodeCall(IOracle.responseCreatedAt, (_responseId)), abi.encode(block.number)); + // Check: reverts? vm.expectRevert(IBondedResponseModule.BondedResponseModule_InvalidReleaseParameters.selector); - bondedResponseModule.releaseUnutilizedResponse(mockRequest, mockResponse); + bondedResponseModule.releaseUnutilizedResponse(mockRequest, _response); } /** @@ -517,9 +519,8 @@ contract BondedResponseModule_Unit_ReleaseUnutilizedResponse is BaseTest { // Updating IDs bytes32 _requestId = _getId(mockRequest); - mockResponse.requestId = _requestId; - mockResponse.proposer = _proposer; - bytes32 _responseId = _getId(mockResponse); + IOracle.Response memory _response = _getResponse(mockRequest, _proposer); + bytes32 _responseId = _getId(_response); // Make sure there is a dispute vm.assume(_disputeId > 0); @@ -536,6 +537,10 @@ contract BondedResponseModule_Unit_ReleaseUnutilizedResponse is BaseTest { address(oracle), abi.encodeCall(IOracle.finalizedResponseId, (_requestId)), abi.encode(_finalizedResponseId) ); + _mockAndExpect( + address(oracle), abi.encodeCall(IOracle.responseCreatedAt, (_responseId)), abi.encode(block.timestamp) + ); + // We're going to test all possible dispute statuses for (uint256 _i = 0; _i < uint256(type(IOracle.DisputeStatus).max); _i++) { IOracle.DisputeStatus _status = IOracle.DisputeStatus(_i); @@ -554,7 +559,7 @@ contract BondedResponseModule_Unit_ReleaseUnutilizedResponse is BaseTest { vm.expectRevert(IBondedResponseModule.BondedResponseModule_InvalidReleaseParameters.selector); } - bondedResponseModule.releaseUnutilizedResponse(mockRequest, mockResponse); + bondedResponseModule.releaseUnutilizedResponse(mockRequest, _response); } } } diff --git a/solidity/test/utils/Helpers.sol b/solidity/test/utils/Helpers.sol index 42b3d001..993d8aac 100644 --- a/solidity/test/utils/Helpers.sol +++ b/solidity/test/utils/Helpers.sol @@ -6,18 +6,36 @@ import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfac import {DSTestPlus} from '@defi-wonderland/solidity-utils/solidity/test/DSTestPlus.sol'; contract Helpers is DSTestPlus, TestConstants { - // 100% random sequence of bytes representing request, response, or dispute id - bytes32 public mockId = bytes32('69'); - // Placeholder addresses address public disputer = makeAddr('disputer'); address public proposer = makeAddr('proposer'); // Mock objects - IOracle.Request public mockRequest; - IOracle.Response public mockResponse = IOracle.Response({proposer: proposer, requestId: mockId, response: bytes('')}); + IOracle.Request public mockRequest = IOracle.Request({ + requestModule: address(0), + responseModule: address(0), + disputeModule: address(0), + resolutionModule: address(0), + finalityModule: address(0), + requestModuleData: bytes(''), + responseModuleData: bytes(''), + disputeModuleData: bytes(''), + resolutionModuleData: bytes(''), + finalityModuleData: bytes(''), + requester: address(this), + nonce: 1 + }); + bytes32 _mockRequestId = keccak256(abi.encode(mockRequest)); + + IOracle.Response public mockResponse = + IOracle.Response({proposer: proposer, requestId: _mockRequestId, response: bytes('')}); + + bytes32 _mockResponseId = keccak256(abi.encode(mockResponse)); + IOracle.Dispute public mockDispute = - IOracle.Dispute({disputer: disputer, responseId: mockId, proposer: proposer, requestId: mockId}); + IOracle.Dispute({disputer: disputer, responseId: _mockResponseId, proposer: proposer, requestId: _mockRequestId}); + + bytes32 _mockDisputeId = keccak256(abi.encode(mockDispute)); // Shared events that all modules emit event RequestFinalized(bytes32 indexed _requestId, IOracle.Response _response, address _finalizer); @@ -27,6 +45,38 @@ contract Helpers is DSTestPlus, TestConstants { _; } + function _getResponse( + IOracle.Request memory _request, + address _proposer + ) internal pure returns (IOracle.Response memory _response) { + return IOracle.Response({proposer: _proposer, requestId: _getId(_request), response: bytes('')}); + } + + function _getDispute( + IOracle.Request memory _request, + IOracle.Response memory _response + ) internal view returns (IOracle.Dispute memory _dispute) { + return IOracle.Dispute({ + disputer: disputer, + responseId: _getId(_response), + proposer: proposer, + requestId: _getId(_request) + }); + } + + function _getResponseAndDispute(IOracle _oracle) + internal + returns (IOracle.Response memory _response, IOracle.Dispute memory _dispute) + { + // Compute proper IDs + _response = _getResponse(mockRequest, proposer); + _dispute = _getDispute(mockRequest, _response); + bytes32 _disputeId = _getId(_dispute); + + // Mock and expect IOracle.disputeCreatedAt to be called + _mockAndExpect(address(_oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_disputeId)), abi.encode(1)); + } + /** * @notice Ensures that a fuzzed address can be used for deployment and calls * diff --git a/yarn.lock b/yarn.lock index be7ec18e..68ccce90 100644 --- a/yarn.lock +++ b/yarn.lock @@ -193,10 +193,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@defi-wonderland/prophet-core-contracts@0.0.0-c25103ea": - version "0.0.0-c25103ea" - resolved "https://registry.yarnpkg.com/@defi-wonderland/prophet-core-contracts/-/prophet-core-contracts-0.0.0-c25103ea.tgz#e7a83271251d6ffbe0644c5971e6748d41ae9255" - integrity sha512-VCIeXwutXaih/ZF0JeqBjqkIs1ALWoFmn9OMeM5ZGcRZfx3JSV+axhi4YiIQVfrTLxICyu2hnbIEV7T1OmLVMQ== +"@defi-wonderland/prophet-core-contracts@0.0.0-d01bc1a0": + version "0.0.0-d01bc1a0" + resolved "https://registry.yarnpkg.com/@defi-wonderland/prophet-core-contracts/-/prophet-core-contracts-0.0.0-d01bc1a0.tgz#ee4e8d970289a26966f6565b2f691d68d7b4232a" + integrity sha512-n4Dl1QgQAZafOtV7ef/fSoew2qlxWSdS389Z6PdIn7LxrHrzzRJi+nmJ1DJazMvMuhk/0dZbMhnaXMBi05E1zQ== "@defi-wonderland/solidity-utils@0.0.0-3e9c8e8b": version "0.0.0-3e9c8e8b"