Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
pancakeSwaper
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
pancakeSwaper
Commits
5860be39
Commit
5860be39
authored
Apr 10, 2025
by
luxq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
34b01480
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
238 additions
and
142 deletions
+238
-142
README.md
README.md
+12
-14
accounts.csv
accounts.csv
+2
-0
accounts.json
accounts.json
+0
-5
config.yml
config.yml
+7
-1
config.go
config/config.go
+6
-0
pack.go
pancake/pack.go
+8
-6
swapper.go
swapper/swapper.go
+1
-1
account.go
types/account.go
+3
-2
env.go
types/env.go
+13
-15
account.go
work/account.go
+186
-98
No files found.
README.md
View file @
5860be39
...
@@ -23,19 +23,11 @@ cd pancakeswaper
...
@@ -23,19 +23,11 @@ cd pancakeswaper
make
make
```
```
#### 2. fill in the `accounts.json` file with the accounts you want to do swap for.
#### 2. fill in the `accounts.csv` file with the accounts you want to do swap for.
The example of the
`accounts.json`
file is as follow:
The example of the
`accounts.csv`
file is as follow:
```
json
```
csv
[
useraddress, privatekey, recipient
{
0xeFbb75e446Ec2d8493B3d4d91aC3118953f69b55, 0x1111111111111111, 0xc437593d9C296bf9A5002522A86dad8a4d4Af808
"address"
:
"0x"
,
"private"
:
"0x"
},
{
"address"
:
"0x"
,
"private"
:
"0x"
}
]
```
```
#### 4. change configure
#### 4. change configure
...
@@ -55,6 +47,12 @@ param:
...
@@ -55,6 +47,12 @@ param:
# tx deadline, unit is minutes, set 0 to disable.
# tx deadline, unit is minutes, set 0 to disable.
deadline
:
20
deadline
:
20
pair
:
# pair address.
pair
:
"
0xcB0AE3B8337f0Cc35563e6b9fC357F2298C0D24a"
# klko address
token
:
"
0x215324115417a13879f865Dc5BB651B18A781a59"
rpc
:
rpc
:
env
:
"
bsc"
env
:
"
bsc"
pool
:
20
pool
:
20
...
@@ -62,7 +60,7 @@ rpc:
...
@@ -62,7 +60,7 @@ rpc:
log
:
log
:
level
:
"
debug"
level
:
"
debug"
users
:
"
accounts.
json
"
users
:
"
accounts.
csv
"
```
```
#### 5. run the program
#### 5. run the program
...
...
accounts.csv
0 → 100644
View file @
5860be39
useraddress, privatekey, recipient
0xeFbb75e446Ec2d8493B3d4d91aC3118953f69b55, 0x1111111111111111, 0xc437593d9C296bf9A5002522A86dad8a4d4Af808
\ No newline at end of file
accounts.json
deleted
100755 → 0
View file @
34b01480
[
{
"address"
:
"","private"
:
"0x"
},
{
"address"
:
"","private"
:
"0x"
},
{
"address"
:
"","private"
:
"0x"
}
]
\ No newline at end of file
config.yml
View file @
5860be39
...
@@ -12,6 +12,12 @@ param:
...
@@ -12,6 +12,12 @@ param:
# tx deadline, unit is minutes, set 0 to disable.
# tx deadline, unit is minutes, set 0 to disable.
deadline
:
20
deadline
:
20
pair
:
# pair address.
pair
:
"
0xcB0AE3B8337f0Cc35563e6b9fC357F2298C0D24a"
# klko address
token
:
"
0x215324115417a13879f865Dc5BB651B18A781a59"
rpc
:
rpc
:
env
:
"
bsc"
env
:
"
bsc"
pool
:
20
pool
:
20
...
@@ -19,4 +25,4 @@ rpc:
...
@@ -19,4 +25,4 @@ rpc:
log
:
log
:
level
:
"
debug"
level
:
"
debug"
users
:
"
accounts.json"
users
:
"
accounts.csv"
\ No newline at end of file
\ No newline at end of file
config/config.go
View file @
5860be39
...
@@ -12,6 +12,7 @@ import (
...
@@ -12,6 +12,7 @@ import (
type
Config
struct
{
type
Config
struct
{
Log
LogConfig
`yaml:"log"`
Log
LogConfig
`yaml:"log"`
Param
ParamConfig
`yaml:"param"`
Param
ParamConfig
`yaml:"param"`
Pair
PairConfig
`yaml:"pair"`
Rpc
RpcConfig
`yaml:"rpc"`
Rpc
RpcConfig
`yaml:"rpc"`
Users
string
`yaml:"users"`
Users
string
`yaml:"users"`
}
}
...
@@ -25,6 +26,11 @@ type ParamConfig struct {
...
@@ -25,6 +26,11 @@ type ParamConfig struct {
Deadline
int64
`yaml:"deadline"`
Deadline
int64
`yaml:"deadline"`
}
}
type
PairConfig
struct
{
Pair
string
`yaml:"pair"`
Token
string
`yaml:"token"`
}
type
RpcConfig
struct
{
type
RpcConfig
struct
{
Env
string
`yaml:"env"`
Env
string
`yaml:"env"`
PoolSize
int
`yaml:"pool"`
PoolSize
int
`yaml:"pool"`
...
...
pancake/pack.go
View file @
5860be39
package
pancake
package
pancake
import
(
import
(
"code.wuban.net.cn/service/pancakeswapper/config"
"code.wuban.net.cn/service/pancakeswapper/contracts/buildparam"
"code.wuban.net.cn/service/pancakeswapper/contracts/buildparam"
"code.wuban.net.cn/service/pancakeswapper/contracts/v3pool"
"code.wuban.net.cn/service/pancakeswapper/contracts/v3pool"
"code.wuban.net.cn/service/pancakeswapper/types"
"code.wuban.net.cn/service/pancakeswapper/types"
...
@@ -30,7 +31,7 @@ func leftPadding(data []byte, length int) []byte {
...
@@ -30,7 +31,7 @@ func leftPadding(data []byte, length int) []byte {
return
append
(
padding
,
data
...
)
return
append
(
padding
,
data
...
)
}
}
func
MakeV3SwapExactInPathData
(
env
types
.
Env
)
[]
byte
{
func
MakeV3SwapExactInPathData
(
env
types
.
Env
,
cfg
*
config
.
Config
)
[]
byte
{
//0000000000000000000000003e3b4d16ce35840c28f90edb7f38e5bdd976c7e3
//0000000000000000000000003e3b4d16ce35840c28f90edb7f38e5bdd976c7e3
//0000000000000000000000000000000000000000000000001bc16d674ec80000
//0000000000000000000000000000000000000000000000001bc16d674ec80000
//0000000000000000000000000000000000000000000000002620b5d4cdab6c04
//0000000000000000000000000000000000000000000000002620b5d4cdab6c04
...
@@ -40,7 +41,7 @@ func MakeV3SwapExactInPathData(env types.Env) []byte {
...
@@ -40,7 +41,7 @@ func MakeV3SwapExactInPathData(env types.Env) []byte {
//55d398326f99059ff775485246999027b3197955002710215324115417a13879f865dc5bb651b18a781a59000000000000000000000000000000000000000000
//55d398326f99059ff775485246999027b3197955002710215324115417a13879f865dc5bb651b18a781a59000000000000000000000000000000000000000000
token0
:=
common
.
HexToAddress
(
env
.
USDT
)
token0
:=
common
.
HexToAddress
(
env
.
USDT
)
token1
:=
common
.
HexToAddress
(
env
.
KLKO
)
token1
:=
common
.
HexToAddress
(
cfg
.
Pair
.
Token
)
fee
:=
big
.
NewInt
(
10000
)
fee
:=
big
.
NewInt
(
10000
)
data
:=
make
([]
byte
,
0
)
data
:=
make
([]
byte
,
0
)
data
=
append
(
data
,
token0
.
Bytes
()
...
)
data
=
append
(
data
,
token0
.
Bytes
()
...
)
...
@@ -49,7 +50,7 @@ func MakeV3SwapExactInPathData(env types.Env) []byte {
...
@@ -49,7 +50,7 @@ func MakeV3SwapExactInPathData(env types.Env) []byte {
return
data
return
data
}
}
func
MakeV3SwapExactInData
(
env
types
.
Env
,
param
ParamV3SwapExactIn
)
([]
byte
,
error
)
{
func
MakeV3SwapExactInData
(
env
types
.
Env
,
param
ParamV3SwapExactIn
,
cfg
*
config
.
Config
)
([]
byte
,
error
)
{
//0000000000000000000000003e3b4d16ce35840c28f90edb7f38e5bdd976c7e3
//0000000000000000000000003e3b4d16ce35840c28f90edb7f38e5bdd976c7e3
//0000000000000000000000000000000000000000000000000de0b6b3a7640000
//0000000000000000000000000000000000000000000000000de0b6b3a7640000
//00000000000000000000000000000000000000000000000012d0ee4f5819f972
//00000000000000000000000000000000000000000000000012d0ee4f5819f972
...
@@ -59,7 +60,7 @@ func MakeV3SwapExactInData(env types.Env, param ParamV3SwapExactIn) ([]byte, err
...
@@ -59,7 +60,7 @@ func MakeV3SwapExactInData(env types.Env, param ParamV3SwapExactIn) ([]byte, err
//55d398326f99059ff775485246999027b3197955002710215324115417a13879
//55d398326f99059ff775485246999027b3197955002710215324115417a13879
//f865dc5bb651b18a781a59000000000000000000000000000000000000000000
//f865dc5bb651b18a781a59000000000000000000000000000000000000000000
param
.
Path
=
MakeV3SwapExactInPathData
(
env
)
param
.
Path
=
MakeV3SwapExactInPathData
(
env
,
cfg
)
buildAbi
,
_
:=
abi
.
JSON
(
strings
.
NewReader
(
buildparam
.
ParamContractMetaData
.
ABI
))
buildAbi
,
_
:=
abi
.
JSON
(
strings
.
NewReader
(
buildparam
.
ParamContractMetaData
.
ABI
))
data
,
err
:=
buildAbi
.
Pack
(
"buildParamV3_SWAP_EXACT_IN"
,
param
.
Recipient
,
param
.
AmountIn
,
param
.
AmountOutMin
,
param
.
Path
,
param
.
PayerIsUser
)
data
,
err
:=
buildAbi
.
Pack
(
"buildParamV3_SWAP_EXACT_IN"
,
param
.
Recipient
,
param
.
AmountIn
,
param
.
AmountOutMin
,
param
.
Path
,
param
.
PayerIsUser
)
...
@@ -103,10 +104,10 @@ func MakePermit2PermitData(acc *types.Account, env types.Env) ([]byte, error) {
...
@@ -103,10 +104,10 @@ func MakePermit2PermitData(acc *types.Account, env types.Env) ([]byte, error) {
// amountIn is the amount of input token (USDT) to swap.
// amountIn is the amount of input token (USDT) to swap.
// slippage is the maximum slippage allowed for the swap, the value is percent mul 1000, eg: 20 is 2%.
// slippage is the maximum slippage allowed for the swap, the value is percent mul 1000, eg: 20 is 2%.
// feeRate is the fee charged by the pool, the value is percent mul 1000000, eg: 10000 is 1%.
// feeRate is the fee charged by the pool, the value is percent mul 1000000, eg: 10000 is 1%.
func
GetAmountOutMin
(
client
*
ethclient
.
Client
,
env
types
.
Env
,
amountIn
*
big
.
Int
,
func
GetAmountOutMin
(
c
fg
*
config
.
Config
,
c
lient
*
ethclient
.
Client
,
env
types
.
Env
,
amountIn
*
big
.
Int
,
slippage
int64
,
feeRate
*
big
.
Int
)
(
*
big
.
Int
,
error
)
{
slippage
int64
,
feeRate
*
big
.
Int
)
(
*
big
.
Int
,
error
)
{
// get slot0 data.
// get slot0 data.
pool
:=
common
.
HexToAddress
(
env
.
Pool
)
pool
:=
common
.
HexToAddress
(
cfg
.
Pair
.
Pair
)
contract
,
err
:=
v3pool
.
NewV3Pool
(
pool
,
client
)
contract
,
err
:=
v3pool
.
NewV3Pool
(
pool
,
client
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -216,6 +217,7 @@ func MakePermit2PermitData2(acc *types.Account, env types.Env, client *ethclient
...
@@ -216,6 +217,7 @@ func MakePermit2PermitData2(acc *types.Account, env types.Env, client *ethclient
// Pack the data
// Pack the data
buildAbi
,
_
:=
abi
.
JSON
(
strings
.
NewReader
(
buildparam
.
ParamContractMetaData
.
ABI
))
buildAbi
,
_
:=
abi
.
JSON
(
strings
.
NewReader
(
buildparam
.
ParamContractMetaData
.
ABI
))
// todo: check method name.
data
,
err
:=
buildAbi
.
Pack
(
"buildParamPermit2"
,
permitSingle
,
signature
)
data
,
err
:=
buildAbi
.
Pack
(
"buildParamPermit2"
,
permitSingle
,
signature
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
...
swapper/swapper.go
View file @
5860be39
...
@@ -26,7 +26,7 @@ func (s *Swapper) Run() {
...
@@ -26,7 +26,7 @@ func (s *Swapper) Run() {
work
.
WorkInit
(
env
.
ChainId
)
work
.
WorkInit
(
env
.
ChainId
)
// 1. read account info from json file
// 1. read account info from json file
accs
:=
work
.
LoadAccounts
(
s
.
cfg
.
Users
)
accs
:=
work
.
LoadAccounts
FromCsv
(
s
.
cfg
.
Users
)
work
.
SetTotalUser
(
len
(
accs
))
work
.
SetTotalUser
(
len
(
accs
))
waitCh
:=
make
(
chan
struct
{})
waitCh
:=
make
(
chan
struct
{})
...
...
types/account.go
View file @
5860be39
...
@@ -13,8 +13,9 @@ type Account struct {
...
@@ -13,8 +13,9 @@ type Account struct {
Address
string
`json:"address"`
Address
string
`json:"address"`
PrivateKey
string
`json:"private"`
PrivateKey
string
`json:"private"`
//Nonce uint64 `json:"-"`
//Nonce uint64 `json:"-"`
PK
*
ecdsa
.
PrivateKey
`json:"-"`
PK
*
ecdsa
.
PrivateKey
`json:"-"`
Addr
common
.
Address
`json:"-"`
Addr
common
.
Address
`json:"-"`
Recipient
string
`json:“recipient"`
}
}
func
(
a
*
Account
)
sign
(
chainid
*
big
.
Int
,
tx
*
types
.
Transaction
)
(
*
types
.
Transaction
,
error
)
{
func
(
a
*
Account
)
sign
(
chainid
*
big
.
Int
,
tx
*
types
.
Transaction
)
(
*
types
.
Transaction
,
error
)
{
...
...
types/env.go
View file @
5860be39
...
@@ -6,25 +6,23 @@ var (
...
@@ -6,25 +6,23 @@ var (
func
init
()
{
func
init
()
{
allEnv
[
"bsc"
]
=
Env
{
allEnv
[
"bsc"
]
=
Env
{
//RPC: "https://bscnode.bitheart.org",
RPC
:
"https://four.rpc.48.club"
,
RPC
:
"https://four.rpc.48.club"
,
USDT
:
"0x55d398326f99059ff775485246999027b3197955"
,
USDT
:
"0x55d398326f99059ff775485246999027b3197955"
,
Permit2
:
"0x31c2F6fcFf4F8759b3Bd5Bf0e1084A055615c768"
,
KLKO
:
"0x215324115417a13879f865Dc5BB651B18A781a59"
,
// KLKO
Router
:
"0x1b81D678ffb9C0263b24A97847620C99d213eB14"
,
Permit2
:
"0x31c2F6fcFf4F8759b3Bd5Bf0e1084A055615c768"
,
UniversalRouter
:
"0x1A0A18AC4BECDDbd6389559687d1A73d8927E416"
,
Router
:
"0x1b81D678ffb9C0263b24A97847620C99d213eB14"
,
ChainId
:
56
,
//Router: "0x1A0A18AC4BECDDbd6389559687d1A73d8927E416",
Pool
:
"0xcB0AE3B8337f0Cc35563e6b9fC357F2298C0D24a"
,
ChainId
:
56
,
}
}
}
}
type
Env
struct
{
type
Env
struct
{
RPC
string
RPC
string
USDT
string
USDT
string
KLKO
string
//KLKO string
Permit2
string
Permit2
string
Router
string
Router
string
// v3 router.
Pool
string
UniversalRouter
string
//Pool string
ChainId
int64
ChainId
int64
}
}
...
...
work/account.go
View file @
5860be39
...
@@ -9,6 +9,7 @@ import (
...
@@ -9,6 +9,7 @@ import (
"code.wuban.net.cn/service/pancakeswapper/pancake"
"code.wuban.net.cn/service/pancakeswapper/pancake"
"code.wuban.net.cn/service/pancakeswapper/types"
"code.wuban.net.cn/service/pancakeswapper/types"
"context"
"context"
"encoding/csv"
"encoding/json"
"encoding/json"
"fmt"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi"
...
@@ -17,6 +18,7 @@ import (
...
@@ -17,6 +18,7 @@ import (
ethtypes
"github.com/ethereum/go-ethereum/core/types"
ethtypes
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient"
log
"github.com/sirupsen/logrus"
"math/big"
"math/big"
"os"
"os"
"strings"
"strings"
...
@@ -25,6 +27,8 @@ import (
...
@@ -25,6 +27,8 @@ import (
var
(
var
(
failedHistory
=
make
(
chan
*
types
.
Account
,
1000000
)
failedHistory
=
make
(
chan
*
types
.
Account
,
1000000
)
dec
=
new
(
big
.
Int
)
.
SetUint64
(
1000000000000000000
)
fee
=
big
.
NewInt
(
10000
)
)
)
func
LoadAccounts
(
file
string
)
[]
*
types
.
Account
{
func
LoadAccounts
(
file
string
)
[]
*
types
.
Account
{
...
@@ -39,6 +43,48 @@ func LoadAccounts(file string) []*types.Account {
...
@@ -39,6 +43,48 @@ func LoadAccounts(file string) []*types.Account {
}
}
return
accs
return
accs
}
}
func
LoadAccountsFromCsv
(
filepath
string
)
[]
*
types
.
Account
{
// parse csv file, column is address, private key, recipient.
file
,
err
:=
os
.
Open
(
filepath
)
if
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"Error opening file:"
,
err
))
}
defer
file
.
Close
()
// Create a CSV reader
reader
:=
csv
.
NewReader
(
file
)
records
,
err
:=
reader
.
ReadAll
()
if
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"Error reading CSV file:"
,
err
))
}
var
parsedRecords
[]
*
types
.
Account
for
i
,
record
:=
range
records
{
// Ensure the record has the expected number of columns
if
len
(
record
)
!=
3
{
log
.
Errorf
(
"Skipping malformed record at row %d: %+v
\n
"
,
i
,
record
)
continue
}
if
i
==
0
&&
!
strings
.
HasPrefix
(
record
[
0
],
"0x"
)
{
log
.
Warningf
(
"Skipping malformed record at row %d: %+v
\n
"
,
i
,
record
)
// skip title line.
continue
}
// Map the fields to the Record struct
parsedRecord
:=
&
types
.
Account
{
Address
:
strings
.
TrimSpace
(
record
[
0
]),
PrivateKey
:
strings
.
TrimSpace
(
record
[
1
]),
Recipient
:
strings
.
TrimSpace
(
record
[
2
]),
}
parsedRecords
=
append
(
parsedRecords
,
parsedRecord
)
}
log
.
WithField
(
"records"
,
len
(
parsedRecords
))
.
Info
(
"Successfully loaded accounts from csv file"
)
return
parsedRecords
}
func
addTofailed
(
acc
*
types
.
Account
)
{
func
addTofailed
(
acc
*
types
.
Account
)
{
IncrFailedUser
()
IncrFailedUser
()
failedHistory
<-
acc
failedHistory
<-
acc
...
@@ -58,17 +104,18 @@ func waitTx(client *ethclient.Client, tx *ethtypes.Transaction) *ethtypes.Receip
...
@@ -58,17 +104,18 @@ func waitTx(client *ethclient.Client, tx *ethtypes.Transaction) *ethtypes.Receip
}
}
}
}
func
accountApprove
(
client
*
ethclient
.
Client
,
acc
*
types
.
Account
,
env
types
.
Env
)
error
{
func
accountApprove
WithPermit
(
client
*
ethclient
.
Client
,
acc
*
types
.
Account
,
env
types
.
Env
)
error
{
cfg
:=
config
.
Global
cfg
:=
config
.
Global
//
permit2 := common.HexToAddress(env.Permit2)
permit2
:=
common
.
HexToAddress
(
env
.
Permit2
)
usdt
,
err
:=
erc20
.
NewTokenContract
(
common
.
HexToAddress
(
env
.
USDT
),
client
)
usdt
,
err
:=
erc20
.
NewTokenContract
(
common
.
HexToAddress
(
env
.
USDT
),
client
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"erc20.NewTokenContract failed: %v"
,
err
)
return
fmt
.
Errorf
(
"erc20.NewTokenContract failed: %v"
,
err
)
}
}
//router, err := buildparam.NewParamContract(common.HexToAddress(env.Router), client)
// router need set to Universal Router.
//if err != nil {
router
,
err
:=
buildparam
.
NewParamContract
(
common
.
HexToAddress
(
env
.
UniversalRouter
),
client
)
// return fmt.Errorf("build param contract failed: %v", err)
if
err
!=
nil
{
//}
return
fmt
.
Errorf
(
"build param contract failed: %v"
,
err
)
}
txopts
:=
&
bind
.
TransactOpts
{
txopts
:=
&
bind
.
TransactOpts
{
From
:
acc
.
Addr
,
From
:
acc
.
Addr
,
...
@@ -78,55 +125,42 @@ func accountApprove(client *ethclient.Client, acc *types.Account, env types.Env)
...
@@ -78,55 +125,42 @@ func accountApprove(client *ethclient.Client, acc *types.Account, env types.Env)
addNewTx
:=
func
(
tx
*
ethtypes
.
Transaction
)
{
addNewTx
:=
func
(
tx
*
ethtypes
.
Transaction
)
{
waitTx
(
client
,
tx
)
waitTx
(
client
,
tx
)
}
}
//if tx, err := usdt.Approve(txopts, permit2, abi.MaxUint256); err != nil {
allow
,
err
:=
usdt
.
Allowance
(
&
bind
.
CallOpts
{
// return fmt.Errorf("usdt approve permit2 failed: %v", err)
From
:
acc
.
Addr
,
//} else {
BlockNumber
:
nil
,
// addNewTx(tx)
Context
:
context
.
Background
(),
//}
},
acc
.
Addr
,
permit2
)
if
allow
.
Int64
()
==
0
{
// first approve usdt to permit2.
if
tx
,
err
:=
usdt
.
Approve
(
txopts
,
permit2
,
abi
.
MaxUint256
);
err
!=
nil
{
//if tx, err := usdt.Approve(txopts, permit2, abi.MaxUint256); err != nil {
return
fmt
.
Errorf
(
"usdt approve permit2 failed: %v"
,
err
)
if
tx
,
err
:=
usdt
.
Approve
(
txopts
,
common
.
HexToAddress
(
env
.
Router
),
abi
.
MaxUint256
);
err
!=
nil
{
}
else
{
return
fmt
.
Errorf
(
"usdt approve pool failed: %v"
,
err
)
addNewTx
(
tx
)
}
else
{
}
addNewTx
(
tx
)
}
}
//permitData, err := pancake.MakePermit2PermitData2(acc, env, client)
permitData
,
err
:=
pancake
.
MakePermit2PermitData2
(
acc
,
env
,
client
)
//if err != nil {
if
err
!=
nil
{
// return fmt.Errorf("make permit data: %v", err)
return
fmt
.
Errorf
(
"make permit data: %v"
,
err
)
//}
}
//
//inputs := make([][]byte, 0)
//inputs = append(inputs, permitData)
//deadline := time.Now().Unix() + cfg.Param.Deadline*60
inputs
:=
make
([][]
byte
,
0
)
inputs
=
append
(
inputs
,
permitData
)
//if execTx, err := router.Execute(txopts, []byte{byte(pancake.PERMIT2_PERMIT)}, inputs, big.NewInt(deadline)); err != nil {
// set permit with universal router execute.
// return fmt.Errorf("execute permit2 permit failed: %v", err)
deadline
:=
time
.
Now
()
.
Unix
()
+
cfg
.
Param
.
Deadline
*
60
//} else {
if
execTx
,
err
:=
router
.
Execute
(
txopts
,
[]
byte
{
byte
(
pancake
.
PERMIT2_PERMIT
)},
inputs
,
big
.
NewInt
(
deadline
));
err
!=
nil
{
// addNewTx(execTx)
return
fmt
.
Errorf
(
"execute permit2 permit failed: %v"
,
err
)
//}
}
else
{
addNewTx
(
execTx
)
}
return
nil
return
nil
}
}
func
HandlerAccountApprove
(
acc
*
types
.
Account
,
env
types
.
Env
,
idx
uint
)
{
func
accountApprove
(
client
*
ethclient
.
Client
,
acc
*
types
.
Account
,
env
types
.
Env
)
error
{
cfg
:=
config
.
Global
cfg
:=
config
.
Global
// 1. approve usdt token to permit2.
// 2. call permit2 to approve usdt token.
permit2
:=
common
.
HexToAddress
(
env
.
Permit2
)
client
:=
clientpool
.
GetClient
()
usdt
,
err
:=
erc20
.
NewTokenContract
(
common
.
HexToAddress
(
env
.
USDT
),
client
)
usdt
,
err
:=
erc20
.
NewTokenContract
(
common
.
HexToAddress
(
env
.
USDT
),
client
)
if
err
!=
nil
{
if
err
!=
nil
{
addTofailed
(
acc
)
return
fmt
.
Errorf
(
"erc20.NewTokenContract failed: %v"
,
err
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed to create usdt contract: %v"
,
acc
.
Address
,
err
))
return
}
router
,
err
:=
buildparam
.
NewParamContract
(
common
.
HexToAddress
(
env
.
Router
),
client
)
if
err
!=
nil
{
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed to create router contract: %v"
,
acc
.
Address
,
err
))
return
}
}
txopts
:=
&
bind
.
TransactOpts
{
txopts
:=
&
bind
.
TransactOpts
{
...
@@ -134,47 +168,117 @@ func HandlerAccountApprove(acc *types.Account, env types.Env, idx uint) {
...
@@ -134,47 +168,117 @@ func HandlerAccountApprove(acc *types.Account, env types.Env, idx uint) {
Signer
:
acc
.
SignTx
,
Signer
:
acc
.
SignTx
,
GasPrice
:
new
(
big
.
Int
)
.
Mul
(
big
.
NewInt
(
cfg
.
Param
.
GasPrice
),
big
.
NewInt
(
1e9
)),
GasPrice
:
new
(
big
.
Int
)
.
Mul
(
big
.
NewInt
(
cfg
.
Param
.
GasPrice
),
big
.
NewInt
(
1e9
)),
}
}
addNewTx
:=
func
(
tx
*
ethtypes
.
Transaction
)
{
addNewTx
:=
func
(
tx
*
ethtypes
.
Transaction
)
{
IncrTotalTx
()
waitTx
(
client
,
tx
)
waitTx
(
client
,
tx
)
IncrFinishedTx
()
}
}
allow
,
_
:=
usdt
.
Allowance
(
&
bind
.
CallOpts
{
From
:
acc
.
Addr
,
BlockNumber
:
nil
,
Context
:
context
.
Background
(),
},
acc
.
Addr
,
common
.
HexToAddress
(
env
.
Router
))
if
allow
.
Int64
()
==
0
{
if
tx
,
err
:=
usdt
.
Approve
(
txopts
,
common
.
HexToAddress
(
env
.
Router
),
abi
.
MaxUint256
);
err
!=
nil
{
return
fmt
.
Errorf
(
"usdt approve pool failed: %v"
,
err
)
}
else
{
addNewTx
(
tx
)
}
}
return
nil
}
// first approve usdt to permit2.
func
HandlerAccountSwap
(
acc
*
types
.
Account
,
env
types
.
Env
,
idx
uint
)
{
if
tx
,
err
:=
usdt
.
Approve
(
txopts
,
permit2
,
abi
.
MaxUint256
);
err
!=
nil
{
cfg
:=
config
.
Global
client
:=
clientpool
.
GetClient
()
pkstr
:=
acc
.
PrivateKey
if
strings
.
HasPrefix
(
pkstr
,
"0x"
)
||
strings
.
HasPrefix
(
pkstr
,
"0X"
)
{
pkstr
=
acc
.
PrivateKey
[
2
:
]
}
var
err
error
acc
.
PK
,
err
=
crypto
.
HexToECDSA
(
pkstr
)
if
err
!=
nil
{
addTofailed
(
acc
)
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed:
failed approve usdt to permit2 nft contract: %v"
,
acc
.
Address
,
er
r
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed:
invalid private hex string: %v"
,
acc
.
Address
,
pkst
r
))
return
return
}
else
{
addNewTx
(
tx
)
}
}
acc
.
Addr
=
crypto
.
PubkeyToAddress
(
acc
.
PK
.
PublicKey
)
permitData
,
err
:=
pancake
.
MakePermit2PermitData
(
acc
,
env
)
if
strings
.
ToLower
(
acc
.
Addr
.
Hex
())
!=
strings
.
ToLower
(
acc
.
Address
)
{
if
err
!=
nil
{
addTofailed
(
acc
)
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed:
failed to make permit data: %v"
,
acc
.
Address
,
er
r
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed:
given address not match with private key (%s), please check"
,
acc
.
Address
,
acc
.
Add
r
))
return
return
}
}
inputs
:=
make
([][]
byte
,
0
)
if
err
:=
accountApprove
(
client
,
acc
,
env
);
err
!=
nil
{
inputs
=
append
(
inputs
,
permitData
)
deadline
:=
time
.
Now
()
.
Unix
()
+
cfg
.
Param
.
Deadline
*
60
if
execTx
,
err
:=
router
.
Execute
(
txopts
,
[]
byte
{
byte
(
pancake
.
PERMIT2_PERMIT
)},
inputs
,
big
.
NewInt
(
deadline
));
err
!=
nil
{
addTofailed
(
acc
)
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s]
failed: failed execute permit2 permit
: %v"
,
acc
.
Address
,
err
))
WriteLog
(
fmt
.
Sprintf
(
"[%s]
do approve failed
: %v"
,
acc
.
Address
,
err
))
return
return
}
else
{
addNewTx
(
execTx
)
}
}
WriteLog
(
fmt
.
Sprintf
(
"[%s] finish: have no more times to mint"
,
acc
.
Address
))
txopts
:=
&
bind
.
TransactOpts
{
From
:
acc
.
Addr
,
Signer
:
acc
.
SignTx
,
GasPrice
:
new
(
big
.
Int
)
.
Mul
(
big
.
NewInt
(
cfg
.
Param
.
GasPrice
),
big
.
NewInt
(
1e9
)),
}
addNewTx
:=
func
(
tx
*
ethtypes
.
Transaction
)
{
IncrTotalTx
()
receipt
:=
waitTx
(
client
,
tx
)
for
_
,
log
:=
range
receipt
.
Logs
{
if
log
.
Topics
[
0
]
==
pancake
.
TransferTopic
{
token
,
_
:=
erc20
.
NewTokenContract
(
common
.
HexToAddress
(
cfg
.
Pair
.
Token
),
client
)
event
,
_
:=
token
.
ParseTransfer
(
*
log
)
if
event
.
To
==
acc
.
Addr
{
val
,
_
:=
new
(
big
.
Float
)
.
SetInt
(
event
.
Value
)
.
Float64
()
val
=
val
/
1e18
WriteLog
(
fmt
.
Sprintf
(
"[%s] receive %f token"
,
acc
.
Address
,
val
))
IncrReceiveToken
(
val
)
}
if
event
.
From
==
acc
.
Addr
{
val
,
_
:=
new
(
big
.
Float
)
.
SetInt
(
event
.
Value
)
.
Float64
()
val
=
val
/
1e18
IncrCostToken
(
val
)
}
}
}
IncrFinishedTx
()
}
for
i
:=
0
;
i
<
cfg
.
Param
.
Count
;
i
++
{
in
:=
new
(
big
.
Int
)
.
Mul
(
big
.
NewInt
(
cfg
.
Param
.
Volume
),
dec
)
in
=
new
(
big
.
Int
)
.
Div
(
in
,
big
.
NewInt
(
10
))
// param volume 1 is 0.1
v3r
,
err
:=
v3router
.
NewV3Router
(
common
.
HexToAddress
(
env
.
Router
),
client
)
// calc amountOutMin with price and slippage.
amountOutMin
,
err
:=
pancake
.
GetAmountOutMin
(
cfg
,
client
,
env
,
in
,
cfg
.
Param
.
Slippage
,
fee
)
if
err
!=
nil
{
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed to get amount out min: %v"
,
acc
.
Address
,
err
))
return
}
deadline
:=
time
.
Now
()
.
Unix
()
+
cfg
.
Param
.
Deadline
*
60
if
execTx
,
err
:=
v3r
.
ExactInputSingle
(
txopts
,
v3router
.
ISwapRouterExactInputSingleParams
{
TokenIn
:
common
.
HexToAddress
(
env
.
USDT
),
TokenOut
:
common
.
HexToAddress
(
cfg
.
Pair
.
Token
),
Recipient
:
common
.
HexToAddress
(
acc
.
Recipient
),
AmountIn
:
in
,
AmountOutMinimum
:
amountOutMin
,
Deadline
:
big
.
NewInt
(
deadline
),
Fee
:
fee
,
SqrtPriceLimitX96
:
big
.
NewInt
(
0
),
});
err
!=
nil
{
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed execute swap: %v"
,
acc
.
Address
,
err
))
return
}
else
{
addNewTx
(
execTx
)
}
}
WriteLog
(
fmt
.
Sprintf
(
"[%s] finish: have finished all swap"
,
acc
.
Address
))
IncrFinishedUser
()
IncrFinishedUser
()
return
}
}
func
HandlerAccountSwap
(
acc
*
types
.
Account
,
env
types
.
Env
,
idx
uint
)
{
func
HandlerAccountSwap
WithUniversalRouter
(
acc
*
types
.
Account
,
env
types
.
Env
,
idx
uint
)
{
cfg
:=
config
.
Global
cfg
:=
config
.
Global
client
:=
clientpool
.
GetClient
()
client
:=
clientpool
.
GetClient
()
pkstr
:=
acc
.
PrivateKey
pkstr
:=
acc
.
PrivateKey
...
@@ -190,35 +294,38 @@ func HandlerAccountSwap(acc *types.Account, env types.Env, idx uint) {
...
@@ -190,35 +294,38 @@ func HandlerAccountSwap(acc *types.Account, env types.Env, idx uint) {
return
return
}
}
acc
.
Addr
=
crypto
.
PubkeyToAddress
(
acc
.
PK
.
PublicKey
)
acc
.
Addr
=
crypto
.
PubkeyToAddress
(
acc
.
PK
.
PublicKey
)
if
strings
.
ToLower
(
acc
.
Addr
.
Hex
())
!=
strings
.
ToLower
(
acc
.
Address
)
{
if
strings
.
ToLower
(
acc
.
Addr
.
Hex
())
!=
strings
.
ToLower
(
acc
.
Address
)
{
addTofailed
(
acc
)
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: given address not match with private key (%s), please check"
,
acc
.
Address
,
acc
.
Addr
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: given address not match with private key (%s), please check"
,
acc
.
Address
,
acc
.
Addr
))
return
return
}
}
if
err
:=
accountApprove
(
client
,
acc
,
env
);
err
!=
nil
{
if
err
:=
accountApproveWithPermit
(
client
,
acc
,
env
);
err
!=
nil
{
addTofailed
(
acc
)
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] do approve failed: %v"
,
acc
.
Address
,
err
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] do approve failed: %v"
,
acc
.
Address
,
err
))
return
return
}
}
//router, err := buildparam.NewParamContract(common.HexToAddress(env.
Router), client)
router
,
err
:=
buildparam
.
NewParamContract
(
common
.
HexToAddress
(
env
.
Universal
Router
),
client
)
//
if err != nil {
if
err
!=
nil
{
//
addTofailed(acc)
addTofailed
(
acc
)
//
WriteLog(fmt.Sprintf("[%s] failed: failed to create router contract: %v", acc.Address, err))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed to create router contract: %v"
,
acc
.
Address
,
err
))
//
return
return
//
}
}
txopts
:=
&
bind
.
TransactOpts
{
txopts
:=
&
bind
.
TransactOpts
{
From
:
acc
.
Addr
,
From
:
acc
.
Addr
,
Signer
:
acc
.
SignTx
,
Signer
:
acc
.
SignTx
,
GasPrice
:
new
(
big
.
Int
)
.
Mul
(
big
.
NewInt
(
cfg
.
Param
.
GasPrice
),
big
.
NewInt
(
1e9
)),
GasPrice
:
new
(
big
.
Int
)
.
Mul
(
big
.
NewInt
(
cfg
.
Param
.
GasPrice
),
big
.
NewInt
(
1e9
)),
}
}
addNewTx
:=
func
(
tx
*
ethtypes
.
Transaction
)
{
addNewTx
:=
func
(
tx
*
ethtypes
.
Transaction
)
{
IncrTotalTx
()
IncrTotalTx
()
receipt
:=
waitTx
(
client
,
tx
)
receipt
:=
waitTx
(
client
,
tx
)
for
_
,
log
:=
range
receipt
.
Logs
{
for
_
,
log
:=
range
receipt
.
Logs
{
if
log
.
Topics
[
0
]
==
pancake
.
TransferTopic
{
if
log
.
Topics
[
0
]
==
pancake
.
TransferTopic
{
token
,
_
:=
erc20
.
NewTokenContract
(
common
.
HexToAddress
(
env
.
KLKO
),
client
)
token
,
_
:=
erc20
.
NewTokenContract
(
common
.
HexToAddress
(
cfg
.
Pair
.
Token
),
client
)
event
,
_
:=
token
.
ParseTransfer
(
*
log
)
event
,
_
:=
token
.
ParseTransfer
(
*
log
)
if
event
.
To
==
acc
.
Addr
{
if
event
.
To
==
acc
.
Addr
{
val
,
_
:=
new
(
big
.
Float
)
.
SetInt
(
event
.
Value
)
.
Float64
()
val
,
_
:=
new
(
big
.
Float
)
.
SetInt
(
event
.
Value
)
.
Float64
()
...
@@ -236,28 +343,25 @@ func HandlerAccountSwap(acc *types.Account, env types.Env, idx uint) {
...
@@ -236,28 +343,25 @@ func HandlerAccountSwap(acc *types.Account, env types.Env, idx uint) {
IncrFinishedTx
()
IncrFinishedTx
()
}
}
dec
:=
new
(
big
.
Int
)
.
SetUint64
(
1000000000000000000
)
fee
:=
big
.
NewInt
(
10000
)
for
i
:=
0
;
i
<
cfg
.
Param
.
Count
;
i
++
{
for
i
:=
0
;
i
<
cfg
.
Param
.
Count
;
i
++
{
in
:=
new
(
big
.
Int
)
.
Mul
(
big
.
NewInt
(
cfg
.
Param
.
Volume
),
dec
)
in
:=
new
(
big
.
Int
)
.
Mul
(
big
.
NewInt
(
cfg
.
Param
.
Volume
),
dec
)
in
=
new
(
big
.
Int
)
.
Div
(
in
,
big
.
NewInt
(
10
))
// param volume 1 is 0.1
in
=
new
(
big
.
Int
)
.
Div
(
in
,
big
.
NewInt
(
10
))
// param volume 1 is 0.1
v3r
,
err
:=
v3router
.
NewV3Router
(
common
.
HexToAddress
(
env
.
Router
),
client
)
// calc amountOutMin with price and slippage.
// calc amountOutMin with price and slippage.
amountOutMin
,
err
:=
pancake
.
GetAmountOutMin
(
client
,
env
,
in
,
cfg
.
Param
.
Slippage
,
fee
)
amountOutMin
,
err
:=
pancake
.
GetAmountOutMin
(
c
fg
,
c
lient
,
env
,
in
,
cfg
.
Param
.
Slippage
,
fee
)
if
err
!=
nil
{
if
err
!=
nil
{
addTofailed
(
acc
)
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed to get amount out min: %v"
,
acc
.
Address
,
err
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed to get amount out min: %v"
,
acc
.
Address
,
err
))
return
return
}
}
param
:=
pancake
.
ParamV3SwapExactIn
{
param
:=
pancake
.
ParamV3SwapExactIn
{
Recipient
:
acc
.
Addr
,
Recipient
:
common
.
HexToAddress
(
acc
.
Recipient
)
,
AmountIn
:
in
,
AmountIn
:
in
,
AmountOutMin
:
amountOutMin
,
AmountOutMin
:
amountOutMin
,
Path
:
nil
,
Path
:
nil
,
PayerIsUser
:
true
,
PayerIsUser
:
true
,
}
}
data
,
err
:=
pancake
.
MakeV3SwapExactInData
(
env
,
param
)
data
,
err
:=
pancake
.
MakeV3SwapExactInData
(
env
,
param
,
cfg
)
if
err
!=
nil
{
if
err
!=
nil
{
addTofailed
(
acc
)
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed to make swap data: %v"
,
acc
.
Address
,
err
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed to make swap data: %v"
,
acc
.
Address
,
err
))
...
@@ -266,23 +370,7 @@ func HandlerAccountSwap(acc *types.Account, env types.Env, idx uint) {
...
@@ -266,23 +370,7 @@ func HandlerAccountSwap(acc *types.Account, env types.Env, idx uint) {
inputs
:=
make
([][]
byte
,
0
)
inputs
:=
make
([][]
byte
,
0
)
inputs
=
append
(
inputs
,
data
)
inputs
=
append
(
inputs
,
data
)
deadline
:=
time
.
Now
()
.
Unix
()
+
cfg
.
Param
.
Deadline
*
60
deadline
:=
time
.
Now
()
.
Unix
()
+
cfg
.
Param
.
Deadline
*
60
//if execTx, err := router.Execute(txopts, []byte{byte(pancake.V3_SWAP_EXACT_IN)}, inputs, big.NewInt(deadline)); err != nil {
if
execTx
,
err
:=
router
.
Execute
(
txopts
,
[]
byte
{
byte
(
pancake
.
V3_SWAP_EXACT_IN
)},
inputs
,
big
.
NewInt
(
deadline
));
err
!=
nil
{
// addTofailed(acc)
// WriteLog(fmt.Sprintf("[%s] failed: failed execute swap: %v", acc.Address, err))
// return
//} else {
// addNewTx(execTx)
//}
if
execTx
,
err
:=
v3r
.
ExactInputSingle
(
txopts
,
v3router
.
ISwapRouterExactInputSingleParams
{
TokenIn
:
common
.
HexToAddress
(
env
.
USDT
),
TokenOut
:
common
.
HexToAddress
(
env
.
KLKO
),
Recipient
:
acc
.
Addr
,
AmountIn
:
in
,
AmountOutMinimum
:
amountOutMin
,
Deadline
:
big
.
NewInt
(
deadline
),
Fee
:
fee
,
SqrtPriceLimitX96
:
big
.
NewInt
(
0
),
});
err
!=
nil
{
addTofailed
(
acc
)
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed execute swap: %v"
,
acc
.
Address
,
err
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed execute swap: %v"
,
acc
.
Address
,
err
))
return
return
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment