Escher contest - tourist's results

A decentralized curated marketplace for editioned artwork.

General Information

Platform: Code4rena

Start Date: 06/12/2022

Pot Size: $36,500 USDC

Total HM: 16

Participants: 119

Period: 3 days

Judge: berndartmueller

Total Solo HM: 2

Id: 189

League: ETH

Escher

Findings Distribution

Researcher Performance

Rank: 119/119

Findings: 1

Award: $0.61

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

0.6136 USDC - $0.61

Labels

bug
2 (Med Risk)
satisfactory
edited-by-warden
duplicate-99

External Links

Lines of code

https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/FixedPrice.sol#L109 https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/LPDA.sol#L85 https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/LPDA.sol#L86 https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/LPDA.sol#L105 https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/OpenEdition.sol#L92

Vulnerability details

Impact

transfer() function forwards only 2300 gas. After EIP-1884 contract fallback functions can consume more than 2300 gas. If the the receiver is a smart contract and its fallback or receive function has a code that uses more than 2300 gas, transfer will always fail. Reference: ConsenSys Blog

Proof of Concept

PoC is demonstrated only for LPDA.sol contract. It is similar for FixedPrice.sol and OpenEdition.sol.

Test

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "forge-std/Test.sol";
import {EscherTest} from "./utils/EscherTest.sol";
import {LPDAFactory, LPDA} from "src/minters/LPDAFactory.sol";

contract SaleReceiver {
    address public teamMember1 = address(9001); // EOA
    event Received(address indexed sender, uint256 indexed amount);

    receive() external payable {
        (bool success, ) = msg.sender.call{value: msg.value}("");
        require(success, "Transfer failed");

        emit Received(msg.sender, msg.value);
    }
}

contract LPDATransfer is EscherTest {
    LPDAFactory public lpdaSales;
    LPDA.Sale public lpdaSale;
    SaleReceiver public saleReceiver;
    LPDA public sale;

    function setUp() public virtual override {
        saleReceiver = new SaleReceiver();

        super.setUp();
        lpdaSales = new LPDAFactory();
        // set up a LPDA Sale
        lpdaSale = LPDA.Sale({
            currentId: uint48(0),
            finalId: uint48(10),
            edition: address(edition),
            startPrice: uint80(uint256(1 ether)),
            finalPrice: uint80(uint256(0.1 ether)),
            dropPerSecond: uint80(uint256(0.1 ether) / 1 days),
            startTime: uint96(block.timestamp),
            saleReceiver: payable(address(saleReceiver)),
            endTime: uint96(block.timestamp + 1 days)
        });
    }

    function test_TransferWhenFinalIdReached() public {
        sale = LPDA(lpdaSales.createLPDASale(lpdaSale));
        // authorize the lpda sale to mint tokens
        edition.grantRole(edition.MINTER_ROLE(), address(sale));

        sale.buy{value: 1 ether}(1);
        assertEq(address(sale).balance, 1 ether);

        vm.warp(block.timestamp + 1 days);
        assertApproxEqRel(sale.getPrice(), 0.9 ether, lpdaSale.dropPerSecond);

        // buy the rest
        // this will auto end the sale
        sale.buy{value: uint256((0.9 ether + lpdaSale.dropPerSecond) * 9)}(9);
    }
}

Failing part of the test's result

│ │ ├─ [97] SaleReceiver::receive{value: 8550000000000334400}() │ │ │ └─ ← "EvmError: OutOfGas" │ │ └─ ← "EvmError: Revert" │ └─ ← "EvmError: Revert" └─ ← "EvmError: Revert" Test result: FAILED. 0 passed; 1 failed; finished in 3.60ms Failing tests: Encountered 1 failing test in test/LPDATransfer.t.sol:LPDATransfer

Tools Used

Foundry

Recommended way is to use call with Reentrancy guard.

#0 - c4-judge

2022-12-10T00:30:25Z

berndartmueller marked the issue as duplicate of #99

#1 - c4-judge

2023-01-03T12:48:06Z

berndartmueller marked the issue as satisfactory

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