Commit d2a272fa authored by hezhengjun's avatar hezhengjun Committed by vipwzw

add dex

parent 824fc0c9
proj := "build"
.PHONY: default build remote winset
SRC_CLI := 33cn/plugin/plugin/dapp/dex/boss
OUT := build
default: build
build:
@go build -o ${OUT}/boss -ldflags "-X ${SRC_CLI}/buildFlags.RPCAddr4Chain33=http://localhost:8801 -X ${SRC_CLI}/buildFlags.RPCAddr4Ethereum=wss://ws-testnet.huobichain.com"
remote:
@go build -v -o ${OUT}/remote -ldflags "-X ${SRC_CLI}/buildFlags.RPCAddr4Chain33=http://183.129.226.74:8901 -X ${SRC_CLI}/buildFlags.RPCAddr4Ethereum=wss://ws-testnet.huobichain.com"
winset:
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o ${OUT}/bosswin.exe -ldflags "-X ${SRC_CLI}/buildFlags.RPCAddr4Chain33=http://183.129.226.74:8901 -X ${SRC_CLI}/buildFlags.RPCAddr4Ethereum=https://http-testnet.huobichain.com"
clean:
@rm ${OUT}/*
package buildFlags
var RPCAddr4Chain33 string
var RPCAddr4Ethereum string
var paraName string
package main
import (
"fmt"
"net/http"
"os"
"strings"
"github.com/33cn/plugin/plugin/dapp/dex/boss/buildFlags"
"github.com/33cn/plugin/plugin/dapp/dex/boss/deploy/chain33"
"github.com/33cn/plugin/plugin/dapp/dex/boss/deploy/chain33/offline"
"github.com/33cn/plugin/plugin/dapp/dex/boss/deploy/ethereum"
ethoffline "github.com/33cn/plugin/plugin/dapp/dex/boss/deploy/ethereum/offline"
"github.com/spf13/cobra"
)
func main() {
if buildFlags.RPCAddr4Chain33 == "" {
buildFlags.RPCAddr4Chain33 = "http://localhost:8801"
}
buildFlags.RPCAddr4Chain33 = testTLS(buildFlags.RPCAddr4Chain33)
if buildFlags.RPCAddr4Ethereum == "" {
//buildFlags.RPCAddr4Ethereum = "https://data-seed-prebsc-1-s1.binance.org:8545"
buildFlags.RPCAddr4Ethereum = "wss://ws-testnet.huobichain.com"
}
rootCmd := RootCmd()
rootCmd.PersistentFlags().String("rpc_laddr", buildFlags.RPCAddr4Chain33, "http url")
rootCmd.PersistentFlags().String("rpc_laddr_ethereum", buildFlags.RPCAddr4Ethereum, "http url")
rootCmd.PersistentFlags().String("paraName", "", "para chain name,Eg:user.p.fzm.")
rootCmd.PersistentFlags().String("expire", "120m", "transaction expire time (optional)")
rootCmd.PersistentFlags().Int32("chainID", 0, "chain id, default to 0")
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
// Cmd x2ethereum client command
func RootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "boss",
Short: "manage create offline tx or deploy contracts(dex) for test",
}
cmd.AddCommand(
DeployCmd(),
OfflineCmd(),
)
return cmd
}
func OfflineCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "offline",
Short: "create and sign offline tx to deploy and set dex contracts to ethereum or chain33",
}
cmd.AddCommand(
offline.Chain33OfflineCmd(),
ethoffline.EthOfflineCmd(),
)
return cmd
}
// Cmd x2ethereum client command
func DeployCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "deploy",
Short: "deploy dex to ethereum or chain33",
}
cmd.AddCommand(
ethereum.EthCmd(),
chain33.Chain33Cmd(),
)
return cmd
}
func testTLS(RPCAddr string) string {
rpcaddr := RPCAddr
if !strings.HasPrefix(rpcaddr, "http://") {
return RPCAddr
}
// if http://
if rpcaddr[len(rpcaddr)-1] != '/' {
rpcaddr += "/"
}
rpcaddr += "test"
/* #nosec */
resp, err := http.Get(rpcaddr)
if err != nil {
return "https://" + RPCAddr[7:]
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
return RPCAddr
}
return "https://" + RPCAddr[7:]
}
package chain33
import (
"encoding/hex"
"fmt"
"math/rand"
"os"
"time"
"github.com/33cn/chain33/rpc/jsonclient"
"github.com/33cn/chain33/types"
"github.com/golang/protobuf/proto"
"github.com/spf13/cobra"
)
func Chain33Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "chain33",
Short: "deploy to chain33",
Args: cobra.MinimumNArgs(1),
}
cmd.AddCommand(
deployMulticallCmd(),
deployERC20ContractCmd(),
deployPancakeContractCmd(),
farmCmd(),
)
return cmd
}
func deployMulticallCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "deployMulticall",
Short: "deploy Multicall",
Run: deployMulticallContract,
}
addDeployMulticallContractFlags(cmd)
return cmd
}
func addDeployMulticallContractFlags(cmd *cobra.Command) {
cmd.Flags().StringP("caller", "c", "", "the caller address")
cmd.MarkFlagRequired("caller")
cmd.Flags().StringP("expire", "", "120s", "transaction expire time (optional)")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
}
func deployMulticallContract(cmd *cobra.Command, args []string) {
err := DeployMulticall(cmd)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
// 创建ERC20合约
func deployERC20ContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "deployERC20",
Short: "deploy ERC20 contract",
Run: deployERC20Contract,
}
addDeployERC20ContractFlags(cmd)
return cmd
}
func addDeployERC20ContractFlags(cmd *cobra.Command) {
cmd.Flags().StringP("caller", "c", "", "the caller address")
cmd.MarkFlagRequired("caller")
cmd.Flags().StringP("name", "a", "", "REC20 name")
cmd.MarkFlagRequired("name")
cmd.Flags().StringP("symbol", "s", "", "REC20 symbol")
cmd.MarkFlagRequired("symbol")
cmd.Flags().StringP("supply", "m", "", "REC20 supply")
cmd.MarkFlagRequired("supply")
cmd.Flags().StringP("expire", "", "120s", "transaction expire time (optional)")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
}
func deployERC20Contract(cmd *cobra.Command, args []string) {
err := DeployERC20(cmd)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
func deployPancakeContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "deployPancake",
Short: "deploy Pancake contract",
Run: deployPancakeContract,
}
addDeployPancakeContractFlags(cmd)
return cmd
}
func addDeployPancakeContractFlags(cmd *cobra.Command) {
cmd.Flags().StringP("caller", "c", "", "the caller address")
cmd.MarkFlagRequired("caller")
cmd.Flags().StringP("expire", "", "120s", "transaction expire time (optional)")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
cmd.Flags().StringP("parameter", "p", "", "construction contract parameter")
}
func deployPancakeContract(cmd *cobra.Command, args []string) {
err := DeployPancake(cmd)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
func createEvmTx(chainID int32, action proto.Message, execer, caller, addr, expire, rpcLaddr string, fee uint64) (string, error) {
tx := &types.Transaction{Execer: []byte(execer), Payload: types.Encode(action), Fee: 0, To: addr}
tx.Fee = int64(1e7)
if tx.Fee < int64(fee) {
tx.Fee += int64(fee)
}
random := rand.New(rand.NewSource(time.Now().UnixNano()))
tx.Nonce = random.Int63()
tx.ChainID = chainID
txHex := types.Encode(tx)
rawTx := hex.EncodeToString(txHex)
unsignedTx := &types.ReqSignRawTx{
Addr: caller,
TxHex: rawTx,
Expire: expire,
Fee: tx.Fee,
}
var res string
client, err := jsonclient.NewJSONClient(rpcLaddr)
if err != nil {
fmt.Println("createEvmTx::", "jsonclient.NewJSONClient failed due to:", err)
return "", err
}
err = client.Call("Chain33.SignRawTx", unsignedTx, &res)
if err != nil {
fmt.Println("createEvmTx::", "Chain33.SignRawTx failed due to:", err)
return "", err
}
return res, nil
}
package chain33
import (
"encoding/json"
"errors"
"fmt"
"strings"
"time"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
erc20 "github.com/33cn/plugin/plugin/dapp/cross2eth/contracts/erc20/generated"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/multicall/multicall"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-swap-periphery/src/pancakeFactory"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-swap-periphery/src/pancakeRouter"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
ethereumcommon "github.com/ethereum/go-ethereum/common"
"github.com/spf13/cobra"
)
func DeployMulticall(cmd *cobra.Command) error {
caller, _ := cmd.Flags().GetString("caller")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
txMulticall, err := deployContract(cmd, multicall.MulticallBin, multicall.MulticallABI, "", "Multicall")
if err != nil {
return errors.New(err.Error())
}
{
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(1 * time.Second)
for {
select {
case <-timeout.C:
panic("Deploy ERC20 timeout")
case <-oneSecondtimeout.C:
data, _ := getTxByHashesRpc(txMulticall, rpcLaddr)
if data == "" {
fmt.Println("No receipt received yet for Deploy Multicall tx and continue to wait")
continue
} else if data != "2" {
return errors.New("Deploy Multicall failed due to" + ", ty = " + data)
}
fmt.Println("Succeed to deploy Multicall with address =", getContractAddr(caller, txMulticall), "\\n")
return nil
}
}
}
}
func DeployERC20(cmd *cobra.Command) error {
caller, _ := cmd.Flags().GetString("caller")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
name, _ := cmd.Flags().GetString("name")
symbol, _ := cmd.Flags().GetString("symbol")
supply, _ := cmd.Flags().GetString("supply")
txhexERC20, err := deployContract(cmd, erc20.ERC20Bin, erc20.ERC20ABI, name+","+symbol+","+supply+","+caller, "ERC20")
if err != nil {
return errors.New(err.Error())
}
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(1 * time.Second)
for {
select {
case <-timeout.C:
panic("Deploy ERC20 timeout")
case <-oneSecondtimeout.C:
data, _ := getTxByHashesRpc(txhexERC20, rpcLaddr)
if data == "" {
fmt.Println("No receipt received yet for Deploy ERC20 tx and continue to wait")
continue
} else if data != "2" {
return errors.New("Deploy ERC20 failed due to" + ", ty = " + data)
}
fmt.Println("Succeed to deploy ERC20 with address =", getContractAddr(caller, txhexERC20), "\\n")
return nil
}
}
}
func DeployPancake(cmd *cobra.Command) error {
caller, _ := cmd.Flags().GetString("caller")
parameter, _ := cmd.Flags().GetString("parameter")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
txhexERC20, err := deployContract(cmd, erc20.ERC20Bin, erc20.ERC20ABI, "ycc, ycc, 3300000000, "+caller, "ERC20")
if err != nil {
return errors.New(err.Error())
}
{
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(1 * time.Second)
for {
select {
case <-timeout.C:
panic("Deploy ERC20 timeout")
case <-oneSecondtimeout.C:
data, _ := getTxByHashesRpc(txhexERC20, rpcLaddr)
if data == "" {
fmt.Println("No receipt received yet for Deploy ERC20 tx and continue to wait")
continue
} else if data != "2" {
return errors.New("Deploy ERC20 failed due to" + ", ty = " + data)
}
fmt.Println("Succeed to deploy ERC20 with address =", getContractAddr(caller, txhexERC20), "\\n")
goto deployPancakeFactory
}
}
}
deployPancakeFactory:
txhexPancakeFactory, err := deployContract(cmd, pancakeFactory.PancakeFactoryBin, pancakeFactory.PancakeFactoryABI, parameter, "PancakeFactory")
if err != nil {
return errors.New(err.Error())
}
{
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(1 * time.Second)
for {
select {
case <-timeout.C:
panic("Deploy PancakeFactory timeout")
case <-oneSecondtimeout.C:
data, _ := getTxByHashesRpc(txhexPancakeFactory, rpcLaddr)
if data == "" {
fmt.Println("No receipt received yet for Deploy PancakeFactory tx and continue to wait")
continue
} else if data != "2" {
return errors.New("Deploy PancakeFactory failed due to" + ", ty = " + data)
}
fmt.Println("Succeed to deploy pancakeFactory with address =", getContractAddr(caller, txhexPancakeFactory), "\\n")
goto deployWeth9
}
}
}
deployWeth9:
txhexWeth9, err := deployContract(cmd, pancakeRouter.WETH9Bin, pancakeRouter.WETH9ABI, "", "Weth9")
if err != nil {
return errors.New(err.Error())
}
{
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(1 * time.Second)
for {
select {
case <-timeout.C:
panic("Deploy Weth9 timeout")
case <-oneSecondtimeout.C:
data, _ := getTxByHashesRpc(txhexWeth9, rpcLaddr)
if data == "" {
fmt.Println("No receipt received yet for Deploy Weth9 tx and continue to wait")
continue
} else if data != "2" {
return errors.New("Deploy Weth9 failed due to" + ", ty = " + data)
}
fmt.Println("Succeed to deploy Weth9 with address =", getContractAddr(caller, txhexWeth9), "\\n")
goto deployPancakeRouter
}
}
}
deployPancakeRouter:
param := getContractAddr(caller, txhexPancakeFactory) + "," + getContractAddr(caller, txhexWeth9)
txhexPancakeRouter, err := deployContract(cmd, pancakeRouter.PancakeRouterBin, pancakeRouter.PancakeRouterABI, param, "PancakeRouter")
if err != nil {
return errors.New(err.Error())
}
{
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(1 * time.Second)
for {
select {
case <-timeout.C:
panic("Deploy PancakeRouter timeout")
case <-oneSecondtimeout.C:
data, _ := getTxByHashesRpc(txhexPancakeRouter, rpcLaddr)
if data == "" {
fmt.Println("No receipt received yet for Deploy PancakeRouter tx and continue to wait")
continue
} else if data != "2" {
return errors.New("Deploy PancakeRouter failed due to" + ", ty = " + data)
}
fmt.Println("Succeed to deploy PancakeRouter with address =", getContractAddr(caller, txhexPancakeRouter), "\\n")
return nil
}
}
}
}
func getContractAddr(caller, txhex string) string {
return address.GetExecAddress(caller + ethereumcommon.Bytes2Hex(common.HexToHash(txhex).Bytes())).String()
}
func deployContract(cmd *cobra.Command, code, abi, parameter, contractName string) (string, error) {
caller, _ := cmd.Flags().GetString("caller")
expire, _ := cmd.Flags().GetString("expire")
note, _ := cmd.Flags().GetString("note")
fee, _ := cmd.Flags().GetFloat64("fee")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
chainID, _ := cmd.Flags().GetInt32("chainID")
feeInt64 := uint64(fee*1e4) * 1e4
var action evmtypes.EVMContractAction
bCode, err := common.FromHex(code)
if err != nil {
return "", errors.New(contractName + " parse evm code error " + err.Error())
}
action = evmtypes.EVMContractAction{Amount: 0, Code: bCode, GasLimit: 0, GasPrice: 0, Note: note, Alias: "PancakeFactory"}
if parameter != "" {
constructorPara := "constructor(" + parameter + ")"
packData, err := evmAbi.PackContructorPara(constructorPara, abi)
if err != nil {
return "", errors.New(contractName + " " + constructorPara + " Pack Contructor Para error:" + err.Error())
}
action.Code = append(action.Code, packData...)
}
data, err := createEvmTx(chainID, &action, paraName+"evm", caller, address.ExecAddress(paraName+"evm"), expire, rpcLaddr, feeInt64)
if err != nil {
return "", errors.New(contractName + " create contract error:" + err.Error())
}
txhex, err := sendTransactionRpc(data, rpcLaddr)
if err != nil {
return "", errors.New(contractName + " send transaction error:" + err.Error())
}
fmt.Println("Deploy", contractName, "tx hash:", txhex)
return txhex, nil
}
func getTxByHashesRpc(txhex, rpcLaddr string) (string, error) {
hashesArr := strings.Split(txhex, " ")
params2 := rpctypes.ReqHashes{
Hashes: hashesArr,
}
var res rpctypes.TransactionDetails
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.GetTxByHashes", params2, &res)
ctx.SetResultCb(queryTxsByHashesRes)
result, err := ctx.RunResult()
if err != nil || result == nil {
return "", err
}
data, err := json.MarshalIndent(result, "", " ")
if err != nil {
return "", err
}
return string(data), nil
}
func queryTxsByHashesRes(arg interface{}) (interface{}, error) {
var receipt *rpctypes.ReceiptDataResult
for _, v := range arg.(*rpctypes.TransactionDetails).Txs {
if v == nil {
continue
}
receipt = v.Receipt
if nil != receipt {
return receipt.Ty, nil
}
}
return nil, nil
}
func sendTransactionRpc(data, rpcLaddr string) (string, error) {
params := rpctypes.RawParm{
Data: data,
}
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.SendTransaction", params, nil)
var txhex string
rpc, err := jsonclient.NewJSONClient(ctx.Addr)
if err != nil {
return "", err
}
err = rpc.Call(ctx.Method, ctx.Params, &txhex)
if err != nil {
return "", err
}
return txhex, nil
}
package chain33
import (
"fmt"
"os"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/masterChef"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/syrupBar"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
"github.com/spf13/cobra"
)
func farmCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "farm",
Short: "deploy farm and set lp, transfer ownership",
}
cmd.AddCommand(
deployFarmContractCmd(),
TransferOwnerShipCmd(),
AddPoolCmd(),
UpdateAllocPointCmd(),
)
return cmd
}
func deployFarmContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "deploy",
Short: "deploy Farm contract",
Run: deployFarmContract,
}
addDeployFarmContractFlags(cmd)
return cmd
}
func addDeployFarmContractFlags(cmd *cobra.Command) {
cmd.Flags().StringP("caller", "c", "", "the caller address")
cmd.MarkFlagRequired("caller")
cmd.Flags().StringP("expire", "", "120s", "transaction expire time (optional)")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
}
func deployFarmContract(cmd *cobra.Command, args []string) {
err := DeployFarm(cmd)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
func AddPoolCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "add",
Short: "add pool to farm, should transfer ownership first",
Run: AddPool2Farm,
}
addAddPoolCmdFlags(cmd)
return cmd
}
func addAddPoolCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("masterchef", "m", "", "master Chef Addr ")
_ = cmd.MarkFlagRequired("masterchef")
cmd.Flags().StringP("lptoken", "l", "", "lp Addr ")
_ = cmd.MarkFlagRequired("lptoken")
cmd.Flags().Int64P("alloc", "p", 0, "allocation point ")
_ = cmd.MarkFlagRequired("alloc")
cmd.Flags().BoolP("update", "u", true, "with update")
_ = cmd.MarkFlagRequired("update")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
cmd.MarkFlagRequired("fee")
cmd.Flags().StringP("caller", "c", "", "caller address")
_ = cmd.MarkFlagRequired("caller")
cmd.Flags().StringP("expire", "e", "120s", "transaction expire time (optional)")
}
func AddPool2Farm(cmd *cobra.Command, args []string) {
masterChefAddrStr, _ := cmd.Flags().GetString("masterchef")
allocPoint, _ := cmd.Flags().GetInt64("alloc")
lpToken, _ := cmd.Flags().GetString("lptoken")
update, _ := cmd.Flags().GetBool("update")
chainID, _ := cmd.Flags().GetInt32("chainID")
caller, _ := cmd.Flags().GetString("caller")
paraName, _ := cmd.Flags().GetString("paraName")
expire, _ := cmd.Flags().GetString("expire")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
fee, _ := cmd.Flags().GetFloat64("fee")
feeInt64 := uint64(fee*1e4) * 1e4
//function add(uint256 _allocPoint, IBEP20 _lpToken, bool _withUpdate) public onlyOwner
parameter := fmt.Sprintf("add(%d, %s, %v)", allocPoint, lpToken, update)
_, packData, err := evmAbi.Pack(parameter, masterChef.MasterChefABI, false)
if nil != err {
fmt.Println("AddPool2FarmHandle", "Failed to do abi.Pack due to:", err.Error())
return
}
action := evmtypes.EVMContractAction{Amount: 0, GasLimit: 0, GasPrice: 0, Note: parameter, Para: packData}
data, err := createEvmTx(chainID, &action, paraName+"evm", caller, masterChefAddrStr, expire, rpcLaddr, feeInt64)
if err != nil {
fmt.Println("AddPool2FarmHandle", "Failed to do createEvmTx due to:", err.Error())
return
}
txhex, err := sendTransactionRpc(data, rpcLaddr)
if err != nil {
fmt.Println("AddPool2FarmHandle", "Failed to do sendTransactionRpc due to:", err.Error())
return
}
fmt.Println(txhex)
}
func UpdateAllocPointCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "update",
Short: "Update the given pool's CAKE allocation point, should transfer ownership first",
Run: UpdateAllocPoint,
}
updateAllocPointCmdFlags(cmd)
return cmd
}
func updateAllocPointCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("masterchef", "m", "", "master Chef Addr ")
_ = cmd.MarkFlagRequired("masterchef")
cmd.Flags().Int64P("pid", "d", 0, "id of pool")
_ = cmd.MarkFlagRequired("pid")
cmd.Flags().Int64P("alloc", "p", 0, "allocation point ")
_ = cmd.MarkFlagRequired("alloc")
cmd.Flags().BoolP("update", "u", true, "with update")
_ = cmd.MarkFlagRequired("update")
cmd.Flags().StringP("caller", "c", "", "caller address")
_ = cmd.MarkFlagRequired("caller")
}
func UpdateAllocPoint(cmd *cobra.Command, args []string) {
masterChefAddrStr, _ := cmd.Flags().GetString("masterchef")
pid, _ := cmd.Flags().GetInt64("pid")
allocPoint, _ := cmd.Flags().GetInt64("alloc")
update, _ := cmd.Flags().GetBool("update")
chainID, _ := cmd.Flags().GetInt32("chainID")
caller, _ := cmd.Flags().GetString("caller")
paraName, _ := cmd.Flags().GetString("paraName")
expire, _ := cmd.Flags().GetString("expire")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
fee, _ := cmd.Flags().GetFloat64("fee")
feeInt64 := uint64(fee*1e4) * 1e4
//function set(uint256 _pid, uint256 _allocPoint, bool _withUpdate) public onlyOwner
parameter := fmt.Sprintf("set(%d, %d, %v)", pid, allocPoint, update)
_, packData, err := evmAbi.Pack(parameter, masterChef.MasterChefABI, false)
if nil != err {
fmt.Println("UpdateAllocPoint", "Failed to do abi.Pack due to:", err.Error())
return
}
action := evmtypes.EVMContractAction{Amount: 0, GasLimit: 0, GasPrice: 0, Note: parameter, Para: packData}
data, err := createEvmTx(chainID, &action, paraName+"evm", caller, masterChefAddrStr, expire, rpcLaddr, feeInt64)
if err != nil {
fmt.Println("UpdateAllocPoint", "Failed to do createEvmTx due to:", err.Error())
return
}
txhex, err := sendTransactionRpc(data, rpcLaddr)
if err != nil {
fmt.Println("UpdateAllocPoint", "Failed to do sendTransactionRpc due to:", err.Error())
return
}
fmt.Println(txhex)
}
func TransferOwnerShipCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "transfer",
Short: "Transfer OwnerShip, should transfer both cakeToken and syrupbar's ownership to masterChef",
Run: TransferOwnerShip,
}
TransferOwnerShipFlags(cmd)
return cmd
}
func TransferOwnerShipFlags(cmd *cobra.Command) {
cmd.Flags().StringP("new", "n", "", "new owner")
_ = cmd.MarkFlagRequired("new")
cmd.Flags().StringP("contract", "c", "", "contract address")
_ = cmd.MarkFlagRequired("contract")
cmd.Flags().StringP("old", "o", "", "old owner")
_ = cmd.MarkFlagRequired("old")
cmd.Flags().Int32P("chainID", "i", 0, "chain id, default to 0(optional)")
}
func TransferOwnerShip(cmd *cobra.Command, args []string) {
newOwner, _ := cmd.Flags().GetString("new")
contract, _ := cmd.Flags().GetString("contract")
chainID, _ := cmd.Flags().GetInt32("chainID")
caller, _ := cmd.Flags().GetString("old")
paraName, _ := cmd.Flags().GetString("paraName")
expire, _ := cmd.Flags().GetString("expire")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
fee, _ := cmd.Flags().GetFloat64("fee")
feeInt64 := uint64(fee*1e4) * 1e4
//function transferOwnership(address newOwner) public onlyOwner
parameter := fmt.Sprintf("transferOwnership(%s)", newOwner)
_, packData, err := evmAbi.Pack(parameter, syrupBar.OwnableABI, false)
if nil != err {
fmt.Println("TransferOwnerShip", "Failed to do abi.Pack due to:", err.Error())
return
}
action := evmtypes.EVMContractAction{Amount: 0, GasLimit: 0, GasPrice: 0, Note: parameter, Para: packData}
data, err := createEvmTx(chainID, &action, paraName+"evm", caller, contract, expire, rpcLaddr, feeInt64)
if err != nil {
fmt.Println("TransferOwnerShip", "Failed to do createEvmTx due to:", err.Error())
return
}
txhex, err := sendTransactionRpc(data, rpcLaddr)
if err != nil {
fmt.Println("TransferOwnerShip", "Failed to do sendTransactionRpc due to:", err.Error())
return
}
fmt.Println(txhex)
}
package chain33
import (
"errors"
"fmt"
"time"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/cakeToken"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/masterChef"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/syrupBar"
"github.com/spf13/cobra"
)
func DeployFarm(cmd *cobra.Command) error {
caller, _ := cmd.Flags().GetString("caller")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
txhexCakeToken, err := deployContract(cmd, cakeToken.CakeTokenBin, cakeToken.CakeTokenABI, "", "CakeToken")
if err != nil {
return errors.New(err.Error())
}
{
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(1 * time.Second)
for {
select {
case <-timeout.C:
panic("Deploy CakeToken timeout")
case <-oneSecondtimeout.C:
data, _ := getTxByHashesRpc(txhexCakeToken, rpcLaddr)
if data == "" {
fmt.Println("No receipt received yet for Deploy CakeToken tx and continue to wait")
continue
} else if data != "2" {
return errors.New("DeployPancakeFactory failed due to" + ", ty = " + data)
}
fmt.Println("Succeed to deploy CakeToken with address =", getContractAddr(caller, txhexCakeToken))
fmt.Println("")
goto deploySyrupBar
}
}
}
deploySyrupBar:
txhexSyrupBar, err := deployContract(cmd, syrupBar.SyrupBarBin, syrupBar.SyrupBarABI, getContractAddr(caller, txhexCakeToken), "SyrupBar")
if err != nil {
return errors.New(err.Error())
}
{
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(1 * time.Second)
for {
select {
case <-timeout.C:
panic("Deploy SyrupBar timeout")
case <-oneSecondtimeout.C:
data, _ := getTxByHashesRpc(txhexSyrupBar, rpcLaddr)
if data == "" {
fmt.Println("No receipt received yet for Deploy SyrupBar tx and continue to wait")
continue
} else if data != "2" {
return errors.New("Deploy SyrupBar failed due to" + ", ty = " + data)
}
fmt.Println("Succeed to deploy SyrupBar with address =", getContractAddr(caller, txhexSyrupBar))
fmt.Println("")
goto deployMasterChef
}
}
}
deployMasterChef:
// constructor(
// CakeToken _cake,
// SyrupBar _syrup,
// address _devaddr,
// uint256 _cakePerBlock,
// uint256 _startBlock
// )
// masterChef.DeployMasterChef(auth, ethClient, cakeTokenAddr, SyrupBarAddr, deployerAddr, big.NewInt(5*1e18), big.NewInt(100))
txparam := getContractAddr(caller, txhexCakeToken) + "," + getContractAddr(caller, txhexSyrupBar) + "," + caller + ", 5000000000000000000, 100"
txhexMasterChef, err := deployContract(cmd, masterChef.MasterChefBin, masterChef.MasterChefABI, txparam, "MasterChef")
if err != nil {
return errors.New(err.Error())
}
{
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(1 * time.Second)
for {
select {
case <-timeout.C:
panic("Deploy MasterChef timeout")
case <-oneSecondtimeout.C:
data, _ := getTxByHashesRpc(txhexMasterChef, rpcLaddr)
if data == "" {
fmt.Println("No receipt received yet for Deploy MasterChef tx and continue to wait")
continue
} else if data != "2" {
return errors.New("Deploy MasterChef failed due to" + ", ty = " + data)
}
fmt.Println("Succeed to deploy MasterChef with address =", getContractAddr(caller, txhexMasterChef))
fmt.Println("")
return nil
}
}
}
}
package offline
import (
"github.com/33cn/plugin/plugin/dapp/dex/utils"
"github.com/spf13/cobra"
)
func Chain33OfflineCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "chain33",
Short: "create and sign offline tx to deploy and set dex contracts to chain33",
Args: cobra.MinimumNArgs(1),
}
cmd.AddCommand(
createERC20ContractCmd(),
createRouterCmd(),
farmofflineCmd(),
sendSignTxs2Chain33Cmd(),
)
return cmd
}
func createRouterCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "router",
Short: "create and sign offline weth9, factory and router contracts",
Run: createRouterContract,
}
addCreateRouterFlags(cmd)
return cmd
}
func addCreateRouterFlags(cmd *cobra.Command) {
cmd.Flags().StringP("key", "k", "", "the private key")
cmd.MarkFlagRequired("key")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
cmd.Flags().StringP("feeToSetter", "a", "", "address for fee to Setter")
cmd.MarkFlagRequired("feeToSetter")
}
func sendSignTxs2Chain33Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "send",
Short: "send one or serval dex txs to chain33 in serial",
Run: sendSignTxs2Chain33,
}
addSendSignTxs2Chain33Flags(cmd)
return cmd
}
func addSendSignTxs2Chain33Flags(cmd *cobra.Command) {
cmd.Flags().StringP("path", "p", "./", "(optional)path of txs file,default to current directroy")
cmd.Flags().StringP("file", "f", "", "file name which contains the txs to be sent to chain33")
_ = cmd.MarkFlagRequired("file")
}
func sendSignTxs2Chain33(cmd *cobra.Command, args []string) {
filePath, _ := cmd.Flags().GetString("path")
file, _ := cmd.Flags().GetString("file")
url, _ := cmd.Flags().GetString("rpc_laddr")
filePath += file
utils.SendSignTxs2Chain33(filePath, url)
}
#在chain33部署操作手册
##步骤一: 离线创建3笔部署router合约的交易
```
交易1: 部署合约: weth9
交易2: 部署合约: factory
交易3: 部署合约: router
./boss offline chain33 router -f 1 -k 0xcc38546e9e659d15e6b4893f0ab32a06d103931a8230b0bde71459d2b27d6944 -n "deploy router to chain33" -a 14KEKbYtKKQm4wMthSK9J4La4nAiidGozt --chainID 33
-f, --fee float: 交易费设置,因为只是少量几笔交易,且部署交易消耗gas较多,直接设置1个代币即可
-k, --key string: 部署人的私钥,用于对交易签名
-n, --note string: 备注信息
-a, --feeToSetter: 设置交易费收费地址(说明:该地址用来指定收取交易费地址的地址,而不是该地址用来收取交易费)
--chainID 平行链的chainID
生成交易文件:farm.txt:router.txt
```
##步骤二: 离线创建5笔部署farm合约的交易
```
交易1: 部署合约: cakeToken
交易2: 部署合约: SyrupBar
交易3: 部署合约: masterChef
交易4: 转移所有权,将cake token的所有权转移给masterchef
交易5: 转移所有权: 将SyrupBar的所有权转移给masterchef
./boss offline chain33 farm masterChef -f 1 -k 0xcc38546e9e659d15e6b4893f0ab32a06d103931a8230b0bde71459d2b27d6944 -n "deploy farm to chain33" -d 14KEKbYtKKQm4wMthSK9J4La4nAiidGozt -s 10 -m 5000000000000000000 --chainID 33
生成交易文件:farm.txt
```
##步骤三: 离线创建多笔增加lp token的交易
```
./boss offline chain33 farm addPool -f 1 -k 0xcc38546e9e659d15e6b4893f0ab32a06d103931a8230b0bde71459d2b27d6944 -p 1000 -l 1HEp4BiA54iaKx5LrgN9iihkgmd3YxC2xM -m 13YwvpqTatoFepe31c5TUXvi26SbNpC3Qq --chainID 33
```
##步骤四: 串行发送交易文件中的交易
```
./boss4x chain33 offline send -f xxx.txt
```
\ No newline at end of file
This diff is collapsed.
package offline
import (
"fmt"
"time"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/system/crypto/secp256k1"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-swap-periphery/src/pancakeFactory"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-swap-periphery/src/pancakeRouter"
"github.com/33cn/plugin/plugin/dapp/dex/utils"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
erc20 "github.com/33cn/plugin/plugin/dapp/cross2eth/contracts/erc20/generated"
"github.com/spf13/cobra"
)
// 创建ERC20合约
func createERC20ContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "erc20",
Short: "create ERC20 contract",
Run: createERC20Contract,
}
addCreateERC20ContractFlags(cmd)
return cmd
}
func addCreateERC20ContractFlags(cmd *cobra.Command) {
cmd.Flags().StringP("key", "k", "", "the caller's private key")
cmd.MarkFlagRequired("key")
cmd.Flags().StringP("name", "a", "", "REC20 name")
cmd.MarkFlagRequired("name")
cmd.Flags().StringP("symbol", "s", "", "REC20 symbol")
cmd.MarkFlagRequired("symbol")
cmd.Flags().StringP("supply", "m", "", "REC20 supply")
cmd.MarkFlagRequired("supply")
cmd.Flags().StringP("note", "n", "", "transaction note info (optional)")
cmd.Flags().Float64P("fee", "f", 0, "contract gas fee (optional)")
}
func createERC20Contract(cmd *cobra.Command, args []string) {
privateKeyStr, _ := cmd.Flags().GetString("key")
name, _ := cmd.Flags().GetString("name")
symbol, _ := cmd.Flags().GetString("symbol")
supply, _ := cmd.Flags().GetString("supply")
expire, _ := cmd.Flags().GetString("expire")
note, _ := cmd.Flags().GetString("note")
fee, _ := cmd.Flags().GetFloat64("fee")
paraName, _ := cmd.Flags().GetString("paraName")
chainID, _ := cmd.Flags().GetInt32("chainID")
feeInt64 := int64(fee*1e4) * 1e4
var driver secp256k1.Driver
privateKeySli := common.FromHex(privateKeyStr)
privateKey, err := driver.PrivKeyFromBytes(privateKeySli)
if nil != err {
fmt.Println("Failed to do PrivKeyFromBytes")
return
}
fromAddr := address.PubKeyToAddress(privateKey.PubKey().Bytes())
from := common.Address{
Addr: fromAddr,
}
info := &utils.TxCreateInfo{
PrivateKey: privateKeyStr,
Expire: expire,
Note: note,
Fee: feeInt64,
ParaName: paraName,
ChainID: chainID,
}
createPara := name + "," + symbol + "," + supply + "," + fromAddr.String()
content, txHash, err := utils.CreateContractAndSign(info, erc20.ERC20Bin, erc20.ERC20ABI, createPara, "erc20")
if nil != err {
fmt.Println("Failed to create erc20 due to cause:", err.Error())
return
}
newContractAddr := common.NewContractAddress(from, txHash).String()
routerTx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy router",
Interval: time.Second * 5,
}
utils.WriteToFileInJson("./erc20.txt", routerTx)
}
func createRouterContract(cmd *cobra.Command, args []string) {
privateKeyStr, _ := cmd.Flags().GetString("key")
var txs []*utils.Chain33OfflineTx
var driver secp256k1.Driver
privateKeySli := common.FromHex(privateKeyStr)
privateKey, err := driver.PrivKeyFromBytes(privateKeySli)
if nil != err {
fmt.Println("Failed to do PrivKeyFromBytes")
return
}
fromAddr := address.PubKeyToAddress(privateKey.PubKey().Bytes())
from := common.Address{
Addr: fromAddr,
}
i := 1
fmt.Printf("%d: Going to create factory\n", i)
i += 1
factoryTx, err := createFactoryContract(cmd, from)
if nil != err {
fmt.Println("Failed to createValsetTxAndSign due to cause:", err.Error())
return
}
txs = append(txs, factoryTx)
fmt.Printf("%d: Going to create weth9\n", i)
i += 1
weth9Tx, err := createWeth9(cmd, from)
if nil != err {
fmt.Println("Failed to createWeth9 due to cause:", err.Error())
return
}
txs = append(txs, weth9Tx)
fmt.Printf("%d: Going to create router\n", i)
expire, _ := cmd.Flags().GetString("expire")
note, _ := cmd.Flags().GetString("note")
fee, _ := cmd.Flags().GetFloat64("fee")
paraName, _ := cmd.Flags().GetString("paraName")
chainID, _ := cmd.Flags().GetInt32("chainID")
feeInt64 := int64(fee*1e4) * 1e4
info := &utils.TxCreateInfo{
PrivateKey: privateKeyStr,
Expire: expire,
Note: note,
Fee: feeInt64,
ParaName: paraName,
ChainID: chainID,
}
//constructor(address _factory, address _WETH)
createPara := factoryTx.ContractAddr + "," + weth9Tx.ContractAddr
content, txHash, err := utils.CreateContractAndSign(info, pancakeRouter.PancakeRouterBin, pancakeRouter.PancakeRouterABI, createPara, "pancakeRouter")
if nil != err {
fmt.Println("Failed to create router due to cause:", err.Error())
return
}
newContractAddr := common.NewContractAddress(from, txHash).String()
routerTx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy router",
Interval: time.Second * 5,
}
txs = append(txs, routerTx)
utils.WriteToFileInJson("./router.txt", txs)
}
func createWeth9(cmd *cobra.Command, from common.Address) (*utils.Chain33OfflineTx, error) {
privateKeyStr, _ := cmd.Flags().GetString("key")
expire, _ := cmd.Flags().GetString("expire")
note, _ := cmd.Flags().GetString("note")
fee, _ := cmd.Flags().GetFloat64("fee")
paraName, _ := cmd.Flags().GetString("paraName")
chainID, _ := cmd.Flags().GetInt32("chainID")
feeInt64 := int64(fee*1e4) * 1e4
info := &utils.TxCreateInfo{
PrivateKey: privateKeyStr,
Expire: expire,
Note: note,
Fee: feeInt64,
ParaName: paraName,
ChainID: chainID,
}
createPara := ""
content, txHash, err := utils.CreateContractAndSign(info, pancakeRouter.WETH9Bin, pancakeRouter.WETH9ABI, createPara, "WETH9")
if nil != err {
return nil, err
}
newContractAddr := common.NewContractAddress(from, txHash).String()
weth9Tx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy weth9",
Interval: time.Second * 5,
}
return weth9Tx, nil
}
func createFactoryContract(cmd *cobra.Command, from common.Address) (*utils.Chain33OfflineTx, error) {
feeToSetter, _ := cmd.Flags().GetString("feeToSetter")
privateKeyStr, _ := cmd.Flags().GetString("key")
expire, _ := cmd.Flags().GetString("expire")
note, _ := cmd.Flags().GetString("note")
fee, _ := cmd.Flags().GetFloat64("fee")
paraName, _ := cmd.Flags().GetString("paraName")
chainID, _ := cmd.Flags().GetInt32("chainID")
feeInt64 := int64(fee*1e4) * 1e4
info := &utils.TxCreateInfo{
PrivateKey: privateKeyStr,
Expire: expire,
Note: note,
Fee: feeInt64,
ParaName: paraName,
ChainID: chainID,
}
//constructor(address _feeToSetter) public
createPara := feeToSetter
content, txHash, err := utils.CreateContractAndSign(info, pancakeFactory.PancakeFactoryBin, pancakeFactory.PancakeFactoryABI, createPara, "PancakeFactory")
if nil != err {
return nil, err
}
newContractAddr := common.NewContractAddress(from, txHash).String()
factoryTx := &utils.Chain33OfflineTx{
ContractAddr: newContractAddr,
TxHash: common.Bytes2Hex(txHash),
SignedRawTx: content,
OperationName: "deploy factory",
Interval: time.Second * 5,
}
return factoryTx, nil
}
package ethereum
import (
"fmt"
"github.com/spf13/cobra"
)
// Cmd x2ethereum client command
func CakeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "cake",
Short: "cake command",
}
cmd.AddCommand(
GetBalanceCmd(),
DeployPancakeCmd(),
AddAllowance4LPCmd(),
CheckAllowance4LPCmd(),
showPairInitCodeHashCmd(),
setFeeToCmd(),
)
return cmd
}
func setFeeToCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "setFeeTo",
Short: "set FeeTo address to factory",
Run: setFeeTo,
}
AddSetFeeToFlags(cmd)
return cmd
}
func AddSetFeeToFlags(cmd *cobra.Command) {
cmd.Flags().StringP("factory", "f", "", "factory Addr ")
_ = cmd.MarkFlagRequired("factory")
cmd.Flags().StringP("feeTo", "t", "", "feeTo Addr ")
_ = cmd.MarkFlagRequired("feeTo")
cmd.Flags().Uint64P("gas", "g", 80*10000, "gaslimit")
cmd.Flags().StringP("key", "k", "f934e9171c5cf13b35e6c989e95f5e95fa471515730af147b66d60fbcd664b7c", "private key of feetoSetter")
}
func setFeeTo(cmd *cobra.Command, args []string) {
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
factroy, _ := cmd.Flags().GetString("factory")
feeTo, _ := cmd.Flags().GetString("feeTo")
key, _ := cmd.Flags().GetString("key")
gasLimit, _ := cmd.Flags().GetUint64("gas")
setupWebsocketEthClient(ethNodeAddr)
err := setFeeToHandle(factroy, feeTo, key, gasLimit)
if nil != err {
fmt.Println("Failed to deploy contracts due to:", err.Error())
return
}
fmt.Println("Succeed to deploy contracts")
}
func DeployPancakeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "deploy",
Short: "deploy pancake router to ethereum ",
Run: DeployContractsCake,
}
cmd.Flags().StringP("key", "k", "", "private key for deploy")
return cmd
}
func DeployContractsCake(cmd *cobra.Command, args []string) {
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
key,_:=cmd.Flags().GetString("key")
setupWebsocketEthClient(ethNodeAddr)
err := DeployPancake(key)
if nil != err {
fmt.Println("Failed to deploy contracts due to:", err.Error())
return
}
fmt.Println("Succeed to deploy contracts")
}
func AddAllowance4LPCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "allowance",
Short: "approve allowance for add lp to pool",
Run: AddAllowance4LP,
}
AddAllowance4LPFlags(cmd)
return cmd
}
func AddAllowance4LPFlags(cmd *cobra.Command) {
cmd.Flags().StringP("masterchef", "m", "", "master Chef Addr ")
_ = cmd.MarkFlagRequired("masterchef")
cmd.Flags().StringP("lptoken", "l", "", "lp Addr ")
_ = cmd.MarkFlagRequired("lptoken")
cmd.Flags().Int64P("amount", "p", 0, "amount to approve")
_ = cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("key","k","","private key")
}
func AddAllowance4LP(cmd *cobra.Command, args []string) {
masterChefAddrStr, _ := cmd.Flags().GetString("masterchef")
amount, _ := cmd.Flags().GetInt64("amount")
lpToken, _ := cmd.Flags().GetString("lptoken")
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
privkey,_:=cmd.Flags().GetString("key")
setupWebsocketEthClient(ethNodeAddr)
//owner string, spender string, amount int64
err := AddAllowance4LPHandle(lpToken, masterChefAddrStr,privkey, amount)
if nil != err {
fmt.Println("Failed to AddPool2Farm due to:", err.Error())
return
}
fmt.Println("Succeed to AddPool2Farm")
}
func CheckAllowance4LPCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "check-allowance",
Short: "check allowance for add lp to pool",
Run: CheckAllowance4LP,
}
CheckAllowance4LPFlags(cmd)
return cmd
}
func CheckAllowance4LPFlags(cmd *cobra.Command) {
cmd.Flags().StringP("masterchef", "m", "", "master Chef Addr ")
_ = cmd.MarkFlagRequired("masterchef")
cmd.Flags().StringP("lptoken", "l", "", "lp Addr ")
_ = cmd.MarkFlagRequired("lptoken")
cmd.Flags().StringP("key","k","","private key")
}
func CheckAllowance4LP(cmd *cobra.Command, args []string) {
masterChefAddrStr, _ := cmd.Flags().GetString("masterchef")
lpToken, _ := cmd.Flags().GetString("lptoken")
privkey,_:=cmd.Flags().GetString("key")
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
setupWebsocketEthClient(ethNodeAddr)
//owner string, spender string, amount int64
err := CheckAllowance4LPHandle(lpToken, masterChefAddrStr,privkey)
if nil != err {
fmt.Println("Failed to CheckAllowance4LP due to:", err.Error())
return
}
fmt.Println("Succeed to CheckAllowance4LP")
}
func showPairInitCodeHashCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "showInitHash",
Short: "show pair's init code hash",
Run: showPairInitCodeHash,
}
showPairInitCodeHashFlags(cmd)
return cmd
}
func showPairInitCodeHashFlags(cmd *cobra.Command) {
cmd.Flags().StringP("factory", "f", "", "factory address")
_ = cmd.MarkFlagRequired("factory")
cmd.Flags().StringP("key","k","","private key")
}
func showPairInitCodeHash(cmd *cobra.Command, args []string) {
factory, _ := cmd.Flags().GetString("factory")
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
privkey,_:=cmd.Flags().GetString("key")
setupWebsocketEthClient(ethNodeAddr)
//owner string, spender string, amount int64
err := showPairInitCodeHashHandle(factory,privkey)
if nil != err {
fmt.Println("Failed to showPairInitCodeHash due to:", err.Error())
return
}
}
This diff is collapsed.
This diff is collapsed.
package ethereum
import (
"context"
"crypto/ecdsa"
"fmt"
"github.com/33cn/plugin/plugin/dapp/cross2eth/contracts/erc20/generated"
"github.com/33cn/plugin/plugin/dapp/cross2eth/ebrelayer/utils"
"github.com/33cn/plugin/plugin/dapp/dex/boss/deploy/ethereum/offline"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/spf13/cobra"
"math/big"
"strings"
)
func EthCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "ethereum",
Short: "ethereumcake command",
}
cmd.AddCommand(
CakeCmd(),
FarmCmd(),
GetBalanceCmd(),
Erc20Cmd(),
)
return cmd
}
//Erc20Cmd
func Erc20Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "erc20",
Short: "deploy erc20 contract",
Run: deplayErc20,
}
DeployERC20Flags(cmd)
return cmd
}
func DeployERC20Flags(cmd *cobra.Command) {
cmd.Flags().StringP("owner", "c", "", "owner address")
_ = cmd.MarkFlagRequired("owner")
cmd.Flags().StringP("name", "n", "", "erc20 name")
_ = cmd.MarkFlagRequired("name")
cmd.Flags().StringP("symbol", "s", "", "erc20 symbol")
_ = cmd.MarkFlagRequired("symbol")
cmd.Flags().StringP("amount", "m", "0", "amount")
_ = cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("key", "k", "", "private key")
_ = cmd.MarkFlagRequired("key")
cmd.Flags().Uint8P("decimals", "d", 18, "token decimals")
_ = cmd.MarkFlagRequired("decimals")
}
func deplayErc20(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
owner, _ := cmd.Flags().GetString("owner")
name, _ := cmd.Flags().GetString("name")
symbol, _ := cmd.Flags().GetString("symbol")
amount, _ := cmd.Flags().GetString("amount")
decimals, _ := cmd.Flags().GetUint8("decimals")
key, _ := cmd.Flags().GetString("key")
fmt.Println("owner", owner, "name", name, "symbol:", symbol, "amount", amount)
priv, err := crypto.ToECDSA(common.FromHex(key))
if nil != err {
panic("Failed to recover private key")
}
deployFrom := crypto.PubkeyToAddress(priv.PublicKey)
client, err := ethclient.Dial(rpcLaddr)
if nil != err {
panic(err)
}
ctx := context.Background()
gasPrice, err := client.SuggestGasPrice(ctx)
if err != nil {
panic(err)
}
nonce, err := client.PendingNonceAt(ctx, deployFrom)
if nil != err {
fmt.Println("err:", err)
}
contractAddr := crypto.CreateAddress(deployFrom, nonce)
signedtx, hash, err := rewriteDeployErc20(owner, name, symbol, amount, decimals, nonce, gasPrice, priv)
if err != nil {
panic(err)
}
var tx = new(types.Transaction)
err = tx.UnmarshalBinary(common.FromHex(signedtx))
if err != nil {
panic(err)
}
err = client.SendTransaction(ctx, tx)
if nil != err {
fmt.Println("err:", err)
}
fmt.Println("success deploy erc20:", symbol, "contract,ContractAddress", contractAddr, "txhash:", hash)
}
func rewriteDeployErc20(owner, name, symbol, amount string, decimals uint8, nonce uint64, gasPrice *big.Int, key *ecdsa.PrivateKey) (signedTx, hash string, err error) {
erc20OwnerAddr := common.HexToAddress(owner)
bn := big.NewInt(1)
supply, ok := bn.SetString(utils.TrimZeroAndDot(amount), 10)
if !ok {
panic("amount format err")
}
parsed, err := abi.JSON(strings.NewReader(generated.ERC20ABI))
if err != nil {
return
}
erc20Bin := common.FromHex(generated.ERC20Bin)
packdata, err := parsed.Pack("", name, symbol, supply, erc20OwnerAddr, decimals)
if err != nil {
panic(err)
}
input := append(erc20Bin, packdata...)
var gasLimit = 100 * 10000
tx := types.NewContractCreation(nonce, big.NewInt(0), uint64(gasLimit), gasPrice, input)
return offline.SignTx(key, tx)
}
//GetBalanceCmd ...
func GetBalanceCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "balance",
Short: "get owner's balance for ETH or ERC20",
Run: ShowBalance,
}
GetBalanceFlags(cmd)
return cmd
}
//GetBalanceFlags ...
func GetBalanceFlags(cmd *cobra.Command) {
cmd.Flags().StringP("owner", "o", "", "owner address")
_ = cmd.MarkFlagRequired("owner")
cmd.Flags().StringP("tokenAddr", "t", "", "token address, optional, nil for Eth")
}
//GetBalance ...
func ShowBalance(cmd *cobra.Command, args []string) {
owner, _ := cmd.Flags().GetString("owner")
tokenAddr, _ := cmd.Flags().GetString("tokenAddr")
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
setupWebsocketEthClient(ethNodeAddr)
balance, err := GetBalance(tokenAddr, owner)
if nil != err {
fmt.Println("err:", err.Error())
}
fmt.Println("balance =", balance)
}
package ethereum
import (
"encoding/json"
"fmt"
"math/big"
"strings"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/masterChef"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/spf13/cobra"
)
func FarmCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "farm",
Short: "farm command",
}
cmd.AddCommand(
DeployFarmCmd(),
AddPoolCmd(),
UpdateAllocPointCmd(),
TransferOwnerShipCmd(),
ShowCackeBalanceCmd(),
UpdateCakePerBlockCmd(),
ShowPoolInfosCmd(),
)
return cmd
}
func ShowPoolInfosCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "pool info",
Short: "query pool length,and pool info by pid",
Run: showPools,
}
ShowPoolInfoFlags(cmd)
return cmd
}
func ShowPoolInfoFlags(cmd *cobra.Command) {
cmd.Flags().StringP("lp", "l", "", "lp address")
cmd.Flags().Int64P("poolid", "p", 0, "pool id")
//_ = cmd.MarkFlagRequired("lp")
cmd.Flags().StringP("masterchef", "m", "", "master Chef Addr ")
_ = cmd.MarkFlagRequired("masterchef")
}
func showPools(cmd *cobra.Command, args []string) {
masterChefAddrStr, _ := cmd.Flags().GetString("masterchef")
lpAddrStr, _ := cmd.Flags().GetString("lp")
poolid, _ := cmd.Flags().GetInt64("poolid")
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
setupWebsocketEthClient(ethNodeAddr)
masterChefAddr := common.HexToAddress(masterChefAddrStr)
masterChefInt, err := masterChef.NewMasterChef(masterChefAddr, ethClient)
if nil != err {
return
}
var opts bind.CallOpts
pl, err := masterChefInt.PoolLength(&opts)
if err != nil {
fmt.Println("query masterChef PoolLength err", err.Error())
return
}
fmt.Println("++++++++++++++++\ntotal pool num:", pl.Int64(), "\\n++++++++++++++++\\n")
//var pid int64 =1
totalPid := pl.Int64()
for pid := 1; pid < int(totalPid); pid++ {
info, err := masterChefInt.PoolInfo(&opts, big.NewInt(int64(pid)))
if err != nil {
fmt.Println("query poolinfo err", err.Error(), "pid", pid)
continue
}
jinfo, _ := json.MarshalIndent(info, "", "\t")
if lpAddrStr != "" {
//find lpaddr-->pid
if strings.ToLower(info.LpToken.String()) == strings.ToLower(lpAddrStr) {
fmt.Println("Find LP PID:", pid, "\nLP info:", string(jinfo))
return
}
continue
}
if poolid != 0 {
//find pid--->lpaddr
if pid == int(poolid) {
fmt.Println("Find LP PID:", pid, "\nLP info:", string(jinfo))
return
}
continue
}
fmt.Println("LP PID:", pid, "\nLP info:", string(jinfo))
}
}
func ShowCackeBalanceCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "balance",
Short: "show cake balance within a specified pool",
Run: ShowCakeBalance,
}
ShowBalanceFlags(cmd)
return cmd
}
//GetBalanceFlags ...
func ShowBalanceFlags(cmd *cobra.Command) {
cmd.Flags().StringP("owner", "o", "", "owner address")
_ = cmd.MarkFlagRequired("owner")
cmd.Flags().Int64P("pid", "d", 0, "id of pool")
_ = cmd.MarkFlagRequired("pid")
}
//GetBalance ...
func ShowCakeBalance(cmd *cobra.Command, args []string) {
owner, _ := cmd.Flags().GetString("owner")
pid, _ := cmd.Flags().GetInt64("pid")
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
setupWebsocketEthClient(ethNodeAddr)
balance, err := GetCakeBalance(owner, pid)
if nil != err {
fmt.Println("err:", err.Error())
}
fmt.Println("balance =", balance)
}
func DeployFarmCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "deploy farm",
Short: "deploy farm to bsc ",
Run: DeployContracts,
}
cmd.Flags().StringP("key", "k", "", "private key")
return cmd
}
func DeployContracts(cmd *cobra.Command, args []string) {
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
privkey, _ := cmd.Flags().GetString("key")
setupWebsocketEthClient(ethNodeAddr)
err := DeployFarm(privkey)
if nil != err {
fmt.Println("Failed to deploy contracts due to:", err.Error())
return
}
fmt.Println("Succeed to deploy contracts")
}
func AddPoolCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "add pool",
Short: "add pool to farm ",
Run: AddPool2Farm,
}
addAddPoolCmdFlags(cmd)
return cmd
}
func addAddPoolCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("masterchef", "m", "", "master Chef Addr ")
_ = cmd.MarkFlagRequired("masterchef")
cmd.Flags().StringP("lptoken", "l", "", "lp Addr ")
_ = cmd.MarkFlagRequired("lptoken")
cmd.Flags().Int64P("alloc", "p", 0, "allocation point ")
_ = cmd.MarkFlagRequired("alloc")
cmd.Flags().BoolP("update", "u", true, "with update")
_ = cmd.MarkFlagRequired("update")
cmd.Flags().Uint64P("gasLimit", "g", 80*10000, "set gas limit")
cmd.Flags().StringP("key", "k", "", "private key")
}
func AddPool2Farm(cmd *cobra.Command, args []string) {
masterChefAddrStr, _ := cmd.Flags().GetString("masterchef")
allocPoint, _ := cmd.Flags().GetInt64("alloc")
lpToken, _ := cmd.Flags().GetString("lptoken")
update, _ := cmd.Flags().GetBool("update")
gasLimit, _ := cmd.Flags().GetUint64("gaslimit")
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
privkey, _ := cmd.Flags().GetString("key")
setupWebsocketEthClient(ethNodeAddr)
err := AddPool2FarmHandle(masterChefAddrStr, privkey, allocPoint, lpToken, update, gasLimit)
if nil != err {
fmt.Println("Failed to AddPool2Farm due to:", err.Error())
return
}
fmt.Println("Succeed to AddPool2Farm")
}
func UpdateAllocPointCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "update alloc point",
Short: "Update the given pool's CAKE allocation point",
Run: UpdateAllocPoint,
}
updateAllocPointCmdFlags(cmd)
return cmd
}
func updateAllocPointCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("masterchef", "m", "", "master Chef Addr ")
_ = cmd.MarkFlagRequired("masterchef")
cmd.Flags().Int64P("pid", "d", 0, "id of pool")
_ = cmd.MarkFlagRequired("pid")
cmd.Flags().Int64P("alloc", "p", 0, "allocation point ")
_ = cmd.MarkFlagRequired("alloc")
cmd.Flags().BoolP("update", "u", true, "with update")
_ = cmd.MarkFlagRequired("update")
cmd.Flags().StringP("key", "k", "", "private key")
}
func UpdateAllocPoint(cmd *cobra.Command, args []string) {
masterChefAddrStr, _ := cmd.Flags().GetString("masterchef")
pid, _ := cmd.Flags().GetInt64("pid")
allocPoint, _ := cmd.Flags().GetInt64("alloc")
update, _ := cmd.Flags().GetBool("update")
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
privkey, _ := cmd.Flags().GetString("key")
setupWebsocketEthClient(ethNodeAddr)
err := UpdateAllocPointHandle(masterChefAddrStr, privkey, pid, allocPoint, update)
if nil != err {
fmt.Println("Failed to AddPool2Farm due to:", err.Error())
return
}
fmt.Println("Succeed to AddPool2Farm")
}
func TransferOwnerShipCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "Transfer OwnerShip",
Short: "Transfer OwnerShip, should transfer both cakeToken and syrupbar's ownership to masterChef",
Run: TransferOwnerShip,
}
TransferOwnerShipFlags(cmd)
return cmd
}
func TransferOwnerShipFlags(cmd *cobra.Command) {
cmd.Flags().StringP("new", "n", "", "new owner")
_ = cmd.MarkFlagRequired("new")
cmd.Flags().StringP("contract", "c", "", "contract address")
_ = cmd.MarkFlagRequired("contract")
cmd.Flags().StringP("key", "k", "", "private key")
}
func TransferOwnerShip(cmd *cobra.Command, args []string) {
newOwner, _ := cmd.Flags().GetString("new")
contract, _ := cmd.Flags().GetString("contract")
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
privkey, _ := cmd.Flags().GetString("key")
setupWebsocketEthClient(ethNodeAddr)
err := TransferOwnerShipHandle(newOwner, contract, privkey)
if nil != err {
fmt.Println("Failed to TransferOwnerShip due to:", err.Error())
return
}
fmt.Println("Succeed to TransferOwnerShip")
}
func UpdateCakePerBlockCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "updateCakePerBlock",
Short: "update CakePerBlock ",
Run: UpdateCakePerBlock,
}
AddUpdateCakePerBlockFlags(cmd)
return cmd
}
func AddUpdateCakePerBlockFlags(cmd *cobra.Command) {
cmd.Flags().Float64P("cakePerBlock", "c", 0, "cakePerBlock, the value will be multiplied by 1e18")
_ = cmd.MarkFlagRequired("cakePerBlock")
cmd.Flags().Float64P("startBlock", "s", 0, "start block to take effect")
_ = cmd.MarkFlagRequired("startBlock")
cmd.Flags().StringP("masterChef", "m", "", "masterChef address")
_ = cmd.MarkFlagRequired("masterChef")
cmd.Flags().StringP("key", "k", "", "private key")
}
func UpdateCakePerBlock(cmd *cobra.Command, args []string) {
cakePerBlockFloat, _ := cmd.Flags().GetFloat64("cakePerBlock")
startBlock, _ := cmd.Flags().GetInt64("startBlock")
ethNodeAddr, _ := cmd.Flags().GetString("rpc_laddr_ethereum")
masterChef, _ := cmd.Flags().GetString("masterChef")
privkey, _ := cmd.Flags().GetString("key")
cakePerBlock := big.NewInt(int64(cakePerBlockFloat*1e4) * 1e14)
setupWebsocketEthClient(ethNodeAddr)
//owner string, spender string, amount int64
err := updateCakePerBlockHandle(cakePerBlock, startBlock, masterChef, privkey)
if nil != err {
fmt.Println("Failed to AddPool2Farm due to:", err.Error())
return
}
fmt.Println("Succeed to AddPool2Farm")
}
package ethereum
import (
"context"
"fmt"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/cakeToken"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/masterChef"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/syrupBar"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"math/big"
"time"
)
func GetCakeBalance(owner string, pid int64) (string, error) {
masterChefInt, err := masterChef.NewMasterChef(common.HexToAddress("0xD88654a6aAc42a7192d697a8250a93246De882C6"), ethClient)
if nil != err {
return "", err
}
ownerAddr := common.HexToAddress(owner)
opts := &bind.CallOpts{
From: ownerAddr,
Context: context.Background(),
}
amount, err := masterChefInt.PendingCake(opts, big.NewInt(pid), ownerAddr)
if nil != err {
return "", err
}
return amount.String(), nil
}
func DeployFarm(key string) error {
_ = recoverEthTestNetPrivateKey(key)
//1st step to deploy factory
auth, err := PrepareAuth(privateKey, deployerAddr)
if nil != err {
return err
}
cakeTokenAddr, deploycakeTokenTx, _, err := cakeToken.DeployCakeToken(auth, ethClient)
if nil != err {
panic(fmt.Sprintf("Failed to DeployCakeToken with err:%s", err.Error()))
}
{
fmt.Println("\nDeployCakeToken tx hash:", deploycakeTokenTx.Hash().String())
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
for {
select {
case <-timeout.C:
panic("DeployCakeToken timeout")
case <-oneSecondtimeout.C:
_, err := ethClient.TransactionReceipt(context.Background(), deploycakeTokenTx.Hash())
if err == ethereum.NotFound {
fmt.Println("\n No receipt received yet for DeployCakeToken tx and continue to wait")
continue
} else if err != nil {
panic("DeployCakeToken failed due to" + err.Error())
}
fmt.Println("\n Succeed to deploy DeployCakeToken with address =", cakeTokenAddr.String())
goto deploySyrupBar
}
}
}
deploySyrupBar:
auth, err = PrepareAuth(privateKey, deployerAddr)
if nil != err {
return err
}
SyrupBarAddr, deploySyrupBarTx, _, err := syrupBar.DeploySyrupBar(auth, ethClient, cakeTokenAddr)
if err != nil {
panic(fmt.Sprintf("Failed to DeploySyrupBar with err:%s", err.Error()))
}
{
fmt.Println("\nDeploySyrupBar tx hash:", deploySyrupBarTx.Hash().String())
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
for {
select {
case <-timeout.C:
panic("DeploySyrupBar timeout")
case <-oneSecondtimeout.C:
_, err := ethClient.TransactionReceipt(context.Background(), deploySyrupBarTx.Hash())
if err == ethereum.NotFound {
fmt.Println("\n No receipt received yet for DeploySyrupBar tx and continue to wait")
continue
} else if err != nil {
panic("DeploySyrupBar failed due to" + err.Error())
}
fmt.Println("\n Succeed to deploy DeploySyrupBar with address =", SyrupBarAddr.String())
goto deployMasterchef
}
}
}
deployMasterchef:
auth, err = PrepareAuth(privateKey, deployerAddr)
if nil != err {
return err
}
//auth *bind.TransactOpts, backend bind.ContractBackend, _cake common.Address, _syrup common.Address, _devaddr common.Address, _cakePerBlock *big.Int, _startBlock *big.Int
MasterChefAddr, deployMasterChefTx, _, err := masterChef.DeployMasterChef(auth, ethClient, cakeTokenAddr, SyrupBarAddr, deployerAddr, big.NewInt(5*1e18), big.NewInt(100))
if err != nil {
panic(fmt.Sprintf("Failed to DeployMasterChef with err:%s", err.Error()))
}
{
fmt.Println("\nDeployMasterChef tx hash:", deployMasterChefTx.Hash().String())
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
for {
select {
case <-timeout.C:
panic("DeployMasterChef timeout")
case <-oneSecondtimeout.C:
_, err := ethClient.TransactionReceipt(context.Background(), deployMasterChefTx.Hash())
if err == ethereum.NotFound {
fmt.Println("\n No receipt received yet for DeployMasterChef tx and continue to wait")
continue
} else if err != nil {
panic("DeployMasterChef failed due to" + err.Error())
}
fmt.Println("\n Succeed to deploy DeployMasterChef with address =", MasterChefAddr.String())
return nil
}
}
}
}
func AddPool2FarmHandle(masterChefAddrStr, key string, allocPoint int64, lpToken string, withUpdate bool, gasLimit uint64) (err error) {
masterChefAddr := common.HexToAddress(masterChefAddrStr)
masterChefInt, err := masterChef.NewMasterChef(masterChefAddr, ethClient)
if nil != err {
return err
}
_ = recoverEthTestNetPrivateKey(key)
//1st step to deploy factory
auth, err := PrepareAuth(privateKey, deployerAddr)
if nil != err {
return err
}
auth.GasLimit = gasLimit
AddPool2FarmTx, err := masterChefInt.Add(auth, big.NewInt(int64(allocPoint)), common.HexToAddress(lpToken), withUpdate)
if err != nil {
panic(fmt.Sprintf("Failed to AddPool2FarmTx with err:%s", err.Error()))
}
fmt.Println("\nAddPool2FarmTx tx hash:", AddPool2FarmTx.Hash().String())
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
for {
select {
case <-timeout.C:
panic("AddPool2FarmTx timeout")
case <-oneSecondtimeout.C:
_, err := ethClient.TransactionReceipt(context.Background(), AddPool2FarmTx.Hash())
if err == ethereum.NotFound {
fmt.Println("\n No receipt received yet for AddPool2FarmTx tx and continue to wait")
continue
} else if err != nil {
panic("AddPool2FarmTx failed due to" + err.Error())
}
return nil
}
}
}
func UpdateAllocPointHandle(masterChefAddrStr, key string, pid, allocPoint int64, withUpdate bool) (err error) {
masterChefAddr := common.HexToAddress(masterChefAddrStr)
masterChefInt, err := masterChef.NewMasterChef(masterChefAddr, ethClient)
if nil != err {
return err
}
_ = recoverEthTestNetPrivateKey(key)
auth, err := PrepareAuth(privateKey, deployerAddr)
if nil != err {
return err
}
//_pid *big.Int, _allocPoint *big.Int, _withUpdate bool
SetPool2FarmTx, err := masterChefInt.Set(auth, big.NewInt(pid), big.NewInt(allocPoint), withUpdate)
if err != nil {
panic(fmt.Sprintf("Failed to SetPool2FarmTx with err:%s", err.Error()))
}
{
fmt.Println("\nSetPool2FarmTx tx hash:", SetPool2FarmTx.Hash().String())
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
for {
select {
case <-timeout.C:
panic("SetPool2FarmTx timeout")
case <-oneSecondtimeout.C:
_, err := ethClient.TransactionReceipt(context.Background(), SetPool2FarmTx.Hash())
if err == ethereum.NotFound {
fmt.Println("\n No receipt received yet for SetPool2FarmTx tx and continue to wait")
continue
} else if err != nil {
panic("SetPool2FarmTx failed due to" + err.Error())
}
return nil
}
}
}
}
func TransferOwnerShipHandle(newOwner, contract, key string) (err error) {
contractAddr := common.HexToAddress(contract)
contractInt, err := syrupBar.NewSyrupBar(contractAddr, ethClient)
if nil != err {
return err
}
_ = recoverEthTestNetPrivateKey(key)
auth, err := PrepareAuth(privateKey, deployerAddr)
if nil != err {
return err
}
//_pid *big.Int, _allocPoint *big.Int, _withUpdate bool
newOwnerAddr := common.HexToAddress(newOwner)
TransferOwnershipTx, err := contractInt.TransferOwnership(auth, newOwnerAddr)
if err != nil {
panic(fmt.Sprintf("Failed to TransferOwnership with err:%s", err.Error()))
}
{
fmt.Println("\nTransferOwnership tx hash:", TransferOwnershipTx.Hash().String())
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
for {
select {
case <-timeout.C:
panic("TransferOwnership timeout")
case <-oneSecondtimeout.C:
_, err := ethClient.TransactionReceipt(context.Background(), TransferOwnershipTx.Hash())
if err == ethereum.NotFound {
fmt.Println("\n No receipt received yet for TransferOwnership tx and continue to wait")
continue
} else if err != nil {
panic("TransferOwnership failed due to" + err.Error())
}
return nil
}
}
}
}
func updateCakePerBlockHandle(cakePerBlock *big.Int, startBlock int64, masterchef, key string) (err error) {
_ = recoverEthTestNetPrivateKey(key)
masterChefInt, err := masterChef.NewMasterChef(common.HexToAddress(masterchef), ethClient)
if nil != err {
return err
}
auth, err := PrepareAuth(privateKey, deployerAddr)
if nil != err {
return err
}
updateCakePerBlockTx, err := masterChefInt.UpdateCakePerBlock(auth, cakePerBlock, big.NewInt(startBlock))
if nil != err {
panic(fmt.Sprintf("Failed to UpdateCakePerBlock with err:%s", err.Error()))
}
{
fmt.Println("\nUpdateCakePerBlock tx hash:", updateCakePerBlockTx.Hash().String())
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
for {
select {
case <-timeout.C:
panic("UpdateCakePerBlock timeout")
case <-oneSecondtimeout.C:
_, err := ethClient.TransactionReceipt(context.Background(), updateCakePerBlockTx.Hash())
if err == ethereum.NotFound {
fmt.Println("\n No receipt received yet for UpdateCakePerBlock tx and continue to wait")
continue
} else if err != nil {
panic("UpdateCakePerBlock failed due to" + err.Error())
}
fmt.Println("\n Succeed to do the UpdateCakePerBlock operation")
return nil
}
}
}
}
package offline
import "github.com/spf13/cobra"
const gasLimit uint64 = 10000 * 800
func EthOfflineCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "eth",
Short: "create and sign offline tx to deploy and set dex contracts to eth",
Args: cobra.MinimumNArgs(1),
}
var query = new(queryCmd)
var signdeployCmd = new(SignCmd)
var deploy = new(DeployContract)
var addpool = new(AddPool)
var update = new(updateAllocPoint)
var transOwner = new(transferOwnerShip)
cmd.AddCommand(
query.queryCmd(), //query fromAccount info such as: nonce,gasprice
signdeployCmd.signCmd(), //sign fatory.weth9,pancakrouter contract
addpool.AddPoolCmd(), //call contract
update.UpdateAllocPointCmd(),
transOwner.TransferOwnerShipCmd(),
deploy.DeployCmd(), //send singned tx to deploy contract:factory,weth9,pancakerouter.
)
return cmd
}
package offline
import (
"crypto/ecdsa"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/cakeToken"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/masterChef"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/syrupBar"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"math/big"
"strings"
)
type SignCakeToken struct {
}
func (s *SignCakeToken) reWriteDeployCakeToken(nonce uint64, gasPrice *big.Int, key *ecdsa.PrivateKey,params... interface{}) (signedTx, hash string, err error) {
parsed, err := abi.JSON(strings.NewReader(cakeToken.CakeTokenABI))
if err != nil {
return
}
input, err := parsed.Pack("", params...)
if err != nil {
return
}
abiBin := cakeToken.CakeTokenBin
data := append(common.FromHex(abiBin), input...)
var amount = new(big.Int)
ntx := types.NewContractCreation(nonce, amount, gasLimit, gasPrice, data)
return SignTx(key, ntx)
}
type signsyrupBar struct {
}
func (s *signsyrupBar)reWriteDeploysyrupBar(nonce uint64, gasPrice *big.Int, key *ecdsa.PrivateKey,cakeAddress common.Address)(signedTx, hash string, err error){
parsed, err := abi.JSON(strings.NewReader(syrupBar.SyrupBarABI))
if err != nil {
return
}
input, err := parsed.Pack("", cakeAddress)
if err != nil {
return
}
abiBin := syrupBar.SyrupBarBin
data := append(common.FromHex(abiBin), input...)
var amount = new(big.Int)
ntx:=types.NewContractCreation(nonce, amount, gasLimit, gasPrice, data)
return SignTx(key, ntx)
}
type signMasterChef struct{
}
func (s *signMasterChef)reWriteDeployMasterChef(nonce uint64, gasPrice *big.Int, key *ecdsa.PrivateKey,cakeAddress,syruBarAddress ,fromaddr common.Address,reward,_startBlock *big.Int)(signedTx, hash string, err error){
parsed, err := abi.JSON(strings.NewReader(masterChef.MasterChefABI))
if err != nil {
return
}
input, err := parsed.Pack("", cakeAddress,syruBarAddress,fromaddr,reward,_startBlock)
if err != nil {
return
}
abiBin := masterChef.MasterChefBin
data := append(common.FromHex(abiBin), input...)
var amount = new(big.Int)
ntx := types.NewContractCreation(nonce, amount, gasLimit, gasPrice, data)
return SignTx(key, ntx)
}
\ No newline at end of file
package offline
import (
"crypto/ecdsa"
"fmt"
"math/big"
"strings"
"time"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/masterChef"
"github.com/33cn/plugin/plugin/dapp/dex/contracts/pancake-farm/src/syrupBar"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/spf13/cobra"
)
type AddPool struct {
allocPoint int64
lpToken string
withUpdate bool
}
func (a *AddPool) AddPoolCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "add pool",
Short: "add pool to farm ",
Run: a.AddPool2Farm,
}
a.addAddPoolCmdFlags(cmd)
return cmd
}
func (a *AddPool) addAddPoolCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("masterchef", "m", "", "master Chef Addr ")
_ = cmd.MarkFlagRequired("masterchef")
cmd.Flags().StringP("lptoken", "l", "", "lp Addr ")
_ = cmd.MarkFlagRequired("lptoken")
cmd.Flags().Int64P("alloc", "a", 0, "allocation point ")
_ = cmd.MarkFlagRequired("alloc")
cmd.Flags().BoolP("update", "u", true, "with update")
_ = cmd.MarkFlagRequired("update")
cmd.Flags().StringP("priv", "p", "", "private key")
_ = cmd.MarkFlagRequired("priv")
cmd.Flags().StringP("file", "f", "accountinfo.txt", "account info")
_ = cmd.MarkFlagRequired("file")
cmd.Flags().Uint64P("nonce", "n", 0, "transaction count")
cmd.MarkFlagRequired("nonce")
cmd.Flags().Uint64P("gasprice", "g", 1000000000, "gas price")
cmd.MarkFlagRequired("gasprice")
}
func (a *AddPool) AddPool2Farm(cmd *cobra.Command, args []string) {
masterChefAddrStr, _ := cmd.Flags().GetString("masterchef")
allocPoint, _ := cmd.Flags().GetInt64("alloc")
lpToken, _ := cmd.Flags().GetString("lptoken")
update, _ := cmd.Flags().GetBool("update")
key, _ := cmd.Flags().GetString("priv")
nonce, _ := cmd.Flags().GetUint64("nonce")
price, _ := cmd.Flags().GetUint64("gasprice")
priv, from, err := recoverBinancePrivateKey(key)
if err != nil {
panic(err)
}
a.allocPoint = allocPoint
a.lpToken = lpToken
a.withUpdate = update
var signData = make([]*DeployContract, 0)
var signInfo SignCmd
signInfo.Nonce = nonce
signInfo.GasPrice = price
signInfo.From = from.String()
//--------------------
//sign addpool
//--------------------
signedtx, hash, err := a.reWriteAddPool2Farm(signInfo.Nonce, masterChefAddrStr, big.NewInt(int64(signInfo.GasPrice)), priv)
if nil != err {
fmt.Println("Failed to AddPool2Farm due to:", err.Error())
return
}
var addPoolData = new(DeployContract)
addPoolData.Nonce = signInfo.Nonce
addPoolData.RawTx = signedtx
addPoolData.TxHash = hash
addPoolData.ContractName = "addpool"
signData = append(signData, addPoolData)
writeToFile("addPool.txt", signData)
fmt.Println("Succeed to sign AddPool")
}
func (a *AddPool) reWriteAddPool2Farm(nonce uint64, masterChefAddrStr string, gasPrice *big.Int, key *ecdsa.PrivateKey) (signedTx, hash string, err error) {
masterChefAddr := common.HexToAddress(masterChefAddrStr)
parsed, err := abi.JSON(strings.NewReader(masterChef.MasterChefABI))
input, err := parsed.Pack("add", big.NewInt(a.allocPoint), common.HexToAddress(a.lpToken), a.withUpdate)
if err != nil {
panic(err)
}
ntx := types.NewTransaction(nonce, masterChefAddr, new(big.Int), gasLimit, gasPrice, input)
return SignTx(key, ntx)
}
//------------
//update
type updateAllocPoint struct {
pid, allocPoint int64
withUpdate bool
}
func (u *updateAllocPoint) UpdateAllocPointCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "update alloc point",
Short: "Update the given pool's CAKE allocation point",
Run: u.UpdateAllocPoint,
}
u.updateAllocPointCmdFlags(cmd)
return cmd
}
func (u *updateAllocPoint) UpdateAllocPoint(cmd *cobra.Command, args []string) {
masterChefAddrStr, _ := cmd.Flags().GetString("masterchef")
pid, _ := cmd.Flags().GetInt64("pid")
allocPoint, _ := cmd.Flags().GetInt64("alloc")
update, _ := cmd.Flags().GetBool("update")
key, _ := cmd.Flags().GetString("priv")
nonce, _ := cmd.Flags().GetUint64("nonce")
price, _ := cmd.Flags().GetUint64("gasprice")
priv, from, err := recoverBinancePrivateKey(key)
if err != nil {
panic(err)
}
u.pid = pid
u.allocPoint = allocPoint
u.withUpdate = update
var signInfo SignCmd
var signData = make([]*DeployContract, 0)
signInfo.Nonce = nonce
signInfo.GasPrice = price
signInfo.From = from.String()
signedtx, hash, err := u.rewriteUpdateAllocPoint(masterChefAddrStr, signInfo.Nonce, big.NewInt(int64(signInfo.GasPrice)), priv)
if err != nil {
panic(err)
}
var updateAllocData = new(DeployContract)
updateAllocData.Nonce = signInfo.Nonce
updateAllocData.RawTx = signedtx
updateAllocData.TxHash = hash
updateAllocData.ContractName = "updateAllocPoint"
signData = append(signData, updateAllocData)
writeToFile("updateAllocPoint.txt", signData)
fmt.Println("Succeed to sign updateAllocPoint")
}
func (u *updateAllocPoint) updateAllocPointCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("masterchef", "m", "", "master Chef Addr ")
_ = cmd.MarkFlagRequired("masterchef")
cmd.Flags().Int64P("pid", "d", 0, "id of pool")
_ = cmd.MarkFlagRequired("pid")
cmd.Flags().Int64P("alloc", "a", 0, "allocation point ")
_ = cmd.MarkFlagRequired("alloc")
cmd.Flags().BoolP("update", "u", true, "with update")
_ = cmd.MarkFlagRequired("update")
cmd.Flags().StringP("priv", "p", "", "private key")
_ = cmd.MarkFlagRequired("priv")
cmd.Flags().Uint64P("nonce", "n", 0, "transaction count")
cmd.MarkFlagRequired("nonce")
cmd.Flags().Uint64P("gasprice", "g", 1000000000, "gas price")
cmd.MarkFlagRequired("gasprice")
}
func (u *updateAllocPoint) rewriteUpdateAllocPoint(masterChefAddrStr string, nonce uint64, gasPrice *big.Int, key *ecdsa.PrivateKey) (signedTx, hash string, err error) {
masterChefAddr := common.HexToAddress(masterChefAddrStr)
parsed, err := abi.JSON(strings.NewReader(masterChef.MasterChefABI))
input, err := parsed.Pack("set", big.NewInt(u.pid), big.NewInt(u.allocPoint), u.withUpdate)
if err != nil {
panic(err)
}
ntx := types.NewTransaction(nonce, masterChefAddr, new(big.Int), gasLimit, gasPrice, input)
return SignTx(key, ntx)
}
type transferOwnerShip struct {
}
func (t *transferOwnerShip) TransferOwnerShipCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "transfer OwnerShip",
Short: "transfer OwnerShip",
Run: t.TransferOwnerShip,
}
t.TransferOwnerShipFlags(cmd)
return cmd
}
func (t *transferOwnerShip) TransferOwnerShipFlags(cmd *cobra.Command) {
cmd.Flags().StringP("new", "n", "", "new owner")
_ = cmd.MarkFlagRequired("new")
cmd.Flags().StringP("contract", "c", "", "contract address")
_ = cmd.MarkFlagRequired("contract")
cmd.Flags().StringP("file", "f", "accountinfo.txt", "account info")
_ = cmd.MarkFlagRequired("file")
cmd.Flags().StringP("priv", "p", "", "private key")
_ = cmd.MarkFlagRequired("priv")
}
func (t *transferOwnerShip) TransferOwnerShip(cmd *cobra.Command, args []string) {
newOwner, _ := cmd.Flags().GetString("new")
contract, _ := cmd.Flags().GetString("contract")
key, _ := cmd.Flags().GetString("priv")
filePath, _ := cmd.Flags().GetString("file")
priv, from, err := recoverBinancePrivateKey(key)
if err != nil {
panic(err)
}
var signInfo SignCmd
paraseFile(filePath, &signInfo)
checkFile(signInfo.From, from.String(), signInfo.Timestamp)
signedtx, hash, err := TransferOwnerShipHandle(signInfo.Nonce, big.NewInt(int64(signInfo.GasPrice)), newOwner, contract, priv)
if nil != err {
fmt.Println("Failed to TransferOwnerShip due to:", err.Error())
return
}
var transferOwner = new(DeployContract)
var signData = make([]*DeployContract, 0)
transferOwner.Nonce = signInfo.Nonce
transferOwner.RawTx = signedtx
transferOwner.TxHash = hash
transferOwner.ContractName = "transferOwnership"
signData = append(signData, transferOwner)
writeToFile("transferOwner.txt", signData)
fmt.Println("Succeed to sign TransferOwnerShip")
}
func TransferOwnerShipHandle(nonce uint64, gasPrice *big.Int, newOwner, contract string, key *ecdsa.PrivateKey) (signedtx, hash string, err error) {
contractAddr := common.HexToAddress(contract)
newOwnerAddr := common.HexToAddress(newOwner)
parsed, err := abi.JSON(strings.NewReader(syrupBar.SyrupBarABI))
input, err := parsed.Pack("transferOwnership", newOwnerAddr)
if err != nil {
return
}
ntx := types.NewTransaction(nonce, contractAddr, big.NewInt(0), gasLimit, gasPrice, input)
return SignTx(key, ntx)
}
func checkFile(from, keyaddr, timestamp string) {
//check is timeout
tim, err := time.Parse(time.RFC3339, timestamp)
if err != nil {
panic(err)
}
if time.Now().After(tim.Add(time.Hour)) {
panic("after 60 minutes timeout,the accountinfo.txt invalid,please reQuery")
}
if !strings.EqualFold(from, keyaddr) {
panic("deployed address mismatch!!!")
}
}
package offline
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/spf13/cobra"
)
type queryCmd struct {
}
func (q *queryCmd) queryCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "query address", //first step
Short: " query gasPrice,nonce from the spec address",
Run: q.query, //对要部署的factory合约进行签名
}
q.addQueryFlags(cmd)
return cmd
}
func (q *queryCmd) addQueryFlags(cmd *cobra.Command) {
cmd.Flags().StringP("address", "a", "", "account address")
_ = cmd.MarkFlagRequired("address")
}
func (q *queryCmd) query(cmd *cobra.Command, args []string) {
_ = args
url, _ := cmd.Flags().GetString("rpc_laddr")
addr, _ := cmd.Flags().GetString("address")
client, err := ethclient.Dial(url)
if err != nil {
panic(err)
}
ctx := context.Background()
price, err := client.SuggestGasPrice(ctx)
if err != nil {
panic(err)
}
nonce, err := client.PendingNonceAt(context.Background(), common.HexToAddress(addr))
if nil != err {
fmt.Println("err:", err)
}
var info SignCmd
info.From = addr
info.GasPrice = price.Uint64()
info.Nonce = nonce
info.Timestamp = time.Now().Format(time.RFC3339)
writeToFile("accountinfo.txt", &info)
return
}
//deploay Factory contractor
type DeployContract struct {
ContractAddr string
TxHash string
Nonce uint64
RawTx string
ContractName string
Interval time.Duration
}
func (d *DeployContract) DeployCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "send", //first step
Short: " send signed raw tx",
Run: d.send, //对要部署的factory合约进行签名
}
d.addSendFlags(cmd)
return cmd
}
func (d *DeployContract) addSendFlags(cmd *cobra.Command) {
cmd.Flags().StringP("file", "f", "", "*.txt signed tx")
_ = cmd.MarkFlagRequired("file")
}
func (d *DeployContract) send(cmd *cobra.Command, args []string) {
_ = args
filePath, _ := cmd.Flags().GetString("file")
url, _ := cmd.Flags().GetString("rpc_laddr")
//解析文件数据
fmt.Println("file", filePath)
var rdata = make([]*DeployContract, 0)
err := paraseFile(filePath, &rdata)
if err != nil {
fmt.Println("paraseFile,err", err.Error())
return
}
fmt.Println("parase ready total tx num.", len(rdata))
for i, deployInfo := range rdata {
if deployInfo.Interval != 0 {
time.Sleep(deployInfo.Interval)
}
tx := new(types.Transaction)
err = tx.UnmarshalBinary(common.FromHex(deployInfo.RawTx))
if err != nil {
panic(err)
}
client, err := ethclient.Dial(url)
if err != nil {
panic(err)
}
err = client.SendTransaction(context.Background(), tx)
if err != nil {
fmt.Println("err:", err)
panic(err)
}
fmt.Println("deplay contract Index Tx", i+1, "TxHash", tx.Hash().String(), "contractName", deployInfo.ContractName, "contractAddr", deployInfo.ContractAddr)
time.Sleep(time.Second)
}
fmt.Println("All tx send ...")
}
func paraseFile(file string, result interface{}) error {
_, err := os.Stat(file)
if err != nil {
fmt.Println(err.Error())
return err
}
f, err := os.Open(file)
if err != nil {
panic(err)
}
b, err := ioutil.ReadAll(f)
if err != nil {
panic(err)
}
return json.Unmarshal(b, result)
}
func writeToFile(fileName string, content interface{}) {
jbytes, err := json.MarshalIndent(content, "", "\t")
if err != nil {
panic(err)
}
err = ioutil.WriteFile(fileName, jbytes, 0666)
if err != nil {
fmt.Println("Failed to write to file:", fileName)
}
fmt.Println("tx is written to file: ", fileName, "writeContent:", string(jbytes))
}
SRC_CONTRACT := src
GO_OUT := multicall
PACKAGE := multicall
proj := "build"
.PHONY: default multicall
default: multicall
multicall:
@abigen --sol $(SRC_CONTRACT)/Multicall.sol --pkg $(PACKAGE) --out $(GO_OUT)/multicall.go
# Multicall <img width="100" align="right" alt="Multicall" src="https://user-images.githubusercontent.com/304108/55666937-320cb180-5888-11e9-907b-48ba66150523.png" />
Multicall aggregates results from multiple contract constant function calls.
This reduces the number of separate JSON RPC requests that need to be sent
(especially useful if using remote nodes like Infura), while also providing the
guarantee that all values returned are from the same block (like an atomic read)
and returning the block number the values are from (giving them important
context so that results from old blocks can be ignored if they're from an
out-of-date node).
For use in front-end dapps, this smart contract is intended to be used with
[Multicall.js](https://github.com/makerdao/multicall.js).
### Contract Addresses
| Chain | Address |
| ------- | ------- |
| Mainnet | [0xeefba1e63905ef1d7acba5a8513c70307c1ce441](https://etherscan.io/address/0xeefba1e63905ef1d7acba5a8513c70307c1ce441#contracts) |
| Kovan | [0x2cc8688c5f75e365aaeeb4ea8d6a480405a48d2a](https://kovan.etherscan.io/address/0x2cc8688c5f75e365aaeeb4ea8d6a480405a48d2a#contracts) |
| Rinkeby | [0x42ad527de7d4e9d9d011ac45b31d8551f8fe9821](https://rinkeby.etherscan.io/address/0x42ad527de7d4e9d9d011ac45b31d8551f8fe9821#contracts) |
| Görli | [0x77dca2c955b15e9de4dbbcf1246b4b85b651e50e](https://goerli.etherscan.io/address/0x77dca2c955b15e9de4dbbcf1246b4b85b651e50e#contracts) |
| Ropsten | [0x53c43764255c17bd724f74c4ef150724ac50a3ed](https://ropsten.etherscan.io/address/0x53c43764255c17bd724f74c4ef150724ac50a3ed#code) |
| xDai | [0xb5b692a88bdfc81ca69dcb1d924f59f0413a602a](https://blockscout.com/poa/dai/address/0xb5b692a88bdfc81ca69dcb1d924f59f0413a602a) |
This diff is collapsed.
pragma solidity >=0.5.0;
pragma experimental ABIEncoderV2;
/// @title Multicall - Aggregate results from multiple read-only function calls
/// @author Michael Elliot <mike@makerdao.com>
/// @author Joshua Levine <joshua@makerdao.com>
/// @author Nick Johnson <arachnid@notdot.net>
contract Multicall {
struct Call {
address target;
bytes callData;
}
function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) {
blockNumber = block.number;
returnData = new bytes[](calls.length);
for(uint256 i = 0; i < calls.length; i++) {
(bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
require(success);
returnData[i] = ret;
}
}
// Helper functions
function getEthBalance(address addr) public view returns (uint256 balance) {
balance = addr.balance;
}
function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) {
blockHash = blockhash(blockNumber);
}
function getLastBlockHash() public view returns (bytes32 blockHash) {
blockHash = blockhash(block.number - 1);
}
function getCurrentBlockTimestamp() public view returns (uint256 timestamp) {
timestamp = block.timestamp;
}
function getCurrentBlockDifficulty() public view returns (uint256 difficulty) {
difficulty = block.difficulty;
}
function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) {
gaslimit = block.gaslimit;
}
function getCurrentBlockCoinbase() public view returns (address coinbase) {
coinbase = block.coinbase;
}
}
pragma solidity >=0.5.0;
pragma experimental ABIEncoderV2;
import "ds-test/test.sol";
import "./Multicall.sol";
contract Store {
uint256 internal val;
function set(uint256 _val) public { val = _val; }
function get() public view returns (uint256) { return val; }
function getAnd10() public view returns (uint256, uint256) { return (val, 10); }
function getAdd(uint256 _val) public view returns (uint256) { return val + _val; }
}
// We inherit from Multicall rather than deploy an instance because solidity
// can't return dynamically sized byte arrays from external contracts
contract MulticallTest is DSTest, Multicall {
Store public storeA;
Store public storeB;
function setUp() public {
storeA = new Store();
storeB = new Store();
}
function test_store_basic_sanity() public {
assertEq(storeA.get(), 0);
storeA.set(100);
assertEq(storeA.get(), 100);
storeA.set(0);
assertEq(storeA.get(), 0);
}
function test_single_call_single_return_no_args() public {
storeA.set(123);
Call[] memory _calls = new Call[](1);
_calls[0].target = address(storeA);
_calls[0].callData = abi.encodeWithSignature("get()");
(, bytes[] memory _returnData) = aggregate(_calls);
bytes memory _word = _returnData[0];
uint256 _returnVal;
assembly { _returnVal := mload(add(0x20, _word)) }
assertEq(_returnVal, 123);
}
function test_multi_call_single_return_no_args() public {
storeA.set(123);
storeB.set(321);
Call[] memory _calls = new Call[](2);
_calls[0].target = address(storeA);
_calls[0].callData = abi.encodeWithSignature("get()");
_calls[1].target = address(storeB);
_calls[1].callData = abi.encodeWithSignature("get()");
(, bytes[] memory _returnData) = aggregate(_calls);
bytes memory _wordA = _returnData[0];
bytes memory _wordB = _returnData[1];
uint256 _returnValA;
uint256 _returnValB;
assembly { _returnValA := mload(add(0x20, _wordA)) }
assembly { _returnValB := mload(add(0x20, _wordB)) }
assertEq(_returnValA, 123);
assertEq(_returnValB, 321);
}
function test_single_call_single_return_single_arg() public {
storeA.set(123);
Call[] memory _calls = new Call[](1);
_calls[0].target = address(storeA);
_calls[0].callData = abi.encodeWithSignature("getAdd(uint256)", 1);
(, bytes[] memory _returnData) = aggregate(_calls);
bytes memory _word = _returnData[0];
uint256 _returnVal;
assembly { _returnVal := mload(add(0x20, _word)) }
assertEq(_returnVal, 124);
}
function test_multi_call_single_return_single_arg() public {
storeA.set(123);
storeB.set(321);
Call[] memory _calls = new Call[](2);
_calls[0].target = address(storeA);
_calls[0].callData = abi.encodeWithSignature("getAdd(uint256)", 1);
_calls[1].target = address(storeB);
_calls[1].callData = abi.encodeWithSignature("getAdd(uint256)", 1);
(, bytes[] memory _returnData) = aggregate(_calls);
bytes memory _wordA = _returnData[0];
bytes memory _wordB = _returnData[1];
uint256 _returnValA;
uint256 _returnValB;
assembly { _returnValA := mload(add(0x20, _wordA)) }
assembly { _returnValB := mload(add(0x20, _wordB)) }
assertEq(_returnValA, 124);
assertEq(_returnValB, 322);
}
function test_single_call_multi_return_no_args() public {
storeA.set(123);
Call[] memory _calls = new Call[](1);
_calls[0].target = address(storeA);
_calls[0].callData = abi.encodeWithSignature("getAnd10()");
(, bytes[] memory _returnData) = aggregate(_calls);
bytes memory _words = _returnData[0];
uint256 _returnValA1;
uint256 _returnValA2;
assembly { _returnValA1 := mload(add(0x20, _words)) }
assembly { _returnValA2 := mload(add(0x40, _words)) }
assertEq(_returnValA1, 123);
assertEq(_returnValA2, 10);
}
function test_helpers() public {
bytes32 blockHash = getBlockHash(510);
bytes32 lastBlockHash = getLastBlockHash();
uint256 timestamp = getCurrentBlockTimestamp();
uint256 difficulty = getCurrentBlockDifficulty();
uint256 gaslimit = getCurrentBlockGasLimit();
address coinbase = getCurrentBlockCoinbase();
uint256 balance = getEthBalance(address(this));
assertEq(blockHash, blockhash(510));
assertEq(lastBlockHash, blockhash(block.number - 1));
assertEq(timestamp, block.timestamp);
assertEq(difficulty, block.difficulty);
assertEq(gaslimit, block.gaslimit);
assertEq(coinbase, block.coinbase);
assertEq(balance, address(this).balance);
}
}
##
##编译solidity,并产生bin文件,abi文件,和相应的go文件
SRC_CONTRACT := contracts
GO_OUT0 := src/cakeToken/
GO_OUT1 := src/syrupBar/
GO_OUT2 := src/sousChef/
GO_OUT3 := src/masterChef/
PACKAGE0 := cakeToken
PACKAGE1 := syrupBar
PACKAGE2 := sousChef
PACKAGE3 := masterChef
proj := "build"
.PHONY: default build clean
default: sol build
sol:
@abigen --sol $(SRC_CONTRACT)/CakeToken.sol --pkg $(PACKAGE0) --out $(GO_OUT0)/cakeToken.go
@abigen --sol $(SRC_CONTRACT)/SyrupBar.sol --pkg $(PACKAGE1) --out $(GO_OUT1)/syrupBar.go
@abigen --sol $(SRC_CONTRACT)/SousChef.sol --pkg $(PACKAGE2) --out $(GO_OUT2)/sousChef.go
@abigen --sol $(SRC_CONTRACT)/MasterChef.sol --pkg $(PACKAGE3) --out $(GO_OUT3)/masterChef.go
build:
cd bsctest && go build && cd ..
clean:
@rm -fr $(GO_OUT)/*.go
pragma solidity 0.6.12;
import '../pancake-swap-lib/contracts/math/SafeMath.sol';
import '../pancake-swap-lib/contracts/token/BEP20/IBEP20.sol';
import '../pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol';
import '../pancake-swap-lib/contracts/access/Ownable.sol';
// import "@nomiclabs/buidler/console.sol";
interface IWBNB {
function deposit() external payable;
function transfer(address to, uint256 value) external returns (bool);
function withdraw(uint256) external;
}
contract BnbStaking is Ownable {
using SafeMath for uint256;
using SafeBEP20 for IBEP20;
// Info of each user.
struct UserInfo {
uint256 amount; // How many LP tokens the user has provided.
uint256 rewardDebt; // Reward debt. See explanation below.
bool inBlackList;
}
// Info of each pool.
struct PoolInfo {
IBEP20 lpToken; // Address of LP token contract.
uint256 allocPoint; // How many allocation points assigned to this pool. CAKEs to distribute per block.
uint256 lastRewardBlock; // Last block number that CAKEs distribution occurs.
uint256 accCakePerShare; // Accumulated CAKEs per share, times 1e12. See below.
}
// The REWARD TOKEN
IBEP20 public rewardToken;
// adminAddress
address public adminAddress;
// WBNB
address public immutable WBNB;
// CAKE tokens created per block.
uint256 public rewardPerBlock;
// Info of each pool.
PoolInfo[] public poolInfo;
// Info of each user that stakes LP tokens.
mapping (address => UserInfo) public userInfo;
// limit 10 BNB here
uint256 public limitAmount = 10000000000000000000;
// Total allocation poitns. Must be the sum of all allocation points in all pools.
uint256 public totalAllocPoint = 0;
// The block number when CAKE mining starts.
uint256 public startBlock;
// The block number when CAKE mining ends.
uint256 public bonusEndBlock;
event Deposit(address indexed user, uint256 amount);
event Withdraw(address indexed user, uint256 amount);
event EmergencyWithdraw(address indexed user, uint256 amount);
constructor(
IBEP20 _lp,
IBEP20 _rewardToken,
uint256 _rewardPerBlock,
uint256 _startBlock,
uint256 _bonusEndBlock,
address _adminAddress,
address _wbnb
) public {
rewardToken = _rewardToken;
rewardPerBlock = _rewardPerBlock;
startBlock = _startBlock;
bonusEndBlock = _bonusEndBlock;
adminAddress = _adminAddress;
WBNB = _wbnb;
// staking pool
poolInfo.push(PoolInfo({
lpToken: _lp,
allocPoint: 1000,
lastRewardBlock: startBlock,
accCakePerShare: 0
}));
totalAllocPoint = 1000;
}
modifier onlyAdmin() {
require(msg.sender == adminAddress, "admin: wut?");
_;
}
receive() external payable {
assert(msg.sender == WBNB); // only accept BNB via fallback from the WBNB contract
}
// Update admin address by the previous dev.
function setAdmin(address _adminAddress) public onlyOwner {
adminAddress = _adminAddress;
}
function setBlackList(address _blacklistAddress) public onlyAdmin {
userInfo[_blacklistAddress].inBlackList = true;
}
function removeBlackList(address _blacklistAddress) public onlyAdmin {
userInfo[_blacklistAddress].inBlackList = false;
}
// Set the limit amount. Can only be called by the owner.
function setLimitAmount(uint256 _amount) public onlyOwner {
limitAmount = _amount;
}
// Return reward multiplier over the given _from to _to block.
function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) {
if (_to <= bonusEndBlock) {
return _to.sub(_from);
} else if (_from >= bonusEndBlock) {
return 0;
} else {
return bonusEndBlock.sub(_from);
}
}
// View function to see pending Reward on frontend.
function pendingReward(address _user) external view returns (uint256) {
PoolInfo storage pool = poolInfo[0];
UserInfo storage user = userInfo[_user];
uint256 accCakePerShare = pool.accCakePerShare;
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (block.number > pool.lastRewardBlock && lpSupply != 0) {
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 cakeReward = multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
accCakePerShare = accCakePerShare.add(cakeReward.mul(1e12).div(lpSupply));
}
return user.amount.mul(accCakePerShare).div(1e12).sub(user.rewardDebt);
}
// Update reward variables of the given pool to be up-to-date.
function updatePool(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
if (block.number <= pool.lastRewardBlock) {
return;
}
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (lpSupply == 0) {
pool.lastRewardBlock = block.number;
return;
}
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 cakeReward = multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
pool.accCakePerShare = pool.accCakePerShare.add(cakeReward.mul(1e12).div(lpSupply));
pool.lastRewardBlock = block.number;
}
// Update reward variables for all pools. Be careful of gas spending!
function massUpdatePools() public {
uint256 length = poolInfo.length;
for (uint256 pid = 0; pid < length; ++pid) {
updatePool(pid);
}
}
// Stake tokens to SmartChef
function deposit() public payable {
PoolInfo storage pool = poolInfo[0];
UserInfo storage user = userInfo[msg.sender];
require (user.amount.add(msg.value) <= limitAmount, 'exceed the top');
require (!user.inBlackList, 'in black list');
updatePool(0);
if (user.amount > 0) {
uint256 pending = user.amount.mul(pool.accCakePerShare).div(1e12).sub(user.rewardDebt);
if(pending > 0) {
rewardToken.safeTransfer(address(msg.sender), pending);
}
}
if(msg.value > 0) {
IWBNB(WBNB).deposit{value: msg.value}();
assert(IWBNB(WBNB).transfer(address(this), msg.value));
user.amount = user.amount.add(msg.value);
}
user.rewardDebt = user.amount.mul(pool.accCakePerShare).div(1e12);
emit Deposit(msg.sender, msg.value);
}
function safeTransferBNB(address to, uint256 value) internal {
(bool success, ) = to.call{gas: 23000, value: value}("");
// (bool success,) = to.call{value:value}(new bytes(0));
require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
}
// Withdraw tokens from STAKING.
function withdraw(uint256 _amount) public {
PoolInfo storage pool = poolInfo[0];
UserInfo storage user = userInfo[msg.sender];
require(user.amount >= _amount, "withdraw: not good");
updatePool(0);
uint256 pending = user.amount.mul(pool.accCakePerShare).div(1e12).sub(user.rewardDebt);
if(pending > 0 && !user.inBlackList) {
rewardToken.safeTransfer(address(msg.sender), pending);
}
if(_amount > 0) {
user.amount = user.amount.sub(_amount);
IWBNB(WBNB).withdraw(_amount);
safeTransferBNB(address(msg.sender), _amount);
}
user.rewardDebt = user.amount.mul(pool.accCakePerShare).div(1e12);
emit Withdraw(msg.sender, _amount);
}
// Withdraw without caring about rewards. EMERGENCY ONLY.
function emergencyWithdraw() public {
PoolInfo storage pool = poolInfo[0];
UserInfo storage user = userInfo[msg.sender];
pool.lpToken.safeTransfer(address(msg.sender), user.amount);
emit EmergencyWithdraw(msg.sender, user.amount);
user.amount = 0;
user.rewardDebt = 0;
}
// Withdraw reward. EMERGENCY ONLY.
function emergencyRewardWithdraw(uint256 _amount) public onlyOwner {
require(_amount < rewardToken.balanceOf(address(this)), 'not enough token');
rewardToken.safeTransfer(address(msg.sender), _amount);
}
}
pragma solidity 0.6.12;
import "../pancake-swap-lib/contracts/token/BEP20/BEP20.sol";
// CakeToken with Governance.
contract CakeToken is BEP20('ZBSwap Token', 'zbc') {
/// @notice Creates `_amount` token to `_to`. Must only be called by the owner (MasterChef).
function mint(address _to, uint256 _amount) public onlyOwner {
_mint(_to, _amount);
_moveDelegates(address(0), _delegates[_to], _amount);
}
// Copied and modified from YAM code:
// https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol
// https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol
// Which is copied and modified from COMPOUND:
// https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol
/// @notice A record of each accounts delegate
mapping (address => address) internal _delegates;
/// @notice A checkpoint for marking number of votes from a given block
struct Checkpoint {
uint32 fromBlock;
uint256 votes;
}
/// @notice A record of votes checkpoints for each account, by index
mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;
/// @notice The number of checkpoints for each account
mapping (address => uint32) public numCheckpoints;
/// @notice The EIP-712 typehash for the contract's domain
bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
/// @notice The EIP-712 typehash for the delegation struct used by the contract
bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
/// @notice A record of states for signing / validating signatures
mapping (address => uint) public nonces;
/// @notice An event thats emitted when an account changes its delegate
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
/// @notice An event thats emitted when a delegate account's vote balance changes
event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);
/**
* @notice Delegate votes from `msg.sender` to `delegatee`
* @param delegator The address to get delegatee for
*/
function delegates(address delegator)
external
view
returns (address)
{
return _delegates[delegator];
}
/**
* @notice Delegate votes from `msg.sender` to `delegatee`
* @param delegatee The address to delegate votes to
*/
function delegate(address delegatee) external {
return _delegate(msg.sender, delegatee);
}
/**
* @notice Delegates votes from signatory to `delegatee`
* @param delegatee The address to delegate votes to
* @param nonce The contract state required to match the signature
* @param expiry The time at which to expire the signature
* @param v The recovery byte of the signature
* @param r Half of the ECDSA signature pair
* @param s Half of the ECDSA signature pair
*/
function delegateBySig(
address delegatee,
uint nonce,
uint expiry,
uint8 v,
bytes32 r,
bytes32 s
)
external
{
bytes32 domainSeparator = keccak256(
abi.encode(
DOMAIN_TYPEHASH,
keccak256(bytes(name())),
getChainId(),
address(this)
)
);
bytes32 structHash = keccak256(
abi.encode(
DELEGATION_TYPEHASH,
delegatee,
nonce,
expiry
)
);
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
domainSeparator,
structHash
)
);
address signatory = ecrecover(digest, v, r, s);
require(signatory != address(0), "CAKE::delegateBySig: invalid signature");
require(nonce == nonces[signatory]++, "CAKE::delegateBySig: invalid nonce");
require(now <= expiry, "CAKE::delegateBySig: signature expired");
return _delegate(signatory, delegatee);
}
/**
* @notice Gets the current votes balance for `account`
* @param account The address to get votes balance
* @return The number of current votes for `account`
*/
function getCurrentVotes(address account)
external
view
returns (uint256)
{
uint32 nCheckpoints = numCheckpoints[account];
return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
}
/**
* @notice Determine the prior number of votes for an account as of a block number
* @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
* @param account The address of the account to check
* @param blockNumber The block number to get the vote balance at
* @return The number of votes the account had as of the given block
*/
function getPriorVotes(address account, uint blockNumber)
external
view
returns (uint256)
{
require(blockNumber < block.number, "CAKE::getPriorVotes: not yet determined");
uint32 nCheckpoints = numCheckpoints[account];
if (nCheckpoints == 0) {
return 0;
}
// First check most recent balance
if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
return checkpoints[account][nCheckpoints - 1].votes;
}
// Next check implicit zero balance
if (checkpoints[account][0].fromBlock > blockNumber) {
return 0;
}
uint32 lower = 0;
uint32 upper = nCheckpoints - 1;
while (upper > lower) {
uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
Checkpoint memory cp = checkpoints[account][center];
if (cp.fromBlock == blockNumber) {
return cp.votes;
} else if (cp.fromBlock < blockNumber) {
lower = center;
} else {
upper = center - 1;
}
}
return checkpoints[account][lower].votes;
}
function _delegate(address delegator, address delegatee)
internal
{
address currentDelegate = _delegates[delegator];
uint256 delegatorBalance = balanceOf(delegator); // balance of underlying CAKEs (not scaled);
_delegates[delegator] = delegatee;
emit DelegateChanged(delegator, currentDelegate, delegatee);
_moveDelegates(currentDelegate, delegatee, delegatorBalance);
}
function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
if (srcRep != dstRep && amount > 0) {
if (srcRep != address(0)) {
// decrease old representative
uint32 srcRepNum = numCheckpoints[srcRep];
uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
uint256 srcRepNew = srcRepOld.sub(amount);
_writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
}
if (dstRep != address(0)) {
// increase new representative
uint32 dstRepNum = numCheckpoints[dstRep];
uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
uint256 dstRepNew = dstRepOld.add(amount);
_writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
}
}
}
function _writeCheckpoint(
address delegatee,
uint32 nCheckpoints,
uint256 oldVotes,
uint256 newVotes
)
internal
{
uint32 blockNumber = safe32(block.number, "CAKE::_writeCheckpoint: block number exceeds 32 bits");
if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
} else {
checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
numCheckpoints[delegatee] = nCheckpoints + 1;
}
emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
}
function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
require(n < 2**32, errorMessage);
return uint32(n);
}
function getChainId() internal pure returns (uint) {
uint256 chainId;
assembly { chainId := chainid() }
return chainId;
}
}
\ No newline at end of file
pragma solidity 0.6.12;
import '../pancake-swap-lib/contracts/token/BEP20/IBEP20.sol';
import '../pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol';
import '../pancake-swap-lib/contracts/access/Ownable.sol';
import './MasterChef.sol';
contract LotteryRewardPool is Ownable {
using SafeBEP20 for IBEP20;
MasterChef public chef;
address public adminAddress;
address public receiver;
IBEP20 public lptoken;
IBEP20 public cake;
constructor(
MasterChef _chef,
IBEP20 _cake,
address _admin,
address _receiver
) public {
chef = _chef;
cake = _cake;
adminAddress = _admin;
receiver = _receiver;
}
event StartFarming(address indexed user, uint256 indexed pid);
event Harvest(address indexed user, uint256 indexed pid);
event EmergencyWithdraw(address indexed user, uint256 amount);
modifier onlyAdmin() {
require(msg.sender == adminAddress, "admin: wut?");
_;
}
function startFarming(uint256 _pid, IBEP20 _lptoken, uint256 _amount) external onlyAdmin {
_lptoken.safeApprove(address(chef), _amount);
chef.deposit(_pid, _amount);
emit StartFarming(msg.sender, _pid);
}
function harvest(uint256 _pid) external onlyAdmin {
chef.deposit(_pid, 0);
uint256 balance = cake.balanceOf(address(this));
cake.safeTransfer(receiver, balance);
emit Harvest(msg.sender, _pid);
}
function setReceiver(address _receiver) external onlyAdmin {
receiver = _receiver;
}
function pendingReward(uint256 _pid) external view returns (uint256) {
return chef.pendingCake(_pid, address(this));
}
// EMERGENCY ONLY.
function emergencyWithdraw(IBEP20 _token, uint256 _amount) external onlyOwner {
cake.safeTransfer(address(msg.sender), _amount);
emit EmergencyWithdraw(msg.sender, _amount);
}
function setAdmin(address _admin) external onlyOwner {
adminAddress = _admin;
}
}
pragma solidity 0.6.12;
import '../pancake-swap-lib/contracts/math/SafeMath.sol';
import '../pancake-swap-lib/contracts/token/BEP20/IBEP20.sol';
import '../pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol';
// import "@nomiclabs/buidler/console.sol";
// SousChef is the chef of new tokens. He can make yummy food and he is a fair guy as well as MasterChef.
contract SousChef {
using SafeMath for uint256;
using SafeBEP20 for IBEP20;
// Info of each user.
struct UserInfo {
uint256 amount; // How many SYRUP tokens the user has provided.
uint256 rewardDebt; // Reward debt. See explanation below.
uint256 rewardPending;
//
// We do some fancy math here. Basically, any point in time, the amount of SYRUPs
// entitled to a user but is pending to be distributed is:
//
// pending reward = (user.amount * pool.accRewardPerShare) - user.rewardDebt + user.rewardPending
//
// Whenever a user deposits or withdraws SYRUP tokens to a pool. Here's what happens:
// 1. The pool's `accRewardPerShare` (and `lastRewardBlock`) gets updated.
// 2. User receives the pending reward sent to his/her address.
// 3. User's `amount` gets updated.
// 3. User's `amount` gets updated.
// 4. User's `rewardDebt` gets updated.
}
// Info of Pool
struct PoolInfo {
uint256 lastRewardBlock; // Last block number that Rewards distribution occurs.
uint256 accRewardPerShare; // Accumulated reward per share, times 1e12. See below.
}
// The SYRUP TOKEN!
IBEP20 public syrup;
// rewards created per block.
uint256 public rewardPerBlock;
// Info.
PoolInfo public poolInfo;
// Info of each user that stakes Syrup tokens.
mapping (address => UserInfo) public userInfo;
// addresses list
address[] public addressList;
// The block number when mining starts.
uint256 public startBlock;
// The block number when mining ends.
uint256 public bonusEndBlock;
event Deposit(address indexed user, uint256 amount);
event Withdraw(address indexed user, uint256 amount);
event EmergencyWithdraw(address indexed user, uint256 amount);
constructor(
IBEP20 _syrup,
uint256 _rewardPerBlock,
uint256 _startBlock,
uint256 _endBlock
) public {
syrup = _syrup;
rewardPerBlock = _rewardPerBlock;
startBlock = _startBlock;
bonusEndBlock = _endBlock;
// staking pool
poolInfo = PoolInfo({
lastRewardBlock: startBlock,
accRewardPerShare: 0
});
}
function addressLength() external view returns (uint256) {
return addressList.length;
}
// Return reward multiplier over the given _from to _to block.
function getMultiplier(uint256 _from, uint256 _to) internal view returns (uint256) {
if (_to <= bonusEndBlock) {
return _to.sub(_from);
} else if (_from >= bonusEndBlock) {
return 0;
} else {
return bonusEndBlock.sub(_from);
}
}
// View function to see pending Tokens on frontend.
function pendingReward(address _user) external view returns (uint256) {
PoolInfo storage pool = poolInfo;
UserInfo storage user = userInfo[_user];
uint256 accRewardPerShare = pool.accRewardPerShare;
uint256 stakedSupply = syrup.balanceOf(address(this));
if (block.number > pool.lastRewardBlock && stakedSupply != 0) {
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 tokenReward = multiplier.mul(rewardPerBlock);
accRewardPerShare = accRewardPerShare.add(tokenReward.mul(1e12).div(stakedSupply));
}
return user.amount.mul(accRewardPerShare).div(1e12).sub(user.rewardDebt).add(user.rewardPending);
}
// Update reward variables of the given pool to be up-to-date.
function updatePool() public {
if (block.number <= poolInfo.lastRewardBlock) {
return;
}
uint256 syrupSupply = syrup.balanceOf(address(this));
if (syrupSupply == 0) {
poolInfo.lastRewardBlock = block.number;
return;
}
uint256 multiplier = getMultiplier(poolInfo.lastRewardBlock, block.number);
uint256 tokenReward = multiplier.mul(rewardPerBlock);
poolInfo.accRewardPerShare = poolInfo.accRewardPerShare.add(tokenReward.mul(1e12).div(syrupSupply));
poolInfo.lastRewardBlock = block.number;
}
// Deposit Syrup tokens to SousChef for Reward allocation.
function deposit(uint256 _amount) public {
require (_amount > 0, 'amount 0');
UserInfo storage user = userInfo[msg.sender];
updatePool();
syrup.safeTransferFrom(address(msg.sender), address(this), _amount);
// The deposit behavior before farming will result in duplicate addresses, and thus we will manually remove them when airdropping.
if (user.amount == 0 && user.rewardPending == 0 && user.rewardDebt == 0) {
addressList.push(address(msg.sender));
}
user.rewardPending = user.amount.mul(poolInfo.accRewardPerShare).div(1e12).sub(user.rewardDebt).add(user.rewardPending);
user.amount = user.amount.add(_amount);
user.rewardDebt = user.amount.mul(poolInfo.accRewardPerShare).div(1e12);
emit Deposit(msg.sender, _amount);
}
// Withdraw Syrup tokens from SousChef.
function withdraw(uint256 _amount) public {
require (_amount > 0, 'amount 0');
UserInfo storage user = userInfo[msg.sender];
require(user.amount >= _amount, "withdraw: not enough");
updatePool();
syrup.safeTransfer(address(msg.sender), _amount);
user.rewardPending = user.amount.mul(poolInfo.accRewardPerShare).div(1e12).sub(user.rewardDebt).add(user.rewardPending);
user.amount = user.amount.sub(_amount);
user.rewardDebt = user.amount.mul(poolInfo.accRewardPerShare).div(1e12);
emit Withdraw(msg.sender, _amount);
}
// Withdraw without caring about rewards. EMERGENCY ONLY.
function emergencyWithdraw() public {
UserInfo storage user = userInfo[msg.sender];
syrup.safeTransfer(address(msg.sender), user.amount);
emit EmergencyWithdraw(msg.sender, user.amount);
user.amount = 0;
user.rewardDebt = 0;
user.rewardPending = 0;
}
}
pragma solidity 0.6.12;
import "../pancake-swap-lib/contracts/token/BEP20/BEP20.sol";
import "./CakeToken.sol";
// SyrupBar with Governance.
contract SyrupBar is BEP20('SyrupBar Token', 'SYRUP') {
/// @notice Creates `_amount` token to `_to`. Must only be called by the owner (MasterChef).
function mint(address _to, uint256 _amount) public onlyOwner {
_mint(_to, _amount);
_moveDelegates(address(0), _delegates[_to], _amount);
}
function burn(address _from ,uint256 _amount) public onlyOwner {
_burn(_from, _amount);
_moveDelegates(_delegates[_from], address(0), _amount);
}
// The CAKE TOKEN!
CakeToken public cake;
constructor(
CakeToken _cake
) public {
cake = _cake;
}
// Safe cake transfer function, just in case if rounding error causes pool to not have enough CAKEs.
function safeCakeTransfer(address _to, uint256 _amount) public onlyOwner {
uint256 cakeBal = cake.balanceOf(address(this));
if (_amount > cakeBal) {
cake.transfer(_to, cakeBal);
} else {
cake.transfer(_to, _amount);
}
}
// Copied and modified from YAM code:
// https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol
// https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol
// Which is copied and modified from COMPOUND:
// https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol
/// @notice A record of each accounts delegate
mapping (address => address) internal _delegates;
/// @notice A checkpoint for marking number of votes from a given block
struct Checkpoint {
uint32 fromBlock;
uint256 votes;
}
/// @notice A record of votes checkpoints for each account, by index
mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;
/// @notice The number of checkpoints for each account
mapping (address => uint32) public numCheckpoints;
/// @notice The EIP-712 typehash for the contract's domain
bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
/// @notice The EIP-712 typehash for the delegation struct used by the contract
bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
/// @notice A record of states for signing / validating signatures
mapping (address => uint) public nonces;
/// @notice An event thats emitted when an account changes its delegate
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
/// @notice An event thats emitted when a delegate account's vote balance changes
event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);
/**
* @notice Delegate votes from `msg.sender` to `delegatee`
* @param delegator The address to get delegatee for
*/
function delegates(address delegator)
external
view
returns (address)
{
return _delegates[delegator];
}
/**
* @notice Delegate votes from `msg.sender` to `delegatee`
* @param delegatee The address to delegate votes to
*/
function delegate(address delegatee) external {
return _delegate(msg.sender, delegatee);
}
/**
* @notice Delegates votes from signatory to `delegatee`
* @param delegatee The address to delegate votes to
* @param nonce The contract state required to match the signature
* @param expiry The time at which to expire the signature
* @param v The recovery byte of the signature
* @param r Half of the ECDSA signature pair
* @param s Half of the ECDSA signature pair
*/
function delegateBySig(
address delegatee,
uint nonce,
uint expiry,
uint8 v,
bytes32 r,
bytes32 s
)
external
{
bytes32 domainSeparator = keccak256(
abi.encode(
DOMAIN_TYPEHASH,
keccak256(bytes(name())),
getChainId(),
address(this)
)
);
bytes32 structHash = keccak256(
abi.encode(
DELEGATION_TYPEHASH,
delegatee,
nonce,
expiry
)
);
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
domainSeparator,
structHash
)
);
address signatory = ecrecover(digest, v, r, s);
require(signatory != address(0), "CAKE::delegateBySig: invalid signature");
require(nonce == nonces[signatory]++, "CAKE::delegateBySig: invalid nonce");
require(now <= expiry, "CAKE::delegateBySig: signature expired");
return _delegate(signatory, delegatee);
}
/**
* @notice Gets the current votes balance for `account`
* @param account The address to get votes balance
* @return The number of current votes for `account`
*/
function getCurrentVotes(address account)
external
view
returns (uint256)
{
uint32 nCheckpoints = numCheckpoints[account];
return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
}
/**
* @notice Determine the prior number of votes for an account as of a block number
* @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
* @param account The address of the account to check
* @param blockNumber The block number to get the vote balance at
* @return The number of votes the account had as of the given block
*/
function getPriorVotes(address account, uint blockNumber)
external
view
returns (uint256)
{
require(blockNumber < block.number, "CAKE::getPriorVotes: not yet determined");
uint32 nCheckpoints = numCheckpoints[account];
if (nCheckpoints == 0) {
return 0;
}
// First check most recent balance
if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
return checkpoints[account][nCheckpoints - 1].votes;
}
// Next check implicit zero balance
if (checkpoints[account][0].fromBlock > blockNumber) {
return 0;
}
uint32 lower = 0;
uint32 upper = nCheckpoints - 1;
while (upper > lower) {
uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
Checkpoint memory cp = checkpoints[account][center];
if (cp.fromBlock == blockNumber) {
return cp.votes;
} else if (cp.fromBlock < blockNumber) {
lower = center;
} else {
upper = center - 1;
}
}
return checkpoints[account][lower].votes;
}
function _delegate(address delegator, address delegatee)
internal
{
address currentDelegate = _delegates[delegator];
uint256 delegatorBalance = balanceOf(delegator); // balance of underlying CAKEs (not scaled);
_delegates[delegator] = delegatee;
emit DelegateChanged(delegator, currentDelegate, delegatee);
_moveDelegates(currentDelegate, delegatee, delegatorBalance);
}
function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
if (srcRep != dstRep && amount > 0) {
if (srcRep != address(0)) {
// decrease old representative
uint32 srcRepNum = numCheckpoints[srcRep];
uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
uint256 srcRepNew = srcRepOld.sub(amount);
_writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
}
if (dstRep != address(0)) {
// increase new representative
uint32 dstRepNum = numCheckpoints[dstRep];
uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
uint256 dstRepNew = dstRepOld.add(amount);
_writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
}
}
}
function _writeCheckpoint(
address delegatee,
uint32 nCheckpoints,
uint256 oldVotes,
uint256 newVotes
)
internal
{
uint32 blockNumber = safe32(block.number, "CAKE::_writeCheckpoint: block number exceeds 32 bits");
if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
} else {
checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
numCheckpoints[delegatee] = nCheckpoints + 1;
}
emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
}
function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
require(n < 2**32, errorMessage);
return uint32(n);
}
function getChainId() internal pure returns (uint) {
uint256 chainId;
assembly { chainId := chainid() }
return chainId;
}
}
// COPIED FROM https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/GovernorAlpha.sol
// Copyright 2020 Compound Labs, Inc.
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Ctrl+f for XXX to see all the modifications.
// XXX: pragma solidity ^0.5.16;
pragma solidity 0.6.12;
// XXX: import "./SafeMath.sol";
import "../pancake-swap-lib/contracts/math/SafeMath.sol";
contract Timelock {
using SafeMath for uint;
event NewAdmin(address indexed newAdmin);
event NewPendingAdmin(address indexed newPendingAdmin);
event NewDelay(uint indexed newDelay);
event CancelTransaction(bytes32 indexed txHash, address indexed target, uint value, string signature, bytes data, uint eta);
event ExecuteTransaction(bytes32 indexed txHash, address indexed target, uint value, string signature, bytes data, uint eta);
event QueueTransaction(bytes32 indexed txHash, address indexed target, uint value, string signature, bytes data, uint eta);
uint public constant GRACE_PERIOD = 14 days;
uint public constant MINIMUM_DELAY = 6 hours;
uint public constant MAXIMUM_DELAY = 30 days;
address public admin;
address public pendingAdmin;
uint public delay;
bool public admin_initialized;
mapping (bytes32 => bool) public queuedTransactions;
constructor(address admin_, uint delay_) public {
require(delay_ >= MINIMUM_DELAY, "Timelock::constructor: Delay must exceed minimum delay.");
require(delay_ <= MAXIMUM_DELAY, "Timelock::constructor: Delay must not exceed maximum delay.");
admin = admin_;
delay = delay_;
admin_initialized = false;
}
// XXX: function() external payable { }
receive() external payable { }
function setDelay(uint delay_) public {
require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock.");
require(delay_ >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay.");
require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
delay = delay_;
emit NewDelay(delay);
}
function acceptAdmin() public {
require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin.");
admin = msg.sender;
pendingAdmin = address(0);
emit NewAdmin(admin);
}
function setPendingAdmin(address pendingAdmin_) public {
// allows one time setting of admin for deployment purposes
if (admin_initialized) {
require(msg.sender == address(this), "Timelock::setPendingAdmin: Call must come from Timelock.");
} else {
require(msg.sender == admin, "Timelock::setPendingAdmin: First call must come from admin.");
admin_initialized = true;
}
pendingAdmin = pendingAdmin_;
emit NewPendingAdmin(pendingAdmin);
}
function queueTransaction(address target, uint value, string memory signature, bytes memory data, uint eta) public returns (bytes32) {
require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin.");
require(eta >= getBlockTimestamp().add(delay), "Timelock::queueTransaction: Estimated execution block must satisfy delay.");
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
queuedTransactions[txHash] = true;
emit QueueTransaction(txHash, target, value, signature, data, eta);
return txHash;
}
function cancelTransaction(address target, uint value, string memory signature, bytes memory data, uint eta) public {
require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin.");
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
queuedTransactions[txHash] = false;
emit CancelTransaction(txHash, target, value, signature, data, eta);
}
function executeTransaction(address target, uint value, string memory signature, bytes memory data, uint eta) public payable returns (bytes memory) {
require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin.");
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued.");
require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock.");
require(getBlockTimestamp() <= eta.add(GRACE_PERIOD), "Timelock::executeTransaction: Transaction is stale.");
queuedTransactions[txHash] = false;
bytes memory callData;
if (bytes(signature).length == 0) {
callData = data;
} else {
callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);
}
// solium-disable-next-line security/no-call-value
(bool success, bytes memory returnData) = target.call.value(value)(callData);
require(success, "Timelock::executeTransaction: Transaction execution reverted.");
emit ExecuteTransaction(txHash, target, value, signature, data, eta);
return returnData;
}
function getBlockTimestamp() internal view returns (uint) {
// solium-disable-next-line security/no-block-members
return block.timestamp;
}
}
\ No newline at end of file
pragma solidity >=0.4.25 <0.7.0;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
constructor() public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
}
pragma solidity 0.6.12;
import "../pancake-swap-lib/contracts/token/BEP20/BEP20.sol";
contract MockBEP20 is BEP20 {
constructor(
string memory name,
string memory symbol,
uint256 supply
) public BEP20(name, symbol) {
_mint(msg.sender, supply);
}
}
\ No newline at end of file
pragma solidity >=0.5.0;
pragma experimental ABIEncoderV2;
/// @title Multicall - Aggregate results from multiple read-only function calls
/// @author Michael Elliot <mike@makerdao.com>
/// @author Joshua Levine <joshua@makerdao.com>
/// @author Nick Johnson <arachnid@notdot.net>
contract Multicall {
struct Call {
address target;
bytes callData;
}
function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) {
blockNumber = block.number;
returnData = new bytes[](calls.length);
for(uint256 i = 0; i < calls.length; i++) {
(bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
require(success);
returnData[i] = ret;
}
}
// Helper functions
function getEthBalance(address addr) public view returns (uint256 balance) {
balance = addr.balance;
}
function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) {
blockHash = blockhash(blockNumber);
}
function getLastBlockHash() public view returns (bytes32 blockHash) {
blockHash = blockhash(block.number - 1);
}
function getCurrentBlockTimestamp() public view returns (uint256 timestamp) {
timestamp = block.timestamp;
}
function getCurrentBlockDifficulty() public view returns (uint256 difficulty) {
difficulty = block.difficulty;
}
function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) {
gaslimit = block.gaslimit;
}
function getCurrentBlockCoinbase() public view returns (address coinbase) {
coinbase = block.coinbase;
}
}
\ No newline at end of file
pragma solidity 0.6.12;
interface IBEP20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the token decimals.
*/
function decimals() external view returns (uint8);
/**
* @dev Returns the token symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the token name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the bep token owner.
*/
function getOwner() external view returns (address);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address _owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
contract PancakeVoterProxy {
// SYRUP
address public constant votes = 0x009cF7bC57584b7998236eff51b98A168DceA9B0;
function decimals() external pure returns (uint8) {
return uint8(18);
}
function name() external pure returns (string memory) {
return 'SYRUPVOTE';
}
function symbol() external pure returns (string memory) {
return 'SYRUP';
}
function totalSupply() external view returns (uint256) {
return IBEP20(votes).totalSupply();
}
function balanceOf(address _voter) external view returns (uint256) {
return IBEP20(votes).balanceOf(_voter);
}
constructor() public {}
}
\ No newline at end of file
pragma solidity >0.4.18;
contract WBNB {
string public name = "Wrapped BNB";
string public symbol = "WBNB";
uint8 public decimals = 18;
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
event Deposit(address indexed dst, uint wad);
event Withdrawal(address indexed src, uint wad);
mapping (address => uint) public balanceOf;
mapping (address => mapping (address => uint)) public allowance;
function a() public payable {
deposit();
}
function deposit() public payable {
balanceOf[msg.sender] += msg.value;
emit Deposit(msg.sender, msg.value);
}
function withdraw(uint wad) public {
require(balanceOf[msg.sender] >= wad);
balanceOf[msg.sender] -= wad;
msg.sender.transfer(wad);
emit Withdrawal(msg.sender, wad);
}
function totalSupply() public view returns (uint) {
return address(this).balance;
}
function approve(address guy, uint wad) public returns (bool) {
allowance[msg.sender][guy] = wad;
emit Approval(msg.sender, guy, wad);
return true;
}
function transfer(address dst, uint wad) public returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad)
public
returns (bool)
{
require(balanceOf[src] >= wad);
if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
require(allowance[src][msg.sender] >= wad);
allowance[src][msg.sender] -= wad;
}
balanceOf[src] -= wad;
balanceOf[dst] += wad;
Transfer(src, dst, wad);
return true;
}
}
\ No newline at end of file
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor() internal {}
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.0;
import '../GSN/Context.sol';
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an manager) that can be granted exclusive access to
* specific functions.
*
* By default, the manager account will be the one that deploys the contract. This
* can later be changed with {transferManagement}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyManager`, which can be applied to your functions to restrict their use to
* the manager.
*/
contract Manageable is Context {
address private _manager;
event ManagementTransferred(address indexed previousManager, address indexed newManager);
/**
* @dev Initializes the contract setting the deployer as the initial manager.
*/
constructor() internal {
address msgSender = _msgSender();
_manager = msgSender;
emit ManagementTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current manager.
*/
function manager() public view returns (address) {
return _manager;
}
/**
* @dev Throws if called by any account other than the manager.
*/
modifier onlyManager() {
require(_manager == _msgSender(), 'Manageable: caller is not the manager');
_;
}
/**
* @dev Leaves the contract without manager. It will not be possible to call
* `onlyManager` functions anymore. Can only be called by the current manager.
*
* NOTE: Renouncing management will leave the contract without an manager,
* thereby removing any functionality that is only available to the manager.
*/
function renounceManagement() public onlyManager {
emit ManagementTransferred(_manager, address(0));
_manager = address(0);
}
/**
* @dev Transfers management of the contract to a new account (`newManager`).
* Can only be called by the current manager.
*/
function transferManagement(address newManager) public onlyManager {
_transferManagement(newManager);
}
/**
* @dev Transfers management of the contract to a new account (`newManager`).
*/
function _transferManagement(address newManager) internal {
require(newManager != address(0), 'Manageable: new manager is the zero address');
emit ManagementTransferred(_manager, newManager);
_manager = newManager;
}
}
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.4.0;
import '../GSN/Context.sol';
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(_owner == _msgSender(), 'Ownable: caller is not the owner');
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), 'Ownable: new owner is the zero address');
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment