Skip to content

Conversation

@jaybuidl
Copy link
Member

@jaybuidl jaybuidl commented Sep 10, 2025

PR-Codex overview

This PR focuses on enhancing the KlerosCore contract by preventing the emission of events and transfers when amounts are zero. It improves the handling of penalties and rewards in the system, ensuring that unnecessary transactions are avoided.

Detailed summary

  • Updated CHANGELOG.md to reflect changes in event emissions and transfers.
  • Removed emissions of KlerosCore.TokenAndETHShift when amounts are zero in KlerosCore_Execution.t.sol.
  • Modified KlerosCore.sol to only emit TokenAndETHShift when penalties or rewards are non-zero.
  • Updated integration tests to use expect syntax for event emissions.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • Bug Fixes
    • Event emissions and transfers for rewards/penalties now occur only when amounts are non-zero, removing noisy zero-value logs without changing outcomes.
  • Refactor
    • Skipped no-op transfers/stakes to avoid unnecessary state updates when reward/penalty values are zero.
  • Tests
    • Unit and integration tests updated to drop zero-value event assertions and to assert precise event arguments.
  • Chores
    • Improved integration assertions for dispute creation and finalization flows.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 10, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Added guards in KlerosCore to skip PNK/ETH transfers, staking, bookkeeping, and TokenAndETHShift emission when corresponding amounts are zero; updated tests and integration assertions to stop expecting zero-value TokenAndETHShift events and to assert precise event args.

Changes

Cohort / File(s) Summary
Core execution guards
contracts/src/arbitration/KlerosCore.sol
Add non-zero checks in _executePenalties and _executeRewards; update pnkPenaltiesInRound, transfers/staking, and TokenAndETHShift emission only when amounts > 0. No public signatures changed.
Foundry test adjustments
contracts/test/foundry/KlerosCore_Execution.t.sol
Remove assertions for zero-amount TokenAndETHShift events and an extra zero-amount StakeLocked; retain non-zero event assertions. Test flow unchanged.
Integration test updates
contracts/test/integration/index.ts
Replace raw tx capture with expect().to.emit assertions; consolidate core.execute/Ruling event checks with withArgs and explicit TokenAndETHShift argument expectations.
Changelog
contracts/CHANGELOG.md
Document fixed behavior: do not emit TokenAndETHShift or perform PNK/ETH transfers when amounts are zero.

Sequence Diagram(s)

sequenceDiagram
  participant U as User
  participant Core as KlerosCore
  participant SM as SortitionModule
  participant PNK as PNK Token

  U->>Core: execute(disputeID, ...)
  activate Core

  rect rgb(235,245,255)
  note right of Core: Penalties flow (guarded)
  Core->>Core: _executePenalties()
  alt availablePenalty > 0
    Core->>SM: update pnkPenaltiesInRound
    Core-->>U: emit TokenAndETHShift (penalty)
  else
    note over Core: Skip updates and event
  end
  end

  rect rgb(240,255,240)
  note right of Core: Rewards flow (guarded)
  Core->>Core: _executeRewards()
  alt feeReward > 0
    Core-->>U: transfer fee reward
  end
  alt pnkReward > 0
    Core->>PNK: stake PNK reward
  end
  opt (feeReward > 0) or (pnkReward > 0)
    Core-->>U: emit TokenAndETHShift (reward)
  end
  end

  deactivate Core
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • unknownunknown1

Poem

I hop through code with whiskers twitching light,
Quiet the zero-shouts that woke the night.
Events now sing only when coins go bop,
Tests applaud — no empty echoes stop.
A tidy little hop, and then a carrot bite. 🥕🐇


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e7578d2 and bd983ca.

📒 Files selected for processing (1)
  • contracts/CHANGELOG.md (1 hunks)
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/no-zero-amount-shift

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
contracts/src/arbitration/KlerosCore.sol (2)

914-941: Zero-penalty: short-circuit to skip external calls and event; keeps semantics, saves gas

