Skip to content

Commit 958b5d2

Browse files
authored
Add aave in helix liquidity check (#5)
* Add aave in helix liquidity check * Add more test
1 parent ce7c501 commit 958b5d2

File tree

20 files changed

+1984
-81
lines changed

20 files changed

+1984
-81
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ require (
119119
github.com/russross/blackfriday/v2 v2.1.0 // indirect
120120
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
121121
github.com/status-im/keycard-go v0.2.0 // indirect
122+
github.com/stretchr/objx v0.5.2 // indirect
122123
github.com/supranational/blst v0.3.11 // indirect
123124
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
124125
github.com/tklauser/go-sysconf v0.3.13 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@ github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cA
294294
github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA=
295295
github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg=
296296
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
297+
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
298+
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
297299
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
298300
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
299301
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=

internal/daemons/bot/bot.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func Run(ctx context.Context, conf configs.Config) error {
9292

9393
func process(ctx context.Context, conf configs.Config, walletAddress, tokenName, chainName, botType string,
9494
client simulated.Client) func() ([]bot.Task, bot.ProcessType, error) {
95-
m := bot.GetMonitor(botType)
95+
m := bot.GetBot(botType)
9696
if m == nil {
9797
panic(fmt.Sprintf("%s botType not found", botType))
9898
}

utils/bot/balance_on_chain/monitor.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ package balance_on_chain
22

33
import (
44
"context"
5+
"omni-balance/utils/bot"
6+
57
"github.com/ethereum/go-ethereum/common"
68
"github.com/pkg/errors"
79
"github.com/shopspring/decimal"
810
"github.com/sirupsen/logrus"
9-
"omni-balance/utils/bot"
1011
)
1112

1213
func init() {
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package balance_on_chain
2+
3+
import (
4+
"context"
5+
"omni-balance/utils/bot"
6+
"omni-balance/utils/configs"
7+
"omni-balance/utils/constant"
8+
"omni-balance/utils/wallets/wallet_mocks"
9+
"strconv"
10+
"testing"
11+
12+
"github.com/shopspring/decimal"
13+
"github.com/stretchr/testify/assert"
14+
)
15+
16+
func TestBalanceOnChain_Check(t *testing.T) {
17+
testConf := &configs.Config{
18+
Chains: []configs.Chain{
19+
{
20+
Id: 1,
21+
Name: constant.Ethereum,
22+
NativeToken: "ETH",
23+
Tokens: []configs.Token{
24+
{
25+
ContractAddress: "0x0000000000000000000000000000000000000000",
26+
Decimals: 18,
27+
Name: "ETH",
28+
},
29+
},
30+
},
31+
},
32+
Wallets: []configs.Wallet{
33+
configs.Wallet{
34+
Address: constant.ZeroAddress.Hex(),
35+
Tokens: []configs.WalletToken{
36+
configs.WalletToken{
37+
Name: "ETH",
38+
Amount: decimal.RequireFromString("1"),
39+
Threshold: decimal.RequireFromString("1000"),
40+
Chains: []string{constant.Ethereum},
41+
},
42+
},
43+
},
44+
},
45+
}
46+
testConf.Init()
47+
b := new(BalanceOnChain)
48+
w := wallet_mocks.NewWallets(t)
49+
w.On("GetExternalBalance", context.Background(), constant.ZeroAddress, int32(18), nil).Return(decimal.RequireFromString("1000"), nil)
50+
w.On("GetAddress").Return(constant.ZeroAddress)
51+
tasks, Type, err := b.Check(context.Background(), bot.Params{
52+
Conf: *testConf,
53+
Info: bot.Config{
54+
Wallet: w,
55+
TokenName: "ETH",
56+
Chain: constant.Ethereum,
57+
},
58+
})
59+
assert.NoError(t, err)
60+
assert.Equal(t, bot.Queue, Type)
61+
assert.Len(t, tasks, 1)
62+
assert.Equal(t, "1", tasks[0].Amount.String())
63+
assert.Equal(t, constant.ZeroAddress.Hex(), tasks[0].Wallet)
64+
assert.Equal(t, "ETH", tasks[0].TokenOutName)
65+
assert.Equal(t, constant.Ethereum, tasks[0].TokenOutChainName)
66+
67+
w = wallet_mocks.NewWallets(t)
68+
w.On("GetExternalBalance", context.Background(), constant.ZeroAddress, int32(18), nil).Return(decimal.RequireFromString("1"), nil)
69+
w.On("GetAddress").Return(constant.ZeroAddress)
70+
tasks, Type, err = b.Check(context.Background(), bot.Params{
71+
Conf: *testConf,
72+
Info: bot.Config{
73+
Wallet: w,
74+
TokenName: "ETH",
75+
Chain: constant.Ethereum,
76+
},
77+
})
78+
assert.NoError(t, err)
79+
assert.Equal(t, bot.Queue, Type)
80+
assert.Len(t, tasks, 1)
81+
// 1000 + (1000 * 0.3)
82+
assert.Equal(t, strconv.Itoa(1000+(1000*0.3)), tasks[0].Amount.String())
83+
assert.Equal(t, constant.ZeroAddress.Hex(), tasks[0].Wallet)
84+
assert.Equal(t, "ETH", tasks[0].TokenOutName)
85+
assert.Equal(t, constant.Ethereum, tasks[0].TokenOutChainName)
86+
}

utils/bot/gate_liquidity/gate_liquidity.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,18 @@ func init() {
1414
}
1515

1616
type GateLiquidity struct {
17-
balance_on_chain.BalanceOnChain
17+
Bot bot.Bot
1818
}
1919

2020
func (g GateLiquidity) Name() string {
2121
return "gate_liquidity"
2222
}
2323

2424
func (b GateLiquidity) Check(ctx context.Context, args bot.Params) ([]bot.Task, bot.ProcessType, error) {
25-
tasks, processType, err := b.BalanceOnChain.Check(ctx, args)
25+
if b.Bot == nil {
26+
b.Bot = balance_on_chain.BalanceOnChain{}
27+
}
28+
tasks, processType, err := b.Bot.Check(ctx, args)
2629
if err != nil {
2730
return nil, processType, err
2831
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package gate_liquidity
2+
3+
import (
4+
"context"
5+
"omni-balance/utils/bot"
6+
"omni-balance/utils/bot_mocks"
7+
"omni-balance/utils/configs"
8+
"omni-balance/utils/constant"
9+
"testing"
10+
11+
"github.com/shopspring/decimal"
12+
"github.com/stretchr/testify/assert"
13+
"github.com/stretchr/testify/mock"
14+
)
15+
16+
func TestGateLiquidity_Check(t *testing.T) {
17+
testConf := &configs.Config{
18+
Chains: []configs.Chain{
19+
{
20+
Id: 1,
21+
Name: constant.Ethereum,
22+
NativeToken: "ETH",
23+
Tokens: []configs.Token{
24+
{
25+
ContractAddress: "0x0000000000000000000000000000000000000000",
26+
Decimals: 18,
27+
Name: "ETH",
28+
},
29+
},
30+
},
31+
},
32+
Wallets: []configs.Wallet{
33+
configs.Wallet{
34+
Address: constant.ZeroAddress.Hex(),
35+
BotTypes: []configs.BotConfig{
36+
{
37+
Name: "gate_liquidity",
38+
TokenChains: map[string][]string{
39+
"ETH": []string{constant.Ethereum},
40+
},
41+
Config: map[string]interface{}{
42+
"toChain": constant.Arbitrum,
43+
},
44+
},
45+
},
46+
Tokens: []configs.WalletToken{
47+
configs.WalletToken{
48+
49+
Name: "ETH",
50+
Amount: decimal.RequireFromString("1"),
51+
Threshold: decimal.RequireFromString("1000"),
52+
Chains: []string{constant.Ethereum},
53+
},
54+
},
55+
},
56+
},
57+
}
58+
testConf.Init()
59+
g := new(GateLiquidity)
60+
b := bot_mocks.NewBot(t)
61+
b.On("Check", mock.Anything, mock.Anything).Return(
62+
[]bot.Task{
63+
{
64+
Wallet: constant.ZeroAddress.Hex(),
65+
TokenInName: "ETH",
66+
TokenOutName: "ETH",
67+
TokenOutChainName: constant.Ethereum,
68+
Amount: decimal.RequireFromString("1"),
69+
},
70+
},
71+
bot.Queue,
72+
nil,
73+
)
74+
g.Bot = b
75+
tasks, Type, err := g.Check(context.Background(), bot.Params{
76+
Conf: *testConf,
77+
Info: bot.Config{
78+
TokenName: "ETH",
79+
Chain: constant.Ethereum,
80+
},
81+
})
82+
assert.NoError(t, err)
83+
assert.Equal(t, bot.Queue, Type)
84+
assert.Len(t, tasks, 1)
85+
assert.Equal(t, "1", tasks[0].Amount.String())
86+
assert.Equal(t, constant.ZeroAddress.Hex(), tasks[0].Wallet)
87+
assert.Equal(t, "ETH", tasks[0].TokenOutName)
88+
assert.Equal(t, constant.Arbitrum, tasks[0].TokenOutChainName)
89+
assert.Equal(t, constant.Ethereum, tasks[0].TokenInChainName)
90+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package helix_liquidity
2+
3+
import (
4+
"context"
5+
"omni-balance/utils/chains"
6+
"omni-balance/utils/constant"
7+
8+
"github.com/ethereum/go-ethereum/common"
9+
"github.com/pkg/errors"
10+
"github.com/shopspring/decimal"
11+
)
12+
13+
var (
14+
aaveAddressBook = map[string]AvaeConfig{
15+
constant.Arbitrum: AvaeConfig{
16+
Chain: constant.Arbitrum,
17+
L2Pool: common.HexToAddress("0x794a61358D6845594F94dc1DB02A252b5b4814aD"),
18+
Oracle: common.HexToAddress("0xb56c2F0B653B2e0b10C9b928C8580Ac5Df02C7C7"),
19+
Multicall: common.HexToAddress("0xcA11bde05977b3631167028862bE2a173976CA11"),
20+
DebtTokens: map[string]debtTokens{
21+
"USDT": debtTokens{
22+
Name: "USDT",
23+
AToken: common.HexToAddress("0x6ab707Aca953eDAeFBc4fD23bA73294241490620"),
24+
VToken: common.HexToAddress("0xfb00AC187a8Eb5AFAE4eACE434F493Eb62672df7"),
25+
UnderlyingToken: common.HexToAddress("0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"),
26+
Decimals: 6,
27+
},
28+
"WETH": debtTokens{
29+
Name: "WETH",
30+
AToken: common.HexToAddress("0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8"),
31+
VToken: common.HexToAddress("0x0c84331e39d6658Cd6e6b9ba04736cC4c4734351"),
32+
UnderlyingToken: common.HexToAddress("0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"),
33+
Decimals: 18,
34+
},
35+
},
36+
},
37+
constant.Optimism: AvaeConfig{
38+
Chain: constant.Optimism,
39+
L2Pool: common.HexToAddress("0x794a61358D6845594F94dc1DB02A252b5b4814aD"),
40+
Oracle: common.HexToAddress("0xD81eb3728a631871a7eBBaD631b5f424909f0c77"),
41+
Multicall: common.HexToAddress("0xcA11bde05977b3631167028862bE2a173976CA11"),
42+
DebtTokens: map[string]debtTokens{
43+
"USDT": debtTokens{
44+
Name: "USDT",
45+
AToken: common.HexToAddress("0x6ab707Aca953eDAeFBc4fD23bA73294241490620"),
46+
VToken: common.HexToAddress("0xfb00AC187a8Eb5AFAE4eACE434F493Eb62672df7"),
47+
UnderlyingToken: common.HexToAddress("0x94b008aA00579c1307B0EF2c499aD98a8ce58e58"),
48+
Decimals: 6,
49+
},
50+
"WETH": debtTokens{
51+
Name: "WETH",
52+
AToken: common.HexToAddress("0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8"),
53+
VToken: common.HexToAddress("0x0c84331e39d6658Cd6e6b9ba04736cC4c4734351"),
54+
UnderlyingToken: common.HexToAddress("0x4200000000000000000000000000000000000006"),
55+
Decimals: 18,
56+
},
57+
},
58+
},
59+
constant.ArbitrumSepolia: AvaeConfig{
60+
Chain: constant.ArbitrumSepolia,
61+
DebtTokens: map[string]debtTokens{
62+
"USDC": debtTokens{
63+
Name: "USDC",
64+
AToken: common.HexToAddress("0x460b97BD498E1157530AEb3086301d5225b91216"),
65+
VToken: common.HexToAddress("0x4fBE3A94C60A5085dA6a2D309965DcF34c36711d"),
66+
UnderlyingToken: common.HexToAddress("0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d"),
67+
Decimals: 6,
68+
},
69+
},
70+
},
71+
}
72+
)
73+
74+
type AvaeConfig struct {
75+
Chain string
76+
L2Pool common.Address
77+
Oracle common.Address
78+
Multicall common.Address
79+
DebtTokens map[string]debtTokens
80+
}
81+
82+
type debtTokens struct {
83+
Name string
84+
AToken common.Address
85+
VToken common.Address
86+
UnderlyingToken common.Address
87+
Decimals int32
88+
}
89+
90+
type Aave struct {
91+
}
92+
93+
func (a Aave) BalanceOf(ctx context.Context, args DebtParams) (decimal.Decimal, error) {
94+
conf, ok := aaveAddressBook[args.Chain]
95+
if !ok || conf.Chain == "" || conf.DebtTokens[args.Token].Name == "" {
96+
return decimal.Zero, errors.Errorf("chain %s not support", args.Chain)
97+
}
98+
atokenBalance, err := chains.GetTokenBalance(ctx, args.Client, conf.DebtTokens[args.Token].AToken.Hex(),
99+
args.Address.Hex(), conf.DebtTokens[args.Token].Decimals)
100+
if err != nil {
101+
return decimal.Zero, errors.Wrap(err, "get atoken balance error")
102+
}
103+
104+
vtokenBalance, err := chains.GetTokenBalance(ctx, args.Client, conf.DebtTokens[args.Token].VToken.Hex(),
105+
args.Address.Hex(), conf.DebtTokens[args.Token].Decimals)
106+
if err != nil {
107+
return decimal.Zero, errors.Wrap(err, "get vtoken balance error")
108+
}
109+
return atokenBalance.Sub(vtokenBalance), nil
110+
}
111+
112+
func (a Aave) Name() string {
113+
return "aave"
114+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package helix_liquidity
2+
3+
import (
4+
"context"
5+
"omni-balance/utils/chains"
6+
"omni-balance/utils/chains/chain_mocks"
7+
"omni-balance/utils/constant"
8+
"omni-balance/utils/erc20"
9+
"strconv"
10+
"testing"
11+
12+
"github.com/ethereum/go-ethereum"
13+
"github.com/ethereum/go-ethereum/common"
14+
"github.com/shopspring/decimal"
15+
"github.com/stretchr/testify/assert"
16+
"github.com/stretchr/testify/mock"
17+
)
18+
19+
func TestAave_BalanceOf(t *testing.T) {
20+
mockClient := chain_mocks.NewMockClient(t)
21+
22+
erc20Abi, err := erc20.TokenMetaData.GetAbi()
23+
assert.NoError(t, err)
24+
input, err := erc20Abi.Pack("balanceOf", constant.ZeroAddress)
25+
assert.NoError(t, err)
26+
token := common.HexToAddress("0x460b97BD498E1157530AEb3086301d5225b91216")
27+
mockClient.On("CallContract", context.TODO(), ethereum.CallMsg{To: &token, Data: input}, mock.Anything).Return(
28+
chains.EthToWei(decimal.RequireFromString("1000"), 6).Bytes(), nil,
29+
)
30+
31+
vtoken := common.HexToAddress("0x4fBE3A94C60A5085dA6a2D309965DcF34c36711d")
32+
mockClient.On("CallContract", context.TODO(), ethereum.CallMsg{To: &vtoken, Data: input}, mock.Anything).Return(
33+
chains.EthToWei(decimal.RequireFromString("900"), 6).Bytes(), nil,
34+
)
35+
36+
balance, err := new(Aave).BalanceOf(context.TODO(), DebtParams{
37+
Address: constant.ZeroAddress,
38+
Token: "USDC",
39+
Client: mockClient,
40+
Chain: constant.ArbitrumSepolia,
41+
})
42+
assert.NoError(t, err)
43+
assert.Equal(t, balance.String(), strconv.Itoa(1000-900))
44+
}

0 commit comments

Comments
 (0)