hats-finance / Proof-Of-Humanity-V2-0xef0709445d394a22704850c772a28a863bb780b0

Proof of Humanity Protocol v2
2 stars 1 forks source link

Funding the last round doesn't invert the ruling result #88

Open hats-bug-reporter[bot] opened 2 months ago

hats-bug-reporter[bot] commented 2 months ago

Github username: @MehdiKarimi81 Twitter username: MahdiKarimi81 Submission hash (on-chain): 0x690a92333eb0b1b3156880c9866538c141818831d11128cac0e0f923b5b5bf36 Severity: high

Description: Description\ funding the last round doesn't invert the ruling result

Attack Scenario\ accoding to comments and implementation: The ruling is inverted if the loser paid its fees, and if a side funds the last round it can invert the ruling result for its benefit, however it's not possible to fund lastRoundId, even if user funds the last round a new round is created even if there is no funding in that round previously. firstFunded refers to round.sideFunded in storage

    Round storage round = challenge.rounds[challenge.lastRoundId];
    Party firstFunded = round.sideFunded;

since _contribute would update sideFunded so firstFunded is also updated and won't be none and in result this if statement gets performd, each time fundAppeal is called, even if there is no funding in the underlying round so each time a funding is created it creates a new round ( increase lastRoundId ) so lastRoundId can't be funded since each time a new round is created, rule function checks if lastRoundId which can't be funded and despite that user has made the last funding but rule doesn't invert ruling result.

        if (
            _contribute(
                disputeData.humanityId,
                disputeData.requestId,
                disputeData.challengeId,
                challenge.lastRoundId,
                _side,
                totalCost
            ) &&
            // If firstFunded was assigned, it means other side was funded and if this one gets fully funded as well appeal can be created.
            firstFunded != Party.None
        ) {
            IArbitrator(_arbitrator).appeal{value: appealCost}(
                _disputeId,
                arbitratorDataHistory[request.arbitratorDataId].arbitratorExtraData
            );
            challenge.lastRoundId++;

            // Subtract the costs from the total of staked contributions
            round.feeRewards = round.feeRewards.subCap(appealCost);

            emit AppealCreated(IArbitrator(_arbitrator), _disputeId);
        }
MehdiKarimi81 commented 2 months ago

This is invalid