Tadle

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

Buyer Can't Withdraw Their Fund When Seller Fails to Settle

Summary

In the Tadle protocol, when a seller fails to settle a transaction, the buyer should be able to withdraw their funds, along with any compensation from the seller, from the DeliveryPlace contract. However, due to the current implementation, the buyer is unable to do so.

Vulnerability Details

The issue arises from the logic in the DeliveryPlace contract. The contract is supposed to facilitate the withdrawal of funds for the buyer if the seller fails to settle. However, the current implementation lacks the proper mechanisms or conditions that trigger this withdrawal process, leaving the buyer's funds locked within the contract.

Proof of concept

  1. Scenario: Alice (Seller) fails to settle a transaction for Bob (Buyer) within the specified timeframe.

  2. Contract Interaction: Bob attempts to withdraw his funds plus compensation from the DeliveryPlace contract.

  3. Expected Outcome: Bob successfully withdraws his funds and compensation.

  4. Actual Outcome: Bob’s transaction fails, and he is unable to withdraw his funds.

function test_seller_failed_settlement() public {
//create the three user and deal then usdc
address alice = vm.addr(10);
address bob = vm.addr(11);
deal(address(mockUSDCToken), alice, 12000 );
deal(address(mockUSDCToken), bob, 5175 );
// alice create an ask offer
vm.startPrank(alice);
mockUSDCToken.approve(address(tokenManager), type(uint256).max);
preMarktes.createOffer(
CreateOfferParams(
marketPlace,
address(mockUSDCToken),
1000,
10000,
12000,
300,
OfferType.Ask,
OfferSettleType.Turbo
)
);
address aliceOffr = GenerateAddress.generateOfferAddress(0);
address aliceStock = GenerateAddress.generateStockAddress(0);
vm.stopPrank();
// bob buy 500 point
vm.startPrank(bob);
mockUSDCToken.approve(address(tokenManager), type(uint256).max);
preMarktes.createTaker(aliceOffr, 500);
address bobStock = GenerateAddress.generateStockAddress(1);
vm.stopPrank();
// alice call wthdraw and get salesRevenue an TaxIncome before settlement
vm.startPrank(alice);
tokenManager.withdraw(address(mockUSDCToken), TokenBalanceType.SalesRevenue);
tokenManager.withdraw(address(mockUSDCToken), TokenBalanceType.TaxIncome);
vm.stopPrank();
// change marketPlace status
vm.prank(user1);
systemConfig.updateMarket(
"Backpack",
address(mockPointToken),
1,
block.timestamp - 1,
3600
);
// update time so alice failed sttlement
vm.warp(block.timestamp + 3600);
vm.stopPrank();
vm.startPrank(bob);
// buyer call closeBidTaker and it revert
vm.expectRevert(IPerMarkets.InvalidOfferStatus.selector);
deliveryPlace.closeBidTaker(bobStock);
// tryin to withdraw all funds
tokenManager.withdraw(address(mockUSDCToken), TokenBalanceType.SalesRevenue);
tokenManager.withdraw(address(mockUSDCToken), TokenBalanceType.TaxIncome);
tokenManager.withdraw(address(mockUSDCToken), TokenBalanceType.RemainingCash);
tokenManager.withdraw(address(mockUSDCToken), TokenBalanceType.MakerRefund);
tokenManager.withdraw(address(mockPointToken), TokenBalanceType.PointToken);
assertEq(mockUSDCToken.balanceOf(bob), 0);
assertEq(mockPointToken.balanceOf(bob), 0);
vm.stopPrank();
}

Impact

This issue has a significant impact on the usability of the Tadle protocol.

recommended Mitigation

Review and Refactor Withdrawal Logic: Ensure that the withdrawal function correctly checks the settlement state and allows buyers to withdraw their funds and compensation when a seller fails to settle.

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

Appeal created

oxelmiguel Submitter
about 1 year ago
0xnevi Lead Judge
12 months ago
0xnevi Lead Judge 12 months 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.