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
f68cffcd
Commit
f68cffcd
authored
Apr 11, 2025
by
vicotor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add test code.
parent
baf36d8e
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
114 additions
and
78 deletions
+114
-78
pack.go
pancake/pack.go
+44
-66
swapper.go
swapper/swapper.go
+1
-0
account.go
types/account.go
+57
-11
account.go
work/account.go
+12
-1
No files found.
pancake/pack.go
View file @
f68cffcd
...
...
@@ -5,14 +5,12 @@ import (
"code.wuban.net.cn/service/pancakeswapper/contracts/buildparam"
"code.wuban.net.cn/service/pancakeswapper/contracts/v3pool"
"code.wuban.net.cn/service/pancakeswapper/types"
"context"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/signer/core/apitype
s"
log
"github.com/sirupsen/logru
s"
"math/big"
"strings"
"time"
...
...
@@ -142,88 +140,68 @@ func GetAmountOutMin(cfg *config.Config, client *ethclient.Client, env types.Env
}
func
MakePermit2PermitData2
(
acc
*
types
.
Account
,
env
types
.
Env
,
client
*
ethclient
.
Client
)
([]
byte
,
error
)
{
//00000000000000000000000055d398326f99059ff775485246999027b3197955
//000000000000000000000000ffffffffffffffffffffffffffffffffffffffff
//00000000000000000000000000000000000000000000000000000000681dd1ab
//0000000000000000000000000000000000000000000000000000000000000000
//0000000000000000000000001a0a18ac4becddbd6389559687d1a73d8927e416
//0000000000000000000000000000000000000000000000000000000067f64bb3
//00000000000000000000000000000000000000000000000000000000000000e0
//0000000000000000000000000000000000000000000000000000000000000041
//747b8fa98714e48b5db6e5585c8278ef7de03431ab30aed0b3d999cbf360d8db
//4fd9920bf48fbec49957def82ffa6e3441c6094b5cccd5ceee70ce19b1f96d11
//1c00000000000000000000000000000000000000000000000000000000000000
//00000000000000000000000055d398326f99059ff775485246999027b3197955
//000000000000000000000000ffffffffffffffffffffffffffffffffffffffff
//0000000000000000000000000000000000000000000000000000000069d9bfbd
//0000000000000000000000000000000000000000000000000000000067f88c3d
//0000000000000000000000001a0a18ac4becddbd6389559687d1a73d8927e416
//0000000000000000000000000000000000000000000000000000000067f9ddbd
//00000000000000000000000000000000000000000000000000000000000000e0
//0000000000000000000000000000000000000000000000000000000000000041
//7e90d529be5a0c36f2a59226382e22b9b38e258584ca7cca8e6c74faf4734fbe
//42d5b2b152b6325729818115eb27b0421104fc5ad0b9a068d8212e1e17e8e8fd
//1c00000000000000000000000000000000000000000000000000000000000000
// Constants
year
:=
int64
(
365
*
24
*
60
*
60
)
hour
:=
int64
(
60
*
60
)
day
:=
int64
(
60
*
60
*
24
)
// Create permit details
permitSingle
:=
buildparam
.
IPancakePermitSingle
{
Details
:
buildparam
.
IPancakePermitDetails
{
Token
:
common
.
HexToAddress
(
env
.
USDT
),
Amount
:
abi
.
MaxUint256
,
Expiration
:
big
.
NewInt
(
time
.
Now
()
.
Unix
()
+
year
),
Nonce
:
big
.
NewInt
(
time
.
Now
()
.
Unix
()),
},
Spender
:
common
.
HexToAddress
(
env
.
Router
),
SigDeadline
:
big
.
NewInt
(
time
.
Now
()
.
Unix
()
+
hour
),
}
expiration
:=
big
.
NewInt
(
time
.
Now
()
.
Unix
()
+
year
)
chainId
:=
big
.
NewInt
(
env
.
ChainId
)
token
:=
common
.
HexToAddress
(
env
.
USDT
)
permit2Address
:=
common
.
HexToAddress
(
env
.
Permit2
)
amount
:=
new
(
big
.
Int
)
.
Sub
(
new
(
big
.
Int
)
.
Lsh
(
big
.
NewInt
(
1
),
160
),
big
.
NewInt
(
1
))
nonce
:=
big
.
NewInt
(
time
.
Now
()
.
Unix
())
// Get chain ID for domain separator
chainId
,
err
:=
client
.
ChainID
(
context
.
Background
())
signature
,
err
:=
acc
.
SignTypedData
(
chainId
,
permit2Address
,
token
,
amount
,
expiration
,
nonce
)
if
err
!=
nil
{
return
nil
,
err
}
// Get permit2 contract address
permit2Address
:=
common
.
HexToAddress
(
env
.
Permit2
)
// Create the domain separator
domain
:=
apitypes
.
TypedDataDomain
{
Name
:
"Permit2"
,
ChainId
:
math
.
NewHexOrDecimal256
(
chainId
.
Int64
()),
VerifyingContract
:
permit2Address
.
Hex
(),
}
// Create the types for EIP-712 signing
types
:=
apitypes
.
Types
{
"PermitSingle"
:
[]
apitypes
.
Type
{
{
Name
:
"details"
,
Type
:
"PermitDetails"
},
{
Name
:
"spender"
,
Type
:
"address"
},
{
Name
:
"sigDeadline"
,
Type
:
"uint256"
},
},
"PermitDetails"
:
[]
apitypes
.
Type
{
{
Name
:
"token"
,
Type
:
"address"
},
{
Name
:
"amount"
,
Type
:
"uint256"
},
{
Name
:
"expiration"
,
Type
:
"uint256"
},
{
Name
:
"nonce"
,
Type
:
"uint256"
},
},
}
// Create the typed data message
message
:=
map
[
string
]
interface
{}{
"details"
:
map
[
string
]
interface
{}{
"token"
:
permitSingle
.
Details
.
Token
.
Hex
(),
"amount"
:
permitSingle
.
Details
.
Amount
,
"expiration"
:
permitSingle
.
Details
.
Expiration
,
"nonce"
:
permitSingle
.
Details
.
Nonce
,
// Create permit details
permitSingle
:=
buildparam
.
IPancakePermitSingle
{
Details
:
buildparam
.
IPancakePermitDetails
{
Token
:
common
.
HexToAddress
(
env
.
USDT
),
Amount
:
amount
,
Expiration
:
expiration
,
Nonce
:
nonce
,
},
"spender"
:
permitSingle
.
Spender
.
Hex
(),
"sigDeadline"
:
permitSingle
.
SigDeadline
,
}
// Create the typed data
typedData
:=
apitypes
.
TypedData
{
Types
:
types
,
PrimaryType
:
"PermitSingle"
,
Domain
:
domain
,
Message
:
message
,
}
// Generate EIP-712 signature hash
signature
,
err
:=
acc
.
SignTypedData
(
typedData
)
if
err
!=
nil
{
return
nil
,
err
Spender
:
common
.
HexToAddress
(
env
.
UniversalRouter
),
SigDeadline
:
big
.
NewInt
(
time
.
Now
()
.
Unix
()
+
day
),
}
// 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
{
log
.
WithError
(
err
)
.
Error
(
"build permit2 permit"
)
return
nil
,
err
}
// Remove method ID
data
=
data
[
4
:
]
return
data
,
nil
}
swapper/swapper.go
View file @
f68cffcd
...
...
@@ -33,6 +33,7 @@ func (s *Swapper) Run() {
// 2. init account info
go
func
(
w
chan
struct
{},
accounts
[]
*
types
.
Account
)
{
grouptask
.
DoMultiTasks
(
s
.
cfg
.
Param
.
Routine
,
env
,
work
.
HandlerAccountSwap
,
accounts
)
//grouptask.DoMultiTasks(s.cfg.Param.Routine, env, work.HandlerAccountSwapWithUniversalRouter, accounts)
w
<-
struct
{}{}
}(
waitCh
,
accs
)
...
...
types/account.go
View file @
f68cffcd
...
...
@@ -2,7 +2,10 @@ package types
import
(
"crypto/ecdsa"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/signer/core/apitypes"
...
...
@@ -40,23 +43,66 @@ func (a *Account) SignMessage(msg []byte) ([]byte, error) {
return
sig
,
nil
}
func
(
a
*
Account
)
SignTypedData
(
typedData
apitypes
.
TypedData
)
([]
byte
,
error
)
{
// Use the go-ethereum hash generator for EIP-712
hash
,
_
,
err
:=
apitypes
.
TypedDataAndHash
(
typedData
)
func
(
a
*
Account
)
SignTypedData
(
chainID
*
big
.
Int
,
permit2Address
,
tokenAddress
common
.
Address
,
amount
*
big
.
Int
,
expiration
*
big
.
Int
,
nonce
*
big
.
Int
)
([]
byte
,
error
)
{
mchainId
:=
math
.
HexOrDecimal256
(
*
chainID
)
// 创建EIP-712结构化数据
typedData
:=
apitypes
.
TypedData
{
Types
:
apitypes
.
Types
{
"EIP712Domain"
:
[]
apitypes
.
Type
{
{
Name
:
"name"
,
Type
:
"string"
},
{
Name
:
"version"
,
Type
:
"string"
},
{
Name
:
"chainId"
,
Type
:
"uint256"
},
{
Name
:
"verifyingContract"
,
Type
:
"address"
},
},
"TokenPermissions"
:
[]
apitypes
.
Type
{
{
Name
:
"token"
,
Type
:
"address"
},
{
Name
:
"amount"
,
Type
:
"uint256"
},
},
"PermitTransferFrom"
:
[]
apitypes
.
Type
{
{
Name
:
"permitted"
,
Type
:
"TokenPermissions"
},
{
Name
:
"nonce"
,
Type
:
"uint256"
},
{
Name
:
"deadline"
,
Type
:
"uint256"
},
},
},
PrimaryType
:
"PermitTransferFrom"
,
Domain
:
apitypes
.
TypedDataDomain
{
Name
:
"Permit2"
,
Version
:
"1"
,
ChainId
:
&
mchainId
,
VerifyingContract
:
permit2Address
.
Hex
(),
},
Message
:
apitypes
.
TypedDataMessage
{
"permitted"
:
map
[
string
]
interface
{}{
"token"
:
tokenAddress
.
Hex
(),
"amount"
:
amount
.
String
(),
},
"nonce"
:
hexutil
.
EncodeUint64
(
nonce
.
Uint64
()),
"deadline"
:
expiration
.
String
(),
},
}
domain
,
err
:=
typedData
.
HashStruct
(
"EIP712Domain"
,
typedData
.
Domain
.
Map
())
if
err
!=
nil
{
return
nil
,
err
return
nil
,
fmt
.
Errorf
(
"domain hash failed: %v"
,
err
)
}
// Sign the hash with the private key
sig
,
err
:=
crypto
.
Sign
(
hash
,
a
.
PK
)
permitHash
,
err
:=
typedData
.
HashStruct
(
typedData
.
PrimaryType
,
typedData
.
Message
)
if
err
!=
nil
{
return
nil
,
err
return
nil
,
fmt
.
Errorf
(
"message hash failed: %v"
,
err
)
}
// Adjust V value for Ethereum standard
if
sig
[
64
]
<
27
{
sig
[
64
]
+=
27
rawData
:=
[]
byte
(
fmt
.
Sprintf
(
"
\x19\x01
%s%s"
,
string
(
domain
),
string
(
permitHash
)))
signHash
:=
crypto
.
Keccak256
(
rawData
)
signature
,
err
:=
crypto
.
Sign
(
signHash
,
a
.
PK
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"sign message failed: %v"
,
err
)
}
return
sig
,
nil
signature
[
64
]
+=
27
return
signature
,
nil
}
work/account.go
View file @
f68cffcd
...
...
@@ -5,11 +5,13 @@ import (
"code.wuban.net.cn/service/pancakeswapper/config"
"code.wuban.net.cn/service/pancakeswapper/contracts/buildparam"
"code.wuban.net.cn/service/pancakeswapper/contracts/erc20"
router2
"code.wuban.net.cn/service/pancakeswapper/contracts/router"
"code.wuban.net.cn/service/pancakeswapper/contracts/v3router"
"code.wuban.net.cn/service/pancakeswapper/pancake"
"code.wuban.net.cn/service/pancakeswapper/types"
"context"
"encoding/csv"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi"
...
...
@@ -145,9 +147,18 @@ func accountApproveWithPermit(client *ethclient.Client, acc *types.Account, env
inputs
:=
make
([][]
byte
,
0
)
inputs
=
append
(
inputs
,
permitData
)
fmt
.
Println
(
"permit input data is "
,
hex
.
EncodeToString
(
permitData
))
deadline
:=
time
.
Now
()
.
Unix
()
+
cfg
.
Param
.
Deadline
*
60
routerAbi
,
_
:=
abi
.
JSON
(
strings
.
NewReader
(
router2
.
RouterMetaData
.
ABI
))
txdata
,
err
:=
routerAbi
.
Pack
(
"execute0"
,
[]
byte
{
byte
(
pancake
.
PERMIT2_PERMIT
)},
inputs
,
big
.
NewInt
(
deadline
))
if
err
!=
nil
{
fmt
.
Println
()
return
fmt
.
Errorf
(
"pack execute failed: %v"
,
err
)
}
fmt
.
Println
(
"txdata is "
,
hex
.
EncodeToString
(
txdata
))
// 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
{
...
...
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