Dussehra::killRavana function is susceptible to a reentrancy attack by the organiser, allowing the organiser to retrieve all funds from the Dussehra contract through one transaction.Description: The function killRavana sets IsRavanKilled to true and sends half of the collected fees to the organiser address. However, because funds are send to the organiser through a low level .call, it is possible to set the organiser as a malicious contract that will recall killRavana at the moment it receives funds.
Note that this vulnerability is enabled by the vulnerability described in [H-1]. Because its root cause is different, I note it as an additional vulnerability.
Impact: The reentrancy vulnerability allows the organiser to drain all funds from the contract, breaking the intended functionality of the Dussehra protocol.
Please note that it is also possible to create a malicious contract that reverts on receiving funds. This will make it impossible to kill Ravana, breaking the protocol. It is a different execution of the same vulnerability.
Proof of Concept:
A malicious organiser creates a contract (here named organiserReenters) with a receive function that calls Dussehra::killRavana until no funds are left.
The organiserReenters contract is used to initiate the Dussehra contract.
Players enter the Dussehra contract, without any problems.
The organiser of the RamNFT contract calls selectRamIfNotSelected (this allows the killRavana function to be called).
Anyone calls the killRavana function.
All funds end up at the organiserReenters contract.
Add the following code underneath the CounterTest contract in Dussehra.t.sol.
Place the following in the CounterTest contract in the Dussehra.t.sol test file.
Recommended Mitigation: Currently, funds are pushed through a low level call to the organiser address. This allows for a reentrancy attack to be executed. The mitigation is to refactor the code to a pull logic. Create a separate function that allows the organiser the pull the funds from the contract the moment that Ravana has been killed. See the following page for more information: https://fravoll.github.io/solidity-patterns/pull_over_push.html.
The following solution draws from this page.
Add a mapping to keep track of credits owed.
Add a function to retrieve funds when address has credits.
Refactor the existing killRavana function to add credits to credits mapping instead of directly transferring funds.
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.