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.