Tadle

Tadle
DeFi
30,000 USDC
View results
Submission Details
Severity: high
Valid

Wrong token is added to userTokenBalanceMap due to incorrect argument

Summary

Wrong token is added to userTokenBalanceMap due to incorrect argument in tokenManager::addTokenBalance() call.

Vulnerability Details

The DeliveryPlace::settleAskTaker() is supposed to called by a Ask type stock owner to settle points for a bid offer [that offer for which this stock was created]. This settleAskTaker() is responsible to take pointTokens from the stock owner and add that in userTokenBalanceMap for TokenBalanceType.PointToken. However while adding the balance in the mapping USDC token was used instead of Point token, as a result USDC token will be added in the mapping instead of Point token.
NOTE: To execute the PoC given below we need to fix a issue of this code, I already submitted the report regarding that issue, you can find that issue with this title: Call to settleAskTaker() will fail every time due to wrong authority check. In short you need to correct the authority check in settleAskTaker() by changing it from offerInfo.authority to stockInfo.authority, here.I hope you fixed that issue, now lets run the PoC in Premarkets.t.sol contract:

function test_wrongToken() public {
deal(address(mockPointToken), address(user4), 100e18);
//@audit User creating a Bid offer, to buy 1000 point
vm.startPrank(user);
preMarktes.createOffer(
CreateOfferParams(
marketPlace,
address(mockUSDCToken),
1000,
0.01 * 1e18,
12000,
300,
OfferType.Bid,
OfferSettleType.Turbo
)
);
vm.stopPrank();
//@audit User4 created a stock to sell 500 point to user's Bid offer
vm.startPrank(user4);
address offerAddr = GenerateAddress.generateOfferAddress(0);
preMarktes.createTaker(offerAddr, 500);
address stock1Addr = GenerateAddress.generateStockAddress(1);
vm.stopPrank();
//@audit updateMarket() is called to set the timestamp in 'settlementPeriod' i.e tge was done
// & we are in now settlementPeriod
vm.startPrank(user1);
systemConfig.updateMarket(
"Backpack",
address(mockPointToken),
0.01 * 1e18,
block.timestamp - 1,
3600
);
//@audit updating the marketPlaceStatus to AskSettling
systemConfig.updateMarketPlaceStatus(
"Backpack",
MarketPlaceStatus.AskSettling
);
vm.stopPrank();
//@audit Now the user came & closed the Bid offer
vm.prank(user);
deliveryPlace.closeBidOffer(offerAddr);
vm.startPrank(user4);
//@audit user4 tried to settle his Ask type stock so that he can sell points to the user
mockPointToken.approve(address(tokenManager), 10000 * 10 ** 18);
console2.log(
"USDC token balance of user before settling: ",
mockUSDCToken.balanceOf(address(user))
);
console2.log(
"Point token balance of user before settling: ",
mockPointToken.balanceOf(address(user))
);
deliveryPlace.settleAskTaker(stock1Addr, 300);
vm.stopPrank();
uint ownerMakerRefund = tokenManager.userTokenBalanceMap(
address(user),
address(mockUSDCToken),
TokenBalanceType.MakerRefund
);
uint totalUSDCTokenForUser = ownerMakerRefund +
mockUSDCToken.balanceOf(address(user));
uint ownerPointToken = tokenManager.userTokenBalanceMap(
address(user),
address(mockPointToken),
TokenBalanceType.PointToken
);
uint totalPointTokenForUser = ownerPointToken +
mockPointToken.balanceOf(address(user));
console2.log(
"USDC token balance of user after settling: ",
totalUSDCTokenForUser
);
console2.log(
"Point token balance of user after settling: ",
totalPointTokenForUser
);
}

Logs:

USDC token balance of user before settling: 99999999990000000000000000
Point token balance of user before settling: 100000000000000000000000000
USDC token balance of user after settling: 100000000001000000000000000
Point token balance of user after settling: 100000000000000000000000000

As you can USDC balance was increased instead of Point token.

Impact

Wrong token will added to userTokenBalanceMap mapping.

Tool Used

Manual review, Foundry

Recommendation

tokenManager.addTokenBalance(
TokenBalanceType.PointToken,
offerInfo.authority,
- makerInfo.tokenAddress,
+ marketPlaceInfo.tokenAddress,
settledPointTokenAmount
);

This is the log of same test after editing the code as above:

USDC token balance of user before settling: 99999999990000000000000000
Point token balance of user before settling: 100000000000000000000000000
USDC token balance of user after settling: 100000000001000000000000000
Point token balance of user after settling: 100000003000000000000000000

You can see the Point token balance was increased.

Related Links

  1. https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/DeliveryPlace.sol#L384-L389

Updates

Lead Judging Commences

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

finding-DeliveryPlace-settleAskTaker-closeBidTaker-wrong-makerinfo-token-address-addToken-balance

Valid high severity, In `settleAskTaker/closeBidTaker`, by assigning collateral token to user balance instead of point token, if collateral token is worth more than point, this can cause stealing of other users collateral tokens within the CapitalPool contract, If the opposite occurs, user loses funds based on the points they are supposed to receive

Support

FAQs

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