After settlement, the taker of an ask offer should receive the point tokens they bought. This is done through a token balance which
is added to the taker's account in the TokenManager::addTokenBalance function.
The system incorrectly adds a balance of the collateral token (USDC in the following PoC) to the taker instead of point tokens which the actually bought.
When a taker (buyer) purchases point tokens from a maker (seller), the following process occurs:
The maker creates an offer to sell point tokens (PreMarkets::createOffer)
The taker fills the offer (PreMarkets::createTaker)
The owner updates the market to after the TGE (SystemConfig::updateMarket)
The maker settles the offer (DeliveryPlace::settleAskMaker)
The taker closes the bid taker (DeliveryPlace::closeBidTaker)
In the last step a token balance is added to the taker's account which allows them to withdraw the point tokens they bought later on (DeliveryPlace line 195-200):
However, makerInfo.tokenAddress is not the address of the point token but the collateral token. Therefore the TokenManager::addTokenBalance function give the taker the wrong token balance to withdraw (TokenManager line 113-129):
The following PoC demonstrates the issue. The test will revert because the expected event (allow taker to withdraw 1000 point tokens) does not match the emitted event (allow taker to withdraw 1000 collateral tokens (USDC)).
testSeller: The maker who wants to sell point token
testBuyer: The taker who wants to buy point token
user1: The owner of the market
Please copy the test into PreMarkets.t.sol:
The taker is unable to withdraw the point tokens they bought, effectively locking their funds in the contract.
Probably even more serious: The taker gets a wrong token balance for the collateral token which they can withdraw
This disrupts the collateral balance of the system and may prevent others to withdraw their collateral
Impact: High
Likelihood: High
-> Severity: High
Manual code review
Forge unit tests
The MarketPlaceInfo.tokenAddress contains the address of the point token. Use it instead of the makerInfo.tokenAddress in the DeliveryPlace::closeBidTaker function:
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
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.