Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incomplete Processing due to edge case in ProcessVouches Function #156

Open
hats-bug-reporter bot opened this issue Sep 3, 2024 · 1 comment
Open
Labels
bug Something isn't working invalid This doesn't seem right

Comments

@hats-bug-reporter
Copy link

Github username: --
Twitter username: --
Submission hash (on-chain): 0x21d618865748d34c81d6a44af88d7fcce3a3348988b3cc7f18e665933d0393fb
Severity: medium

Description:
Description
The processVouches function processes a specified number of vouches (_iterations) for a resolved request. However, if the number of vouches (vouchCount) is greater than the specified _iterations, the function will not process all vouches. The function does check for endIndex > vouchCount but it does not check if the vouchCount is greater than endIndex. This behavior can lead to incomplete processing of vouches.

Attack Scenario
Describe how the vulnerability can be exploited.

Attachments

  1. Proof of Concept (PoC) File
 function processVouches(bytes20 _humanityId, uint256 _requestId, uint256 _iterations) public {
        Request storage request = humanityData[_humanityId].requests[_requestId];
        require(request.status == Status.Resolved);

        uint256 lastProcessed = request.lastProcessedVouch;
        uint256 endIndex = _iterations.addCap(lastProcessed);
        uint256 vouchCount = request.vouches.length;

        if (endIndex > vouchCount) endIndex = vouchCount;//@audit-some vouches may not be iterate

        Reason currentReason = request.currentReason;
        // Penalty is applied for sybil attacks.
        bool applyPenalty = request.ultimateChallenger != address(0x0) &&
            (currentReason == Reason.SybilAttack || currentReason == Reason.IdentityTheft);

        while (lastProcessed < endIndex) {
            Humanity storage voucherHumanity = humanityData[request.vouches[lastProcessed]];
            voucherHumanity.vouching = false;

            if (applyPenalty) {
                // Situation when vouching address is in the middle of renewal process.
                uint256 voucherRequestId = voucherHumanity.requestCount[voucherHumanity.owner] - 1;
                if (voucherRequestId != 0) voucherHumanity.requests[voucherRequestId].punishedVouch = true;

                delete voucherHumanity.owner;

                emit HumanityDischargedDirectly(request.vouches[lastProcessed]);
            }

            unchecked {
                lastProcessed++;
            }
        }

        request.lastProcessedVouch = uint32(endIndex);

        emit VouchesProcessed(_humanityId, _requestId, endIndex);
    }

Example Scenario
Consider a scenario where:

  • lastProcessed is 0.
  • _iterations is 10.
  • vouchCount is 12.

In this case:

  • endIndex will be calculated as 10 + 0 = 10.
  • The function will process vouches from index 0 to 9 (10 vouches).
  • The remaining 2 vouches (index 10 and 11) will not be processed
  1. Revised Code File (Optional)
@hats-bug-reporter hats-bug-reporter bot added the bug Something isn't working label Sep 3, 2024
@clesaege
Copy link

clesaege commented Sep 3, 2024

This is a public function so people can call processVouches by themselves.
Processing a fixed amount of vouches is just a quality of life courtesy to save from calling processVouches in the general case.

@clesaege clesaege added the invalid This doesn't seem right label Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

1 participant