Liquidity: Lidar com problemas de envio de moedas para a conta de reserva

Criado em 27 mai. 2021  ·  4Comentários  ·  Fonte: tendermint/liquidity

Resumo do Bug

Quando alguém envia moedas para a conta de reserva de um pool, isso pode causar alguns problemas, incluindo:

  • Um pool com saldo de valor zero em um lado da moeda de reserva, levando ao cálculo incorreto do preço do pool

    • Ao retirar todas as moedas do pool e, em seguida, enviar apenas uma moeda de reserva diretamente para a conta de reserva

  • Um pânico na lógica de depósito, ao calcular a proporção da moeda de reserva (divida por erro zero com um pool descrito acima)
  • ...

Versão

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

Passos para reproduzir

Executar este teste causa pânico:

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)
}

Para uso administrativo

  • [x] Problema não duplicado
  • [x] Rótulos apropriados aplicados
  • [] Contribuidores apropriados marcados
  • [] Contribuidor atribuído / auto-atribuído
bug

Comentários muito úteis

Se definirmos um reservatório esgotado como um reservatório com estoque zero de moedas , não um reservatório com reserva zero , podemos evitar que a cadeia entre em pânico nas situações mencionadas.

Vou trabalhar nisso.

Todos 4 comentários

Se definirmos um reservatório esgotado como um reservatório com estoque zero de moedas , não um reservatório com reserva zero , podemos evitar que a cadeia entre em pânico nas situações mencionadas.

Vou trabalhar nisso.

Algo que pode ser considerado é fazer uso de contas de módulo que estão na lista negra (por meio do módulo do banco) para o recebimento de tokens, mas esta é uma mudança maior em comparação com a solução acima.

@ migueldingli1997 No início pensamos nessa abordagem, mas como ReserveAcc é criado dinamicamente quando há um novo pool, achamos que a implementação requer uma mudança maior em blockedAddrs . Ainda estamos explorando essa abordagem para ver se há uma solução alternativa.

Sim, está correto. Uma solução alternativa para isso é usar apenas uma conta de módulo (criada no genesis e com as restrições apropriadas), mas então você terá que manter o controle dos saldos de reserva para cada pool no módulo de liquidez, ao invés de deixá-lo para o banco módulo. Eu entendo que isso pode não ser desejável, no entanto.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

James-Osmo picture James-Osmo  ·  4Comentários

Cysioland picture Cysioland  ·  3Comentários

CodingAgainstChaos picture CodingAgainstChaos  ·  3Comentários

leebrooks0 picture leebrooks0  ·  3Comentários

karellm picture karellm  ·  3Comentários