The heal function, intended to facilitate healing of wounded agents, is susceptible to be front-run and revert due to a status check that causes the entire transaction to revert if any single agent in the batch is not in the expected wounded status.
Vulnerability Detail
heal() performs a status check for each agent to ensure they are eligible for healing by being in a wounded state. This check is done through _assertAgentStatus(), which reverts the transaction if the status condition is not met
Imagine the scenario where Alice who has 100 agents, attempts to heal 20 agents wounded, an attacker, Bob, can observe the transaction in the mempool and send a transaction with a higher gas price to heal one of the 20 Alice's agents
If Bob's transaction is confirmed first, the status of the agent changes, and when Alice's transaction is processed, it fails due to the status check, causing her to lose the gas spent on the transaction and leaving her agents at risk for another round
Suppose 15 of the agents were wounded at currentRoundId-ROUNDS_TO_BE_WOUNDED_BEFORE_DEAD and Bob performs it's attack until enough block pass to be able to call startNewRound(), 15 of Alice's agents will be killed in fulfillRandomWords()
Impact
loss of gas for Alice
Alice agents killed without any chance to survive or at least increased risk of Alice's agents being killed next round
I think it's important to allow anyone to heal anyone agents so simply continue the loop for healing if one of the agents status of uint256[] calldata agentIds is not status.wounded
lil.eth
medium
Front-running heal function
Summary
The
heal
function, intended to facilitate healing of wounded agents, is susceptible to be front-run and revert due to a status check that causes the entire transaction to revert if any single agent in the batch is not in the expected wounded status.Vulnerability Detail
heal()
performs a status check for each agent to ensure they are eligible for healing by being in a wounded state. This check is done through_assertAgentStatus()
, which reverts the transaction if the status condition is not metImagine the scenario where Alice who has
100
agents, attempts to heal20
agents wounded, an attacker, Bob, can observe the transaction in the mempool and send a transaction with a higher gas price to heal one of the20
Alice's agents If Bob's transaction is confirmed first, the status of the agent changes, and when Alice's transaction is processed, it fails due to the status check, causing her to lose the gas spent on the transaction and leaving her agents at risk for another round Suppose 15 of the agents were wounded atcurrentRoundId-ROUNDS_TO_BE_WOUNDED_BEFORE_DEAD
and Bob performs it's attack until enough block pass to be able to callstartNewRound()
, 15 of Alice's agents will be killed infulfillRandomWords()
Impact
Code Snippet
https://github.com/sherlock-audit/2023-10-looksrare/blob/main/contracts-infiltration/contracts/Infiltration.sol#L829
Tool used
Manual Review
Recommendation
I think it's important to allow anyone to heal anyone agents so simply continue the loop for healing if one of the agents status of
uint256[] calldata agentIds
is notstatus.wounded
Duplicate of #57