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
Rank: 52/119
Findings: 1
Award: $57.63
🌟 Selected for report: 0
🚀 Solo Findings: 0
57.6274 USDC - $57.63
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
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.
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); }
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