Submitted by castle_chain, also found by bin2chen
https://github.com/code-423n4/2024-02-hydradx/blob/603187123a20e0cb8a7ea85c6a6d718429caad8d/HydraDX-node/pallets/stableswap/src/lib.rs#L787-L842
https://github.com/code-423n4/2024-02-hydradx/blob/603187123a20e0cb8a7ea85c6a6d718429caad8d/HydraDX-node/math/src/stableswap/math.rs#L40-L41
This vulnerability has been identified in the Stableswap pallet that could potentially drain all liquidity from all pools without any permissions. This vulnerability can be exploited by malicious actors, resulting in significant financial losses for both the protocol and liquidity providers.
The vulnerability lies in the buy() function, which can be exploited by setting asset_in to an asset already present in the pool and subsequently setting asset_out to the same asset. The function does not validate or prevent this input, allowing an attacker to receive the entire amount_out without providing any corresponding amount_in.
Attack Flow:
This will result in amount_in = 1 and with the fee, it will be equal to  amount_in = 1.001.
If the attacker set amount_out = 100_000_000_000_000 he will take them and only pay amount_in = 1.001.
Consider add this test into the test file trade.rs here, and see the logs resulted from this test:
The logs will be:
As shown here, Bob can drain almost all the liquidity of asset_a in the pool, and he can repeat this attack to drain all the assets exists in all the pools.
To mitigate this vulnerability, it is crucial to prevent the setting of asset_in equal to asset_out. This can be achieved by adding the following line to the buy() function:
Integrating this check into the buy() function will effectively prevent attackers from draining liquidity from the pool.
Invalid Validation
enthusiastmartin (HydraDX) confirmed and commented:
