Submitted by trustindistrust, also found by Trust, fs0c, imare, and chaduke

The TokenSender.send() method is called during the course of users withdrawing or redeeming tokens from the protocol. The method is called via DepositHook.hook(), RedeemHook.hook(), and WithdrawHook.hook(). These in turn are called in prePOMarket.redeem() or Collateral.deposit()|.withdraw()

TokenSender.send() contains some logic to return early without sending any of the outputToken, such as if the price of the outputToken has fallen below an adjustable lower bound, or if the amount would be 0.

However, it also checks its own balance to see if it can cover the required amount. If it cannot, it simply doesnt send tokens. These tokens are intended to be a compensation for fees paid elsewhere in the process, and thus do represent a value loss.


The documentation in ITokenSender.sol states this is so the protocol doesnt halt the redeem and deposit/withdraw actions.
The warden agrees that the protocol halting is generally undesirable.
However, there isnt any facility in the code for the user who triggered the overage amount to be able to later receive their tokens when the contract is topped up. They must rely upon governance to send them any owed tokens. This increases centralization risks and isnt necessary.

Since the contract makes no attempt to track the tokens that should have been sent, manually reviewing and verifying owed tokens becomes a non-trivial task if any more than a handful of users were affected.

Since the user did receive their underlying collateral in any case and the loss isnt necessarily permanent, medium seems to be the right severity for this issue.

Bob wants to redeem his long and short tokens via PrePOMarket.redeem(). However, Alices redemption prior to his, significantly drained the TokenSender contract of its tokens. As a result, Bobs redemption fails to benefit him in the amount of the outputToken he should have received in compensation for the fees paid.
Because the quantity of tokens paid to Bob is partially dependent upon the tokens price at the time of redemption, the protocol might shoulder more  downside loss (token price dropped compared to when Bob redeemed, must pay out more tokens) or Bob might suffer upside loss (price went up compared to time of redemption, Bob loses the difference).

Bobs recourse is to contact the project administrators and try to have his tokens sent to him manually. Agreeing to a value adds friction to the process.

The TokenSender contract should track users whose balance wasnt covered in a mapping, as well as a function for them to manually claim tokens later on if the contracts balance is topped up. 
Such a function might record the price at redemption time, or it might calculate it with the current price.
Picodes (judge) commented:
ramenforbreakfast (prePO) disagreed with severity and commented:
Picodes (judge) commented:
For this contest, 37 reports were submitted by wardens detailing low risk and non-critical issues. The report highlighted below by 0xSmartContract received the top score from the judge.
The following wardens also submitted reports: joestakey,
Zarf,
Aymen0909,
0x52,
Udsen,
0Kage,
yongskiws,
0xNazgul,
caventa,
gz627,
trustindistrust,
neumo,
obront,
deliriusz,
izhelyazkov,
wait,
idkwhatimdoing,
rvierdiiev,
0xAgro,
Janio,
Rolezn,
Awesome,
Mukund,
shark,
Englave,
Tointer,
oyc_109,
Parth,
RaymondFam,
SmartSek,
csanuragjain,
UdarTeam,
Bnke0x0,
chaduke,
0xTraub, and
0xhacksmithh.
