From 1322512443c0a05fe0ec93a0cedd0e6f409c2e09 Mon Sep 17 00:00:00 2001 From: ajaskolski Date: Wed, 6 May 2026 14:47:41 +0200 Subject: [PATCH] feat: port token approve --- common/changeset/token_approve.go | 45 ++++++++++++++++++ common/changeset/token_approve_test.go | 65 ++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 common/changeset/token_approve.go create mode 100644 common/changeset/token_approve_test.go diff --git a/common/changeset/token_approve.go b/common/changeset/token_approve.go new file mode 100644 index 0000000..dbb16c1 --- /dev/null +++ b/common/changeset/token_approve.go @@ -0,0 +1,45 @@ +package changeset + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + + cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-evm/gethwrappers/shared/generated/initial/erc20" +) + +// ApproveToken approves routerAddress to pull up to amount of token from the deployer on chain src. +func ApproveToken(env cldf.Environment, src uint64, tokenAddress common.Address, routerAddress common.Address, amount *big.Int) error { + evmChains := env.BlockChains.EVMChains() + ch, ok := evmChains[src] + if !ok { + return fmt.Errorf("evm chain %d not found in environment", src) + } + + if ch.Client == nil { + return fmt.Errorf("evm chain %d has no RPC client", src) + } + + if ch.DeployerKey == nil { + return fmt.Errorf("evm chain %d has no deployer key", src) + } + + token, err := erc20.NewERC20(tokenAddress, ch.Client) + if err != nil { + return err + } + + tx, err := token.Approve(ch.DeployerKey, routerAddress, amount) + if err != nil { + return err + } + + _, err = ch.Confirm(tx) + if err != nil { + return err + } + + return nil +} diff --git a/common/changeset/token_approve_test.go b/common/changeset/token_approve_test.go new file mode 100644 index 0000000..2488b53 --- /dev/null +++ b/common/changeset/token_approve_test.go @@ -0,0 +1,65 @@ +package changeset + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + chainselectors "github.com/smartcontractkit/chain-selectors" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/environment" + "github.com/smartcontractkit/chainlink-evm/gethwrappers/shared/generated/initial/erc20" + "github.com/smartcontractkit/chainlink-evm/gethwrappers/shared/generated/initial/link_token" +) + +func TestApproveToken_success_simulatedEVM(t *testing.T) { + t.Parallel() + + selector := chainselectors.TEST_90000001.Selector + env, err := environment.New(t.Context(), + environment.WithEVMSimulated(t, []uint64{selector}), + ) + require.NoError(t, err) + + chain := env.BlockChains.EVMChains()[selector] + + _, tx, lt, err := link_token.DeployLinkToken(chain.DeployerKey, chain.Client) + require.NoError(t, err) + _, err = chain.Confirm(tx) + require.NoError(t, err) + + tx, err = lt.GrantMintAndBurnRoles(chain.DeployerKey, chain.DeployerKey.From) + require.NoError(t, err) + _, err = chain.Confirm(tx) + require.NoError(t, err) + + tx, err = lt.Mint(chain.DeployerKey, chain.DeployerKey.From, big.NewInt(1_000_000)) + require.NoError(t, err) + _, err = chain.Confirm(tx) + require.NoError(t, err) + + spender := common.HexToAddress("0x00000000000000000000000000000000000000Ab") + amount := big.NewInt(12345) + + require.NoError(t, ApproveToken(*env, selector, lt.Address(), spender, amount)) + + token, err := erc20.NewERC20(lt.Address(), chain.Client) + require.NoError(t, err) + got, err := token.Allowance(nil, chain.DeployerKey.From, spender) + require.NoError(t, err) + require.Zero(t, got.Cmp(amount)) +} + +func TestApproveToken_unknownChainSelector(t *testing.T) { + t.Parallel() + + selector := chainselectors.TEST_90000001.Selector + env, err := environment.New(t.Context(), + environment.WithEVMSimulated(t, []uint64{selector}), + ) + require.NoError(t, err) + + err = ApproveToken(*env, selector+999_999_999, common.Address{}, common.Address{}, big.NewInt(1)) + require.ErrorContains(t, err, "not found in environment") +}