Closed c4-bot-4 closed 6 months ago
Consider QA, round loss seems too low considering tokens may have precision of at least 6 decimals.
0xRobocop marked the issue as insufficient quality report
0xRobocop marked the issue as primary issue
Dup of #163 by the same warden, closing this one as the other one was already downgraded to QA
OpenCoreCH marked the issue as nullified
Lines of code
https://github.com/code-423n4/2024-02-hydradx/blob/main/HydraDX-node/math/src/omnipool/math.rs#L1
Vulnerability details
Bug Description
The Omnipool imposes a protocol fee which is used to rebalance the pool. This rebalancing is intended to protect the pool against the imbalance that occurs due to impermanent loss in the case of price changes. The protocol fee is imposed when a user swaps tokens using the pool.
Unfortunately this rounds in favor of the user instead of in favor of the protocol, rounding down the fee on each calculation. So if a user swaps his funds in very small tranches, he can circumvent the protocol fee and get a cheaper swap price. The maximum swap amount for this to work will be
$$amountToWithdraw < 1/feePercentage$$
For a fee of 0.05% this would for example be:
$$amountToWithdraw < 1/0.0005$$
$$amountToWithdraw < 2000$$
As the protocol fee is substantial to keep the pool balanced, this will also allow the pool to get into imbalance way quicker.
Feasibility
In the runtime configuration the minimum trading limit is defined as
MinTradingLimit : Balance = 1_000u128;
. The protocol fee is a dynamic fee which is restricted by the runtime configuration in the range from 0.05% to 0.1%. Using our calculation from above, this means that this attack will be possible almost all the time as theminTradingLimit
could only not be reached if the protocol fee is exactly 0.1%.Impact
This issue allows a user to intentionally trade in smaller portions, so that the protocol fee will be 0. This will allow the user to trade at better prices and circumvent the protocol fee which is one of the security measures that protects the pool from imbalance.
Proof of Concept
Logical
The rounding direction can clearly be seen in the following LOC when selling, as well as this LOC when buying:
Mathematical Example
A short mathematical example can also add to describe the issue. In this case a user wants to trade 5997 Token1 for Token2. In the first case he does this in one trade, in the second he splits it into multiple smaller swaps. For simplicity we will assume that the prices to LRNA are pegged 1:1 and don't significantly change (due to there being huge volume in the pool).
Testcase
The following testcase shows an exemplary situation.
The testcase must be added to the
math/src/omnipool/tests.rs
folder to run it correctly.Tools Used
Manual Review
Recommended Mitigation Steps
The issue can be mitigated by rounding in favor of the protocol, instead of in favor of the user. This can be achieved by rounding the imposed fee up instead of down. This can be achieved by using the
mul_ceil()
instead of themul_floor()
function.In the case described above this will not allow the user to circumvent the protocol fee in the way described:
Assessed type
Math