@@ -3,9 +3,11 @@ package aave
33import (
44 "fmt"
55 "math/big"
6+ "slices"
67 "strings"
78
89 "github.com/goccy/go-json"
10+ "github.com/samber/lo"
911
1012 "github.com/KyberNetwork/kyberswap-dex-lib/pkg/entity"
1113 "github.com/KyberNetwork/kyberswap-dex-lib/pkg/source/curve"
@@ -15,7 +17,9 @@ import (
1517
1618type PoolSimulator struct {
1719 pool.Pool
18- Multipliers []* big.Int
20+ LpToken string
21+ UnderlyingTokens []string
22+ Multipliers []* big.Int
1923 // extra fields
2024 InitialA * big.Int
2125 FutureA * big.Int
@@ -46,7 +50,7 @@ func NewPoolSimulator(entityPool entity.Pool) (*PoolSimulator, error) {
4650 var reserves = make ([]* big.Int , numTokens )
4751 var multipliers = make ([]* big.Int , numTokens )
4852 for i := 0 ; i < numTokens ; i += 1 {
49- tokens [i ] = staticExtra . UnderlyingTokens [i ]
53+ tokens [i ] = entityPool . Tokens [i ]. Address
5054 reserves [i ] = bignumber .NewBig10 (entityPool .Reserves [i ])
5155 multipliers [i ] = bignumber .NewBig10 (staticExtra .PrecisionMultipliers [i ])
5256 }
@@ -67,6 +71,8 @@ func NewPoolSimulator(entityPool entity.Pool) (*PoolSimulator, error) {
6771 Reserves : reserves ,
6872 },
6973 },
74+ LpToken : staticExtra .LpToken ,
75+ UnderlyingTokens : staticExtra .UnderlyingTokens ,
7076 Multipliers : multipliers ,
7177 InitialA : bignumber .NewBig10 (extra .InitialA ),
7278 FutureA : bignumber .NewBig10 (extra .FutureA ),
@@ -80,28 +86,23 @@ func NewPoolSimulator(entityPool entity.Pool) (*PoolSimulator, error) {
8086}
8187
8288func (t * PoolSimulator ) CalcAmountOut (param pool.CalcAmountOutParams ) (* pool.CalcAmountOutResult , error ) {
83- tokenAmountIn := param .TokenAmountIn
84- tokenOut := param .TokenOut
85- var tokenIndexFrom = t .GetTokenIndex (tokenAmountIn .Token )
86- var tokenIndexTo = t .GetTokenIndex (tokenOut )
87- if tokenIndexFrom >= 0 && tokenIndexTo >= 0 {
88- amountOut , fee , err := GetDyUnderlying (
89- t .Info .Reserves ,
90- t .Multipliers ,
91- t .FutureATime ,
92- t .FutureA ,
93- t .InitialATime ,
94- t .InitialA ,
95- t .Info .SwapFee ,
96- t .OffpegFeeMultiplier ,
97- tokenIndexFrom ,
98- tokenIndexTo ,
89+ tokenAmountIn , tokenOut := param .TokenAmountIn , param .TokenOut
90+ idxIn , idxOut := t .GetTokenIndex (tokenAmountIn .Token ), t .GetTokenIndex (tokenOut )
91+ if idxIn >= 0 && idxOut >= 0 {
92+ A := _getAPrecise (t .FutureATime , t .FutureA , t .InitialATime , t .InitialA )
93+ D , err := t .getDPrecision (t .Info .Reserves , A )
94+ if err != nil {
95+ return nil , err
96+ }
97+ amountOut , fee , err := t .GetDy (
98+ idxIn ,
99+ idxOut ,
99100 tokenAmountIn .Amount ,
101+ D ,
100102 )
101103 if err != nil {
102104 return nil , err
103- }
104- if err == nil && amountOut .Cmp (bignumber .ZeroBI ) > 0 {
105+ } else if amountOut .Sign () > 0 {
105106 return & pool.CalcAmountOutResult {
106107 TokenAmountOut : & pool.TokenAmount {
107108 Token : tokenOut ,
@@ -114,8 +115,44 @@ func (t *PoolSimulator) CalcAmountOut(param pool.CalcAmountOutParams) (*pool.Cal
114115 Gas : t .gas .Exchange ,
115116 }, nil
116117 }
118+ return nil , ErrInvalidAmountOut
119+ } else if DepositFrozen {
120+ return nil , ErrTokenNotFound
117121 }
118- return & pool.CalcAmountOutResult {}, fmt .Errorf ("tokenIndexFrom or tokenIndexTo is not correct: tokenIndexFrom: %v, tokenIndexTo: %v" , tokenIndexFrom , tokenIndexTo )
122+
123+ idxIn , idxOut = slices .Index (t .UnderlyingTokens , tokenAmountIn .Token ), slices .Index (t .UnderlyingTokens , tokenOut )
124+ if idxIn < 0 || idxOut < 0 {
125+ return nil , ErrTokenNotFound
126+ }
127+ amountOut , fee , err := GetDyUnderlying (
128+ t .Info .Reserves ,
129+ t .Multipliers ,
130+ t .FutureATime ,
131+ t .FutureA ,
132+ t .InitialATime ,
133+ t .InitialA ,
134+ t .Info .SwapFee ,
135+ t .OffpegFeeMultiplier ,
136+ idxIn ,
137+ idxOut ,
138+ tokenAmountIn .Amount ,
139+ )
140+ if err != nil {
141+ return nil , err
142+ } else if amountOut .Sign () > 0 {
143+ return & pool.CalcAmountOutResult {
144+ TokenAmountOut : & pool.TokenAmount {
145+ Token : tokenOut ,
146+ Amount : amountOut ,
147+ },
148+ Fee : & pool.TokenAmount {
149+ Token : tokenOut ,
150+ Amount : fee ,
151+ },
152+ Gas : t .gas .Exchange ,
153+ }, nil
154+ }
155+ return nil , ErrInvalidAmountOut
119156}
120157
121158func (t * PoolSimulator ) UpdateBalance (params pool.UpdateBalanceParams ) {
@@ -144,17 +181,49 @@ func (t *PoolSimulator) UpdateBalance(params pool.UpdateBalanceParams) {
144181 }
145182}
146183
184+ func (t * PoolSimulator ) CanSwapTo (address string ) []string {
185+ if t .GetTokenIndex (address ) >= 0 {
186+ // exchange
187+ return lo .Filter (t .Info .Tokens , func (item string , _ int ) bool {
188+ return item != address
189+ })
190+ }
191+ // check from underlying
192+ if DepositFrozen || slices .Index (t .UnderlyingTokens , address ) < 0 {
193+ return nil
194+ }
195+ // exchange_underlying can swap underlying token to other underlying tokens
196+ return lo .Filter (t .UnderlyingTokens , func (item string , _ int ) bool {
197+ return item != address
198+ })
199+ }
200+
201+ func (t * PoolSimulator ) CanSwapFrom (address string ) []string { return t .CanSwapTo (address ) }
202+
203+ func (t * PoolSimulator ) GetTokens () []string {
204+ if DepositFrozen {
205+ return t .Info .Tokens
206+ }
207+ result := make ([]string , 0 , 2 * len (t .UnderlyingTokens ))
208+ result = append (result , t .Info .Tokens ... )
209+ result = append (result , t .UnderlyingTokens ... )
210+ return result
211+ }
212+
147213func (t * PoolSimulator ) GetLpToken () string {
148- return ""
214+ return t . LpToken
149215}
150216
151- func (t * PoolSimulator ) GetMetaInfo (tokenIn string , tokenOut string ) interface {} {
152- var fromId = t .GetTokenIndex (tokenIn )
153- var toId = t .GetTokenIndex (tokenOut )
217+ func (t * PoolSimulator ) GetMetaInfo (tokenIn string , tokenOut string ) any {
218+ idxIn , idxOut , underlying := t .GetTokenIndex (tokenIn ), t .GetTokenIndex (tokenOut ), false
219+ if idxIn < 0 || idxOut < 0 {
220+ idxIn , idxOut , underlying = slices .Index (t .UnderlyingTokens , tokenIn ), slices .Index (t .UnderlyingTokens ,
221+ tokenOut ), true
222+ }
154223 return curve.Meta {
155- TokenInIndex : fromId ,
156- TokenOutIndex : toId ,
157- Underlying : true ,
224+ TokenInIndex : idxIn ,
225+ TokenOutIndex : idxOut ,
226+ Underlying : underlying ,
158227 }
159228}
160229
@@ -192,7 +261,7 @@ func (t *PoolSimulator) AddLiquidity(amounts []*big.Int) (*big.Int, error) {
192261 return nil , ErrD1LowerThanD0
193262 }
194263 var mint_amount * big.Int
195- if token_supply .Cmp ( bignumber . ZeroBI ) > 0 {
264+ if token_supply .Sign ( ) > 0 {
196265 ys := new (big.Int ).Div (new (big.Int ).Add (D0 , D1 ), nCoinsBi )
197266 var _fee = new (big.Int ).Div (new (big.Int ).Mul (t .Info .SwapFee , nCoinsBi ),
198267 new (big.Int ).Mul (bignumber .Four , big .NewInt (int64 (nCoins - 1 ))))
@@ -210,7 +279,8 @@ func (t *PoolSimulator) AddLiquidity(amounts []*big.Int) (*big.Int, error) {
210279 var fee = new (big.Int ).Div (new (big.Int ).Mul (_dynamicFee (xs , ys , _fee , _feemul ), difference ), FeeDenominator )
211280 new_balances [i ] = new (big.Int ).Sub (new_balances [i ], fee )
212281 }
213- D2 , _ := t .getDPrecision (new_balances , amp )
282+ D2 , err := t .getDPrecision (new_balances , amp )
283+ fmt .Println (err )
214284 mint_amount = new (big.Int ).Div (new (big.Int ).Mul (token_supply , new (big.Int ).Sub (D2 , D0 )), D0 )
215285 } else {
216286 for i := 0 ; i < nCoins ; i += 1 {
@@ -297,12 +367,12 @@ func (t *PoolSimulator) GetDy(i int, j int, dx *big.Int, dCached *big.Int) (*big
297367}
298368
299369func (t * PoolSimulator ) GetVirtualPrice () (* big.Int , * big.Int , error ) {
300- var A = _getAPrecise (t .FutureATime , t .FutureA , t .InitialATime , t .InitialA )
370+ A : = _getAPrecise (t .FutureATime , t .FutureA , t .InitialATime , t .InitialA )
301371 D , err := t .getDPrecision (t .Info .Reserves , A )
302372 if err != nil {
303373 return nil , nil , err
304374 }
305- if t .LpSupply .Cmp ( bignumber . ZeroBI ) == 0 {
375+ if t .LpSupply .Sign ( ) == 0 {
306376 return nil , nil , ErrDenominatorZero
307377 }
308378 return new (big.Int ).Div (new (big.Int ).Mul (D , Precision ), t .LpSupply ), D , nil
0 commit comments