One Shot: Reloaded

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

Users won't earn more CRED when staking longer than 4 days

Author Revealed upon completion

Root + Impact

Description

The readme states that:

Stake a Rapper to the protocol to gradually remove vices and earn CRED per full day staked.

However, staking for longer than 4 days will not earn any more CRED per full day staked, which breaks the invariant.

// streets::unstake
if (days_staked > 0) {
let (wk, ha, ss, cr, wins) = one_shot::read_stats(token_id);
let final_wk = if (days_staked >= 1) { false } else { wk };
let final_ha = if (days_staked >= 2) { false } else { ha };
let final_ss = if (days_staked >= 3) { false } else { ss };
let final_cr = if (days_staked >= 4) { true } else { cr };
@> 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); };
one_shot::write_stats(token_id, final_wk, final_ha, final_ss, final_cr, wins);
};

In the code, we clearly see that rewards are hard-coded to mint CRED for at most 4 days.

Risk

Likelihood:

Every time users will try to unstake after more than 4 days, they will loose on potential reward gains.

Impact:

Users can instead unstake every 4 days to restake straight after to reach the desired behavior, but it is inconvenient and will still make them loose reward over time.

Recommended Mitigation

Provide a steady reward amount for every full day staked, not capping this amount to 4:

let cred_to_mint = days_staked;
cred_token::mint(module_owner, staker_addr, cred_to_mint);

Support

FAQs

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