One Shot: Reloaded

First Flight #47
Beginner FriendlyNFT
100 EXP
Submission Details
Impact: medium
Likelihood: high

Staking rewards are capped at a maximum of 4 CRED.

Author Revealed upon completion

Root + Impact

Description

  • The normal behavior of the unstake function is to reward players with one CRED for each full day a Rapper is staked. The specific issue is that the code uses a series of hardcoded if statements that check for staking durations of 1, 2, 3, and 4 days. This design means a player staking for more than four days will not receive the full amount of CRED they are due, as the reward is capped at 4 tokens.



  • // Root cause in the codebase with @> marks to highlight the relevant section

    if (days_staked >= 1) { cred_token::mint(module_owner, staker_addr, 1); }; @> if (days_staked >= 2) { cred_token::mint(module_owner, staker_addr, 1); }; @> if (days_staked >= 3) { cred_token::mint(module_owner, staker_addr, 1); }; @> if (days_staked >= 4) { cred_token::mint(module_owner, staker_addr, 1); }; @>

Risk

Likelihood:

  • This will occur whenever a user stakes a Rapper for more than 4 full days.

  • The if statements are non-exclusive, but they are repetitive and do not account for a duration greater than 4 days.

Impact:

  • Players are not properly rewarded for long-term staking, which is a key incentive of the protocol.

  • This can lead to user dissatisfaction and a loss of trust in the game's economic model.


Proof of Concept

if (days_staked >= 1) { cred_token::mint(module_owner, staker_addr, 1); }; @>
if (days_staked >= 2) { cred_token::mint(module_owner, staker_addr, 1); }; @>
if (days_staked >= 3) { cred_token::mint(module_owner, staker_addr, 1); }; @>
if (days_staked >= 4) { cred_token::mint(module_owner, staker_addr, 1); }; @>

Recommended Mitigation

- if (days_staked >= 1) { cred_token::mint(module_owner, staker_addr, 1); };
- if (days_staked >= 2) { cred_token::mint(module_owner, staker_addr, 1); };
- if (days_staked >= 3) { cred_token::mint(module_owner, staker_addr, 1); };
- if (days_staked >= 4) { cred_token::mint(module_owner, staker_addr, 1); };
+ if (days_staked > 0) {
+ cred_token::mint(module_owner, staker_addr, days_staked);
+ }

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.