Skip to content

Commit

Permalink
Make claim and identifier parameters not user defined in arbitration …
Browse files Browse the repository at this point in the history
…policy UMA (storyprotocol#4)
  • Loading branch information
Spablob authored and kingster-will committed Jan 31, 2025
1 parent a3b3866 commit d078c6f
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ interface IArbitrationPolicy {
/// @notice Executes custom logic on raising dispute
/// @dev Enforced to be only callable by the DisputeModule
/// @param caller Address of the caller
/// @param disputeId The dispute id
/// @param data The arbitrary data used to raise the dispute
function onRaiseDispute(address caller, bytes calldata data) external;
function onRaiseDispute(address caller, uint256 disputeId, bytes calldata data) external;

/// @notice Executes custom logic on disputing judgement
/// @dev Enforced to be only callable by the DisputeModule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,10 @@ interface IArbitrationPolicyUMA is IArbitrationPolicy, IOOV3Callbacks {
/// @notice Emitted when a dispute is raised
/// @param disputeId The dispute id
/// @param caller The caller address that raised the dispute
/// @param claim The asserted claim
/// @param liveness The liveness time
/// @param currency The bond currency
/// @param bond The bond size
/// @param identifier The UMA specific identifier
event DisputeRaisedUMA(
uint256 disputeId,
address caller,
bytes claim,
uint64 liveness,
address currency,
uint256 bond,
bytes32 identifier
);
event DisputeRaisedUMA(uint256 disputeId, address caller, uint64 liveness, address currency, uint256 bond);

/// @notice Emitted when an assertion is disputed
/// @param assertionId The assertion id
Expand Down
29 changes: 29 additions & 0 deletions contracts/lib/BytesConversion.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.26;

/// @title Bytes Conversion
/// @notice Library for bytes conversion operations
library BytesConversion {
/// @notice Converts a uint into a base-10, UTF-8 representation stored in a `string` type
function toUtf8BytesUint(uint256 x) internal pure returns (bytes memory) {
if (x == 0) {
return "0";
}
uint256 j = x;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len;
while (x != 0) {
k = k - 1;
uint8 temp = (48 + uint8(x - (x / 10) * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
x /= 10;
}
return bstr;
}
}
2 changes: 1 addition & 1 deletion contracts/modules/dispute/DisputeModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ contract DisputeModule is
parentDisputeId: 0
});

IArbitrationPolicy(arbitrationPolicy).onRaiseDispute(msg.sender, data);
IArbitrationPolicy(arbitrationPolicy).onRaiseDispute(msg.sender, disputeId, data);

emit DisputeRaised(
disputeId,
Expand Down
52 changes: 18 additions & 34 deletions contracts/modules/dispute/policies/UMA/ArbitrationPolicyUMA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils
import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";

import { IDisputeModule } from "../../../../interfaces/modules/dispute/IDisputeModule.sol";
import { IRoyaltyModule } from "../../../../interfaces/modules/royalty/IRoyaltyModule.sol";
import { IArbitrationPolicyUMA } from "../../../../interfaces/modules/dispute/policies/UMA/IArbitrationPolicyUMA.sol";
import { IOOV3 } from "../../../../interfaces/modules/dispute/policies/UMA/IOOV3.sol";
import { ProtocolPausableUpgradeable } from "../../../../pause/ProtocolPausableUpgradeable.sol";
Expand All @@ -25,13 +24,12 @@ contract ArbitrationPolicyUMA is
{
using SafeERC20 for IERC20;

/// @notice Dispute module address
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
IDisputeModule public immutable DISPUTE_MODULE;
/// @notice Returns the percentage scale - represents 100%
uint32 public constant MAX_PERCENT = 100_000_000;

/// @notice Royalty module address
/// @notice Dispute module address
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
IRoyaltyModule public immutable ROYALTY_MODULE;
address public immutable DISPUTE_MODULE;

/// @dev Storage structure for the ArbitrationPolicyUMA
/// @param minLiveness The minimum liveness value
Expand All @@ -42,7 +40,6 @@ contract ArbitrationPolicyUMA is
/// @param disputeIdToAssertionId The mapping of dispute id to assertion id
/// @param assertionIdToDisputeId The mapping of assertion id to dispute id
/// @param counterEvidenceHashes The mapping of assertion id to counter evidence hash
/// @param ipOwnerTimePercents The mapping of dispute id to ip owner time percent of the dispute
/// @custom:storage-location erc7201:story-protocol.ArbitrationPolicyUMA
struct ArbitrationPolicyUMAStorage {
uint64 minLiveness;
Expand All @@ -53,7 +50,6 @@ contract ArbitrationPolicyUMA is
mapping(uint256 disputeId => bytes32 assertionId) disputeIdToAssertionId;
mapping(bytes32 assertionId => uint256 disputeId) assertionIdToDisputeId;
mapping(bytes32 assertionId => bytes32 counterEvidenceHash) counterEvidenceHashes;
mapping(uint256 disputeId => uint32 ipOwnerTimePercent) ipOwnerTimePercents;
}

// keccak256(abi.encode(uint256(keccak256("story-protocol.ArbitrationPolicyUMA")) - 1)) & ~bytes32(uint256(0xff));
Expand All @@ -62,21 +58,17 @@ contract ArbitrationPolicyUMA is

/// @dev Restricts the calls to the dispute module
modifier onlyDisputeModule() {
if (msg.sender != address(DISPUTE_MODULE)) revert Errors.ArbitrationPolicyUMA__NotDisputeModule();
if (msg.sender != DISPUTE_MODULE) revert Errors.ArbitrationPolicyUMA__NotDisputeModule();
_;
}

/// Constructor
/// @param disputeModule The address of the dispute module
/// @param royaltyModule The address of the royalty module
/// @custom:oz-upgrades-unsafe-allow constructor
constructor(address disputeModule, address royaltyModule) {
constructor(address disputeModule) {
if (disputeModule == address(0)) revert Errors.ArbitrationPolicyUMA__ZeroDisputeModule();
if (royaltyModule == address(0)) revert Errors.ArbitrationPolicyUMA__ZeroRoyaltyModule();

DISPUTE_MODULE = IDisputeModule(disputeModule);
ROYALTY_MODULE = IRoyaltyModule(royaltyModule);

DISPUTE_MODULE = disputeModule;
_disableInitializers();
}

Expand Down Expand Up @@ -109,8 +101,7 @@ contract ArbitrationPolicyUMA is
if (minLiveness == 0) revert Errors.ArbitrationPolicyUMA__ZeroMinLiveness();
if (maxLiveness == 0) revert Errors.ArbitrationPolicyUMA__ZeroMaxLiveness();
if (minLiveness > maxLiveness) revert Errors.ArbitrationPolicyUMA__MinLivenessAboveMax();
if (ipOwnerTimePercent > ROYALTY_MODULE.maxPercent())
revert Errors.ArbitrationPolicyUMA__IpOwnerTimePercentAboveMax();
if (ipOwnerTimePercent > MAX_PERCENT) revert Errors.ArbitrationPolicyUMA__IpOwnerTimePercentAboveMax();

ArbitrationPolicyUMAStorage storage $ = _getArbitrationPolicyUMAStorage();
$.minLiveness = minLiveness;
Expand All @@ -125,8 +116,6 @@ contract ArbitrationPolicyUMA is
/// @param maxBond The maximum bond value
function setMaxBond(address token, uint256 maxBond) external restricted {
ArbitrationPolicyUMAStorage storage $ = _getArbitrationPolicyUMAStorage();
if (maxBond < $.oov3.getMinimumBond(token)) revert Errors.ArbitrationPolicyUMA__MaxBondBelowMinimumBond();

$.maxBonds[token] = maxBond;

emit MaxBondSet(token, maxBond);
Expand All @@ -148,8 +137,6 @@ contract ArbitrationPolicyUMA is
if (liveness < $.minLiveness) revert Errors.ArbitrationPolicyUMA__LivenessBelowMin();
if (liveness > $.maxLiveness) revert Errors.ArbitrationPolicyUMA__LivenessAboveMax();
if (bond > $.maxBonds[currency]) revert Errors.ArbitrationPolicyUMA__BondAboveMax();
if (!ROYALTY_MODULE.isWhitelistedRoyaltyToken(currency))
revert Errors.ArbitrationPolicyUMA__CurrencyNotWhitelisted();

bytes memory claim = abi.encodePacked(
bytes("This IP is infringing according to the information from the dispute Id "),
Expand All @@ -172,7 +159,6 @@ contract ArbitrationPolicyUMA is
bytes32(0) // domainId
);

$.ipOwnerTimePercents[disputeId] = $.ipOwnerTimePercent;
$.assertionIdToDisputeId[assertionId] = disputeId;
$.disputeIdToAssertionId[disputeId] = assertionId;

Expand Down Expand Up @@ -212,9 +198,9 @@ contract ArbitrationPolicyUMA is
uint256 disputeId = $.assertionIdToDisputeId[assertionId];
if (disputeId == 0) revert Errors.ArbitrationPolicyUMA__DisputeNotFound();

(address targetIpId, , , address arbitrationPolicy, , , , uint256 parentDisputeId) = DISPUTE_MODULE.disputes(
disputeId
);
(address targetIpId, , , address arbitrationPolicy, , , , uint256 parentDisputeId) = IDisputeModule(
DISPUTE_MODULE
).disputes(disputeId);

if (arbitrationPolicy != address(this)) revert Errors.ArbitrationPolicyUMA__OnlyDisputePolicyUMA();
if (parentDisputeId > 0) revert Errors.ArbitrationPolicyUMA__CannotDisputeAssertionIfTagIsInherited();
Expand All @@ -223,8 +209,7 @@ contract ArbitrationPolicyUMA is
IOOV3.Assertion memory assertion = $.oov3.getAssertion(assertionId);
uint64 liveness = assertion.expirationTime - assertion.assertionTime;
uint64 elapsedTime = uint64(block.timestamp) - assertion.assertionTime;
uint32 maxPercent = ROYALTY_MODULE.maxPercent();
bool inIpOwnerTimeWindow = elapsedTime <= (liveness * $.ipOwnerTimePercents[disputeId]) / maxPercent;
bool inIpOwnerTimeWindow = elapsedTime <= (liveness * $.ipOwnerTimePercent) / MAX_PERCENT;
if (inIpOwnerTimeWindow && msg.sender != targetIpId)
revert Errors.ArbitrationPolicyUMA__OnlyTargetIpIdCanDisputeWithinTimeWindow(
elapsedTime,
Expand Down Expand Up @@ -256,7 +241,7 @@ contract ArbitrationPolicyUMA is

uint256 disputeId = $.assertionIdToDisputeId[assertionId];

DISPUTE_MODULE.setDisputeJudgement(disputeId, assertedTruthfully, "");
IDisputeModule(DISPUTE_MODULE).setDisputeJudgement(disputeId, assertedTruthfully, "");
}

/// @notice OOV3 callback function for when an assertion is disputed
Expand All @@ -267,6 +252,11 @@ contract ArbitrationPolicyUMA is
if ($.counterEvidenceHashes[assertionId] == bytes32(0)) revert Errors.ArbitrationPolicyUMA__NoCounterEvidence();
}

/// @notice Returns the maximum percentage - represents 100%
function maxPercent() external view returns (uint32) {
return MAX_PERCENT;
}

/// @notice Returns the minimum liveness for UMA disputes
function minLiveness() external view returns (uint64) {
return _getArbitrationPolicyUMAStorage().minLiveness;
Expand All @@ -282,12 +272,6 @@ contract ArbitrationPolicyUMA is
return _getArbitrationPolicyUMAStorage().ipOwnerTimePercent;
}

/// @notice Returns the percentage of liveness time the IP owner has priority to respond to a dispute
/// for a given dispute id
function ipOwnerTimePercents(uint256 disputeId) external view returns (uint32) {
return _getArbitrationPolicyUMAStorage().ipOwnerTimePercents[disputeId];
}

/// @notice Returns the OOV3 address
function oov3() external view returns (address) {
return address(_getArbitrationPolicyUMAStorage().oov3);
Expand Down
2 changes: 1 addition & 1 deletion test/foundry/mocks/dispute/MockArbitrationPolicy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ contract MockArbitrationPolicy is IArbitrationPolicy {
treasury = newTreasury;
}

function onRaiseDispute(address caller, bytes calldata data) external onlyDisputeModule {
function onRaiseDispute(address caller, uint256 disputeId, bytes calldata data) external onlyDisputeModule {
IERC20(PAYMENT_TOKEN).safeTransferFrom(caller, address(this), ARBITRATION_PRICE);
}

Expand Down
Loading

0 comments on commit d078c6f

Please sign in to comment.