LoopFi - karsar's results

A dedicated lending market for Ethereum carry trades. Users can supply a long tail of Liquid Restaking Tokens (LRT) and their derivatives as collateral to borrow ETH for increased yield exposure.

General Information

Platform: Code4rena

Start Date: 01/05/2024

Pot Size: $12,100 USDC

Total HM: 1

Participants: 47

Period: 7 days

Judge: Koolex

Id: 371

League: ETH

LoopFi

Findings Distribution

Researcher Performance

Rank: 42/47

Findings: 1

Award: $0.00

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Awards

0 USDC - $0.00

Labels

bug
grade-b
QA (Quality Assurance)
sponsor acknowledged
sufficient quality report
edited-by-warden
Q-08

External Links

L1 - user will receive all the balance of contract instead of userClaim claim function is supposed to claim the staked amount but instead will claim balance of the contract.

   function _claim(address _token, address _receiver, uint8 _percentage, Exchange _exchange, bytes calldata _data)
       internal
       returns (uint256 claimedAmount)
   {
     ////  
       } else {
           uint256 userClaim = userStake * _percentage / 100;
           _validateData(_token, userClaim, _exchange, _data);
           balances[msg.sender][_token] = userStake - userClaim;

           // At this point there should not be any ETH in the contract
           // Swap token to ETH
           _fillQuote(IERC20(_token), userClaim, _data);

           // Convert swapped ETH to lpETH (1 to 1 conversion)
           claimedAmount = address(this).balance;
           lpETH.deposit{value: claimedAmount}(_receiver); // here @audit
       }
       emit Claimed(msg.sender, _token, claimedAmount);
   }

Recommendation

  claimedAmount = userClaim;
            lpETH.deposit{value: claimedAmount}(_receiver); 

L2 - in _claim function both the if statements is intended to do the same thing but when the _token== ETHit uses lpETH.safeTransferinstead of lpETH.deposit``

        if (_token == ETH) {
           ////
            lpETH.safeTransfer(_receiver, claimedAmount);
        } else {
           ////
            lpETH.deposit{value: claimedAmount}(_receiver);
        }
        emit Claimed(msg.sender, _token, claimedAmount);
    }

Recpmmendation

 
   if (_token == ETH) {
           ////
            lpETH.deposit{value: claimedAmount}(_receiver);
        } else {
           ////
            lpETH.deposit{value: claimedAmount}(_receiver);
        }
        emit Claimed(msg.sender, _token, claimedAmount);
    }

L3 - wrong variable set in claimed event in function _claim

            // Convert swapped ETH to lpETH (1 to 1 conversion)
            claimedAmount = address(this).balance;
            lpETH.deposit{value: claimedAmount}(_receiver);
        }
        emit Claimed(msg.sender, _token, claimedAmount); //@audit should be userClaim.
    }

Recommendation

 emit Claimed(msg.sender, _token, userClaim);

L4- ETH is not sent to the contract when depositing using lockETH function we can see its updating balance and total supply but there is no ETH sent. Token are transferred if token != ETH

   function _processLock(address _token, uint256 _amount, address _receiver, bytes32 _referral)
        internal
        onlyBeforeDate(loopActivation)
    {
        if (_amount == 0) {
            revert CannotLockZero();
        }
        if (_token == ETH) {
            totalSupply = totalSupply + _amount;
            balances[_receiver][ETH] += _amount;
        } else {
            if (!isTokenAllowed[_token]) {
                revert TokenNotAllowed();
            }
            IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);

            if (_token == address(WETH)) {
                WETH.withdraw(_amount);
                totalSupply = totalSupply + _amount;
                balances[_receiver][ETH] += _amount;
            } else {
                balances[_receiver][_token] += _amount;
            }
        }

        emit Locked(_receiver, _amount, _token, _referral);
    }
Recommendation
set token transfer after the if statements ,so it will send tokens according to token deposited 
```solidity
 if (_token == ETH) {
            totalSupply = totalSupply + _amount;
            balances[_receiver][ETH] += _amount;
        } else {
            if (!isTokenAllowed[_token]) {
                revert TokenNotAllowed();
            }
          

            if (_token == address(WETH)) {
                WETH.withdraw(_amount);
                totalSupply = totalSupply + _amount;
                balances[_receiver][ETH] += _amount;
            } else {
                balances[_receiver][_token] += _amount;
            }
        }
  IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);
        emit Locked(_receiver, _amount, _token, _referral);
``NC-1 - 0x address check in function setOwner`` Recommendation ```solidity unction setOwner(address _owner) external onlyAuthorized { if(owner == address(0){ revert(): } owner = _owner; emit OwnerUpdated(_owner); }

NC-2 make code more redeable

 totalSupply = totalSupply + _amount; 

Recommendation

 totalSupply += _amount; 

#0 - CloudEllie

2024-05-11T17:27:03Z

#1 - 0xd4n1el

2024-05-13T16:57:28Z

L-1 and the notes could be considered

#2 - c4-judge

2024-06-03T10:37:20Z

koolexcrypto marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter