The intended behavior of go_on_stage_or_battle
is that after both defender and challenger stake their NFT and CRED
tokens, the contract determines the winner based on each rapper’s skill plus a random draw. This randomness should make the outcome unpredictable and fair.
However, the contract currently uses timestamp::now_seconds() % total_skill
as the random number source. On mainnet, block timestamps are predictable and partially influenced by validators, making them an insecure source of randomness. An attacker can exploit this by submitting or re-submitting their transaction at moments when the timestamp modulo falls in their favor, tilting outcomes unfairly.
Likelihood:
Timestamps are predictable at the second level, so attackers can time transactions to land in favorable slots.
Validators have discretion over acceptable block timestamps (within protocol bounds), allowing them to bias results.
Impact:
Attackers can systematically bias outcomes in their favor by timing or coordinating transactions.
This breaks fairness: battle outcomes are no longer random but subject to manipulation.
On mainnet, this attack is feasible because block timestamps are visible in mempool and transaction inclusion can be timed or influenced.
Use the Aptos randomness API (aptos_framework::randomness
) instead of timestamps for winner selection.
This ensures unbiased, unpredictable randomness that cannot be manipulated by players or validators.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.