Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: high
Valid

the taker cant call `settleAskTaker()` function

Summary

the taker cant call settleAskTaker() function because it requires caller must be a maker so taker lose collateral

Vulnerability Details

in the settleAskTaker() function needs to be called by taker but there is check that prevents taker calling this function

if (_msgSender() != offerInfo.authority) { revert Errors.Unauthorized();
}

offerInfo.authority is set during offer creation to maker address

if maker call this function needs to add point to capitalpool which is wrong logic because obviously the maker himself is buyer not seller taker needs to fulfil those tokens by adding them to capital pool

POC

  • add this poc to PreMarkets.t.sol contract

  • run with forge test --mt test_settleAskTaker_access_control_poc -vvv

function test_settleAskTaker_access_control_poc() public {
deal(address(mockPointToken), user, 0);
deal(address(mockUSDCToken), user, 10e6);
deal(address(mockUSDCToken), user1, 10.35 * 1e6);
deal(address(mockUSDCToken), address(capitalPool), 1000e6);
console2.log("user USDC token before createOffer():", mockUSDCToken.balanceOf(user));
vm.startPrank(user);
preMarktes.createOffer(
CreateOfferParams(
marketPlace,
address(mockUSDCToken),
10,
10e6,
10000,
300,
OfferType.Bid,
OfferSettleType.Turbo
)
);
vm.stopPrank();
console2.log("user USDC token after createOffer():", mockUSDCToken.balanceOf(user));
vm.startPrank(user1);
console2.log("user1 USDC token before createTaker():", mockUSDCToken.balanceOf(user1));
mockUSDCToken.approve(address(tokenManager), 10.35 * 1e6);
address offerAddr = GenerateAddress.generateOfferAddress(0);
preMarktes.createTaker(offerAddr, 10);
console2.log("user1 USDC token after createTaker():", mockUSDCToken.balanceOf(user1));
address stock1Addr = GenerateAddress.generateStockAddress(1);
vm.stopPrank();
//update market
vm.prank(user1);
systemConfig.updateMarket(
"Backpack",
address(mockPointToken),
1 * 1e18,
block.timestamp + 1 days,
2 days
);
vm.warp(block.timestamp + 3 days);
vm.startPrank(user1);
mockPointToken.approve(address(tokenManager), 10e18);
vm.expectRevert(); //this line will revert with Unauthorized() error
deliveryPlace.settleAskTaker(stock1Addr, 5);
vm.stopPrank();
vm.startPrank(user);
deliveryPlace.closeBidOffer(offerAddr);
}

Impact

taker will lose collateral because they would not be able to call the settleAskTaker() function which they have to call

Tools Used

manually/ vs code

Recommendations

  • consider not preventing taker from adding tokens in settleAsktaker by not reverting if its not authority address which is maker address

Updates

Lead Judging Commences

0xnevi Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-PreMarkets-settleAskTaker-wrong-stock-authority

Valid high severity, when taker offers are created pointing to a `offer`, the relevant `stockInfoMap` offers are created with the owner of the offer aka `authority`, set as the creater of the offer, as seen [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L245). Because of the wrong check within settleAskTaker, it will permanently DoS the final settlement functionality for taker offers for the maker that listed the original offer, essentially bricking the whole functionality of the market i.e. maker will always get refunded the original collateral, and takers will never be able to transact the original points put up by the maker. This occurs regardless of market mode.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.