Skip to content

Commit

Permalink
feat: improving bond escalation test
Browse files Browse the repository at this point in the history
  • Loading branch information
ashitakah committed Oct 7, 2024
1 parent 2d91875 commit 8a6a8fa
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ contract BondEscalationModule is Module, IBondEscalationModule {
// Refund the disputer, the bond escalation status stays Escalated
_newStatus = BondEscalationStatus.Escalated;
_params.accountingExtension.release({
_requestId: _dispute.requestId,
_bonder: _dispute.disputer,
_requestId: _dispute.requestId,
_token: _params.bondToken,
_amount: _params.bondSize
});
Expand Down
219 changes: 215 additions & 4 deletions solidity/test/integration/EscalateDispute.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import './IntegrationBase.sol';
contract Integration_EscalateDispute is IntegrationBase {
bytes32 internal _requestId;
bytes32 internal _disputeId;
uint256 internal _pledgeSize = _expectedBondSize;

function setUp() public override {
super.setUp();
Expand All @@ -29,7 +30,7 @@ contract Integration_EscalateDispute is IntegrationBase {
accountingExtension: _bondEscalationAccounting,
bondToken: usdc,
bondSize: _expectedBondSize,
deadline: _expectedDeadline,
deadline: _expectedDeadline * 2,
disputeWindow: _baseDisputeWindow
})
);
Expand All @@ -48,13 +49,13 @@ contract Integration_EscalateDispute is IntegrationBase {

mockRequest.disputeModule = address(_bondEscalationModule);

_resetMockIds();

vm.startPrank(requester);
_bondEscalationAccounting.approveModule(address(_requestModule));
_requestId = oracle.createRequest(mockRequest, _ipfsHash);
vm.stopPrank();

_resetMockIds();

// Propose a response and dispute it
_deposit(_bondEscalationAccounting, proposer, usdc, _expectedBondSize);
vm.startPrank(proposer);
Expand All @@ -69,14 +70,43 @@ contract Integration_EscalateDispute is IntegrationBase {
vm.stopPrank();
}

function test_escalateDispute() public {
function test_escalateDisputeResolveNoResolution() public {
// Escalate dispute reverts if dispute does not exist
mockDispute.requestId = bytes32(0);
vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector);
oracle.escalateDispute(mockRequest, mockResponse, mockDispute);

mockDispute.requestId = _requestId;

// Escalate dispute reverts if escalation is not over
vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationNotOver.selector);
oracle.escalateDispute(mockRequest, mockResponse, mockDispute);

// Check that the dispute is active
assertTrue(
_bondEscalationModule.getEscalation(_requestId).status == IBondEscalationModule.BondEscalationStatus.Active
);

// Pledge for dispute
_deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize);
vm.prank(disputer);
_bondEscalationModule.pledgeForDispute(mockRequest, mockDispute);

// Mine blocks to pass the escalation deadline
_mineBlocks(_blocksDeadline + 1);

// Escalate dispute reverts if dispute is not escalatable
vm.expectRevert(IBondEscalationModule.BondEscalationModule_NotEscalatable.selector);
oracle.escalateDispute(mockRequest, mockResponse, mockDispute);

// Roll back the blocks
vm.warp(block.timestamp - (_blocksDeadline + 1) * BLOCK_TIME);

// Pledge against dispute
_deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize);
vm.prank(proposer);
_bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute);

// The oracle should call the dispute module
vm.expectCall(
address(_bondEscalationModule),
Expand Down Expand Up @@ -112,5 +142,186 @@ contract Integration_EscalateDispute is IntegrationBase {
// Escalate dispute reverts if dispute is not active
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_CannotEscalate.selector, _disputeId));
oracle.escalateDispute(mockRequest, mockResponse, mockDispute);

// The bond escalation accounting should have been called to release the proposer's bond
vm.expectCall(
address(_bondEscalationAccounting),
abi.encodeCall(
IAccountingExtension.release, (mockDispute.disputer, mockDispute.requestId, usdc, _expectedBondSize)
)
);

