Liquidity: 处理送币到储备账户的问题

创建于 2021-05-27  ·  4评论  ·  资料来源: tendermint/liquidity

错误总结

当有人将硬币发送到池的储备帐户时,可能会导致一些问题,包括:

  • 储备币一侧余额为零的池,导致池价格计算不正确

    • 通过从池中提取所有硬币,然后仅将一枚储备币直接发送到储备账户

  • 存款逻辑中的恐慌,在计算储备币比率时(使用上述池除以零错误)
  • ...

版本

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] 应用了适当的标签
  • [ ] 标记了适当的贡献者
  • [ ] 贡献者分配/自分配

最有用的评论

如果我们将耗尽池定义为池硬币供应量为零的池,而不是储备为零的池,我们可以防止链在上述情况下发生恐慌。

我会努力的。

所有4条评论

如果我们将耗尽池定义为池硬币供应量为零的池,而不是储备为零的池,我们可以防止链在上述情况下发生恐慌。

我会努力的。

可以考虑的是利用被列入黑名单的模块帐户(通过银行模块)接收代币,但与上述解决方案相比,这是一个更大的变化。

@migueldingli1997我们ReserveAcc是在有新池时动态创建的,我们认为实现需要对blockedAddrs进行更大的更改。 我们仍在探索这种方法,看看是否有解决方法。

是的,这是正确的。 一种解决方法是仅使用一个模块帐户(在创世时创建并具有适当的限制),但是您必须跟踪流动性模块中每个池的准备金余额,而不是将其留给银行模块。 我知道这可能不是可取的。

此页面是否有帮助?
0 / 5 - 0 等级