...which is the amount that will be spent by the contract from the buyer's wallet, spending over 99.99% of the (fillAmount) output from each loop iteration as the input of the next, and leaving a trail of dust in the buyer's wallet for each intermediary token.
The first token of a route is not affected by this issue because of LL229-230, meaning also that a swap requires the taker to have pay_amt + fee pay_gems available in his wallet and allowed to the router.
Lines of code
https://github.com/RubiconDeFi/rubicon-protocol-v1/blob/6a0e1d89ff710f81428228d132e7d0c42de3a3cd/contracts/RubiconRouter.sol#L233
Vulnerability details
Impact
By calling
RubiconMarket.buy(id, quantity)
(as a consequence of L239 and L241) with...the fee calculated by the buy function amounts to:
Adding that fee to the quantity (that the buyer sells, possibly as part of a multihop route) results in:
...which is the amount that will be spent by the contract from the buyer's wallet, spending over 99.99% of the (fillAmount) output from each loop iteration as the input of the next, and leaving a trail of dust in the buyer's wallet for each intermediary token.
The first token of a route is not affected by this issue because of LL229-230, meaning also that a swap requires the taker to have
pay_amt + fee
pay_gems available in his wallet and allowed to the router.Recommended Mitigation Steps
Do not subtract the fee at this stage.