From 7a74cf88b0a8778401b2c157f868d84b6e035a9b Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 8 Oct 2025 18:13:33 +0100 Subject: [PATCH] feat: extra _arbitrable parameter for the Evidence event --- .../src/arbitration/evidence/EvidenceModule.sol | 6 ++++-- .../evidence/ModeratedEvidenceModule.sol | 9 ++++++--- .../src/arbitration/interfaces/IEvidence.sol | 9 ++++++++- contracts/test/evidence/index.ts | 17 +++++++++++------ 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/contracts/src/arbitration/evidence/EvidenceModule.sol b/contracts/src/arbitration/evidence/EvidenceModule.sol index e29e3a6ac..609129298 100644 --- a/contracts/src/arbitration/evidence/EvidenceModule.sol +++ b/contracts/src/arbitration/evidence/EvidenceModule.sol @@ -58,10 +58,12 @@ contract EvidenceModule is IEvidence, Initializable, UUPSProxiable { // ************************************* // /// @notice Submits evidence for a dispute. + /// @dev This function is intended for end users, not for arbitrable contracts which should emit their own events. + /// @param _arbitrable The arbitrable contract address. /// @param _externalDisputeID Unique identifier for this dispute outside Kleros. It's the submitter responsibility to submit the right evidence group ID. /// @param _evidence Stringified evidence object, example: `{"name" : "Justification", "description" : "Description", "fileURI" : "/ipfs/QmWQV5ZFFhEJiW8Lm7ay2zLxC2XS4wx1b2W7FfdrLMyQQc"}`. - function submitEvidence(uint256 _externalDisputeID, string calldata _evidence) external { - emit Evidence(_externalDisputeID, msg.sender, _evidence); + function submitEvidence(address _arbitrable, uint256 _externalDisputeID, string calldata _evidence) external { + emit Evidence(_arbitrable, _externalDisputeID, msg.sender, _evidence); } // ************************************* // diff --git a/contracts/src/arbitration/evidence/ModeratedEvidenceModule.sol b/contracts/src/arbitration/evidence/ModeratedEvidenceModule.sol index 2ffd0b30b..e28160572 100644 --- a/contracts/src/arbitration/evidence/ModeratedEvidenceModule.sol +++ b/contracts/src/arbitration/evidence/ModeratedEvidenceModule.sol @@ -72,13 +72,15 @@ contract ModeratedEvidenceModule is IArbitrableV2 { /// @notice To be raised when a moderated evidence is submitted. Should point to the resource (evidences are not to be stored on chain due to gas considerations). /// @param _arbitrator The arbitrator of the contract. + /// @param _arbitrable The arbitrable contract address. /// @param _externalDisputeID Unique identifier for this dispute outside Kleros. It's the submitter responsibility to submit the right evidence group ID. /// @param _party The address of the party submiting the evidence. Note that 0x0 refers to evidence not submitted by any party. /// @param _evidence Stringified evidence object, example: '{"name" : "Justification", "description" : "Description", "fileURI" : "/ipfs/QmWQV5ZFFhEJiW8Lm7ay2zLxC2XS4wx1b2W7FfdrLMyQQc"}'. event ModeratedEvidence( IArbitratorV2 indexed _arbitrator, + address indexed _arbitrable, uint256 indexed _externalDisputeID, - address indexed _party, + address _party, string _evidence ); @@ -190,9 +192,10 @@ contract ModeratedEvidenceModule is IArbitrableV2 { // ************************************* // /// @notice Submits evidence. + /// @param _arbitrable The arbitrable contract address for this evidence. /// @param _evidenceGroupID Unique identifier of the evidence group the evidence belongs to. It's the submitter responsibility to submit the right evidence group ID. /// @param _evidence Stringified evidence object, example: '{"name" : "Justification", "description" : "Description", "fileURI" : "/ipfs/QmWQV5ZFFhEJiW8Lm7ay2zLxC2XS4wx1b2W7FfdrLMyQQc"}'. - function submitEvidence(uint256 _evidenceGroupID, string calldata _evidence) external payable { + function submitEvidence(address _arbitrable, uint256 _evidenceGroupID, string calldata _evidence) external payable { // Optimization opportunity: map evidenceID to an incremental index that can be safely assumed to be less than a small uint. bytes32 evidenceID = keccak256(abi.encodePacked(_evidenceGroupID, _evidence)); EvidenceData storage evidenceData = evidences[evidenceID]; @@ -214,7 +217,7 @@ contract ModeratedEvidenceModule is IArbitrableV2 { moderation.arbitratorDataID = arbitratorDataList.length - 1; // When evidence is submitted for a foreign arbitrable, the arbitrator field of Evidence is ignored. - emit ModeratedEvidence(arbitrator, _evidenceGroupID, msg.sender, _evidence); + emit ModeratedEvidence(arbitrator, _arbitrable, _evidenceGroupID, msg.sender, _evidence); } /// @notice Moderates an evidence submission. Requires the contester to at least double the accumulated stake of the oposing party. diff --git a/contracts/src/arbitration/interfaces/IEvidence.sol b/contracts/src/arbitration/interfaces/IEvidence.sol index f27ce8447..1571a88c1 100644 --- a/contracts/src/arbitration/interfaces/IEvidence.sol +++ b/contracts/src/arbitration/interfaces/IEvidence.sol @@ -5,8 +5,15 @@ pragma solidity >=0.8.0 <0.9.0; /// @title IEvidence interface IEvidence { /// @notice To be raised when evidence is submitted. Should point to the resource (evidences are not to be stored on chain due to gas considerations). + /// @dev This event is intended for end users submitting evidence, not for arbitrable contracts. + /// @param _arbitrable The arbitrable contract address. /// @param _externalDisputeID Unique identifier for this dispute outside Kleros. It's the submitter responsibility to submit the right external dispute ID. /// @param _party The address of the party submitting the evidence. /// @param _evidence Stringified evidence object, example: '{"name" : "Justification", "description" : "Description", "fileURI" : "/ipfs/QmWQV5ZFFhEJiW8Lm7ay2zLxC2XS4wx1b2W7FfdrLMyQQc"}'. - event Evidence(uint256 indexed _externalDisputeID, address indexed _party, string _evidence); + event Evidence( + address indexed _arbitrable, + uint256 indexed _externalDisputeID, + address indexed _party, + string _evidence + ); } diff --git a/contracts/test/evidence/index.ts b/contracts/test/evidence/index.ts index 60c1cb0f5..9c6d66fac 100644 --- a/contracts/test/evidence/index.ts +++ b/contracts/test/evidence/index.ts @@ -23,6 +23,7 @@ describe("Home Evidence contract", async () => { ["uint256", "uint256"], [1, 1] // courtId 1, minJurors 1 ); + const arbitrable = "0x1234567890123456789012345678901234567890"; // Dummy arbitrable address const appealTimeout = 100; const bondTimeout = 60 * 10; const totalCostMultiplier = 15000n; @@ -147,15 +148,19 @@ describe("Home Evidence contract", async () => { describe("Evidence Submission", () => { it("Should submit evidence correctly.", async () => { const newEvidence = "Irrefutable evidence"; - const tx = await evidenceModule.connect(user1).submitEvidence(1234, newEvidence, { + const tx = await evidenceModule.connect(user1).submitEvidence(arbitrable, 1234, newEvidence, { value: minRequiredDeposit, }); // id: 0 const receipt = await tx.wait(); if (receipt === null) throw new Error("Receipt is null"); const evidenceID = ethers.solidityPackedKeccak256(["uint", "string"], [1234, newEvidence]); - const [_arbitrator, _externalDisputeID, _party, _evidence] = getEmittedEvent("ModeratedEvidence", receipt).args; + const [_arbitrator, _arbitrable, _externalDisputeID, _party, _evidence] = getEmittedEvent( + "ModeratedEvidence", + receipt + ).args; expect(_arbitrator).to.equal(arbitrator.target, "Wrong arbitrator."); + expect(_arbitrable).to.equal(arbitrable, "Wrong arbitrable."); expect(_externalDisputeID).to.equal(1234, "Wrong external dispute ID."); expect(_party).to.equal(user1.address, "Wrong submitter."); expect(_evidence).to.equal(newEvidence, "Wrong evidence message."); @@ -169,11 +174,11 @@ describe("Home Evidence contract", async () => { it("Should not allowed the same evidence twice for the same external dispute id.", async () => { const newEvidence = "Irrefutable evidence"; - await evidenceModule.submitEvidence(1234, newEvidence, { + await evidenceModule.submitEvidence(arbitrable, 1234, newEvidence, { value: minRequiredDeposit, }); await expect( - evidenceModule.submitEvidence(1234, newEvidence, { + evidenceModule.submitEvidence(arbitrable, 1234, newEvidence, { value: minRequiredDeposit, }) ).to.be.revertedWith("Evidence already submitted."); @@ -182,7 +187,7 @@ describe("Home Evidence contract", async () => { it("Should revert if deposit is too low.", async () => { const newEvidence = "Irrefutable evidence"; await expect( - evidenceModule.submitEvidence(1234, newEvidence, { + evidenceModule.submitEvidence(arbitrable, 1234, newEvidence, { value: minRequiredDeposit - 1n, }) ).to.be.revertedWith("Insufficient funding."); @@ -192,7 +197,7 @@ describe("Home Evidence contract", async () => { describe("Moderation", () => { beforeEach("Initialize posts and comments", async () => { const newEvidence = "Irrefutable evidence"; - await evidenceModule.connect(user1).submitEvidence(1234, newEvidence, { + await evidenceModule.connect(user1).submitEvidence(arbitrable, 1234, newEvidence, { value: minRequiredDeposit, }); evidenceID = ethers.solidityPackedKeccak256(["uint", "string"], [1234, newEvidence]);