hats-finance / Intuition-0x538dbadc50cc87b281cd655f1edbc6ebda02a66a

The smart contracts of the Intuition protocol v1.
https://intuition.systems
Other
0 stars 1 forks source link

ETH Surplus Unaccounted for in batchCreateTriple Function #78

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

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

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 https://github.com/hats-finance/Intuition-0x538dbadc50cc87b281cd655f1edbc6ebda02a66a/blob/b2e422ff0c3e3729e58d2699fdf2ef8699fbd172/src/EthMultiVault.sol#L544-L570

  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;
    }