Skip to content

Commit

Permalink
level-finance: get reserves
Browse files Browse the repository at this point in the history
  • Loading branch information
guiltylotus committed Nov 3, 2023
1 parent 6c20023 commit dbbaecc
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 10 deletions.
13 changes: 13 additions & 0 deletions pkg/source/level-finance/abi/LiquidityPool.json
Original file line number Diff line number Diff line change
Expand Up @@ -2482,5 +2482,18 @@
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getAllTranches",
"outputs": [
{
"internalType": "address[]",
"name": "tranches",
"type": "address[]"
}
],
"stateMutability": "view",
"type": "function"
}
]
8 changes: 6 additions & 2 deletions pkg/source/level-finance/constant.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package levelfinance

import "github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/bignumber"
import (
"github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/bignumber"
"math/big"
)

const (
DexTypeLevelFinance = "level-finance"
Expand Down Expand Up @@ -28,5 +31,6 @@ const (
var (
DefaultGas = Gas{Swap: 125000}

precision = bignumber.TenPowInt(10)
precision = bignumber.TenPowInt(10)
minSwapFee = big.NewInt(10000000)
)
20 changes: 15 additions & 5 deletions pkg/source/level-finance/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
)

func swap(tokenIn, tokenOut string, amountIn *big.Int, state *PoolState) (*big.Int, error) {
// Check allowSwap

if tokenIn == tokenOut {
return nil, ErrSameTokenSwap
}
Expand All @@ -33,15 +35,18 @@ func swap(tokenIn, tokenOut string, amountIn *big.Int, state *PoolState) (*big.I

rebalanceTranches(tokenInInfo, new(big.Int).Sub(amountIn, daoFee), tokenOutInfo, amountOutAfterFee, state)

// _validateMaxLiquidity

return amountOutAfterFee, nil
}

func calcSwapOutput(tokenIn, tokenOut *TokenInfo, amountIn *big.Int, state *PoolState) (*big.Int, *big.Int, error) {
priceIn := new(big.Int).Set(tokenIn.MinPrice)
priceOut := new(big.Int).Set(tokenOut.MaxPrice)
valueChange := new(big.Int).Mul(amountIn, priceIn)
feeIn := calcSwapFee(tokenIn, priceIn, valueChange, true, state)
feeOut := calcSwapFee(tokenOut, priceOut, valueChange, false, state)
isStableSwap := tokenIn.IsStableCoin && tokenOut.IsStableCoin
feeIn := calcSwapFee(isStableSwap, tokenIn, priceIn, valueChange, true, state)
feeOut := calcSwapFee(isStableSwap, tokenOut, priceOut, valueChange, false, state)

fee := feeIn
if feeIn.Cmp(feeOut) <= 0 {
Expand All @@ -66,9 +71,9 @@ func calcSwapOutput(tokenIn, tokenOut *TokenInfo, amountIn *big.Int, state *Pool
return amountOutAfterFee, feeAmount, nil
}

func calcSwapFee(token *TokenInfo, tokenPrice, valueChange *big.Int, isSwapIn bool, state *PoolState) *big.Int {
func calcSwapFee(isStableSwap bool, token *TokenInfo, tokenPrice, valueChange *big.Int, isSwapIn bool, state *PoolState) *big.Int {
var baseSwapFee, taxBasicPoint *big.Int
if token.IsStableCoin {
if isStableSwap {
baseSwapFee = new(big.Int).Set(state.StableCoinBaseSwapFee)
taxBasicPoint = new(big.Int).Set(state.StableCoinTaxBasisPoint)
} else {
Expand Down Expand Up @@ -112,7 +117,11 @@ func calcFeeRate(token *TokenInfo, tokenPrice, valueChange, baseFee, taxBasicPoi
new(big.Int).Mul(taxBasicPoint, initDiff),
targetValue,
)
return zeroCapSub(baseFee, feeAdjust)
rate := zeroCapSub(baseFee, feeAdjust)
if rate.Cmp(minSwapFee) > 0 {
return rate
}
return new(big.Int).Set(minSwapFee)
} else {
avgDiff := new(big.Int).Div(
new(big.Int).Add(initDiff, nextDiff),
Expand Down Expand Up @@ -166,6 +175,7 @@ func calcTrancheSharesAmount(indexToken, collateralToken *TokenInfo, amount *big
maxShare := make(map[string]*big.Int, len(indexToken.TrancheAssets))

for trancheAddress := range indexToken.TrancheAssets {
reserves[trancheAddress] = big.NewInt(0)
asset := collateralToken.TrancheAssets[trancheAddress]
factors[trancheAddress] = big.NewInt(1)
if !indexToken.IsStableCoin {
Expand Down
16 changes: 15 additions & 1 deletion pkg/source/level-finance/pool_simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ func NewPoolSimulator(entityPool entity.Pool) (*PoolSimulator, error) {
},
},
state: &PoolState{
TokenInfos: extra.TokenInfos,
TokenInfos: extra.TokenInfos,
TotalWeight: extra.TotalWeight,
VirtualPoolValue: extra.VirtualPoolValue,
StableCoinBaseSwapFee: extra.StableCoinBaseSwapFee,
StableCoinTaxBasisPoint: extra.StableCoinTaxBasisPoint,
BaseSwapFee: extra.BaseSwapFee,
TaxBasisPoint: extra.TaxBasisPoint,
DaoFee: extra.DaoFee,
},
}, nil
}
Expand Down Expand Up @@ -74,8 +81,13 @@ func (p *PoolSimulator) UpdateBalance(params pool.UpdateBalanceParams) {
return

Check failure on line 81 in pkg/source/level-finance/pool_simulator.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

S1023: redundant `return` statement (gosimple)
}

func (p *PoolSimulator) GetMetaInfo(tokenIn string, tokenOut string) interface{} {
return nil
}

func (p *PoolSimulator) deepCopyState(state *PoolState) *PoolState {
newState := &PoolState{
TokenInfos: make(map[string]*TokenInfo),
TotalWeight: new(big.Int).Set(state.TotalWeight),
VirtualPoolValue: new(big.Int).Set(state.VirtualPoolValue),
StableCoinBaseSwapFee: new(big.Int).Set(state.StableCoinBaseSwapFee),
Expand All @@ -88,6 +100,8 @@ func (p *PoolSimulator) deepCopyState(state *PoolState) *PoolState {
newState.TokenInfos[key] = &TokenInfo{
IsStableCoin: value.IsStableCoin,
TargetWeight: new(big.Int).Set(value.TargetWeight),
TrancheAssets: make(map[string]*AssetInfo),
RiskFactor: make(map[string]*big.Int),
TotalRiskFactor: new(big.Int).Set(value.TotalRiskFactor),
MinPrice: new(big.Int).Set(value.MinPrice),
MaxPrice: new(big.Int).Set(value.MaxPrice),
Expand Down
43 changes: 43 additions & 0 deletions pkg/source/level-finance/pool_simulator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package levelfinance_test

import (
"github.com/KyberNetwork/kyberswap-dex-lib/pkg/entity"
levelfinance "github.com/KyberNetwork/kyberswap-dex-lib/pkg/source/level-finance"
"github.com/KyberNetwork/kyberswap-dex-lib/pkg/source/pool"
"github.com/KyberNetwork/kyberswap-dex-lib/pkg/util/bignumber"
"github.com/stretchr/testify/assert"
"testing"
)

func TestCalcAmountOut(t *testing.T) {
levelFinancePool, err := levelfinance.NewPoolSimulator(entity.Pool{
Address: "0x73c3a78e5ff0d216a50b11d51b262ca839fcfe17",
Exchange: "level-finance",
Type: "level-finance",
Reserves: entity.PoolReserves{"779313577917429145001279", "1386752187018865380131"},
Tokens: []*entity.PoolToken{
{
Address: "0x2170ed0880ac9a755fd29b2688956bd959f933f8",
Decimals: 18,
},
{
Address: "0x55d398326f99059ff775485246999027b3197955",
Decimals: 18,
},
},
Extra: "{\"oracle\":\"0x347a868537c96650608b0C38a40d65fA8668bb61\",\"tokenInfos\":{\"0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82\":{\"isStableCoin\":false,\"targetWeight\":0,\"trancheAssets\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":{\"poolAmount\":0,\"reserveAmount\":0},\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":{\"poolAmount\":0,\"reserveAmount\":0},\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":{\"poolAmount\":1515612264199876,\"reserveAmount\":0}},\"riskFactor\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":0,\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":0,\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":0},\"totalRiskFactor\":100000,\"minPrice\":1525411950000,\"maxPrice\":1525411950000},\"0x2170ed0880ac9a755fd29b2688956bd959f933f8\":{\"isStableCoin\":false,\"targetWeight\":25000,\"trancheAssets\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":{\"poolAmount\":88409477196046758709,\"reserveAmount\":3758081405615144417},\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":{\"poolAmount\":1273285914369262213583,\"reserveAmount\":19626301909258985334},\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":{\"poolAmount\":25056795453556407839,\"reserveAmount\":4829823313157371109}},\"riskFactor\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":0,\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":0,\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":0},\"totalRiskFactor\":1,\"minPrice\":1800186152960000,\"maxPrice\":1800186152960000},\"0x55d398326f99059ff775485246999027b3197955\":{\"isStableCoin\":true,\"targetWeight\":41000,\"trancheAssets\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":{\"poolAmount\":184341536385327250951544,\"reserveAmount\":29495041636499676110955},\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":{\"poolAmount\":521599008999365338023501,\"reserveAmount\":14800885608374279815880},\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":{\"poolAmount\":73373032532736556026234,\"reserveAmount\":35744357844692178501361}},\"riskFactor\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":0,\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":0,\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":0},\"totalRiskFactor\":0,\"minPrice\":1000270130000,\"maxPrice\":1000270130000},\"0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c\":{\"isStableCoin\":false,\"targetWeight\":30800,\"trancheAssets\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":{\"poolAmount\":5816697803176260078,\"reserveAmount\":3383010407777685588},\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":{\"poolAmount\":111906233603518278521,\"reserveAmount\":4501534065981811378},\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":{\"poolAmount\":4938928540475400967,\"reserveAmount\":3832600695744573765}},\"riskFactor\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":0,\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":0,\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":0},\"totalRiskFactor\":1,\"minPrice\":34699370809700000,\"maxPrice\":34699370809700000},\"0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c\":{\"isStableCoin\":false,\"targetWeight\":3000,\"trancheAssets\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":{\"poolAmount\":359302236490299536203,\"reserveAmount\":103226605503390418504},\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":{\"poolAmount\":454243991764384413972,\"reserveAmount\":7741757526752034806},\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":{\"poolAmount\":264772809488184251242,\"reserveAmount\":140152480740415789817}},\"riskFactor\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":0,\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":0,\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":0},\"totalRiskFactor\":1,\"minPrice\":230162156910000,\"maxPrice\":230162156910000},\"0xe9e7cea3dedca5984780bafc599bd69add087d56\":{\"isStableCoin\":true,\"targetWeight\":0,\"trancheAssets\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":{\"poolAmount\":0,\"reserveAmount\":0},\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":{\"poolAmount\":0,\"reserveAmount\":0},\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":{\"poolAmount\":4351267527855370,\"reserveAmount\":0}},\"riskFactor\":{\"0x4265af66537F7BE1Ca60Ca6070D97531EC571BDd\":0,\"0xB5C42F84Ab3f786bCA9761240546AA9cEC1f8821\":0,\"0xcC5368f152453D497061CB1fB578D2d3C54bD0A0\":0},\"totalRiskFactor\":0,\"minPrice\":1000370160000,\"maxPrice\":1000370160000}},\"totalWeight\":99800,\"virtualPoolValue\":7631639747905684688745700698456428608,\"stableCoinBaseSwapFee\":1000000,\"stableCoinTaxBasisPoint\":5000000,\"baseSwapFee\":25000000,\"taxBasisPoint\":40000000,\"daoFee\":5500000000}",
})

assert.Nil(t, err)

result, err := levelFinancePool.CalcAmountOut(
pool.TokenAmount{
Token: "0x2170ed0880ac9a755fd29b2688956bd959f933f8",
Amount: bignumber.NewBig10("1000000000000000000"),
},
"0x55d398326f99059ff775485246999027b3197955",
)

assert.Nil(t, err)
assert.Equal(t, "1789789741024165775187", result.TokenAmountOut.Amount.String())
}
21 changes: 19 additions & 2 deletions pkg/source/level-finance/pool_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ func (d *PoolTracker) GetNewPoolState(

var tranches = make([]common.Address, 0)
if d.config.ChainID == int(valueobject.ChainIDBSC) {
tranches = make([]common.Address, trancheLength.Int64())
for i := 0; i < int(trancheLength.Int64()); i++ {
tranches = append(tranches, common.Address{})
calls.AddCall(&ethrpc.Call{
ABI: LiquidityPoolAbi,
Target: p.Address,
Expand Down Expand Up @@ -209,7 +209,6 @@ func (d *PoolTracker) GetNewPoolState(
return entity.Pool{}, err
}

reserves := make(entity.PoolReserves, len(p.Tokens))
var extra = Extra{
Oracle: oracle.Hex(),
TotalWeight: totalWeight,
Expand Down Expand Up @@ -255,6 +254,12 @@ func (d *PoolTracker) GetNewPoolState(
return entity.Pool{}, err
}

reserves := make([]string, len(p.Tokens))
for i, token := range p.Tokens {
reserve := d.getReserve(extra.TokenInfos[token.Address])
reserves[i] = reserve.PoolAmount.String()
}

p.Extra = string(extraBytes)
p.Reserves = reserves
p.Timestamp = time.Now().Unix()
Expand All @@ -266,3 +271,15 @@ func (d *PoolTracker) GetNewPoolState(

return p, nil
}

func (d *PoolTracker) getReserve(token *TokenInfo) *AssetInfo {
asset := &AssetInfo{
PoolAmount: big.NewInt(0),
ReserveAmount: big.NewInt(0),
}
for _, tranche := range token.TrancheAssets {
asset.PoolAmount = new(big.Int).Add(asset.PoolAmount, tranche.PoolAmount)
asset.ReserveAmount = new(big.Int).Add(asset.ReserveAmount, tranche.ReserveAmount)
}
return asset
}

0 comments on commit dbbaecc

Please sign in to comment.