Liquidity: リザーブアカウントにコインを送る際の問題に対処する

作成日 2021年05月27日  ·  4コメント  ·  ソース: tendermint/liquidity

バグの概要

誰かがプールのリザーブアカウントにコインを送ると、次のような問題が発生する可能性があります。

  • リザーブコインの片側の残高がゼロのプールで、プール価格の計算が正しくありません

    • プールからすべてのコインを引き出し、1つのリザーブコインのみをリザーブアカウントに直接送信する

  • リザーブコイン比率を計算するときのデポジットロジックのパニック(上記のプールでゼロ除算エラー)
  • ..。

バージョン

https://github.com/tendermint/liquidity/releases/tag/v1.2.5

再現する手順

このテストを実行すると、パニックが発生します。

func TestSwapHalfZeroReserve(t *testing.T) {
    simapp, ctx := createTestInput()
    params := simapp.LiquidityKeeper.GetParams(ctx)
    pool, addr, err := createPool(simapp, ctx, sdk.NewInt(1000000), sdk.NewInt(1000000), DenomX, DenomY)
    require.NoError(t, err)
    pc := simapp.BankKeeper.GetBalance(ctx, addr, pool.PoolCoinDenom)
    _, err = simapp.LiquidityKeeper.WithdrawLiquidityPoolToBatch(ctx, types.NewMsgWithdrawWithinBatch(addr, pool.Id, pc))
    require.NoError(t, err)
    liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
    liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
    require.True(t, simapp.BankKeeper.GetBalance(ctx, pool.GetReserveAccount(), DenomX).IsZero())
    require.True(t, simapp.BankKeeper.GetBalance(ctx, pool.GetReserveAccount(), DenomY).IsZero())
    err = simapp.BankKeeper.SendCoins(ctx, addr, pool.GetReserveAccount(), sdk.NewCoins(sdk.NewInt64Coin(DenomX, 10000)))
    require.NoError(t, err)
    _, err = simapp.LiquidityKeeper.SwapLiquidityPoolToBatch(ctx,
        types.NewMsgSwapWithinBatch(
            addr, pool.Id, types.DefaultSwapTypeId, sdk.NewInt64Coin(DenomX, 1000), DenomY, sdk.MustNewDecFromStr("1.0"), params.SwapFeeRate), 0)
    require.NoError(t, err)
    liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
    liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
}

管理者用

  • [x]重複しない問題
  • [x]適切なラベルが適用されました
  • []タグ付けされた適切な貢献者
  • []コントリビューター割り当て/自己割り当て
bug

最も参考になるコメント

枯渇したプールリザーブがゼロのプールではなくコインの供給がゼロのプールとして定義

私はそれに取り組みます。

全てのコメント4件

枯渇したプールリザーブがゼロのプールではなくコインの供給がゼロのプールとして定義

私はそれに取り組みます。

考慮できることは、トークンの受信から(銀行モジュールを介して)ブラックリストに登録されているモジュールアカウントを利用することですが、これは上記のソリューションと比較して大きな変更です。

@ migueldingli1997最初はそのアプローチについて考えましたが、新しいプールがあるとReserveAccが動的に作成されるため、実装にはblockedAddrsへの大幅な変更が必要になると考えています。 回避策があるかどうかを確認するために、このアプローチを引き続き検討しています。

はい、その通りです。 その場合の回避策は、1つのモジュールアカウント(ジェネシスで作成され、適切な制限付き)を使用することですが、銀行に任せるのではなく、流動性モジュールの各プールの準備金残高を追跡する必要がありますモジュール。 ただし、これは望ましくない場合があることを理解しています。

このページは役に立ちましたか?
0 / 5 - 0 評価