hats-finance / OLD-Accumulated-finance-0x75278bcc0fa7c9e3af98654bce195eaf3bb6a784

MIT License
0 stars 0 forks source link

missing !claimed check in NATIVE `claimWithdrawal()` function #19

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

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

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

Description: Description\ in the contract minter.sol and contract NativeMinterWithdrawal and claimwithdrawal L2126 which is going to claim the withdrawals with native token

  function claimWithdrawal(uint256 withdrawalId, address receiver) public virtual nonReentrant {
        require(ownerOf(withdrawalId) == msg.sender, "NotOwner");
        WithdrawalRequest storage request = _withdrawalRequests[withdrawalId];
        require(request.processed, "NotProcessedYet");
        _burn(withdrawalId);
        request.claimed = true;
        totalUnclaimedWithdrawals = totalUnclaimedWithdrawals-request.amount;
        SafeTransferLib.safeTransferETH(receiver, request.amount);
        emit ClaimWithdrawal(address(msg.sender), receiver, request.amount, withdrawalId);
    }

sets the status to claimed but doesnt check that doesnt actually require that status should be !Claimed

like in the L2170 claimWithdrawal erc20 which DOES check that it should not be claimed but native one doesnt erc20 one: require(!request.claimed, "AlreadyClaimed"); as you see its fixed in the erc20 one but in the native one issue STILL REMAINS

Recommendation

0xRizwan commented 2 months ago

Agreed, it should be checked but it wont lead to any vulnerability as When the user claims his withdrawal, the withdrawalId will burn i.e the withdrawalId owner would be address(0) now. when the user will try again to claim withdrawal the function will revert with "NotOwner".

Would leave on sponsor to decide its validity, imo it should be informational.

0xarshia commented 2 months ago

hey Rizwan thanks for your Comment,

i double check it this will not cause loss of funds however i think it should be at least Low severity cause due to terms of the Hats Platform

Issues where the behavior of the contracts differs from the intended behavior (as described in the docs and by common sense), but no funds are at risk.

 function claimWithdrawal(uint256 withdrawalId, address receiver) public virtual nonReentrant {
        require(ownerOf(withdrawalId) == msg.sender, "NotOwner");
        WithdrawalRequest storage request = _withdrawalRequests[withdrawalId];
        require(request.processed, "NotProcessedYet");
        require(!request.claimed, "AlreadyClaimed");
        _burn(withdrawalId);
        request.claimed = true;
        totalUnclaimedWithdrawals = totalUnclaimedWithdrawals-request.amount;
        baseToken.safeTransfer(receiver, request.amount);
        emit ClaimWithdrawal(address(msg.sender), receiver, request.amount, withdrawalId);
    }

as you see the check is being made in L2170 but not in NATIVE one

Fix of the issue in Native claim

  function claimWithdrawal(uint256 withdrawalId, address receiver) public virtual nonReentrant {
        require(ownerOf(withdrawalId) == msg.sender, "NotOwner");
        WithdrawalRequest storage request = _withdrawalRequests[withdrawalId];
        require(request.processed, "NotProcessedYet");
+       require(!request.claimed, "AlreadyClaimed");
        _burn(withdrawalId);
        request.claimed = true;
        totalUnclaimedWithdrawals = totalUnclaimedWithdrawals-request.amount;
        SafeTransferLib.safeTransferETH(receiver, request.amount);
        emit ClaimWithdrawal(address(msg.sender), receiver, request.amount, withdrawalId);
    }

Thanks

Slavchew commented 2 months ago

That was removed after their first audit since has no actual value, just an unnecessary double check - https://github.com/AccumulatedFinance/contracts-v2/commit/9fae5f3ad8dacee6a6b9c114d26ce512972f71a5

0xRizwan commented 2 months ago

That was removed after their first audit since has no actual value, just an unnecessary double check - AccumulatedFinance/contracts-v2@9fae5f3

Thanks for sharing. request.claim is purposely not checked by protocol team so marking this issue as invalid.

0xarshia commented 2 months ago

yes this was removed in the commit i just saw it today but then it should be deleted from this function also so i believe it's at least low let's see sponsors' point of view

removing this and not removing another one doesn't any makes sense at all

ERC20 claim which has this require and hasn't been removed since last audit

function claimWithdrawal(uint256 withdrawalId, address receiver) public virtual nonReentrant {
        require(ownerOf(withdrawalId) == msg.sender, "NotOwner");
        WithdrawalRequest storage request = _withdrawalRequests[withdrawalId];
        require(request.processed, "NotProcessedYet");
        require(!request.claimed, "AlreadyClaimed");
        _burn(withdrawalId);
        request.claimed = true;
        totalUnclaimedWithdrawals = totalUnclaimedWithdrawals-request.amount;
        baseToken.safeTransfer(receiver, request.amount);
        emit ClaimWithdrawal(address(msg.sender), receiver, request.amount, withdrawalId);
    }

whats your opinion @ilzheev

ilzheev commented 2 months ago

ERC20 claim which has this require and hasn't been removed since last audit

Yes, it's redundant check in ERC20Minter. I marked it as low.

ilzheev commented 2 months ago

@0xRizwan https://github.com/AccumulatedFinance/contracts-v2/commit/4ed403422d0f7b828313b06dbebc2d9538c39a04