Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions contracts/src/arbitration/evidence/EvidenceModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

// ************************************* //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
);

Expand Down Expand Up @@ -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];
Expand All @@ -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.
Expand Down
9 changes: 8 additions & 1 deletion contracts/src/arbitration/interfaces/IEvidence.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
}
17 changes: 11 additions & 6 deletions contracts/test/evidence/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.");
Expand All @@ -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.");
Expand All @@ -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.");
Expand All @@ -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]);
Expand Down
Loading