github.com/ChainSafe/chainbridge-core@v1.4.2/chains/evm/cli/local/deploy.go (about)

     1  // Copyright 2021 ChainSafe Systems
     2  // SPDX-License-Identifier: LGPL-3.0-only
     3  
     4  package local
     5  
     6  import (
     7  	"math/big"
     8  
     9  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls"
    10  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls/contracts/bridge"
    11  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls/contracts/centrifuge"
    12  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls/contracts/erc20"
    13  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls/contracts/erc721"
    14  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls/contracts/generic"
    15  	evmgaspricer "github.com/ChainSafe/chainbridge-core/chains/evm/calls/evmgaspricer"
    16  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls/transactor"
    17  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls/transactor/signAndSend"
    18  	"github.com/ChainSafe/chainbridge-core/keystore"
    19  	"github.com/ChainSafe/chainbridge-core/types"
    20  	"github.com/ethereum/go-ethereum/common"
    21  	"github.com/rs/zerolog/log"
    22  )
    23  
    24  var AliceKp = keystore.TestKeyRing.EthereumKeys[keystore.AliceKey]
    25  var BobKp = keystore.TestKeyRing.EthereumKeys[keystore.BobKey]
    26  var EveKp = keystore.TestKeyRing.EthereumKeys[keystore.EveKey]
    27  
    28  var (
    29  	DefaultRelayerAddresses = []common.Address{
    30  		common.HexToAddress(keystore.TestKeyRing.EthereumKeys[keystore.AliceKey].Address()),
    31  		common.HexToAddress(keystore.TestKeyRing.EthereumKeys[keystore.BobKey].Address()),
    32  		common.HexToAddress(keystore.TestKeyRing.EthereumKeys[keystore.CharlieKey].Address()),
    33  		common.HexToAddress(keystore.TestKeyRing.EthereumKeys[keystore.DaveKey].Address()),
    34  		common.HexToAddress(keystore.TestKeyRing.EthereumKeys[keystore.EveKey].Address()),
    35  	}
    36  )
    37  
    38  type BridgeConfig struct {
    39  	BridgeAddr common.Address
    40  
    41  	Erc20Addr        common.Address
    42  	Erc20HandlerAddr common.Address
    43  	Erc20ResourceID  types.ResourceID
    44  
    45  	AssetStoreAddr     common.Address
    46  	GenericHandlerAddr common.Address
    47  	GenericResourceID  types.ResourceID
    48  
    49  	Erc721Addr        common.Address
    50  	Erc721HandlerAddr common.Address
    51  	Erc721ResourceID  types.ResourceID
    52  
    53  	ResourceIDERC721  string
    54  	ResourceIDGeneric string
    55  }
    56  
    57  type EVMClient interface {
    58  	calls.ContractCallerDispatcher
    59  	evmgaspricer.GasPriceClient
    60  }
    61  
    62  func SetupEVMBridge(
    63  	ethClient EVMClient,
    64  	fabric calls.TxFabric,
    65  	domainID uint8,
    66  	threshold *big.Int,
    67  	mintTo common.Address,
    68  	relayerAddresses []common.Address,
    69  ) (BridgeConfig, error) {
    70  	staticGasPricer := evmgaspricer.NewStaticGasPriceDeterminant(ethClient, nil)
    71  	t := signAndSend.NewSignAndSendTransactor(fabric, staticGasPricer, ethClient)
    72  
    73  	bridgeContract := bridge.NewBridgeContract(ethClient, common.Address{}, t)
    74  	bridgeContractAddress, err := bridgeContract.DeployContract(
    75  		domainID, relayerAddresses, threshold, big.NewInt(0), big.NewInt(100),
    76  	)
    77  	if err != nil {
    78  		return BridgeConfig{}, err
    79  	}
    80  
    81  	erc721Contract, erc721ContractAddress, erc721HandlerContractAddress, err := deployErc721(
    82  		ethClient, t, bridgeContractAddress,
    83  	)
    84  	if err != nil {
    85  		return BridgeConfig{}, err
    86  	}
    87  
    88  	erc20Contract, erc20ContractAddress, erc20HandlerContractAddress, err := deployErc20(
    89  		ethClient, t, bridgeContractAddress,
    90  	)
    91  
    92  	if err != nil {
    93  		return BridgeConfig{}, err
    94  	}
    95  
    96  	genericHandlerAddress, assetStoreAddress, err := deployGeneric(ethClient, t, bridgeContractAddress)
    97  	if err != nil {
    98  		return BridgeConfig{}, err
    99  	}
   100  
   101  	resourceIDERC20 := calls.SliceTo32Bytes(common.LeftPadBytes([]byte{0}, 31))
   102  	resourceIDGenericHandler := calls.SliceTo32Bytes(common.LeftPadBytes([]byte{1}, 31))
   103  	resourceIDERC721 := calls.SliceTo32Bytes(common.LeftPadBytes([]byte{2}, 31))
   104  
   105  	conf := BridgeConfig{
   106  		BridgeAddr: bridgeContractAddress,
   107  
   108  		Erc20Addr:        erc20ContractAddress,
   109  		Erc20HandlerAddr: erc20HandlerContractAddress,
   110  		Erc20ResourceID:  resourceIDERC20,
   111  
   112  		GenericHandlerAddr: genericHandlerAddress,
   113  		AssetStoreAddr:     assetStoreAddress,
   114  		GenericResourceID:  resourceIDGenericHandler,
   115  
   116  		Erc721Addr:        erc721ContractAddress,
   117  		Erc721HandlerAddr: erc721HandlerContractAddress,
   118  		Erc721ResourceID:  resourceIDERC721,
   119  	}
   120  
   121  	err = SetupERC20Handler(bridgeContract, erc20Contract, mintTo, conf, resourceIDERC20)
   122  	if err != nil {
   123  		return BridgeConfig{}, err
   124  	}
   125  
   126  	err = SetupERC721Handler(bridgeContract, erc721Contract, conf, resourceIDERC721)
   127  	if err != nil {
   128  		return BridgeConfig{}, err
   129  	}
   130  
   131  	err = SetupGenericHandler(bridgeContract, conf, resourceIDGenericHandler)
   132  	if err != nil {
   133  		return BridgeConfig{}, err
   134  	}
   135  
   136  	_, err = bridgeContract.AdminChangeRelayerThreshold(threshold.Uint64(), transactor.TransactOptions{})
   137  	if err != nil {
   138  		return BridgeConfig{}, err
   139  	}
   140  
   141  	log.Debug().Msgf("All deployments and preparations are done")
   142  	return conf, nil
   143  }
   144  
   145  func deployGeneric(
   146  	ethClient EVMClient, t transactor.Transactor, bridgeContractAddress common.Address,
   147  ) (common.Address, common.Address, error) {
   148  	assetStoreContract := centrifuge.NewAssetStoreContract(ethClient, common.Address{}, t)
   149  	assetStoreAddress, err := assetStoreContract.DeployContract()
   150  	if err != nil {
   151  		return common.Address{}, common.Address{}, err
   152  	}
   153  	genericHandlerContract := generic.NewGenericHandlerContract(ethClient, common.Address{}, t)
   154  	genericHandlerAddress, err := genericHandlerContract.DeployContract(bridgeContractAddress)
   155  	if err != nil {
   156  		return common.Address{}, common.Address{}, err
   157  	}
   158  	log.Debug().Msgf(
   159  		"Centrifuge asset store deployed to: %s; \n Generic Handler deployed to: %s",
   160  		assetStoreAddress, genericHandlerAddress,
   161  	)
   162  	return genericHandlerAddress, assetStoreAddress, nil
   163  }
   164  
   165  func deployErc20(
   166  	ethClient EVMClient, t transactor.Transactor, bridgeContractAddress common.Address,
   167  ) (*erc20.ERC20Contract, common.Address, common.Address, error) {
   168  	erc20Contract := erc20.NewERC20Contract(ethClient, common.Address{}, t)
   169  	erc20ContractAddress, err := erc20Contract.DeployContract("Test", "TST")
   170  	if err != nil {
   171  		return nil, common.Address{}, common.Address{}, err
   172  	}
   173  	erc20HandlerContract := erc20.NewERC20HandlerContract(ethClient, common.Address{}, t)
   174  	erc20HandlerContractAddress, err := erc20HandlerContract.DeployContract(bridgeContractAddress)
   175  	if err != nil {
   176  		return nil, common.Address{}, common.Address{}, err
   177  	}
   178  	log.Debug().Msgf(
   179  		"Erc20 deployed to: %s; \n Erc20 Handler deployed to: %s",
   180  		erc20ContractAddress, erc20HandlerContractAddress,
   181  	)
   182  	return erc20Contract, erc20ContractAddress, erc20HandlerContractAddress, nil
   183  }
   184  
   185  func deployErc721(
   186  	ethClient EVMClient, t transactor.Transactor, bridgeContractAddress common.Address,
   187  ) (*erc721.ERC721Contract, common.Address, common.Address, error) {
   188  	erc721Contract := erc721.NewErc721Contract(ethClient, common.Address{}, t)
   189  	erc721ContractAddress, err := erc721Contract.DeployContract("TestERC721", "TST721", "")
   190  	if err != nil {
   191  		return nil, common.Address{}, common.Address{}, err
   192  	}
   193  	erc721HandlerContract := erc721.NewERC721HandlerContract(ethClient, common.Address{}, t)
   194  	erc721HandlerContractAddress, err := erc721HandlerContract.DeployContract(bridgeContractAddress)
   195  	if err != nil {
   196  		return nil, common.Address{}, common.Address{}, err
   197  	}
   198  	log.Debug().Msgf(
   199  		"Erc721 deployed to: %s; \n Erc721 Handler deployed to: %s",
   200  		erc721ContractAddress, erc721HandlerContractAddress,
   201  	)
   202  	return erc721Contract, erc721ContractAddress, erc721HandlerContractAddress, nil
   203  }
   204  
   205  func SetupERC20Handler(
   206  	bridgeContract *bridge.BridgeContract, erc20Contract *erc20.ERC20Contract, mintTo common.Address, conf BridgeConfig, resourceID types.ResourceID,
   207  ) error {
   208  	_, err := bridgeContract.AdminSetResource(
   209  		conf.Erc20HandlerAddr, resourceID, conf.Erc20Addr, transactor.TransactOptions{GasLimit: 2000000},
   210  	)
   211  	if err != nil {
   212  		return err
   213  	}
   214  	// Minting tokens
   215  	tenTokens := big.NewInt(0).Mul(big.NewInt(10), big.NewInt(0).Exp(big.NewInt(10), big.NewInt(18), nil))
   216  	_, err = erc20Contract.MintTokens(mintTo, tenTokens, transactor.TransactOptions{})
   217  	if err != nil {
   218  		return err
   219  	}
   220  	// Approving tokens
   221  	_, err = erc20Contract.ApproveTokens(conf.Erc20HandlerAddr, tenTokens, transactor.TransactOptions{})
   222  	if err != nil {
   223  		return err
   224  	}
   225  	// Adding minter
   226  	_, err = erc20Contract.AddMinter(conf.Erc20HandlerAddr, transactor.TransactOptions{})
   227  	if err != nil {
   228  		return err
   229  	}
   230  	// Set burnable input
   231  	_, err = bridgeContract.SetBurnableInput(conf.Erc20HandlerAddr, conf.Erc20Addr, transactor.TransactOptions{})
   232  	if err != nil {
   233  		return err
   234  	}
   235  	return nil
   236  }
   237  
   238  func SetupGenericHandler(bridgeContract *bridge.BridgeContract, conf BridgeConfig, resourceID types.ResourceID) error {
   239  	_, err := bridgeContract.AdminSetGenericResource(
   240  		conf.GenericHandlerAddr,
   241  		resourceID,
   242  		conf.AssetStoreAddr,
   243  		[4]byte{0x65, 0x4c, 0xf8, 0x8c},
   244  		big.NewInt(0),
   245  		[4]byte{0x65, 0x4c, 0xf8, 0x8c},
   246  		transactor.TransactOptions{GasLimit: 2000000},
   247  	)
   248  	if err != nil {
   249  		return err
   250  	}
   251  	return nil
   252  }
   253  
   254  func SetupERC721Handler(bridgeContract *bridge.BridgeContract, erc721Contract *erc721.ERC721Contract, conf BridgeConfig, resourceID types.ResourceID) error {
   255  	_, err := bridgeContract.AdminSetResource(conf.Erc721HandlerAddr, resourceID, conf.Erc721Addr, transactor.TransactOptions{GasLimit: 2000000})
   256  	if err != nil {
   257  		return err
   258  	}
   259  	// Adding minter
   260  	_, err = erc721Contract.AddMinter(conf.Erc721HandlerAddr, transactor.TransactOptions{})
   261  	if err != nil {
   262  		return err
   263  	}
   264  	// Set burnable input
   265  	_, err = bridgeContract.SetBurnableInput(conf.Erc721HandlerAddr, conf.Erc721Addr, transactor.TransactOptions{})
   266  	if err != nil {
   267  		return err
   268  	}
   269  	return nil
   270  }