Skip to content

Commit

Permalink
CCIP-4160 Token Transfer Tests (#15278)
Browse files Browse the repository at this point in the history
* CCIP-4160 test refactoring

* resolving imports and using local dev env

* comments fix

* comments fix

* test update with common methods

* import fix for lint

* refactor: updated test with new setup

* fix: lint (imports)

* Yolo

* feat: self serve pool test + ability to add custom deployer for token and pools

* fix : Use LocalDevEnvironment

* temp: trying out with AdditionalSimulatedPvtKeys

* fix: lints and unused function

* fix: lints and unused function

* fix: imports for lint

* Move tt tests to a separate file

* Move tt tests to a separate file

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

---------

Co-authored-by: Mateusz Sekara <[email protected]>
  • Loading branch information
0xsuryansh and mateusz-sekara authored Nov 29, 2024
1 parent fcc8d3c commit 5633382
Show file tree
Hide file tree
Showing 7 changed files with 437 additions and 294 deletions.
15 changes: 14 additions & 1 deletion .github/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ runner-test-matrix:
test_env_vars:
E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2
E2E_JD_VERSION: 0.6.0

- id: smoke/ccip/ccip_batching_test.go:*
path: integration-tests/smoke/ccip/ccip_batching_test.go
test_env_type: docker
Expand All @@ -961,6 +961,19 @@ runner-test-matrix:
E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2,SIMULATED_3
E2E_JD_VERSION: 0.6.0

- id: smoke/ccip/ccip_token_transfer_test.go:*
path: integration-tests/smoke/ccip/ccip_token_transfer_test.go
test_env_type: docker
runs_on: ubuntu-latest
triggers:
- PR E2E Core Tests
- Nightly E2E Tests
test_cmd: cd integration-tests/ && go test smoke/ccip/ccip_token_transfer_test.go -timeout 16m -test.parallel=1 -count=1 -json
pyroscope_env: ci-smoke-ccipv1_6-evm-simulated
test_env_vars:
E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2
E2E_JD_VERSION: 0.6.0

- id: smoke/ccip/ccip_usdc_test.go:*
path: integration-tests/smoke/ccip/ccip_usdc_test.go
test_env_type: docker
Expand Down
170 changes: 146 additions & 24 deletions deployment/ccip/changeset/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (

"github.com/smartcontractkit/chainlink-common/pkg/logger"
commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"

"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/deployment/environment/devenv"
Expand Down Expand Up @@ -743,53 +744,54 @@ func DeployTransferableToken(
lggr logger.Logger,
chains map[uint64]deployment.Chain,
src, dst uint64,
srcActor, dstActor *bind.TransactOpts,
state CCIPOnChainState,
addresses deployment.AddressBook,
token string,
) (*burn_mint_erc677.BurnMintERC677, *burn_mint_token_pool.BurnMintTokenPool, *burn_mint_erc677.BurnMintERC677, *burn_mint_token_pool.BurnMintTokenPool, error) {
// Deploy token and pools
srcToken, srcPool, err := deployTransferTokenOneEnd(lggr, chains[src], addresses, token)
srcToken, srcPool, err := deployTransferTokenOneEnd(lggr, chains[src], srcActor, addresses, token)
if err != nil {
return nil, nil, nil, nil, err
}
dstToken, dstPool, err := deployTransferTokenOneEnd(lggr, chains[dst], addresses, token)
dstToken, dstPool, err := deployTransferTokenOneEnd(lggr, chains[dst], dstActor, addresses, token)
if err != nil {
return nil, nil, nil, nil, err
}

// Attach token pools to registry
if err := attachTokenToTheRegistry(chains[src], state.Chains[src], chains[src].DeployerKey, srcToken.Address(), srcPool.Address()); err != nil {
if err := attachTokenToTheRegistry(chains[src], state.Chains[src], srcActor, srcToken.Address(), srcPool.Address()); err != nil {
return nil, nil, nil, nil, err
}

if err := attachTokenToTheRegistry(chains[dst], state.Chains[dst], chains[dst].DeployerKey, dstToken.Address(), dstPool.Address()); err != nil {
if err := attachTokenToTheRegistry(chains[dst], state.Chains[dst], dstActor, dstToken.Address(), dstPool.Address()); err != nil {
return nil, nil, nil, nil, err
}

// Connect pool to each other
if err := setTokenPoolCounterPart(chains[src], srcPool, dst, dstToken.Address(), dstPool.Address()); err != nil {
if err := setTokenPoolCounterPart(chains[src], srcPool, srcActor, dst, dstToken.Address(), dstPool.Address()); err != nil {
return nil, nil, nil, nil, err
}

if err := setTokenPoolCounterPart(chains[dst], dstPool, src, srcToken.Address(), srcPool.Address()); err != nil {
if err := setTokenPoolCounterPart(chains[dst], dstPool, dstActor, src, srcToken.Address(), srcPool.Address()); err != nil {
return nil, nil, nil, nil, err
}

// Add burn/mint permissions
if err := grantMintBurnPermissions(lggr, chains[src], srcToken, srcPool.Address()); err != nil {
if err := grantMintBurnPermissions(lggr, chains[src], srcToken, srcActor, srcPool.Address()); err != nil {
return nil, nil, nil, nil, err
}

if err := grantMintBurnPermissions(lggr, chains[dst], dstToken, dstPool.Address()); err != nil {
if err := grantMintBurnPermissions(lggr, chains[dst], dstToken, dstActor, dstPool.Address()); err != nil {
return nil, nil, nil, nil, err
}

return srcToken, srcPool, dstToken, dstPool, nil
}

func grantMintBurnPermissions(lggr logger.Logger, chain deployment.Chain, token *burn_mint_erc677.BurnMintERC677, address common.Address) error {
func grantMintBurnPermissions(lggr logger.Logger, chain deployment.Chain, token *burn_mint_erc677.BurnMintERC677, actor *bind.TransactOpts, address common.Address) error {
lggr.Infow("Granting burn permissions", "token", token.Address(), "burner", address)
tx, err := token.GrantBurnRole(chain.DeployerKey, address)
tx, err := token.GrantBurnRole(actor, address)
if err != nil {
return err
}
Expand All @@ -799,7 +801,7 @@ func grantMintBurnPermissions(lggr logger.Logger, chain deployment.Chain, token
}

lggr.Infow("Granting mint permissions", "token", token.Address(), "minter", address)
tx, err = token.GrantMintRole(chain.DeployerKey, address)
tx, err = token.GrantMintRole(actor, address)
if err != nil {
return err
}
Expand All @@ -811,6 +813,7 @@ func setUSDCTokenPoolCounterPart(
chain deployment.Chain,
tokenPool *usdc_token_pool.USDCTokenPool,
destChainSelector uint64,
actor *bind.TransactOpts,
destTokenAddress common.Address,
destTokenPoolAddress common.Address,
) error {
Expand Down Expand Up @@ -843,18 +846,12 @@ func setUSDCTokenPoolCounterPart(
return err
}

return setTokenPoolCounterPart(chain, pool, destChainSelector, destTokenAddress, destTokenPoolAddress)
return setTokenPoolCounterPart(chain, pool, actor, destChainSelector, destTokenAddress, destTokenPoolAddress)
}

func setTokenPoolCounterPart(
chain deployment.Chain,
tokenPool *burn_mint_token_pool.BurnMintTokenPool,
destChainSelector uint64,
destTokenAddress common.Address,
destTokenPoolAddress common.Address,
) error {
func setTokenPoolCounterPart(chain deployment.Chain, tokenPool *burn_mint_token_pool.BurnMintTokenPool, actor *bind.TransactOpts, destChainSelector uint64, destTokenAddress common.Address, destTokenPoolAddress common.Address) error {
tx, err := tokenPool.ApplyChainUpdates(
chain.DeployerKey,
actor,
[]uint64{},
[]burn_mint_token_pool.TokenPoolChainUpdate{
{
Expand Down Expand Up @@ -884,7 +881,7 @@ func setTokenPoolCounterPart(
}

tx, err = tokenPool.AddRemotePool(
chain.DeployerKey,
actor,
destChainSelector,
destTokenPoolAddress.Bytes(),
)
Expand Down Expand Up @@ -944,6 +941,7 @@ func attachTokenToTheRegistry(
func deployTransferTokenOneEnd(
lggr logger.Logger,
chain deployment.Chain,
deployer *bind.TransactOpts,
addressBook deployment.AddressBook,
tokenSymbol string,
) (*burn_mint_erc677.BurnMintERC677, *burn_mint_token_pool.BurnMintTokenPool, error) {
Expand All @@ -969,7 +967,7 @@ func deployTransferTokenOneEnd(
tokenContract, err := deployment.DeployContract(lggr, chain, addressBook,
func(chain deployment.Chain) deployment.ContractDeploy[*burn_mint_erc677.BurnMintERC677] {
tokenAddress, tx, token, err2 := burn_mint_erc677.DeployBurnMintERC677(
chain.DeployerKey,
deployer,
chain.Client,
tokenSymbol,
tokenSymbol,
Expand All @@ -985,7 +983,7 @@ func deployTransferTokenOneEnd(
return nil, nil, err
}

tx, err := tokenContract.Contract.GrantMintRole(chain.DeployerKey, chain.DeployerKey.From)
tx, err := tokenContract.Contract.GrantMintRole(deployer, deployer.From)
if err != nil {
return nil, nil, err
}
Expand All @@ -997,7 +995,7 @@ func deployTransferTokenOneEnd(
tokenPool, err := deployment.DeployContract(lggr, chain, addressBook,
func(chain deployment.Chain) deployment.ContractDeploy[*burn_mint_token_pool.BurnMintTokenPool] {
tokenPoolAddress, tx, tokenPoolContract, err2 := burn_mint_token_pool.DeployBurnMintTokenPool(
chain.DeployerKey,
deployer,
chain.Client,
tokenContract.Address,
tokenDecimals,
Expand All @@ -1016,3 +1014,127 @@ func deployTransferTokenOneEnd(

return tokenContract.Contract, tokenPool.Contract, nil
}

// MintAndAllow mints tokens for deployers and allow router to spend them
func MintAndAllow(
t *testing.T,
e deployment.Environment,
state CCIPOnChainState,
owners map[uint64]*bind.TransactOpts,
tkMap map[uint64][]*burn_mint_erc677.BurnMintERC677,
) {
tenCoins := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(10))

for chain, tokens := range tkMap {
owner, ok := owners[chain]
require.True(t, ok)

for _, token := range tokens {
tx, err := token.Mint(
owner,
e.Chains[chain].DeployerKey.From,
new(big.Int).Mul(tenCoins, big.NewInt(10)),
)
require.NoError(t, err)
_, err = e.Chains[chain].Confirm(tx)
require.NoError(t, err)

tx, err = token.Approve(e.Chains[chain].DeployerKey, state.Chains[chain].Router.Address(), tenCoins)
require.NoError(t, err)
_, err = e.Chains[chain].Confirm(tx)
require.NoError(t, err)
}
}
}

// TransferAndWaitForSuccess sends a message from sourceChain to destChain and waits for it to be executed
func TransferAndWaitForSuccess(
ctx context.Context,
t *testing.T,
env deployment.Environment,
state CCIPOnChainState,
sourceChain, destChain uint64,
tokens []router.ClientEVMTokenAmount,
receiver common.Address,
data []byte,
expectedStatus int,
) {
identifier := SourceDestPair{
SourceChainSelector: sourceChain,
DestChainSelector: destChain,
}

startBlocks := make(map[uint64]*uint64)
expectedSeqNum := make(map[SourceDestPair]uint64)
expectedSeqNumExec := make(map[SourceDestPair][]uint64)

latesthdr, err := env.Chains[destChain].Client.HeaderByNumber(ctx, nil)
require.NoError(t, err)
block := latesthdr.Number.Uint64()
startBlocks[destChain] = &block

msgSentEvent := TestSendRequest(t, env, state, sourceChain, destChain, false, router.ClientEVM2AnyMessage{
Receiver: common.LeftPadBytes(receiver.Bytes(), 32),
Data: data,
TokenAmounts: tokens,
FeeToken: common.HexToAddress("0x0"),
ExtraArgs: nil,
})
expectedSeqNum[identifier] = msgSentEvent.SequenceNumber
expectedSeqNumExec[identifier] = []uint64{msgSentEvent.SequenceNumber}

// Wait for all commit reports to land.
ConfirmCommitForAllWithExpectedSeqNums(t, env, state, expectedSeqNum, startBlocks)

// Wait for all exec reports to land
states := ConfirmExecWithSeqNrsForAll(t, env, state, expectedSeqNumExec, startBlocks)
require.Equal(t, expectedStatus, states[identifier][msgSentEvent.SequenceNumber])
}

func WaitForTheTokenBalance(
ctx context.Context,
t *testing.T,
token common.Address,
receiver common.Address,
chain deployment.Chain,
expected *big.Int,
) {
tokenContract, err := burn_mint_erc677.NewBurnMintERC677(token, chain.Client)
require.NoError(t, err)

require.Eventually(t, func() bool {
actualBalance, err := tokenContract.BalanceOf(&bind.CallOpts{Context: ctx}, receiver)
require.NoError(t, err)

t.Log("Waiting for the token balance",
"expected", expected,
"actual", actualBalance,
"token", token,
"receiver", receiver,
)

return actualBalance.Cmp(expected) == 0
}, tests.WaitTimeout(t), 100*time.Millisecond)
}

func GetTokenBalance(
ctx context.Context,
t *testing.T,
token common.Address,
receiver common.Address,
chain deployment.Chain,
) *big.Int {
tokenContract, err := burn_mint_erc677.NewBurnMintERC677(token, chain.Client)
require.NoError(t, err)

balance, err := tokenContract.BalanceOf(&bind.CallOpts{Context: ctx}, receiver)
require.NoError(t, err)

t.Log("Getting token balance",
"actual", balance,
"token", token,
"receiver", receiver,
)

return balance
}
8 changes: 4 additions & 4 deletions deployment/ccip/changeset/test_usdc_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ func ConfigureUSDCTokenPools(
}

// Connect pool to each other
if err := setUSDCTokenPoolCounterPart(chains[src], srcPool, dst, dstToken.Address(), dstPool.Address()); err != nil {
if err := setUSDCTokenPoolCounterPart(chains[src], srcPool, dst, chains[src].DeployerKey, dstToken.Address(), dstPool.Address()); err != nil {
lggr.Errorw("Failed to set counter part", "err", err, "srcPool", srcPool.Address(), "dstPool", dstPool.Address())
return nil, nil, err
}

if err := setUSDCTokenPoolCounterPart(chains[dst], dstPool, src, srcToken.Address(), srcPool.Address()); err != nil {
if err := setUSDCTokenPoolCounterPart(chains[dst], dstPool, src, chains[dst].DeployerKey, srcToken.Address(), srcPool.Address()); err != nil {
lggr.Errorw("Failed to set counter part", "err", err, "srcPool", dstPool.Address(), "dstPool", srcPool.Address())
return nil, nil, err
}
Expand All @@ -55,7 +55,7 @@ func ConfigureUSDCTokenPools(
state.Chains[src].MockUSDCTokenMessenger.Address(),
state.Chains[src].MockUSDCTransmitter.Address(),
} {
if err := grantMintBurnPermissions(lggr, chains[src], srcToken, addr); err != nil {
if err := grantMintBurnPermissions(lggr, chains[src], srcToken, chains[src].DeployerKey, addr); err != nil {
lggr.Errorw("Failed to grant mint/burn permissions", "err", err, "token", srcToken.Address(), "minter", addr)
return nil, nil, err
}
Expand All @@ -67,7 +67,7 @@ func ConfigureUSDCTokenPools(
state.Chains[dst].MockUSDCTokenMessenger.Address(),
state.Chains[dst].MockUSDCTransmitter.Address(),
} {
if err := grantMintBurnPermissions(lggr, chains[dst], dstToken, addr); err != nil {
if err := grantMintBurnPermissions(lggr, chains[dst], dstToken, chains[dst].DeployerKey, addr); err != nil {
lggr.Errorw("Failed to grant mint/burn permissions", "err", err, "token", dstToken.Address(), "minter", addr)
return nil, nil, err
}
Expand Down
2 changes: 2 additions & 0 deletions integration-tests/smoke/ccip/ccip_fees_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func setupTokens(
tenv.Env.Chains,
src,
dest,
tenv.Env.Chains[src].DeployerKey,
tenv.Env.Chains[dest].DeployerKey,
state,
tenv.Env.ExistingAddresses,
"MY_TOKEN",
Expand Down
Loading

0 comments on commit 5633382

Please sign in to comment.