Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: low
Invalid

Ask Offer Buyer receives no compensation if the maker fails to settle

Summary

Ask Offer Buyer receives no compensation if the maker fails to settle.

Vulnerability Details

When a maker creates an ask offer, they are required to deposited collaterals, in case they fail to settle the offer, the collaterals can be used to compensate the offer buyer.

{
/// @dev transfer collateral from _msgSender() to capital pool
uint256 transferAmount = OfferLibraries.getDepositAmount(
params.offerType,
params.collateralRate,
params.amount,
true,
Math.Rounding.Ceil
);
ITokenManager tokenManager = tadleFactory.getTokenManager();
tokenManager.tillIn{value: msg.value}(
_msgSender(),
params.tokenAddress,
transferAmount,
false
);
}

The offer authority is able to settle the offer during AskSettling phase by calling settleAskMaker(). If the authority fails to do so, the offer can be settled with point by protocol owner after AskSettling phase, however, the collaterals deposited by the offer authority is not used for compensation, hence the buyer wastes funds for nothing.

Please run the PoC in PreMakets.t.sol to verify:

function testAudit_AskOfferNotSettledAndBuyerReceiveNoCompensation() public {
// Create Market
address auditMarketPlace = GenerateAddress.generateMarketPlaceAddress("AuditMarket");
vm.startPrank(user1);
systemConfig.createMarketPlace("AuditMarket", false);
systemConfig.updateMarket("AuditMarket", address(mockPointToken), 1e18, block.timestamp + 30 days, 2 days);
vm.stopPrank();
address alice = makeAddr("Alice");
deal(address(mockUSDCToken), alice, 1200e18);
address bob = makeAddr("Bob");
deal(address(mockUSDCToken), bob, 103.5e18);
address aliceOfferAddr = GenerateAddress.generateOfferAddress(preMarktes.offerId());
// Alice creates an Bid 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(aliceOfferAddr, 100);
vm.stopPrank();
// BidSettling
vm.warp(block.timestamp + 33 days);
// owner settles the offer
vm.prank(user1);
deliveryPlace.settleAskMaker(aliceOfferAddr, 0);
// Bob receives no point token or compensation
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockUSDCToken), TokenBalanceType.TaxIncome), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockUSDCToken), TokenBalanceType.ReferralBonus), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockUSDCToken), TokenBalanceType.SalesRevenue), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockUSDCToken), TokenBalanceType.RemainingCash), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockUSDCToken), TokenBalanceType.MakerRefund), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockUSDCToken), TokenBalanceType.PointToken), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockPointToken), TokenBalanceType.TaxIncome), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockPointToken), TokenBalanceType.ReferralBonus), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockPointToken), TokenBalanceType.SalesRevenue), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockPointToken), TokenBalanceType.RemainingCash), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockPointToken), TokenBalanceType.MakerRefund), 0);
assertEq(tokenManager.userTokenBalanceMap(bob, address(mockPointToken), TokenBalanceType.PointToken), 0);
}

Impact

Ask offer buyer loses funds.

Tools Used

Manual Review

Recommendations

If an ask offer is not settled, the collaterals should be used to compensate the buyer.

Updates

Lead Judging Commences

0xnevi Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

[invalid] finding-DeliveryPlace-owner-do-not-call-settleAskMaker

Invalid, the makers are incentivized to settle offers to earn maker bonuses when subsequent takers and makers make trade using the original collateral put up for points as well as get back their initial collateral. Additionally, if they do not settle on time, they will lose all their initial collateral, forcing the `owner` to come in and perform the settlement and retrieving that collateral. This is noted as a design decision [here](https://tadle.gitbook.io/tadle/how-tadle-works/features-and-terminologies/settlement-and-collateral-rate) If all else fails, the `owner` can come in to settle as seen [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/DeliveryPlace.sol#L254-L256) and [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/DeliveryPlace.sol#L365-L367) offers to allow closing offers and subsequently allowing refunds. I acknowledge that perhaps a more decentralized

Support

FAQs

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