Debt DAO contest - Tomo's results

A cryptonative credit marketplace for fully anon and trustless loans to DAOs.

General Information

Platform: Code4rena

Start Date: 03/11/2022

Pot Size: $115,500 USDC

Total HM: 17

Participants: 120

Period: 7 days

Judge: LSDan

Total Solo HM: 1

Id: 174

League: ETH

Debt DAO

Findings Distribution

Researcher Performance

Rank: 67/120

Findings: 3

Award: $84.39

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

8.0811 USDC - $8.08

Labels

bug
2 (Med Risk)
satisfactory
duplicate-39

External Links

Lines of code

https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/LineLib.sol#L53-L74

Vulnerability details

https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/LineLib.sol#L53-L74

/**
 * @notice - Receive ETH or ERC20 token at this contract from an external contract
 * @param token - address of token to receive. Denominations.ETH for raw ETH
 * @param sender - address that is sendingtokens/ETH
 * @param amount - amount of tokens to send
 */
function receiveTokenOrETH(
  address token,
  address sender,
  uint256 amount
)
  external
  returns (bool)
{
    if(token == address(0)) { revert TransferFailed(); }
    if(token != Denominations.ETH) { // ERC20
        IERC20(token).safeTransferFrom(sender, address(this), amount);
    } else { // ETH
        if(msg.value < amount) { revert TransferFailed(); }
    }
    return true;
}
  1. Alice executes the addCredit() function. Alice was going to pay 1 ETH as an initial credit.
  2. However, Alice mistakenly set msg.value to 10 ETH.
  3. After executing this function, Alice noticed too much paid but it doesn’t refund because no implementation to measure too much ETH in this contract.

Impact

User may lose their ETH to overpay ETH

Proof of Concept

https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/LineLib.sol#L53-L74

Tools Used

変更してね

You should choose one of these options

  1. Ensure the fee equal to msg.value before transferring ERC20 tokens or NFT.
if(msg.value == amount) { revert TransferFailed(); }
  1. If msg.value is too much paid, refund to msg.sender
if(token != Denominations.ETH) { // ERC20
        IERC20(token).safeTransferFrom(sender, address(this), amount);
    } else { // ETH
        if(msg.value < amount) { revert TransferFailed(); } 
              uint gap = amount - msg.value;
	     if(gap > 0) {
		  (bool success, bytes memory data) = msg.sender.call{value: gap }("");
              }
	     require(success, "Failed to send Ether");		
    }

#0 - c4-judge

2022-11-17T12:12:31Z

dmvt marked the issue as duplicate of #25

#1 - c4-judge

2022-12-06T15:41:26Z

dmvt marked the issue as satisfactory

#2 - C4-Staff

2022-12-20T06:44:54Z

liveactionllama marked the issue as duplicate of #39

Findings Information

Labels

bug
2 (Med Risk)
partial-50
satisfactory
duplicate-355

Awards

70.9705 USDC - $70.97

External Links

Lines of code

https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/LineLib.sol#L59-L74

Vulnerability details

https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/LineLib.sol#L59-L74

function receiveTokenOrETH(
      address token,
      address sender,
      uint256 amount
    )
      external
      returns (bool)
    {
        if(token == address(0)) { revert TransferFailed(); }
        if(token != Denominations.ETH) { // ERC20
            IERC20(token).safeTransferFrom(sender, address(this), amount);
        } else { // ETH
            if(msg.value < amount) { revert TransferFailed(); }
        }
        return true;
    }

Users may mistakenly execute this function with non-zero msg.value white setting the token set non Denominations.ETH

The ETH would be passed to the contract and the user would lose that ETH.

Impact

Possible lost msg.value due to insufficient checking

Proof of Concept

https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/LineLib.sol#L59-L74

Tools Used

Manual

Consider reverting the transaction when the msg.value is not 0

function receiveTokenOrETH(
      address token,
      address sender,
      uint256 amount
    )
      external
      returns (bool)
    {
				if(msg.value != 0) {revert(); }
        if(token == address(0)) { revert TransferFailed(); }
        if(token != Denominations.ETH) { // ERC20
            IERC20(token).safeTransferFrom(sender, address(this), amount);
        } else { // ETH
            if(msg.value < amount) { revert TransferFailed(); }
        }
        return true;
    }

#0 - c4-judge

2022-11-17T12:14:53Z

dmvt marked the issue as duplicate of #89

#1 - c4-judge

2022-11-17T20:51:34Z

dmvt marked the issue as partial-50

#2 - c4-judge

2022-12-06T17:43:26Z

dmvt marked the issue as satisfactory

#3 - C4-Staff

2022-12-20T06:05:46Z

liveactionllama marked the issue as duplicate of #355

Awards

5.3388 USDC - $5.34

Labels

bug
2 (Med Risk)
satisfactory
duplicate-369

External Links

Lines of code

https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/LineLib.sol#L34-L51

Vulnerability details

https://github.com/debtdao/Line-of-Credit/blob/audit/code4rena-2022-11-03/contracts/utils/LineLib.sol#L34-L51

function sendOutTokenOrETH(
      address token,
      address receiver,
      uint256 amount
    )
      external
      returns (bool)
    {
 				/* ... */
        if(token!= Denominations.ETH) { // ERC20
            IERC20(token).safeTransfer(receiver, amount);
  				/* ... */
        return true;
    }

The use of the deprecated transfer() function for an address will inevitably make the transaction fail when:

  1. The claimer smart contract does not implement a payable function.
  2. The claimer smart contract does implement a payable fallback which uses more than 2300 gas unit.
  3. The claimer smart contract implements a payable fallback function that needs less than 2300 gas units but is called through proxy, raising the call's gas usage above 2300.

Additionally, using higher than 2300 gas might be mandatory for some multisig wallets.

Proof of Concept

You can see more detail about this issue

https://solidity-by-example.org/sending-ether/

https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/

Tools Used

Manual

Use call() instead of transfer() when transferring ETH

#0 - c4-judge

2022-11-17T12:14:14Z

dmvt marked the issue as duplicate of #14

#1 - c4-judge

2022-12-06T14:51:16Z

dmvt marked the issue as satisfactory

#2 - C4-Staff

2022-12-20T05:56:43Z

liveactionllama marked the issue as duplicate of #369

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