// Resolve the dispute escalated with no resolution
_mockArbitrator.setAnswer(IOracle.DisputeStatus.NoResolution);
oracle.resolveDispute(mockRequest, mockResponse, mockDispute);

// The arbitrator module should have updated the status of the dispute
assertTrue(_arbitratorModule.getStatus(_disputeId) == IArbitratorModule.ArbitrationStatus.Resolved);

// The BondEscalationModule should have updated the status of the escalation
assertTrue(
_bondEscalationModule.getEscalation(_requestId).status == IBondEscalationModule.BondEscalationStatus.Escalated
);

// Oracle should have updated the status of the dispute
assertTrue(oracle.disputeStatus(_disputeId) == IOracle.DisputeStatus.NoResolution);

// Propose a new response and dispute it
_deposit(_bondEscalationAccounting, proposer, usdc, _expectedBondSize);
mockResponse.response = bytes('new response');
vm.prank(proposer);
oracle.proposeResponse(mockRequest, mockResponse);

// Get the new response id
mockDispute.responseId = _getId(mockResponse);

// The oracle should call the dispute module with the new dispute id
bytes32 _newDisputeId = _getId(mockDispute);

// The oracle should call the dispute module
vm.expectCall(address(oracle), abi.encodeCall(IOracle.escalateDispute, (mockRequest, mockResponse, mockDispute)));

vm.expectCall(
address(_bondEscalationModule),
abi.encodeCall(IDisputeModule.onDisputeStatusChange, (_newDisputeId, mockRequest, mockResponse, mockDispute))
);

_deposit(_bondEscalationAccounting, disputer, usdc, _expectedBondSize);
vm.prank(disputer);
oracle.disputeResponse(mockRequest, mockResponse, mockDispute);

// We check that the dispute was escalated
_disputeStatus = oracle.disputeStatus(_newDisputeId);
assertTrue(_disputeStatus == IOracle.DisputeStatus.Escalated);

// The BondEscalationModule should now have the escalation status escalated
_bondEscalation = _bondEscalationModule.getEscalation(_requestId);
assertTrue(_bondEscalation.status == IBondEscalationModule.BondEscalationStatus.Escalated);
}

function test_escalateDisputeResolveLost() public {
mockDispute.requestId = _requestId;

// The oracle should call the dispute module
vm.expectCall(
address(_bondEscalationModule),
abi.encodeCall(IDisputeModule.onDisputeStatusChange, (_disputeId, mockRequest, mockResponse, mockDispute))
);

// The oracle should call startResolution in the resolution module
vm.expectCall(
address(_arbitratorModule),
abi.encodeCall(IResolutionModule.startResolution, (_disputeId, mockRequest, mockResponse, mockDispute))
);

// The arbitrator module should call the arbitrator
vm.expectCall(
address(_mockArbitrator), abi.encodeCall(MockArbitrator.resolve, (mockRequest, mockResponse, mockDispute))
);

// We escalate the dispute
_mineBlocks(_blocksDeadline + 1);
oracle.escalateDispute(mockRequest, mockResponse, mockDispute);

// We check that the dispute was escalated
IOracle.DisputeStatus _disputeStatus = oracle.disputeStatus(_disputeId);
assertTrue(_disputeStatus == IOracle.DisputeStatus.Escalated);

// The BondEscalationModule should now have the escalation status escalated
IBondEscalationModule.BondEscalation memory _bondEscalation = _bondEscalationModule.getEscalation(_requestId);
assertTrue(_bondEscalation.status == IBondEscalationModule.BondEscalationStatus.Escalated);

// The ArbitratorModule should have updated the status of the dispute
assertTrue(_arbitratorModule.getStatus(_disputeId) == IArbitratorModule.ArbitrationStatus.Active);

// The bond escalation accounting should have been called to pay the proposer
vm.expectCall(
address(_bondEscalationAccounting),
abi.encodeCall(
IAccountingExtension.pay, (_requestId, mockDispute.disputer, mockResponse.proposer, usdc, _expectedBondSize)
)
);

// Resolve the dispute escalated with no resolution
_mockArbitrator.setAnswer(IOracle.DisputeStatus.Lost);
oracle.resolveDispute(mockRequest, mockResponse, mockDispute);

// The arbitrator module should have updated the status of the dispute
assertTrue(_arbitratorModule.getStatus(_disputeId) == IArbitratorModule.ArbitrationStatus.Resolved);

// The BondEscalationModule should have updated the status of the escalation
assertTrue(
_bondEscalationModule.getEscalation(_requestId).status == IBondEscalationModule.BondEscalationStatus.DisputerLost
);

// Oracle should have updated the status of the dispute
assertTrue(oracle.disputeStatus(_disputeId) == IOracle.DisputeStatus.Lost);
}

