Skip to content

Conversation

@yogurtandjam
Copy link
Contributor

What's new in this PR?

In bullet point format, please describe what's new in this PR.

Why?

What problem does this solve?
Why is this important?
What's the context?

Copilot AI review requested due to automatic review settings February 2, 2026 18:33
@octane-security-app
Copy link

Summary by Octane

New Contracts

No new contracts were added.

Updated Contracts

  • Spin.sol: The primary change in the smart contract involves the discontinuation of the raffle ticket reward tier, aligning its threshold with the plume token, and adjusting the prize distribution percentages.

🔗 Commit Hash: 652b917

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to remove raffle tickets as a reward from the spin prize pool and increase the probability of receiving PP (Plume Points) rewards. However, the implementation contains critical bugs that prevent the contract from functioning correctly.

Changes:

  • Set raffleTicketThreshold equal to plumeTokenThreshold (both at 200,000) to effectively disable raffle ticket rewards
  • Updated comments to reflect the intended change in probability distribution
  • Reformatted multiple function signatures to single-line format
  • Minor formatting change to call syntax

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +131 to +132
raffleTicketThreshold: 200_000, // Used to be up to 600,000 (Approx 40%). We have discontinued this tier by
// setting it equivalent to plumeTokenThreshold.
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The existing tests in Spin.t.sol expect raffle ticket rewards to be awarded for probability values in the range 200_001 to 600_000 (see testRaffleTicketReward at line 719-739 and testBrokenStreakRaffleReward at line 598-640). With raffleTicketThreshold now set equal to plumeTokenThreshold, these tests will fail because the raffle ticket reward path is unreachable. The tests need to be updated to reflect the new probability distribution, either by removing raffle ticket test cases or updating them to test PP rewards instead.

Copilot uses AI. Check for mistakes.
function _safeTransferPlume(address payable _to, uint256 _amount) internal {
require(address(this).balance >= _amount, "insufficient Plume in the Spin contract");
(bool success,) = _to.call{ value: _amount }("");
(bool success,) = _to.call{value: _amount}("");
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The spacing in the call syntax has been changed from "call{ value: _amount }" to "call{value: _amount}". This is inconsistent with the codebase convention where other files use a space after the opening brace (e.g., PlumeStakingRewardTreasury.sol:179, ManagementFacet.sol:156, StakingFacet.sol:416, AddressUtils.sol:27, MockPUSD.sol:101). For consistency, this should remain as "call{ value: _amount }".

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ungaro do i have to change my forge version or something? whe ni run forget fmt it changes the existing format of the file

Comment on lines +131 to +132
raffleTicketThreshold: 200_000, // Used to be up to 600,000 (Approx 40%). We have discontinued this tier by
// setting it equivalent to plumeTokenThreshold.
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

Setting raffleTicketThreshold equal to plumeTokenThreshold breaks the validation logic in the setRewardProbabilities function (line 527), which requires strict inequality (plumeTokenThreshold < raffleTicketThreshold). This will prevent administrators from updating reward probabilities after deployment. Additionally, with these values being equal, the condition on line 299 (probability <= rewardProbabilities.raffleTicketThreshold) will be evaluated for probabilities where probability <= 200_000, which are already captured by line 296-298. This means the "Raffle Ticket" reward path becomes unreachable. If the intention is to discontinue raffle tickets, consider using a value slightly greater than plumeTokenThreshold (e.g., 200_001) to satisfy the validation while ensuring the range is effectively empty, or remove the raffle ticket logic entirely.

Suggested change
raffleTicketThreshold: 200_000, // Used to be up to 600,000 (Approx 40%). We have discontinued this tier by
// setting it equivalent to plumeTokenThreshold.
raffleTicketThreshold: 200_001, // Previously up to 600,000 (Approx 40%). We have effectively discontinued
// this tier by setting it just above plumeTokenThreshold to satisfy validation while leaving the
// practical raffle range empty.

Copilot uses AI. Check for mistakes.
});
raffleTicketThreshold: 200_000, // Used to be up to 600,000 (Approx 40%). We have discontinued this tier by
// setting it equivalent to plumeTokenThreshold.
ppThreshold: 900_000 // Up to 900,000 (Approx 70%)
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The comment states PP threshold is "Up to 900,000 (Approx 70%)" but this calculation appears incorrect. If the raffle ticket threshold is effectively discontinued by setting it equal to plumeTokenThreshold at 200_000, then the PP range would be from 200_001 to 900_000, which is 700_000 out of 1_000_000, or exactly 70%. However, the jackpot probabilities also consume part of the range (varying by day from 1 to 20 based on jackpotProbabilities). The actual PP probability would be approximately (700_000 - avg_jackpot_threshold) / 1_000_000. Consider clarifying this comment to account for the dynamic jackpot threshold.

Copilot uses AI. Check for mistakes.
@octane-security-app
Copy link

Overview

Vulnerabilities found: 1                                                                                
Severity breakdown: 1 Low
Warnings found: 4                                                                                

Detailed findings

plume/src/spin/Spin.sol

  • Revert-on-payout in Spin.handleRandomness causes per-user DoS and lost spin fee. See more

Warnings

plume/src/spin/Spin.sol

  • Misconfiguration and payout underfunding in Spin.handleRandomness/determineReward cause stuck spins and fee loss. See more
  • External call before nonce recording in Spin.startSpin causes stuck pending spins and fee loss under certain oracle callbacks. See more
  • No-refund admin cancellation in Spin.sol cancelPendingSpin causes loss of user spin fees. See more
  • Unprotected initializer and payable receive in Spin implementation cause loss or theft of ETH sent to the implementation address. See more

🔗 Commit Hash: 652b917
🛡️ Octane Dashboard: All vulnerabilities

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant