Skip to content

Commit

Permalink
ft: implement CalcAmountIn for algebra integral (#695)
Browse files Browse the repository at this point in the history
  • Loading branch information
NgoKimPhu authored Jan 11, 2025
1 parent 8803f88 commit 16c8216
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 310 deletions.
23 changes: 14 additions & 9 deletions pkg/liquidity-source/algebra/integral/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@ import (
)

var (
ErrStaleTimepoints = errors.New("getting stale timepoint data")
ErrTicksEmpty = errors.New("ticks list is empty")
ErrInvalidToken = errors.New("invalid token info")
ErrZeroAmountOut = errors.New("amountOut is 0")
ErrStaleTimepoints = errors.New("getting stale timepoint data")
ErrTicksEmpty = errors.New("ticks list is empty")
ErrInvalidToken = errors.New("invalid token info")
ErrZeroAmountCalculated = errors.New("zero amount calculated")

ErrNotSupportFetchFullTick = errors.New("not support fetching full ticks")

ErrIncorrectPluginFee = errors.New("incorrect plugin fee")
ErrInvalidLimitSqrtPrice = errors.New("invalid limit sqrt price")
ErrNotInitialized = errors.New("not initialized")
ErrInvalidAmountRequired = errors.New("invalid amount required")
ErrZeroAmountRequired = errors.New("zero amount required")
ErrIncorrectPluginFee = errors.New("incorrect plugin fee")
ErrInvalidLimitSqrtPrice = errors.New("invalid limit sqrt price")
ErrTargetIsTooOld = errors.New("target is too old")
ErrNotInitialized = errors.New("not initialized")
ErrPoolLocked = errors.New("pool has been locked and not usable")
ErrInvalidAmountRequired = errors.New("invalid amount required")
ErrZeroAmountRequired = errors.New("zero amount required")
ErrZeroPrice = errors.New("price cannot be zero")
ErrZeroLiquidity = errors.New("liquidity cannot be zero")
ErrInvalidPriceUpperLower = errors.New("price upper must not be less than price lower")

ErrLiquiditySub = errors.New("liquidity sub error")
ErrLiquidityAdd = errors.New("liquidity add error")
Expand Down
18 changes: 0 additions & 18 deletions pkg/liquidity-source/algebra/integral/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@ import (
"github.com/holiman/uint256"
)

func unsafeDivRoundingUp(x, y *uint256.Int) *uint256.Int {
quotient, remainder := new(uint256.Int).DivMod(x, y, new(uint256.Int))
if remainder.Sign() > 0 {
quotient.AddUint64(quotient, 1)
}

return quotient
}

func addDelta(x *uint256.Int, y *int256.Int) (*uint256.Int, error) {
if y.Sign() >= 0 {
uY, err := ToUInt256(y)
Expand Down Expand Up @@ -48,12 +39,3 @@ func ToUInt256(x *int256.Int) (*uint256.Int, error) {

return res, nil
}

func ToInt256(x *uint256.Int) (*int256.Int, error) {
var res = new(int256.Int)
if err := v3Utils.ToInt256(x, res); err != nil {
return nil, err
}

return res, nil
}
42 changes: 15 additions & 27 deletions pkg/liquidity-source/algebra/integral/plugin.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package integral

import (
"errors"
"fmt"
"sync"

"github.com/KyberNetwork/elastic-go-sdk/v2/utils"
Expand All @@ -12,10 +10,6 @@ import (
"github.com/holiman/uint256"
)

var (
ErrTargetIsTooOld = errors.New("target is too old")
)

type TimepointStorage struct {
mu sync.RWMutex
data map[uint16]Timepoint
Expand Down Expand Up @@ -481,19 +475,19 @@ func getOutputTokenDelta10(to, from, liquidity *uint256.Int) (*uint256.Int, erro

func getToken0Delta(priceLower, priceUpper, liquidity *uint256.Int, roundUp bool) (*uint256.Int, error) {
if priceUpper.Cmp(priceLower) < 0 {
return nil, errors.New("price upper must not be less than price lower")
return nil, ErrInvalidPriceUpperLower
}
priceDelta := new(uint256.Int).Sub(priceUpper, priceLower)

liquidityShifted := new(uint256.Int).Lsh(liquidity, RESOLUTION)

if roundUp {
division, err := v3Utils.MulDivRoundingUp(priceDelta, liquidityShifted, priceUpper)
delta, err := v3Utils.MulDivRoundingUp(priceDelta, liquidityShifted, priceUpper)
if err != nil {
return nil, err
}

return unsafeDivRoundingUp(division, priceLower), nil
v3Utils.DivRoundingUp(delta, priceLower, delta)
return delta, nil
}

mulDivResult, overflow := priceDelta.MulDivOverflow(priceDelta, liquidityShifted, priceUpper)
Expand All @@ -505,7 +499,7 @@ func getToken0Delta(priceLower, priceUpper, liquidity *uint256.Int, roundUp bool

func getToken1Delta(priceLower, priceUpper, liquidity *uint256.Int, roundUp bool) (*uint256.Int, error) {
if priceUpper.Cmp(priceLower) < 0 {
return nil, errors.New("price upper must not be less than price lower")
return nil, ErrInvalidPriceUpperLower
}
priceDelta := new(uint256.Int).Sub(priceUpper, priceLower)

Expand Down Expand Up @@ -534,13 +528,11 @@ func getNewPrice(
zeroToOne, fromInput bool,
) (*uint256.Int, error) {
if price.IsZero() {
return nil, fmt.Errorf("price cannot be zero")
}
if liquidity.IsZero() {
return nil, fmt.Errorf("liquidity cannot be zero")
}
if amount.IsZero() {
return new(uint256.Int).Set(price), nil
return nil, ErrZeroPrice
} else if liquidity.IsZero() {
return nil, ErrZeroLiquidity
} else if amount.IsZero() {
return price.Clone(), nil
}

liquidityShifted := new(uint256.Int).Lsh(liquidity, RESOLUTION)
Expand Down Expand Up @@ -571,17 +563,13 @@ func getNewPrice(
return resultPrice, nil
} else {
if fromInput {
var (
shiftedAmount *uint256.Int
overflow bool
)
shiftedAmount := new(uint256.Int)
if amount.BitLen() < 160 {
shiftedAmount = new(uint256.Int).Lsh(amount, RESOLUTION)
shiftedAmount.Lsh(amount, RESOLUTION)
shiftedAmount.Div(shiftedAmount, liquidity)
} else {
shiftedAmount, overflow = new(uint256.Int).MulDivOverflow(amount,
new(uint256.Int).Lsh(uONE, RESOLUTION), liquidity)
if overflow {
shiftedAmount.Lsh(uONE, RESOLUTION)
if _, overflow := shiftedAmount.MulDivOverflow(amount, shiftedAmount, liquidity); overflow {
return nil, ErrOverflow
}
}
Expand All @@ -598,7 +586,7 @@ func getNewPrice(
)
if amount.BitLen() < 160 {
shiftedAmount = new(uint256.Int).Lsh(amount, RESOLUTION)
shiftedAmount = unsafeDivRoundingUp(shiftedAmount, liquidity)
v3Utils.DivRoundingUp(shiftedAmount, liquidity, shiftedAmount)
} else {
shiftedAmount, err = v3Utils.MulDivRoundingUp(amount, new(uint256.Int).Lsh(uONE, RESOLUTION), liquidity)
if err != nil {
Expand Down
Loading

0 comments on commit 16c8216

Please sign in to comment.