function test_escalateDisputeResolveWon() public {
mockDispute.requestId = _requestId;

// The oracle should call the dispute module
vm.expectCall(
address(_bondEscalationModule),
abi.encodeCall(IDisputeModule.onDisputeStatusChange, (_disputeId, mockRequest, mockResponse, mockDispute))
);

// The oracle should call startResolution in the resolution module
vm.expectCall(
address(_arbitratorModule),
abi.encodeCall(IResolutionModule.startResolution, (_disputeId, mockRequest, mockResponse, mockDispute))
);

// The arbitrator module should call the arbitrator
vm.expectCall(
address(_mockArbitrator), abi.encodeCall(MockArbitrator.resolve, (mockRequest, mockResponse, mockDispute))
);

// We escalate the dispute
_mineBlocks(_blocksDeadline + 1);
oracle.escalateDispute(mockRequest, mockResponse, mockDispute);

// We check that the dispute was escalated
IOracle.DisputeStatus _disputeStatus = oracle.disputeStatus(_disputeId);
assertTrue(_disputeStatus == IOracle.DisputeStatus.Escalated);

// The BondEscalationModule should now have the escalation status escalated
IBondEscalationModule.BondEscalation memory _bondEscalation = _bondEscalationModule.getEscalation(_requestId);
assertTrue(_bondEscalation.status == IBondEscalationModule.BondEscalationStatus.Escalated);

// The ArbitratorModule should have updated the status of the dispute
assertTrue(_arbitratorModule.getStatus(_disputeId) == IArbitratorModule.ArbitrationStatus.Active);

// The bond escalation accounting should have been called to pay the disputer
vm.expectCall(
address(_bondEscalationAccounting),
abi.encodeCall(
IAccountingExtension.pay, (_requestId, mockResponse.proposer, mockDispute.disputer, usdc, _expectedBondSize)
)
);

// The bond escalation accounting should have been called to release the proposer's bond
vm.expectCall(
address(_bondEscalationAccounting),
abi.encodeCall(
IAccountingExtension.release, (mockDispute.disputer, mockDispute.requestId, usdc, _expectedBondSize)
)
);

// Resolve the dispute escalated with no resolution
_mockArbitrator.setAnswer(IOracle.DisputeStatus.Won);
oracle.resolveDispute(mockRequest, mockResponse, mockDispute);

// The arbitrator module should have updated the status of the dispute
assertTrue(_arbitratorModule.getStatus(_disputeId) == IArbitratorModule.ArbitrationStatus.Resolved);

// The BondEscalationModule should have updated the status of the escalation
assertTrue(
_bondEscalationModule.getEscalation(_requestId).status == IBondEscalationModule.BondEscalationStatus.DisputerWon
);

// Oracle should have updated the status of the dispute
assertTrue(oracle.disputeStatus(_disputeId) == IOracle.DisputeStatus.Won);
}
}

0 comments on commit 8a6a8fa

Please sign in to comment.