diff --git a/cmd/zetae2e/config/config.go b/cmd/zetae2e/config/config.go index c3584dc720..d483a4ea02 100644 --- a/cmd/zetae2e/config/config.go +++ b/cmd/zetae2e/config/config.go @@ -91,6 +91,7 @@ func ExportContractsFromRunner(r *runner.E2ERunner, conf config.Config) config.C conf.Contracts.ZEVM.ETHZRC20Addr = config.DoubleQuotedString(r.ETHZRC20Addr.Hex()) conf.Contracts.ZEVM.ERC20ZRC20Addr = config.DoubleQuotedString(r.ERC20ZRC20Addr.Hex()) conf.Contracts.ZEVM.BTCZRC20Addr = config.DoubleQuotedString(r.BTCZRC20Addr.Hex()) + conf.Contracts.ZEVM.SOLZRC20Addr = config.DoubleQuotedString(r.SOLZRC20Addr.Hex()) conf.Contracts.ZEVM.UniswapFactoryAddr = config.DoubleQuotedString(r.UniswapV2FactoryAddr.Hex()) conf.Contracts.ZEVM.UniswapRouterAddr = config.DoubleQuotedString(r.UniswapV2RouterAddr.Hex()) conf.Contracts.ZEVM.ConnectorZEVMAddr = config.DoubleQuotedString(r.ConnectorZEVMAddr.Hex()) diff --git a/cmd/zetae2e/config/contracts.go b/cmd/zetae2e/config/contracts.go index 6ca59f0414..9edb50cfe8 100644 --- a/cmd/zetae2e/config/contracts.go +++ b/cmd/zetae2e/config/contracts.go @@ -109,6 +109,17 @@ func setContractsFromConfig(r *runner.E2ERunner, conf config.Config) error { } } + if c := conf.Contracts.ZEVM.SOLZRC20Addr; c != "" { + r.SOLZRC20Addr, err = c.AsEVMAddress() + if err != nil { + return fmt.Errorf("invalid SOLZRC20Addr: %w", err) + } + r.SOLZRC20, err = zrc20.NewZRC20(r.SOLZRC20Addr, r.ZEVMClient) + if err != nil { + return err + } + } + if c := conf.Contracts.ZEVM.BTCZRC20Addr; c != "" { r.BTCZRC20Addr, err = c.AsEVMAddress() if err != nil { diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index c5626646d6..38d869ec2b 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -231,6 +231,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { solanaTests := []string{ e2etests.TestSolanaIntializeGatewayName, e2etests.TestSolanaDepositName, + e2etests.TestSolanaWithdrawName, } bitcoinTests := []string{ diff --git a/e2e/config/config.go b/e2e/config/config.go index 5f69f2470e..e50a4d0fac 100644 --- a/e2e/config/config.go +++ b/e2e/config/config.go @@ -114,6 +114,7 @@ type ZEVM struct { ETHZRC20Addr DoubleQuotedString `yaml:"eth_zrc20"` ERC20ZRC20Addr DoubleQuotedString `yaml:"erc20_zrc20"` BTCZRC20Addr DoubleQuotedString `yaml:"btc_zrc20"` + SOLZRC20Addr DoubleQuotedString `yaml:"sol_zrc20"` UniswapFactoryAddr DoubleQuotedString `yaml:"uniswap_factory"` UniswapRouterAddr DoubleQuotedString `yaml:"uniswap_router"` ConnectorZEVMAddr DoubleQuotedString `yaml:"connector_zevm"` diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index b18826c00f..1d346e3fb2 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -56,7 +56,7 @@ const ( */ TestSolanaIntializeGatewayName = "solana_initialize_gateway" TestSolanaDepositName = "solana_deposit" - + TestSolanaWithdrawName = "solana_withdraw" /* Bitcoin tests Test transfer of Bitcoin asset across chains @@ -346,6 +346,14 @@ var AllE2ETests = []runner.E2ETest{ }, TestSolanaDeposit, ), + runner.NewE2ETest( + TestSolanaWithdrawName, + "withdraw Sol from ZEVM", + []runner.ArgDefinition{ + {Description: "amount in SOL", DefaultValue: "0.1"}, + }, + TestSolanaWithdraw, + ), /* Bitcoin tests diff --git a/e2e/e2etests/test_solana_deposit.go b/e2e/e2etests/test_solana_deposit.go index b9057b5f3c..1854883d8a 100644 --- a/e2e/e2etests/test_solana_deposit.go +++ b/e2e/e2etests/test_solana_deposit.go @@ -3,11 +3,14 @@ package e2etests import ( "context" "fmt" + "math/big" "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/gagliardetto/solana-go" "github.com/gagliardetto/solana-go/rpc" "github.com/near/borsh-go" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" "github.com/zeta-chain/zetacore/pkg/chains" @@ -177,8 +180,8 @@ func TestSolanaDeposit(r *runner.E2ERunner, args []string) { inst.DataBytes, err = borsh.Serialize(DepositInstructionParams{ Discriminator: [8]byte{0xf2, 0x23, 0xc6, 0x89, 0x52, 0xe1, 0xf2, 0xb6}, - Amount: 1338, - Memo: r.Account.EVMAddress().Bytes(), + Amount: 13370000, + Memo: r.EVMAddress().Bytes(), }) if err != nil { r.Logger.Error("Error serializing deposit instruction: %v", err) @@ -242,3 +245,29 @@ func TestSolanaDeposit(r *runner.E2ERunner, args []string) { } } + +func TestSolanaWithdraw(r *runner.E2ERunner, args []string) { + r.Logger.Print("TestSolanaWithdraw...sol zrc20 %s", r.SOLZRC20Addr.String()) + + solZRC20 := r.SOLZRC20 + supply, err := solZRC20.BalanceOf(&bind.CallOpts{}, r.EVMAddress()) + if err != nil { + r.Logger.Error("Error getting total supply of sol zrc20: %v", err) + panic(err) + } + r.Logger.Print(" supply of %s sol zrc20: %d", r.EVMAddress(), supply) + + amount := big.NewInt(1337) + + tx, err := r.SOLZRC20.Approve(r.ZEVMAuth, r.SOLZRC20Addr, amount) + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt) + + tx, err = r.SOLZRC20.Withdraw(r.ZEVMAuth, r.EVMAddress().Bytes(), amount) + require.NoError(r, err) + r.Logger.EVMTransaction(*tx, "withdraw") + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("Receipt txhash %s status %d", receipt.TxHash, receipt.Status) +} diff --git a/e2e/runner/runner.go b/e2e/runner/runner.go index 99c67c9b1a..b65a7cbf42 100644 --- a/e2e/runner/runner.go +++ b/e2e/runner/runner.go @@ -101,6 +101,8 @@ type E2ERunner struct { ETHZRC20 *zrc20.ZRC20 BTCZRC20Addr ethcommon.Address BTCZRC20 *zrc20.ZRC20 + SOLZRC20Addr ethcommon.Address + SOLZRC20 *zrc20.ZRC20 UniswapV2FactoryAddr ethcommon.Address UniswapV2Factory *uniswapv2factory.UniswapV2Factory UniswapV2RouterAddr ethcommon.Address @@ -196,6 +198,7 @@ func (r *E2ERunner) CopyAddressesFrom(other *E2ERunner) (err error) { r.ERC20ZRC20Addr = other.ERC20ZRC20Addr r.ETHZRC20Addr = other.ETHZRC20Addr r.BTCZRC20Addr = other.BTCZRC20Addr + r.SOLZRC20Addr = other.SOLZRC20Addr r.UniswapV2FactoryAddr = other.UniswapV2FactoryAddr r.UniswapV2RouterAddr = other.UniswapV2RouterAddr r.ConnectorZEVMAddr = other.ConnectorZEVMAddr @@ -237,6 +240,10 @@ func (r *E2ERunner) CopyAddressesFrom(other *E2ERunner) (err error) { if err != nil { return err } + r.SOLZRC20, err = zrc20.NewZRC20(r.SOLZRC20Addr, r.ZEVMClient) + if err != nil { + return err + } r.UniswapV2Factory, err = uniswapv2factory.NewUniswapV2Factory(r.UniswapV2FactoryAddr, r.ZEVMClient) if err != nil { return err @@ -291,6 +298,7 @@ func (r *E2ERunner) PrintContractAddresses() { r.Logger.Print("ETHZRC20: %s", r.ETHZRC20Addr.Hex()) r.Logger.Print("ERC20ZRC20: %s", r.ERC20ZRC20Addr.Hex()) r.Logger.Print("BTCZRC20: %s", r.BTCZRC20Addr.Hex()) + r.Logger.Print("SOLZRC20: %s", r.SOLZRC20Addr.Hex()) r.Logger.Print("UniswapFactory: %s", r.UniswapV2FactoryAddr.Hex()) r.Logger.Print("UniswapRouter: %s", r.UniswapV2RouterAddr.Hex()) r.Logger.Print("ConnectorZEVM: %s", r.ConnectorZEVMAddr.Hex()) diff --git a/e2e/runner/setup_zeta.go b/e2e/runner/setup_zeta.go index 3dc01dc51f..2af534195d 100644 --- a/e2e/runner/setup_zeta.go +++ b/e2e/runner/setup_zeta.go @@ -135,6 +135,7 @@ func (r *E2ERunner) SetZEVMContracts() { // set ZRC20 contracts r.SetupETHZRC20() r.SetupBTCZRC20() + r.SetupSOLZRC20() // deploy TestDApp contract on zEVM appAddr, txApp, _, err := testdapp.DeployTestDApp( @@ -185,6 +186,22 @@ func (r *E2ERunner) SetZEVMContracts() { r.ContextApp = contextApp } +// SetupETHZRC20 sets up the ETH ZRC20 in the runner from the values queried from the chain +func (r *E2ERunner) SetupSOLZRC20() { + solZRC20Addr, err := r.SystemContract.GasCoinZRC20ByChainId( + &bind.CallOpts{}, + big.NewInt(chains.SolanaLocalnet.ChainId), + ) + require.NoError(r, err) + require.NotEqual(r, ethcommon.Address{}, solZRC20Addr, "sol zrc20 not found") + + r.SOLZRC20Addr = solZRC20Addr + solZRC20, err := zrc20.NewZRC20(solZRC20Addr, r.ZEVMClient) + require.NoError(r, err) + + r.SOLZRC20 = solZRC20 +} + // SetupETHZRC20 sets up the ETH ZRC20 in the runner from the values queried from the chain func (r *E2ERunner) SetupETHZRC20() { ethZRC20Addr, err := r.SystemContract.GasCoinZRC20ByChainId( diff --git a/e2e/txserver/zeta_tx_server.go b/e2e/txserver/zeta_tx_server.go index 1ccc489b09..7e2a2a2b80 100644 --- a/e2e/txserver/zeta_tx_server.go +++ b/e2e/txserver/zeta_tx_server.go @@ -2,7 +2,6 @@ package txserver import ( "context" - "encoding/base64" "encoding/hex" "encoding/json" "errors" @@ -190,11 +189,6 @@ func (zts ZetaTxServer) BroadcastTx(account string, msg sdktypes.Msg) (*sdktypes return nil, err } - { - tx := txBuilder.GetTx() - fmt.Printf("txBuilder.GetTx(): fee %s, gas %d", tx.GetFee().String(), tx.GetGas()) - } - // Sign tx err = tx.Sign(zts.txFactory, account, txBuilder, true) if err != nil { @@ -208,7 +202,6 @@ func (zts ZetaTxServer) BroadcastTx(account string, msg sdktypes.Msg) (*sdktypes } func broadcastWithBlockTimeout(zts ZetaTxServer, txBytes []byte) (*sdktypes.TxResponse, error) { - fmt.Printf("broadcasting tx:\n%s\n", base64.StdEncoding.EncodeToString(txBytes)) res, err := zts.clientCtx.BroadcastTx(txBytes) if err != nil { if res == nil {