Summary
The settleAskTaker
and closeBidTaker
functions in DeliveryPlace
incorrectly credit the collateral token instead of the point token during settlement
Vulnerability Details
During the settlment period, bidder takers call settleAskTaker
to settle the points they sold to bid offer makers. The issue is that the function incorrectly credits the collateral token to the offer makers' balance instead of the point token.
function settleAskTaker(address _stock, uint256 _settledPoints) external {
IPerMarkets perMarkets = tadleFactory.getPerMarkets();
StockInfo memory stockInfo = perMarkets.getStockInfo(_stock);
(
OfferInfo memory offerInfo,
MakerInfo memory makerInfo,
MarketPlaceInfo memory marketPlaceInfo,
MarketPlaceStatus status
) = getOfferInfo(stockInfo.preOffer);
if (settledPointTokenAmount > 0) {
tokenManager.tillIn(
_msgSender(),
marketPlaceInfo.tokenAddress,
settledPointTokenAmount,
true
);
tokenManager.addTokenBalance(
TokenBalanceType.PointToken,
offerInfo.authority,
>>> makerInfo.tokenAddress,
settledPointTokenAmount
);
}
}
In the above code, the function correctly deposits the point token from the taker with tokenManager.tillIn(_msgSender(), marketPlaceInfo.tokenAddress, settledPointTokenAmount, true)
. However, it mistakenly credits the offer maker with the collateral token (makerInfo.tokenAddress
) instead of the point token (marketPlaceInfo.tokenAddress
):
tokenManager.addTokenBalance(TokenBalanceType.PointToken,offerInfo.authority,
makerInfo.tokenAddress,
settledPointTokenAmount
);
This issue also appears in the closeBidTaker
function, where ask takers attempting to claim their point tokens after the settlement are incorrectly credited with the collateral token:
function closeBidTaker(address _stock) external {
IPerMarkets perMarkets = tadleFactory.getPerMarkets();
ITokenManager tokenManager = tadleFactory.getTokenManager();
StockInfo memory stockInfo = perMarkets.getStockInfo(_stock);
uint256 pointTokenAmount = offerInfo.settledPointTokenAmount.mulDiv(
userRemainingPoints,
offerInfo.usedPoints,
Math.Rounding.Floor
);
tokenManager.addTokenBalance(
TokenBalanceType.PointToken,
_msgSender(),
>>> makerInfo.tokenAddress,
pointTokenAmount
);
}
In this function, ask takers are similarly credited with the collateral token (makerInfo.tokenAddress
) instead of the correct point token.
Impact
This vulnerability results in bid offer makers and ask offer takers not receiving the appropriate point tokens
Tools Used
Manual review
Recommendations
The settleAskTaker
and closeBidTaker
functions should be updated to correctly credit the point token. Below are the suggested code changes:
settleAskTaker
:
function settleAskTaker(address _stock, uint256 _settledPoints) external {
IPerMarkets perMarkets = tadleFactory.getPerMarkets();
StockInfo memory stockInfo = perMarkets.getStockInfo(_stock);
(
OfferInfo memory offerInfo,
MakerInfo memory makerInfo,
MarketPlaceInfo memory marketPlaceInfo,
MarketPlaceStatus status
) = getOfferInfo(stockInfo.preOffer);
//...
if (settledPointTokenAmount > 0) {
tokenManager.tillIn(
_msgSender(),
marketPlaceInfo.tokenAddress,
true
);
tokenManager.addTokenBalance(
TokenBalanceType.PointToken,
offerInfo.authority,
- makerInfo.tokenAddress,
+ marketPlaceInfo.tokenAddress
settledPointTokenAmount
);
}
// ...
}
closeBidTaker
:
function closeBidTaker(address _stock) external {
IPerMarkets perMarkets = tadleFactory.getPerMarkets();
ITokenManager tokenManager = tadleFactory.getTokenManager();
StockInfo memory stockInfo = perMarkets.getStockInfo(_stock);
(
OfferInfo memory preOfferInfo,
MakerInfo memory makerInfo,
+ MarketPlaceInfo memory marketPlaceInfo
,
) = getOfferInfo(stockInfo.preOffer);
// ...
uint256 pointTokenAmount = offerInfo.settledPointTokenAmount.mulDiv(
userRemainingPoints,
offerInfo.usedPoints,
Math.Rounding.Floor
);
tokenManager.addTokenBalance(
TokenBalanceType.PointToken,
_msgSender(),
- makerInfo.tokenAddress,
+ marketPlaceInfo.tokenAddress
pointTokenAmount
);
}