Good guard on emitting only when availablePenalty != 0. You can also early-return when penalty == 0 to avoid an external call to unlockStake() and bypass setStakePenalty entirely for fully coherent jurors.

Apply:

         // Fully coherent jurors won't be penalized.
         uint256 penalty = (round.pnkAtStakePerJuror * (ONE_BASIS_POINT - coherence)) / ONE_BASIS_POINT;

-        // Unlock the PNKs affected by the penalty
-        address account = round.drawnJurors[_params.repartition];
-        sortitionModule.unlockStake(account, penalty);
+        // Nothing to penalize? Skip external calls and event emission.
+        if (penalty == 0) {
+            return _params.pnkPenaltiesInRound;
+        }
+
+        // Unlock the PNKs affected by the penalty
+        address account = round.drawnJurors[_params.repartition];
+        sortitionModule.unlockStake(account, penalty);

989-1011: Reward path gas nits: skip unlock when zero and avoid += 0 SSTOREs

The new zero-amount guards look good. Two tiny gas wins:

  • Only call unlockStake when pnkLocked != 0.
  • Avoid += 0 writes to sumPnkRewardPaid / sumFeeRewardPaid.

Apply:

-        // Release the rest of the PNKs of the juror for this round.
-        sortitionModule.unlockStake(account, pnkLocked);
+        // Release the rest of the PNKs of the juror for this round.
+        if (pnkLocked != 0) {
+            sortitionModule.unlockStake(account, pnkLocked);
+        }

         // Compute the rewards
         uint256 pnkReward = _applyCoherence(_params.pnkPenaltiesInRound / _params.coherentCount, pnkCoherence);
-        round.sumPnkRewardPaid += pnkReward;
+        if (pnkReward != 0) {
+            round.sumPnkRewardPaid += pnkReward;
+        }
         uint256 feeReward = _applyCoherence(round.totalFeesForJurors / _params.coherentCount, feeCoherence);
-        round.sumFeeRewardPaid += feeReward;
+        if (feeReward != 0) {
+            round.sumFeeRewardPaid += feeReward;
+        }
contracts/test/integration/index.ts (2)

134-151: Assert event payload to prevent silent regressions

Nice swap to asserting DisputeRequest. Consider asserting critical args with withArgs(...) (use anyValue for non-deterministic ones) so changes in ordering/IDs don’t slip by.

If you share HomeGateway.DisputeRequest signature, I can propose an exact withArgs(...) snippet.


189-197: Good: positive assertion on non-zero TokenAndETHShift; also assert absence of zero-value shifts

You can additionally verify that no TokenAndETHShift with both amounts equal to zero was emitted.

Apply:

-    await expect(core.execute(0, 0, 1000))
+    const execTx = await core.execute(0, 0, 1000);
+    await expect(execTx)
       .to.emit(core, "TokenAndETHShift")
       .withArgs(deployer, 0, 0, 10000, 10000, 0, arbitrationCost / 3n, ethers.ZeroAddress);
+
+    // Ensure no zero-amount TokenAndETHShift slipped through.
+    const rc = await execTx.wait();
+    const parsed = rc.logs
+      .map((l) => {
+        try { return core.interface.parseLog(l); } catch { return null; }
+      })
+      .filter((x) => x && x.name === "TokenAndETHShift");
+    expect(parsed.every((ev: any) => ev.args._amountPnk !== 0n || ev.args._amountFee !== 0n)).to.equal(true);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96bb505 and 801e42e.

