Closed c4-bot-2 closed 8 months ago
raymondfam marked the issue as sufficient quality report
raymondfam marked the issue as duplicate of #136
HickupHH3 marked the issue as unsatisfactory: Invalid
HickupHH3 marked the issue as unsatisfactory: Invalid
HickupHH3 changed the severity to 2 (Med Risk)
Lines of code
https://github.com/code-423n4/2024-02-ai-arena/blob/cd1a0e6d1b40168657d1aaee8223dc050e15f8cc/src/RankedBattle.sol#L322-L349 https://github.com/code-423n4/2024-02-ai-arena/blob/cd1a0e6d1b40168657d1aaee8223dc050e15f8cc/src/RankedBattle.sol#L270-L290
Vulnerability details
Title
User which lose a fight can frontrun the AiArena server to prevent his scores update
Impact
If a user lose a fight, a user can frontrun the
updateBattleRecord()
execution of AiArena server to prevent the score update and losing points. Also he can potentially sell the fighter to another user and when the new owner stake NRN$, the scores fighter is updated and the new owner lose points and potentially getstakeAtRisk
.Proof of Concept
The
updateBattleRecord()
function on theRankedBattle
contract is a function called by the server of AIArena to updates the battle record for a fighter after a fight, the team say that:Check to the following scenario: 1) Bob have an ERC721 fighter on AIArena and he stakes NRN$ tokens to participate in the battles. 2) After fews fights, Bob have a lot of victory, good amounts of points and doesn't want to lose them 3) Bob is now losing a fight but don't want to lose points/etc 4) Bob use his frontrunning bot to call the
unstakeNRN()
function to unstake all his NRN$ and because theamountStaked[tokenId]
become0
and Bob doesn't havestakeAtRisk
, it prevent the AIArena server to make the update of his score/elo.In my opinion, and with the MEV on Ethereum ecosystem, a bot made by a user can easily frontrun the transaction of the AiArena server and execute a transaction of
unstakeNRN()
to prevent the correct updates of scores.Also the team say:
But a user can sell the Fighter/token to e.g. Alice, and when Alice stakes NRN$, the server call
updateBattleRecord()
and Alice begin the round with losing points and potentials amount ofstakeAtRisk
without made any fight.If multiples users make this trick, imo it can happen some others weird inconsistencies in the ecosystem.
Tools Used
Manual Review
Recommended Mitigation Steps
You can prevent this scenario in multiples ways, my recommendation is to add a function on
RankedBattle()
which register when a user begin a fight with a certains fighter(tokenId) and prevent this user to unstake for this tokenId for a timelock (e.g. 1 hour to be sure the server can handle the score update correctly). It cost gas at each fight but I think it a necessary check to prevent no updates of scores.I will be happy to discuss with you for others possibles solutions.
Assessed type
MEV