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

ETH Surplus Unaccounted for in batchCreateTriple Function #78

Open
hats-bug-reporter bot opened this issue Jun 30, 2024 · 1 comment
Open

ETH Surplus Unaccounted for in batchCreateTriple Function #78

hats-bug-reporter bot opened this issue Jun 30, 2024 · 1 comment
Labels
bug Something isn't working duplicate This issue or pull request already exists

Comments

@hats-bug-reporter
Copy link

Github username: --
Twitter username: --
Submission hash (on-chain): 0x45af594e37907786efc19eea5046d4b897518936ba6dc1ee0e011e4b1bfa26dd
Severity: high

Description:
Description
In the batchCreateTriple function of the EthMultiVault contract, there's an issue where potential ETH surplus from the division of msg.value by the number of triples is not accounted for or returned to the user. This can lead to small amounts of ETH being trapped in the contract, inaccessible to both users and the protocol.

Attack Scenario
While not a direct security vulnerability, this issue can lead to the following problems:

  1. Users consistently lose small amounts of ETH when creating multiple triples.
  2. Over time, these small amounts can accumulate in the contract without any mechanism to retrieve them.
  3. In extreme cases with many transactions, the accumulated ETH could become significant.

Attachments

  1. Proof of Concept (PoC) File

    ) external payable nonReentrant whenNotPaused returns (uint256[] memory) {
    if (subjectIds.length != predicateIds.length || subjectIds.length != objectIds.length) {
    revert Errors.MultiVault_ArraysNotSameLength();
    }
    uint256 length = subjectIds.length;
    uint256 tripleCost = getTripleCost();
    if (msg.value < tripleCost * length) {
    revert Errors.MultiVault_InsufficientBalance();
    }
    uint256 valuePerTriple = msg.value / length;
    uint256 protocolDepositFeeTotal;
    uint256[] memory ids = new uint256[](length);
    for (uint256 i = 0; i < length; i++) {
    uint256 protocolDepositFee;
    (ids[i], protocolDepositFee) = _createTriple(subjectIds[i], predicateIds[i], objectIds[i], valuePerTriple);
    // add protocol deposit fees to total
    protocolDepositFeeTotal += protocolDepositFee;
    }
    uint256 totalFeesForProtocol = tripleConfig.tripleCreationProtocolFee * length + protocolDepositFeeTotal;
    _transferFeesToProtocolVault(totalFeesForProtocol);
    return ids;

  2. Revised Code File (Optional)

function batchCreateTriple(
    uint256[] calldata subjectIds,
    uint256[] calldata predicateIds,
    uint256[] calldata objectIds
) external payable nonReentrant whenNotPaused returns (uint256[] memory) {
    if (subjectIds.length != predicateIds.length || subjectIds.length != objectIds.length) {
        revert Errors.MultiVault_ArraysNotSameLength();
    }

    uint256 length = subjectIds.length;
    uint256 tripleCost = getTripleCost();
    if (msg.value < tripleCost * length) {
        revert Errors.MultiVault_InsufficientBalance();
    }

    uint256 valuePerTriple = msg.value / length;
    uint256 protocolDepositFeeTotal;
    uint256[] memory ids = new uint256[](length);

    for (uint256 i = 0; i < length; i++) {
        uint256 protocolDepositFee;
        (ids[i], protocolDepositFee) = _createTriple(
            subjectIds[i],
            predicateIds[i],
            objectIds[i],
            valuePerTriple
        );

        protocolDepositFeeTotal += protocolDepositFee;
    }

    uint256 totalFeesForProtocol = tripleConfig.tripleCreationProtocolFee * length + protocolDepositFeeTotal;
    _transferFeesToProtocolVault(totalFeesForProtocol);

    // Calculate and refund any surplus
    uint256 surplus = msg.value - (valuePerTriple * length);
    if (surplus > 0) {
        (bool success,) = msg.sender.call{value: surplus}("");
        require(success, "Surplus refund failed");
    }

    return ids;
}
@hats-bug-reporter hats-bug-reporter bot added the bug Something isn't working label Jun 30, 2024
@mihailo-maksa mihailo-maksa added duplicate This issue or pull request already exists invalid This doesn't seem right labels Jul 1, 2024
@mihailo-maksa
Copy link
Collaborator

Essentially a duplicate of issue #69, just related to batchCreateTriple instead of batchCreateAtom.

@mihailo-maksa mihailo-maksa removed the invalid This doesn't seem right label Jul 4, 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 duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

1 participant