| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- package e2e
- import (
- "context"
- "testing"
- "time"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/mr-tron/base58"
- "k8s.io/client-go/kubernetes"
- "github.com/certusone/wormhole/node/pkg/devnet"
- "github.com/certusone/wormhole/node/pkg/ethereum"
- "github.com/certusone/wormhole/node/pkg/vaa"
- "github.com/ethereum/go-ethereum/ethclient"
- )
- func setup(t *testing.T) (*kubernetes.Clientset, *ethclient.Client, *bind.TransactOpts, *TerraClient) {
- // List of pods we need in a ready state before we can run tests.
- want := []string{
- // Our test guardian set.
- "guardian-0",
- //"guardian-1",
- //"guardian-2",
- //"guardian-3",
- //"guardian-4",
- //"guardian-5",
- // Connected chains
- "solana-devnet-0",
- "terra-terrad-0",
- "terra-lcd-0",
- "eth-devnet-0",
- }
- c := getk8sClient()
- // Wait for all pods to be ready. This blocks until the bridge is ready to receive lockups.
- ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
- defer cancel()
- waitForPods(ctx, c, want)
- if ctx.Err() != nil {
- t.Fatal(ctx.Err())
- }
- // Ethereum client.
- ec, err := ethclient.Dial(devnet.GanacheRPCURL)
- if err != nil {
- t.Fatalf("dialing devnet eth rpc failed: %v", err)
- }
- kt := devnet.GetKeyedTransactor(context.Background())
- // Terra client
- tc, err := NewTerraClient()
- if err != nil {
- t.Fatalf("creating devnet terra client failed: %v", err)
- }
- return c, ec, kt, tc
- }
- // Careful about parallel tests - accounts on some chains like Ethereum cannot be
- // used concurrently as they have monotonically increasing nonces that would conflict.
- // Either use different Ethereum account, or do not run Ethereum tests in parallel.
- func TestEndToEnd_SOL_ETH(t *testing.T) {
- c, ec, kt, _ := setup(t)
- t.Run("[SOL] Native -> [ETH] Wrapped", func(t *testing.T) {
- testSolanaLockup(t, context.Background(), ec, c,
- // Source SPL account
- devnet.SolanaExampleTokenOwningAccount,
- // Source SPL token
- devnet.SolanaExampleToken,
- // Our wrapped destination token on Ethereum
- devnet.GanacheExampleERC20WrappedSOL,
- // Amount of SPL token value to transfer.
- 50*devnet.SolanaDefaultPrecision,
- // Same precision - same amount, no precision gained.
- 0,
- )
- })
- t.Run("[ETH] Wrapped -> [SOL] Native", func(t *testing.T) {
- testEthereumLockup(t, context.Background(), ec, kt, c,
- // Source ERC20 token
- devnet.GanacheExampleERC20WrappedSOL,
- // Destination SPL token account
- devnet.SolanaExampleTokenOwningAccount,
- // Amount (the reverse of what the previous test did, with the same precision because
- // the wrapped ERC20 is set to the original asset's 10**9 precision).
- 50*devnet.SolanaDefaultPrecision,
- // No precision loss
- 0,
- )
- })
- t.Run("[ETH] Native -> [SOL] Wrapped", func(t *testing.T) {
- testEthereumLockup(t, context.Background(), ec, kt, c,
- // Source ERC20 token
- devnet.GanacheExampleERC20Token,
- // Destination SPL token account
- devnet.SolanaExampleWrappedERCTokenOwningAccount,
- // Amount
- 0.000000012*devnet.ERC20DefaultPrecision,
- // We lose 9 digits of precision on this path, as the default ERC20 token has 10**18 precision.
- 9,
- )
- })
- t.Run("[SOL] Wrapped -> [ETH] Native", func(t *testing.T) {
- testSolanaLockup(t, context.Background(), ec, c,
- // Source SPL account
- devnet.SolanaExampleWrappedERCTokenOwningAccount,
- // Source SPL token
- devnet.SolanaExampleWrappedERCToken,
- // Our wrapped destination token on Ethereum
- devnet.GanacheExampleERC20Token,
- // Amount of SPL token value to transfer.
- 0.000000012*devnet.SolanaDefaultPrecision,
- // We gain 9 digits of precision on Eth.
- 9,
- )
- })
- }
- func TestEndToEnd_SOL_Terra(t *testing.T) {
- c, _, _, tc := setup(t)
- t.Run("[Terra] Native -> [SOL] Wrapped", func(t *testing.T) {
- testTerraLockup(t, context.Background(), tc, c,
- // Source CW20 token
- devnet.TerraTokenAddress,
- // Destination SPL token account
- devnet.SolanaExampleWrappedCWTokenOwningAccount,
- // Amount
- 2*devnet.TerraDefaultPrecision,
- // Same precision - same amount, no precision gained.
- 0,
- )
- })
- t.Run("[SOL] Wrapped -> [Terra] Native", func(t *testing.T) {
- testSolanaToTerraLockup(t, context.Background(), c,
- // Source SPL account
- devnet.SolanaExampleWrappedCWTokenOwningAccount,
- // Source SPL token
- devnet.SolanaExampleWrappedCWToken,
- // Wrapped
- false,
- // Amount of SPL token value to transfer.
- 2*devnet.TerraDefaultPrecision,
- // Same precision - same amount, no precision gained.
- 0,
- )
- })
- t.Run("[SOL] Native -> [Terra] Wrapped", func(t *testing.T) {
- testSolanaToTerraLockup(t, context.Background(), c,
- // Source SPL account
- devnet.SolanaExampleTokenOwningAccount,
- // Source SPL token
- devnet.SolanaExampleToken,
- // Native
- true,
- // Amount of SPL token value to transfer.
- 50*devnet.SolanaDefaultPrecision,
- // Same precision - same amount, no precision gained.
- 0,
- )
- })
- t.Run("[Terra] Wrapped -> [SOL] Native", func(t *testing.T) {
- tokenSlice, err := base58.Decode(devnet.SolanaExampleToken)
- if err != nil {
- t.Fatal(err)
- }
- wrappedAsset, err := waitTerraAsset(t, context.Background(), devnet.TerraBridgeAddress, vaa.ChainIDSolana, tokenSlice)
- if err != nil {
- t.Fatal(err)
- }
- testTerraLockup(t, context.Background(), tc, c,
- // Source wrapped token
- wrappedAsset,
- // Destination SPL token account
- devnet.SolanaExampleTokenOwningAccount,
- // Amount of Terra token value to transfer.
- 50*devnet.SolanaDefaultPrecision,
- // Same precision
- 0,
- )
- })
- }
- func TestEndToEnd_ETH_Terra(t *testing.T) {
- _, ec, kt, tc := setup(t)
- t.Run("[Terra] Native -> [ETH] Wrapped", func(t *testing.T) {
- testTerraToEthLockup(t, context.Background(), tc, ec,
- // Source CW20 token
- devnet.TerraTokenAddress,
- // Destination ETH token
- devnet.GanacheExampleERC20WrappedTerra,
- // Amount
- 2*devnet.TerraDefaultPrecision,
- // Same precision - same amount, no precision gained.
- 0,
- )
- })
- t.Run("[ETH] Wrapped -> [Terra] Native", func(t *testing.T) {
- testEthereumToTerraLockup(t, context.Background(), ec, kt,
- // Source Ethereum token
- devnet.GanacheExampleERC20WrappedTerra,
- // Wrapped
- false,
- // Amount of Ethereum token value to transfer.
- 2*devnet.TerraDefaultPrecision,
- // Same precision
- 0,
- )
- })
- t.Run("[ETH] Native -> [Terra] Wrapped", func(t *testing.T) {
- testEthereumToTerraLockup(t, context.Background(), ec, kt,
- // Source Ethereum token
- devnet.GanacheExampleERC20Token,
- // Native
- true,
- // Amount of Ethereum token value to transfer.
- 0.000000012*devnet.ERC20DefaultPrecision,
- // We lose 9 digits of precision on this path, as the default ERC20 token has 10**18 precision.
- 9,
- )
- })
- t.Run("[Terra] Wrapped -> [ETH] Native", func(t *testing.T) {
- paddedTokenAddress := ethereum.PadAddress(devnet.GanacheExampleERC20Token)
- wrappedAsset, err := waitTerraAsset(t, context.Background(), devnet.TerraBridgeAddress, vaa.ChainIDEthereum, paddedTokenAddress[:])
- if err != nil {
- t.Fatal(err)
- }
- testTerraToEthLockup(t, context.Background(), tc, ec,
- // Source wrapped token
- wrappedAsset,
- // Destination ETH token
- devnet.GanacheExampleERC20Token,
- // Amount of Terra token value to transfer.
- 0.000000012*1e9, // 10**9 because default ETH precision is 18 and we lost 9 digits on wrapping
- // We gain 9 digits of precision on Eth.
- 9,
- )
- })
- }
|