Skip to content

Commit

Permalink
fix: escalations mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
0xShaito committed Dec 19, 2024
1 parent af33b14 commit c99d655
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 192 deletions.
196 changes: 77 additions & 119 deletions solidity/contracts/modules/dispute/BondEscalationModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ import {ModuleTypehash} from '../../utils/ModuleTypehash.sol';

contract BondEscalationModule is ModuleAccessController, IBondEscalationModule {
/// @inheritdoc IBondEscalationModule
mapping(bytes32 _requestId => mapping(address _pledger => uint256 pledges)) public pledgesForDispute;
mapping(bytes32 _disputeId => mapping(address _pledger => uint256 pledges)) public pledgesForDispute;

/// @inheritdoc IBondEscalationModule
mapping(bytes32 _requestId => mapping(address _pledger => uint256 pledges)) public pledgesAgainstDispute;
mapping(bytes32 _disputeId => mapping(address _pledger => uint256 pledges)) public pledgesAgainstDispute;

/**
* @notice Struct containing all the data for a given escalation.
*/
mapping(bytes32 _requestId => BondEscalation) internal _escalations;
// mapping(bytes32 _requestId => BondEscalation) internal _escalations;
mapping(bytes32 _disputeId => BondEscalation) internal _escalations;

constructor(IOracle _oracle) ModuleAccessController(_oracle) {}

Expand All @@ -39,7 +40,7 @@ contract BondEscalationModule is ModuleAccessController, IBondEscalationModule {
) external onlyOracle {
bytes32 _disputeId = _getId(_dispute);
RequestParameters memory _params = decodeRequestData(_request.disputeModuleData);
BondEscalation storage _escalation = _escalations[_dispute.requestId];
BondEscalation storage _escalation = _escalations[_disputeId];

if (block.timestamp >= ORACLE.responseCreatedAt(_dispute.responseId) + _params.disputeWindow) {
revert BondEscalationModule_DisputeWindowOver();
Expand Down Expand Up @@ -78,128 +79,85 @@ contract BondEscalationModule is ModuleAccessController, IBondEscalationModule {
IOracle.Dispute calldata _dispute
) external onlyOracle {
RequestParameters memory _params = decodeRequestData(_request.disputeModuleData);
BondEscalation storage _escalation = _escalations[_dispute.requestId];
BondEscalation storage _escalation = _escalations[_disputeId];
IOracle.DisputeStatus _disputeStatus = ORACLE.disputeStatus(_disputeId);
BondEscalationStatus _newStatus;

if (_disputeId == _escalation.disputeId) {
// The bond escalated (first) dispute has been updated
if (_disputeStatus == IOracle.DisputeStatus.Escalated) {
// The dispute has been escalated to the Resolution module
// Make sure the bond escalation deadline has passed and update the status
if (block.timestamp < ORACLE.disputeCreatedAt(_disputeId) + _params.bondEscalationDeadline) {
revert BondEscalationModule_BondEscalationNotOver();
}

if (
_escalation.status != BondEscalationStatus.Active
|| _escalation.amountOfPledgesForDispute != _escalation.amountOfPledgesAgainstDispute
) {
revert BondEscalationModule_NotEscalatable();
}

_newStatus = BondEscalationStatus.Escalated;
} else if (_disputeStatus == IOracle.DisputeStatus.NoResolution) {
// The resolution module failed to reach a resolution
// Refund the disputer and all pledgers, the bond escalation escalation status stays Escalated
_newStatus = BondEscalationStatus.Escalated;

if (_escalation.amountOfPledgesForDispute + _escalation.amountOfPledgesAgainstDispute > 0) {
_params.accountingExtension.onSettleBondEscalation({
_request: _request,
_dispute: _dispute,
_token: _params.bondToken,
_amountPerPledger: _params.bondSize,
_winningPledgersLength: _escalation.amountOfPledgesForDispute + _escalation.amountOfPledgesAgainstDispute
});
}
// The bond escalated (first) dispute has been updated
if (_disputeStatus == IOracle.DisputeStatus.Escalated) {
// The dispute has been escalated to the Resolution module
// Make sure the bond escalation deadline has passed and update the status
if (block.timestamp < ORACLE.disputeCreatedAt(_disputeId) + _params.bondEscalationDeadline) {
revert BondEscalationModule_BondEscalationNotOver();
}

_params.accountingExtension.release({
_requestId: _dispute.requestId,
_bonder: _dispute.disputer,
_token: _params.bondToken,
_amount: _params.bondSize
});
} else {
// One of the sides won
// Pay the winner (proposer/disputer) and the pledgers, the bond escalation status changes to DisputerWon/DisputerLost
bool _won = _disputeStatus == IOracle.DisputeStatus.Won;
_newStatus = _won ? BondEscalationStatus.DisputerWon : BondEscalationStatus.DisputerLost;

uint256 _pledgesForDispute = _escalation.amountOfPledgesForDispute;
uint256 _pledgesAgainstDispute = _escalation.amountOfPledgesAgainstDispute;

if (_pledgesAgainstDispute > 0 || _pledgesForDispute > 0) {
uint256 _amountToPay = _won
? _params.bondSize
+ FixedPointMathLib.mulDivDown(_pledgesAgainstDispute, _params.bondSize, _pledgesForDispute)
: _params.bondSize
+ FixedPointMathLib.mulDivDown(_pledgesForDispute, _params.bondSize, _pledgesAgainstDispute);

_params.accountingExtension.onSettleBondEscalation({
_request: _request,
_dispute: _dispute,
_token: _params.bondToken,
_amountPerPledger: _amountToPay,
_winningPledgersLength: _won ? _pledgesForDispute : _pledgesAgainstDispute
});
}

_params.accountingExtension.pay({
_requestId: _dispute.requestId,
_payer: _won ? _dispute.proposer : _dispute.disputer,
_receiver: _won ? _dispute.disputer : _dispute.proposer,
if (
_escalation.status != BondEscalationStatus.Active
|| _escalation.amountOfPledgesForDispute != _escalation.amountOfPledgesAgainstDispute
) {
revert BondEscalationModule_NotEscalatable();
}

_newStatus = BondEscalationStatus.Escalated;
} else if (_disputeStatus == IOracle.DisputeStatus.NoResolution) {
// The resolution module failed to reach a resolution
// Refund the disputer and all pledgers, the bond escalation escalation status stays Escalated
_newStatus = BondEscalationStatus.Escalated;

if (_escalation.amountOfPledgesForDispute + _escalation.amountOfPledgesAgainstDispute > 0) {
_params.accountingExtension.onSettleBondEscalation({
_request: _request,
_dispute: _dispute,
_token: _params.bondToken,
_amount: _params.bondSize
_amountPerPledger: _params.bondSize,
_winningPledgersLength: _escalation.amountOfPledgesForDispute + _escalation.amountOfPledgesAgainstDispute
});

if (_won) {
_params.accountingExtension.release({
_requestId: _dispute.requestId,
_bonder: _dispute.disputer,
_token: _params.bondToken,
_amount: _params.bondSize
});
}
}

_params.accountingExtension.release({
_requestId: _dispute.requestId,
_bonder: _dispute.disputer,
_token: _params.bondToken,
_amount: _params.bondSize
});
} else {
// The non-bond escalated (second and subsequent) dispute has been updated
if (_disputeStatus == IOracle.DisputeStatus.Escalated) {
// The dispute has been escalated to the Resolution module
// Update the bond escalation status to Escalated
_newStatus = BondEscalationStatus.Escalated;
} else if (_disputeStatus == IOracle.DisputeStatus.NoResolution) {
// The resolution module failed to reach a resolution
// Refund the disputer, the bond escalation status stays Escalated
_newStatus = BondEscalationStatus.Escalated;
_params.accountingExtension.release({
_bonder: _dispute.disputer,
_requestId: _dispute.requestId,
// One of the sides won
// Pay the winner (proposer/disputer) and the pledgers, the bond escalation status changes to DisputerWon/DisputerLost
bool _won = _disputeStatus == IOracle.DisputeStatus.Won;
_newStatus = _won ? BondEscalationStatus.DisputerWon : BondEscalationStatus.DisputerLost;

uint256 _pledgesForDispute = _escalation.amountOfPledgesForDispute;
uint256 _pledgesAgainstDispute = _escalation.amountOfPledgesAgainstDispute;

if (_pledgesAgainstDispute > 0 || _pledgesForDispute > 0) {
uint256 _amountToPay = _won
? _params.bondSize + FixedPointMathLib.mulDivDown(_pledgesAgainstDispute, _params.bondSize, _pledgesForDispute)
: _params.bondSize + FixedPointMathLib.mulDivDown(_pledgesForDispute, _params.bondSize, _pledgesAgainstDispute);

_params.accountingExtension.onSettleBondEscalation({
_request: _request,
_dispute: _dispute,
_token: _params.bondToken,
_amount: _params.bondSize
_amountPerPledger: _amountToPay,
_winningPledgersLength: _won ? _pledgesForDispute : _pledgesAgainstDispute
});
} else {
// One of the sides won
// Pay the winner (proposer/disputer), the bond escalation status changes to DisputerWon/DisputerLost
bool _won = _disputeStatus == IOracle.DisputeStatus.Won;
_newStatus = _won ? BondEscalationStatus.DisputerWon : BondEscalationStatus.DisputerLost;
}

_params.accountingExtension.pay({
_requestId: _dispute.requestId,
_payer: _won ? _dispute.proposer : _dispute.disputer,
_receiver: _won ? _dispute.disputer : _dispute.proposer,
_token: _params.bondToken,
_amount: _params.bondSize
});

_params.accountingExtension.pay({
if (_won) {
_params.accountingExtension.release({
_requestId: _dispute.requestId,
_payer: _won ? _dispute.proposer : _dispute.disputer,
_receiver: _won ? _dispute.disputer : _dispute.proposer,
_bonder: _dispute.disputer,
_token: _params.bondToken,
_amount: _params.bondSize
});

if (_won) {
_params.accountingExtension.release({
_requestId: _dispute.requestId,
_bonder: _dispute.disputer,
_token: _params.bondToken,
_amount: _params.bondSize
});
}
}
}

Expand Down Expand Up @@ -231,8 +189,8 @@ contract BondEscalationModule is ModuleAccessController, IBondEscalationModule {

address _pledger = _accessControl.user;

_escalations[_dispute.requestId].amountOfPledgesForDispute += 1;
pledgesForDispute[_dispute.requestId][_pledger] += 1;
_escalations[_disputeId].amountOfPledgesForDispute += 1;
pledgesForDispute[_disputeId][_pledger] += 1;
_params.accountingExtension.pledge({
_pledger: _pledger,
_request: _request,
Expand Down Expand Up @@ -263,8 +221,8 @@ contract BondEscalationModule is ModuleAccessController, IBondEscalationModule {

address _pledger = _accessControl.user;

_escalations[_dispute.requestId].amountOfPledgesAgainstDispute += 1;
pledgesAgainstDispute[_dispute.requestId][_pledger] += 1;
_escalations[_disputeId].amountOfPledgesAgainstDispute += 1;
pledgesAgainstDispute[_disputeId][_pledger] += 1;
_params.accountingExtension.pledge({
_pledger: _pledger,
_request: _request,
Expand All @@ -284,7 +242,7 @@ contract BondEscalationModule is ModuleAccessController, IBondEscalationModule {
) external {
(, bytes32 _disputeId) = _validateResponseAndDispute(_request, _response, _dispute);
RequestParameters memory _params = decodeRequestData(_request.disputeModuleData);
BondEscalation storage _escalation = _escalations[_dispute.requestId];
BondEscalation storage _escalation = _escalations[_disputeId];

uint256 _disputeCreatedAt = ORACLE.disputeCreatedAt(_disputeId);
if (block.timestamp < _disputeCreatedAt + _params.bondEscalationDeadline + _params.tyingBuffer) {
Expand Down Expand Up @@ -329,7 +287,7 @@ contract BondEscalationModule is ModuleAccessController, IBondEscalationModule {
) internal view returns (RequestParameters memory _params) {
bytes32 _disputeId = _validateDispute(_request, _dispute);

BondEscalation memory _escalation = _escalations[_dispute.requestId];
BondEscalation memory _escalation = _escalations[_disputeId];

if (_disputeId != _escalation.disputeId) {
revert BondEscalationModule_InvalidDispute();
Expand Down Expand Up @@ -375,8 +333,8 @@ contract BondEscalationModule is ModuleAccessController, IBondEscalationModule {
}

/// @inheritdoc IBondEscalationModule
function getEscalation(bytes32 _requestId) public view returns (BondEscalation memory _escalation) {
_escalation = _escalations[_requestId];
function getEscalation(bytes32 _disputeId) public view returns (BondEscalation memory _escalation) {
_escalation = _escalations[_disputeId];
}

/// @inheritdoc IModule
Expand Down
Loading

0 comments on commit c99d655

Please sign in to comment.