script3 / yieldblox-beta

15 stars 5 forks source link

Weird Interaction With Liquidity Pool #339

Closed Firdausfarul closed 2 years ago

Firdausfarul commented 2 years ago

be me, yesterday create a YBX-USDC liquidity pool for fun Deposited 10 USDC and 1 YBX Tried to check the liquidity pool again an hour ago whatthefuck.jpg YBX balance becomes near zero, while USDC balance grows to ~3 Million "Wait, no beta tester have that much USDC' Check the account that trades in the liquidity pool it's Yieldblox account that used for smart contract

Liq Pool Id : d600a004ecf7d07b4b2305ae9a7305e402bed3e0a16375ca948177c25798a65d The weird transaction : https://horizon-testnet.stellar.org/operations/2231858280542227 https://horizon-testnet.stellar.org/operations/2231858280542228

f0xie7 commented 2 years ago

Seems u got additional assets from the profit of YBX trading, 1 YBX got 3Million USDC, congrats

Firdausfarul commented 2 years ago

Dang it, this is a problem/misapplication with Horizon API. A new liquidity pool fucks up things. So this is probably what happened.

  1. Yieldblox want to trade ~48 BTC for YBX
  2. for some reason YBX market makers only provide ~150k USDC liquidity
  3. yieldblox fetching Path for Path Payment Strict Send
  4. Horizon API return BTC-USDC-YBX path instead BTC-USDC-XLM-YBX since there isn't enough liquidity
  5. There are only 10 USDC and 1 YBX in the liquidity pool, a new 3 Million USDC will only return ~0.9999 YBX (x*y=k thing)
  6. The trade will still be executed since the minimum received for that OP is only 0.0000001 YBX, despite it's bad price.
  7. Liquidity pool balance is now 3 Million USDC + small amount of YBX
  8. The same transaction but instead of BTC it's ETH
  9. now it's only 150k USDC worth of ETH exchanged for 1 stroop of YBX
  10. The next EURT & USDC Path Payment are executed on orderbook since there's enough liquidity

I speculate that the amount of USDC liquidity provided by the market makers also fetched from Path for Path Payment Strict Send. It only provided liquidity for EURT & USDC - YBX, because the bot thinks that there's enough liquidity for the earlier 2 transaction. There aren't enough liquidity for USDC & EURT because the price is so high that you can't even buy 1 stroop of YBX with it. Remember that during ETH trade, it costs ~150k for 1 YBX, meanwhile both USDC and EURT sent amount are worth less than ~150k USDC.

Since Liquidity pool transaction are interleavable, a weird thing will happen with Horizon Path for Path Payment Strict Send API, it'll return something like this chart image

I think SDF need to "Fix" the API or do something with this. Maybe orbitlens was right with his CAP 37 after all. This abnormality mostly doesn't effect most apps, since most app have their Minimum Received amount setted not on 0.0000001 (I know YBX goes with 1 stroop because it's liquidation, it must be sold at all cost.). This problem can be considered very rare edge case though, you need an order exceeding orderbook depth and have near zero minimum received amount.

mootz12 commented 2 years ago

Good catch on this - we were able to successfully file this with against Horizon - https://github.com/stellar/go/issues/4014

While this isn't technically a bug against our protocol, I still want to award this something.

Firdausfarul commented 2 years ago

Discord : Fahrul#7469