📒 Files selected for processing (3)
  • contracts/src/arbitration/KlerosCore.sol (2 hunks)
  • contracts/test/foundry/KlerosCore_Execution.t.sol (0 hunks)
  • contracts/test/integration/index.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • contracts/test/foundry/KlerosCore_Execution.t.sol
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: jaybuidl
PR: kleros/kleros-v2#0
File: :0-0
Timestamp: 2025-09-03T22:48:32.972Z
Learning: In the Kleros v2 codebase, the team prioritizes gas optimization over strict CEI pattern compliance when dealing with trusted contracts. For penalty execution logic, they prefer batching storage writes (`round.pnkPenalties`) rather than updating incrementally after each penalty calculation to save gas costs, as the risk is extremely low between trusted contracts.
Learnt from: jaybuidl
PR: kleros/kleros-v2#2126
File: contracts/src/arbitration/KlerosCore.sol:472-489
Timestamp: 2025-09-04T23:36:16.415Z
Learning: In this repo, KlerosCore emits AcceptedFeeToken and NewCurrencyRate events that are declared in contracts/src/arbitration/interfaces/IArbitratorV2.sol; implementations don’t need to redeclare these events.
📚 Learning: 2025-09-03T22:48:32.972Z
Learnt from: jaybuidl
PR: kleros/kleros-v2#0
File: :0-0
Timestamp: 2025-09-03T22:48:32.972Z
Learning: In the Kleros v2 codebase, the team prioritizes gas optimization over strict CEI pattern compliance when dealing with trusted contracts. For penalty execution logic, they prefer batching storage writes (`round.pnkPenalties`) rather than updating incrementally after each penalty calculation to save gas costs, as the risk is extremely low between trusted contracts.

Applied to files:

  • contracts/src/arbitration/KlerosCore.sol
📚 Learning: 2025-09-04T23:36:16.415Z
Learnt from: jaybuidl
PR: kleros/kleros-v2#2126
File: contracts/src/arbitration/KlerosCore.sol:472-489
Timestamp: 2025-09-04T23:36:16.415Z
Learning: In this repo, KlerosCore emits AcceptedFeeToken and NewCurrencyRate events that are declared in contracts/src/arbitration/interfaces/IArbitratorV2.sol; implementations don’t need to redeclare these events.

Applied to files:

  • contracts/src/arbitration/KlerosCore.sol
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: SonarCloud

coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 10, 2025
Base automatically changed from feat/storage-gap to dev September 11, 2025 01:05
@jaybuidl jaybuidl dismissed stale reviews from unknownunknown1 and coderabbitai[bot] September 11, 2025 01:05

The base branch was changed.

@jaybuidl jaybuidl force-pushed the fix/no-zero-amount-shift branch from 801e42e to e7578d2 Compare September 11, 2025 01:07
@jaybuidl jaybuidl force-pushed the fix/no-zero-amount-shift branch from 878bf28 to bd983ca Compare September 11, 2025 01:11
@jaybuidl jaybuidl merged commit c97270a into dev Sep 11, 2025
5 checks passed
@jaybuidl jaybuidl deleted the fix/no-zero-amount-shift branch September 11, 2025 01:12
@sonarqubecloud
Copy link

@netlify
Copy link

netlify bot commented Sep 11, 2025

Deploy Preview for kleros-v2-testnet ready!

Name Link
🔨 Latest commit bd983ca
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-testnet/deploys/68c221d29730dc0008e5865f
😎 Deploy Preview https://deploy-preview-2135--kleros-v2-testnet.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Sep 11, 2025

Deploy Preview for kleros-v2-university failed. Why did it fail? →

Name Link
🔨 Latest commit bd983ca
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-university/deploys/68c221d29c421c0008d70a43

@netlify
Copy link

netlify bot commented Sep 11, 2025

Deploy Preview for kleros-v2-neo ready!

Name Link
🔨 Latest commit bd983ca
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-neo/deploys/68c221d2f1ecb200088c186d
😎 Deploy Preview https://deploy-preview-2135--kleros-v2-neo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Sep 11, 2025

Deploy Preview for kleros-v2-testnet-devtools failed. Why did it fail? →

Name Link
🔨 Latest commit bd983ca
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-testnet-devtools/deploys/68c221d27cc7c2000895da01

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants