Escher contest - jadezti'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: 87/119

Findings: 2

Award: $2.18

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/LPDA.sol#L117-L125

Vulnerability details

Impact

If sale.dropPerSecond is too large, the sale.price will drop to negative value before the sale endtime sale.endTime. If the auction has not completed yet, it will fail and never finish since the transaction will revert when calling getPrice() function which underflows. All funds are stuck in the contract.

Proof of Concept

In the following test, the buy on the Day 6 will revert due to sale.price calculation underflow. Funds are stuck in the contract.

// 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 LPDAPriceFastDropTest is EscherTest {
    LPDAFactory public lpdaSales;
    LPDA.Sale public lpdaSale;

    LPDA public sale;

    function test_PriceFastDrop_LPDA() public {
        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(1 ether) / 5 days),
            startTime: uint96(block.timestamp),
            saleReceiver: payable(address(69)),
            endTime: uint96(block.timestamp + 10 days)
        });

        // make the lpda sales contract
        sale = LPDA(lpdaSales.createLPDASale(lpdaSale));
        // authorize the lpda sale to mint tokens
        edition.grantRole(edition.MINTER_ROLE(), address(sale));
        // immediatly buying 1 NFT succeed
        sale.buy{value: 5 ether}(5);
        assertEq(address(sale).balance, 5 ether);

        // price will drop to negative in 6 days; transaction will revert
        vm.warp(block.timestamp + 6 days);
        vm.expectRevert();
        sale.buy{value: uint256(1 ether)}(1);
    }
}

Tools Used

manual audit.

Setting parameters to guarantee sale.dropPerSecond < sale.startPrice/(sale.endTime - sale.startTime).

#0 - c4-judge

2022-12-11T11:38:00Z

berndartmueller marked the issue as duplicate of #392

#1 - c4-judge

2023-01-02T19:54:41Z

berndartmueller marked the issue as satisfactory

Awards

1.3417 USDC - $1.34

Labels

bug
2 (Med Risk)
satisfactory
duplicate-328

External Links

Lines of code

https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/LPDA.sol#L81

Vulnerability details

Impact

Under certain situations LPDA auction may never sell out all items. The sales income and fees have to leave in the contract.

Proof of Concept

With current coding logic, a normal LPDA auction can only be completed by selling out all items. However, in some situations, this may not happen, e.g. people are no longer interested in those NFTs. In these situations, artists cannot get the sales income; the feeReceiver cannot get the fee.

Tools Used

manual audit

To implement a mechanism to permit artists to end the auction after a pre-specified time period if the auction has not completed yet.

#0 - c4-judge

2022-12-12T09:01:32Z

berndartmueller marked the issue as duplicate of #328

#1 - c4-judge

2023-01-02T20:22:49Z

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