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
Show 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
make
```
#### 2. fill in the `accounts.json` file with the accounts you want to do swap for.
The example of the
`accounts.json`
file is as follow:
```
json
[
{
"address"
:
"0x"
,
"private"
:
"0x"
},
{
"address"
:
"0x"
,
"private"
:
"0x"
}
]
#### 2. fill in the `accounts.csv` file with the accounts you want to do swap for.
The example of the
`accounts.csv`
file is as follow:
```
csv
useraddress, privatekey, recipient
0xeFbb75e446Ec2d8493B3d4d91aC3118953f69b55, 0x1111111111111111, 0xc437593d9C296bf9A5002522A86dad8a4d4Af808
```
#### 4. change configure
...
...
@@ -55,6 +47,12 @@ param:
# tx deadline, unit is minutes, set 0 to disable.
deadline
:
20
pair
:
# pair address.
pair
:
"
0xcB0AE3B8337f0Cc35563e6b9fC357F2298C0D24a"
# klko address
token
:
"
0x215324115417a13879f865Dc5BB651B18A781a59"
rpc
:
env
:
"
bsc"
pool
:
20
...
...
@@ -62,7 +60,7 @@ rpc:
log
:
level
:
"
debug"
users
:
"
accounts.
json
"
users
:
"
accounts.
csv
"
```
#### 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:
# tx deadline, unit is minutes, set 0 to disable.
deadline
:
20
pair
:
# pair address.
pair
:
"
0xcB0AE3B8337f0Cc35563e6b9fC357F2298C0D24a"
# klko address
token
:
"
0x215324115417a13879f865Dc5BB651B18A781a59"
rpc
:
env
:
"
bsc"
pool
:
20
...
...
@@ -19,4 +25,4 @@ rpc:
log
:
level
:
"
debug"
users
:
"
accounts.json"
\ No newline at end of file
users
:
"
accounts.csv"
\ No newline at end of file
config/config.go
View file @
5860be39
...
...
@@ -12,6 +12,7 @@ import (
type
Config
struct
{
Log
LogConfig
`yaml:"log"`
Param
ParamConfig
`yaml:"param"`
Pair
PairConfig
`yaml:"pair"`
Rpc
RpcConfig
`yaml:"rpc"`
Users
string
`yaml:"users"`
}
...
...
@@ -25,6 +26,11 @@ type ParamConfig struct {
Deadline
int64
`yaml:"deadline"`
}
type
PairConfig
struct
{
Pair
string
`yaml:"pair"`
Token
string
`yaml:"token"`
}
type
RpcConfig
struct
{
Env
string
`yaml:"env"`
PoolSize
int
`yaml:"pool"`
...
...
pancake/pack.go
View file @
5860be39
package
pancake
import
(
"code.wuban.net.cn/service/pancakeswapper/config"
"code.wuban.net.cn/service/pancakeswapper/contracts/buildparam"
"code.wuban.net.cn/service/pancakeswapper/contracts/v3pool"
"code.wuban.net.cn/service/pancakeswapper/types"
...
...
@@ -30,7 +31,7 @@ func leftPadding(data []byte, length int) []byte {
return
append
(
padding
,
data
...
)
}
func
MakeV3SwapExactInPathData
(
env
types
.
Env
)
[]
byte
{
func
MakeV3SwapExactInPathData
(
env
types
.
Env
,
cfg
*
config
.
Config
)
[]
byte
{
//0000000000000000000000003e3b4d16ce35840c28f90edb7f38e5bdd976c7e3
//0000000000000000000000000000000000000000000000001bc16d674ec80000
//0000000000000000000000000000000000000000000000002620b5d4cdab6c04
...
...
@@ -40,7 +41,7 @@ func MakeV3SwapExactInPathData(env types.Env) []byte {
//55d398326f99059ff775485246999027b3197955002710215324115417a13879f865dc5bb651b18a781a59000000000000000000000000000000000000000000
token0
:=
common
.
HexToAddress
(
env
.
USDT
)
token1
:=
common
.
HexToAddress
(
env
.
KLKO
)
token1
:=
common
.
HexToAddress
(
cfg
.
Pair
.
Token
)
fee
:=
big
.
NewInt
(
10000
)
data
:=
make
([]
byte
,
0
)
data
=
append
(
data
,
token0
.
Bytes
()
...
)
...
...
@@ -49,7 +50,7 @@ func MakeV3SwapExactInPathData(env types.Env) []byte {
return
data
}
func
MakeV3SwapExactInData
(
env
types
.
Env
,
param
ParamV3SwapExactIn
)
([]
byte
,
error
)
{
func
MakeV3SwapExactInData
(
env
types
.
Env
,
param
ParamV3SwapExactIn
,
cfg
*
config
.
Config
)
([]
byte
,
error
)
{
//0000000000000000000000003e3b4d16ce35840c28f90edb7f38e5bdd976c7e3
//0000000000000000000000000000000000000000000000000de0b6b3a7640000
//00000000000000000000000000000000000000000000000012d0ee4f5819f972
...
...
@@ -59,7 +60,7 @@ func MakeV3SwapExactInData(env types.Env, param ParamV3SwapExactIn) ([]byte, err
//55d398326f99059ff775485246999027b3197955002710215324115417a13879
//f865dc5bb651b18a781a59000000000000000000000000000000000000000000
param
.
Path
=
MakeV3SwapExactInPathData
(
env
)
param
.
Path
=
MakeV3SwapExactInPathData
(
env
,
cfg
)
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
)
...
...
@@ -103,10 +104,10 @@ func MakePermit2PermitData(acc *types.Account, env types.Env) ([]byte, error) {
// 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%.
// 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
)
{
// get slot0 data.
pool
:=
common
.
HexToAddress
(
env
.
Pool
)
pool
:=
common
.
HexToAddress
(
cfg
.
Pair
.
Pair
)
contract
,
err
:=
v3pool
.
NewV3Pool
(
pool
,
client
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -216,6 +217,7 @@ func MakePermit2PermitData2(acc *types.Account, env types.Env, client *ethclient
// Pack the data
buildAbi
,
_
:=
abi
.
JSON
(
strings
.
NewReader
(
buildparam
.
ParamContractMetaData
.
ABI
))
// todo: check method name.
data
,
err
:=
buildAbi
.
Pack
(
"buildParamPermit2"
,
permitSingle
,
signature
)
if
err
!=
nil
{
return
nil
,
err
...
...
swapper/swapper.go
View file @
5860be39
...
...
@@ -26,7 +26,7 @@ func (s *Swapper) Run() {
work
.
WorkInit
(
env
.
ChainId
)
// 1. read account info from json file
accs
:=
work
.
LoadAccounts
(
s
.
cfg
.
Users
)
accs
:=
work
.
LoadAccounts
FromCsv
(
s
.
cfg
.
Users
)
work
.
SetTotalUser
(
len
(
accs
))
waitCh
:=
make
(
chan
struct
{})
...
...
types/account.go
View file @
5860be39
...
...
@@ -15,6 +15,7 @@ type Account struct {
//Nonce uint64 `json:"-"`
PK
*
ecdsa
.
PrivateKey
`json:"-"`
Addr
common
.
Address
`json:"-"`
Recipient
string
`json:“recipient"`
}
func
(
a
*
Account
)
sign
(
chainid
*
big
.
Int
,
tx
*
types
.
Transaction
)
(
*
types
.
Transaction
,
error
)
{
...
...
types/env.go
View file @
5860be39
...
...
@@ -6,14 +6,11 @@ var (
func
init
()
{
allEnv
[
"bsc"
]
=
Env
{
//RPC: "https://bscnode.bitheart.org",
RPC
:
"https://four.rpc.48.club"
,
USDT
:
"0x55d398326f99059ff775485246999027b3197955"
,
KLKO
:
"0x215324115417a13879f865Dc5BB651B18A781a59"
,
// KLKO
Permit2
:
"0x31c2F6fcFf4F8759b3Bd5Bf0e1084A055615c768"
,
Router
:
"0x1b81D678ffb9C0263b24A97847620C99d213eB14"
,
//Router: "0x1A0A18AC4BECDDbd6389559687d1A73d8927E416",
Pool
:
"0xcB0AE3B8337f0Cc35563e6b9fC357F2298C0D24a"
,
UniversalRouter
:
"0x1A0A18AC4BECDDbd6389559687d1A73d8927E416"
,
ChainId
:
56
,
}
}
...
...
@@ -21,10 +18,11 @@ func init() {
type
Env
struct
{
RPC
string
USDT
string
KLKO
string
//
KLKO string
Permit2
string
Router
string
Pool
string
Router
string
// v3 router.
UniversalRouter
string
//Pool string
ChainId
int64
}
...
...
work/account.go
View file @
5860be39
...
...
@@ -9,6 +9,7 @@ import (
"code.wuban.net.cn/service/pancakeswapper/pancake"
"code.wuban.net.cn/service/pancakeswapper/types"
"context"
"encoding/csv"
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi"
...
...
@@ -17,6 +18,7 @@ import (
ethtypes
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
log
"github.com/sirupsen/logrus"
"math/big"
"os"
"strings"
...
...
@@ -25,6 +27,8 @@ import (
var
(
failedHistory
=
make
(
chan
*
types
.
Account
,
1000000
)
dec
=
new
(
big
.
Int
)
.
SetUint64
(
1000000000000000000
)
fee
=
big
.
NewInt
(
10000
)
)
func
LoadAccounts
(
file
string
)
[]
*
types
.
Account
{
...
...
@@ -39,6 +43,48 @@ func LoadAccounts(file string) []*types.Account {
}
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
)
{
IncrFailedUser
()
failedHistory
<-
acc
...
...
@@ -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
//
permit2 := common.HexToAddress(env.Permit2)
permit2
:=
common
.
HexToAddress
(
env
.
Permit2
)
usdt
,
err
:=
erc20
.
NewTokenContract
(
common
.
HexToAddress
(
env
.
USDT
),
client
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"erc20.NewTokenContract failed: %v"
,
err
)
}
//router, err := buildparam.NewParamContract(common.HexToAddress(env.Router), client)
//if err != nil {
// return fmt.Errorf("build param contract failed: %v", err)
//}
// router need set to Universal Router.
router
,
err
:=
buildparam
.
NewParamContract
(
common
.
HexToAddress
(
env
.
UniversalRouter
),
client
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"build param contract failed: %v"
,
err
)
}
txopts
:=
&
bind
.
TransactOpts
{
From
:
acc
.
Addr
,
...
...
@@ -78,54 +125,93 @@ func accountApprove(client *ethclient.Client, acc *types.Account, env types.Env)
addNewTx
:=
func
(
tx
*
ethtypes
.
Transaction
)
{
waitTx
(
client
,
tx
)
}
//if tx, err := usdt.Approve(txopts, permit2, abi.MaxUint256); err != nil {
// return fmt.Errorf("usdt approve permit2 failed: %v", err)
//} else {
// addNewTx(tx)
//}
// first approve usdt to permit2.
//if tx, err := usdt.Approve(txopts, permit2, abi.MaxUint256); err != nil {
if
tx
,
err
:=
usdt
.
Approve
(
txopts
,
common
.
HexToAddress
(
env
.
Router
),
abi
.
MaxUint256
);
err
!=
nil
{
return
fmt
.
Errorf
(
"usdt approve pool failed: %v"
,
err
)
allow
,
err
:=
usdt
.
Allowance
(
&
bind
.
CallOpts
{
From
:
acc
.
Addr
,
BlockNumber
:
nil
,
Context
:
context
.
Background
(),
},
acc
.
Addr
,
permit2
)
if
allow
.
Int64
()
==
0
{
if
tx
,
err
:=
usdt
.
Approve
(
txopts
,
permit2
,
abi
.
MaxUint256
);
err
!=
nil
{
return
fmt
.
Errorf
(
"usdt approve permit2 failed: %v"
,
err
)
}
else
{
addNewTx
(
tx
)
}
}
//permitData, err := pancake.MakePermit2PermitData2(acc, env, client)
//if err != nil {
// return fmt.Errorf("make permit data: %v", err)
//}
//
//inputs := make([][]byte, 0)
//inputs = append(inputs, permitData)
permitData
,
err
:=
pancake
.
MakePermit2PermitData2
(
acc
,
env
,
client
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"make permit data: %v"
,
err
)
}
//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 {
// return fmt.Errorf("execute permit2 permit failed: %v", err)
//} else {
// addNewTx(execTx)
//}
// set permit with universal router execute.
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
{
return
fmt
.
Errorf
(
"execute permit2 permit failed: %v"
,
err
)
}
else
{
addNewTx
(
execTx
)
}
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
// 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
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"erc20.NewTokenContract failed: %v"
,
err
)
}
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
)
{
waitTx
(
client
,
tx
)
}
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
}
func
HandlerAccountSwap
(
acc
*
types
.
Account
,
env
types
.
Env
,
idx
uint
)
{
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
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed:
failed to create usdt contract: %v"
,
acc
.
Address
,
er
r
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed:
invalid private hex string: %v"
,
acc
.
Address
,
pkst
r
))
return
}
router
,
err
:=
buildparam
.
NewParamContract
(
common
.
HexToAddress
(
env
.
Router
),
client
)
if
err
!=
nil
{
acc
.
Addr
=
crypto
.
PubkeyToAddress
(
acc
.
PK
.
PublicKey
)
if
strings
.
ToLower
(
acc
.
Addr
.
Hex
())
!=
strings
.
ToLower
(
acc
.
Address
)
{
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed to create router contract: %v"
,
acc
.
Address
,
err
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: given address not match with private key (%s), please check"
,
acc
.
Address
,
acc
.
Addr
))
return
}
if
err
:=
accountApprove
(
client
,
acc
,
env
);
err
!=
nil
{
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] do approve failed: %v"
,
acc
.
Address
,
err
))
return
}
...
...
@@ -136,45 +222,63 @@ func HandlerAccountApprove(acc *types.Account, env types.Env, idx uint) {
}
addNewTx
:=
func
(
tx
*
ethtypes
.
Transaction
)
{
IncrTotalTx
()
waitTx
(
client
,
tx
)
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
()
}
// first approve usdt to permit2.
if
tx
,
err
:=
usdt
.
Approve
(
txopts
,
permit2
,
abi
.
MaxUint256
);
err
!=
nil
{
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed approve usdt to permit2 nft contract: %v"
,
acc
.
Address
,
err
))
return
}
else
{
addNewTx
(
tx
)
}
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
)
permitData
,
err
:=
pancake
.
MakePermit2PermitData
(
acc
,
env
)
// 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 make permit data
: %v"
,
acc
.
Address
,
err
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed to get amount out min
: %v"
,
acc
.
Address
,
err
))
return
}
inputs
:=
make
([][]
byte
,
0
)
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
{
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 permit2 permit
: %v"
,
acc
.
Address
,
err
))
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: failed execute swap
: %v"
,
acc
.
Address
,
err
))
return
}
else
{
addNewTx
(
execTx
)
}
WriteLog
(
fmt
.
Sprintf
(
"[%s] finish: have
no more times to mint
"
,
acc
.
Address
))
}
WriteLog
(
fmt
.
Sprintf
(
"[%s] finish: have
finished all swap
"
,
acc
.
Address
))
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
client
:=
clientpool
.
GetClient
()
pkstr
:=
acc
.
PrivateKey
...
...
@@ -190,35 +294,38 @@ func HandlerAccountSwap(acc *types.Account, env types.Env, idx uint) {
return
}
acc
.
Addr
=
crypto
.
PubkeyToAddress
(
acc
.
PK
.
PublicKey
)
if
strings
.
ToLower
(
acc
.
Addr
.
Hex
())
!=
strings
.
ToLower
(
acc
.
Address
)
{
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] failed: given address not match with private key (%s), please check"
,
acc
.
Address
,
acc
.
Addr
))
return
}
if
err
:=
accountApprove
(
client
,
acc
,
env
);
err
!=
nil
{
if
err
:=
accountApproveWithPermit
(
client
,
acc
,
env
);
err
!=
nil
{
addTofailed
(
acc
)
WriteLog
(
fmt
.
Sprintf
(
"[%s] do approve failed: %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
//
}
router
,
err
:=
buildparam
.
NewParamContract
(
common
.
HexToAddress
(
env
.
Universal
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
{
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
(
env
.
KLKO
),
client
)
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
()
...
...
@@ -236,28 +343,25 @@ func HandlerAccountSwap(acc *types.Account, env types.Env, idx uint) {
IncrFinishedTx
()
}
dec
:=
new
(
big
.
Int
)
.
SetUint64
(
1000000000000000000
)
fee
:=
big
.
NewInt
(
10000
)
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
(
client
,
env
,
in
,
cfg
.
Param
.
Slippage
,
fee
)
amountOutMin
,
err
:=
pancake
.
GetAmountOutMin
(
c
fg
,
c
lient
,
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
}
param
:=
pancake
.
ParamV3SwapExactIn
{
Recipient
:
acc
.
Addr
,
Recipient
:
common
.
HexToAddress
(
acc
.
Recipient
)
,
AmountIn
:
in
,
AmountOutMin
:
amountOutMin
,
Path
:
nil
,
PayerIsUser
:
true
,
}
data
,
err
:=
pancake
.
MakeV3SwapExactInData
(
env
,
param
)
data
,
err
:=
pancake
.
MakeV3SwapExactInData
(
env
,
param
,
cfg
)
if
err
!=
nil
{
addTofailed
(
acc
)
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) {
inputs
:=
make
([][]
byte
,
0
)
inputs
=
append
(
inputs
,
data
)
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 {
// 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
{
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
...
...
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