Skip to content

Commit 901189a

Browse files
fix dex price e6 overflow with bigint math
1 parent 380df63 commit 901189a

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

fsm/dex.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,13 +706,19 @@ func (s *StateMachine) getPrice(batch *lib.DexBatch) (p *lib.DexPrice, err lib.E
706706
if batch.PoolSize == 0 || batch.CounterPoolSize == 0 {
707707
return nil, ErrInvalidLiquidityPool()
708708
}
709+
priceNumerator := new(big.Int).Mul(new(big.Int).SetUint64(batch.PoolSize), big.NewInt(1_000_000))
710+
price := priceNumerator.Div(priceNumerator, new(big.Int).SetUint64(batch.CounterPoolSize))
711+
// DexPrice stores e6-scaled price as uint64; reject unrepresentable values instead of wrapping.
712+
if !price.IsUint64() {
713+
return nil, ErrInvalidLiquidityPool()
714+
}
709715
// exit with the dex price
710716
return &lib.DexPrice{
711717
LocalChainId: s.Config.ChainId,
712718
RemoteChainId: batch.Committee,
713719
LocalPool: batch.PoolSize,
714720
RemotePool: batch.CounterPoolSize,
715-
E6ScaledPrice: batch.PoolSize * 1_000_000 / batch.CounterPoolSize,
721+
E6ScaledPrice: price.Uint64(),
716722
}, nil
717723
}
718724

fsm/dex_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3453,6 +3453,24 @@ func clearLocks(t *testing.T, chain1, chain2 StateMachine, chain1Id, chain2Id ui
34533453
require.NoError(t, chain2.Delete(KeyForNextBatch(chain1Id)))
34543454
}
34553455

3456+
func TestGetPriceUsesBigIntForE6ScaledPrice(t *testing.T) {
3457+
sm := newTestStateMachine(t)
3458+
sm.Config.ChainId = 10
3459+
3460+
price, err := sm.getPrice(&lib.DexBatch{
3461+
Committee: 1,
3462+
PoolSize: 24515572443456,
3463+
CounterPoolSize: 50998020079,
3464+
})
3465+
require.NoError(t, err)
3466+
require.NotNil(t, price)
3467+
require.Equal(t, uint64(24515572443456), price.LocalPool)
3468+
require.Equal(t, uint64(50998020079), price.RemotePool)
3469+
require.Equal(t, uint64(480716161), price.E6ScaledPrice)
3470+
// Previous uint64 multiplication overflow produced this incorrect wrapped value.
3471+
require.NotEqual(t, uint64(119001254), price.E6ScaledPrice)
3472+
}
3473+
34563474
var _ lib.RCManagerI = new(MockRCManager)
34573475

34583476
// MockRCManager is a minimal mock implementation of lib.RCManagerI for testing

0 commit comments

Comments
 (0)