Tadle

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

Askers Loses All Their Collateral and Point Tokens When They Partially Settle Bidder

Summary

The protocol reasonably supports partial settlements but unfairly punishes Askers when they partially settle their Bidders.

Vulnerability Details

In DeliveryPlace::settleAskTaker, the Ask taker loses all their collateral and point tokens to the Bid maker for partially settling them.

@> if (_settledPoints == stockInfo.points) {
tokenManager.addTokenBalance(
TokenBalanceType.RemainingCash,
_msgSender(),
makerInfo.tokenAddress,
collateralFee
);
} else {
tokenManager.addTokenBalance(
TokenBalanceType.MakerRefund,
offerInfo.authority,
makerInfo.tokenAddress,
collateralFee
);
}

Similarly, the maker loses their collateral and pointTokens in DeliveryPlace::settleAskMaker when they partially settle their taker.

if (_settledPoints == offerInfo.usedPoints) {
if (offerInfo.offerStatus == OfferStatus.Virgin) {
makerRefundAmount = OfferLibraries.getDepositAmount(
offerInfo.offerType,
offerInfo.collateralRate,
offerInfo.amount,
true,
Math.Rounding.Floor
);
} else {
uint256 usedAmount = offerInfo.amount.mulDiv(
offerInfo.usedPoints,
offerInfo.points,
Math.Rounding.Floor
);
makerRefundAmount = OfferLibraries.getDepositAmount(
offerInfo.offerType,
offerInfo.collateralRate,
usedAmount,
true,
Math.Rounding.Floor
);
}

Not returning any of the Asker's collateral to them while transferring their point tokens to the Bidder is problematic, as it can cause a significant loss for the Askers, despite them not violating any protocol rules.

Related Protocol Rule from to the Doc:

"If sellers fail to settle in time after the settlement period is over, they will lose their collateral funds, and the buyer could claim compensation from your collateral via the smart contract."

Emphasis on "if they fail to settle in time."
Note that there is no specification on whether the settlement has to be full or partial, and the only indication of this is the code, which clearly shows that Tadle supports partial settlement. The availability of the _settledPoints argument in the DeliveryPlace::settleAskMaker and DeliveryPlace::settleBidTaker functions indicates the support for partial settlement. And partial settlement does not constitute failure to settle.

The above comments from the documentation may lead one to interpret this finding as a design choice. However, the documentation is clear that the taker is only punished if they "fail to settle in time." This vulnerability points out the loss for takers despite settling, albeit partially. Consider that partial settlement can occur for various reasons, such as:

  • The third-party protocol team misallocating point tokens to the taker’s address. This is a possibility considering Tadle doesn't cap the number of points that can be created. The higher the supply of points, the lower the value of point tokens at TGE, which could cause protocols to reallocate their token supply.

  • The protocol team delaying their supply of point tokens after TGE date has been set, for the same reason mentioned above, as the value of a newly launched token is a critical tokenomics factor.

Note that the two examples given above are rooted in Tadle's problematic implementation of their points system. The point supply isn't controlled, causing issues for the token value of their partner projects.

function settleAskTaker(address _stock, uint256 _settledPoints) external {
function settleAskMaker(address _offer, uint256 _settledPoints) external {

The above code snippet proves that the protocol supports partial settlements, as evidenced by the availability of the _settledPoints argument in the DeliveryPlace::settleAskMaker and DeliveryPlace::settleBidTaker functions.

Impact

Loss of funds for users (Ask taker)

Tools Used

Manual

Recommendations

The correct implementation would be to send the Ask taker the corresponding portion of their collateral for the points they settled, and if needed, charge extra fees based on the unsettled amount of points that can be used to compensate the Bid maker for any inconviniences.

Updates

Lead Judging Commences

0xnevi Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-DeliveryPlace-settleAskTaker-settleAskMaker-partial-settlements

Valid high, in settleAskTaker/settleAskMaker, if the original offer maker performs a partial final settlement, the existing checks [here](https://github.com/Cyfrin/2024-08-tadle/blob/main/src/core/DeliveryPlace.sol#L356-L358) and [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/DeliveryPlace.sol#L230-L232) will cause an revert when attempting to complete a full settlement, resulting in their collateral being locked and requiring a rescue from the admin. To note, although examples in the documentation implies settlement in a single click, it is not stated that partial settlements are not allowed, so I believe it is a valid user flow.

Support

FAQs

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