Skip to content

Commit 34faefa

Browse files
committed
feed forward
1 parent c43ece7 commit 34faefa

6 files changed

Lines changed: 144 additions & 436 deletions

File tree

ccv/chains/evm/deployment/v1_7_0/adapters/tokens.go

Lines changed: 5 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
evm_tokens "github.com/smartcontractkit/chainlink-ccip/ccv/chains/evm/deployment/v1_7_0/sequences/tokens"
1313
"github.com/smartcontractkit/chainlink-ccip/ccv/chains/evm/deployment/v2_0_0/operations/siloed_lock_release_token_pool"
1414
"github.com/smartcontractkit/chainlink-ccip/ccv/chains/evm/deployment/v2_0_0/operations/token_pool"
15-
evmutils "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/utils"
1615
"github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/utils/operations/contract"
1716
bnmOps "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_0_0/operations/burn_mint_erc20"
1817
bnmDripOps "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_0_0/operations/burn_mint_erc20_with_drip"
@@ -22,12 +21,9 @@ import (
2221
tarseq "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_5_0/sequences"
2322
evm16seq "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_6_0/sequences"
2423

25-
ownershipAdapters "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_0_0/adapters"
26-
deployapi "github.com/smartcontractkit/chainlink-ccip/deployment/deploy"
2724
"github.com/smartcontractkit/chainlink-ccip/deployment/tokens"
2825
cciputils "github.com/smartcontractkit/chainlink-ccip/deployment/utils"
2926
datastore_utils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore"
30-
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/mcms"
3127
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/sequences"
3228
"github.com/smartcontractkit/chainlink-deployments-framework/chain"
3329
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
@@ -39,18 +35,17 @@ import (
3935
var _ tokens.TokenAdapter = &TokenAdapter{}
4036

4137
// TokenAdapter is the adapter for EVM tokens using 2.0.0 token pools.
42-
type TokenAdapter struct{}
38+
// It embeds the v1.6.0 EVMAdapter (which itself embeds EVMTokenBase) and
39+
// overrides only the methods that differ for 2.0.0 pools.
40+
type TokenAdapter struct {
41+
evm16seq.EVMAdapter
42+
}
4343

4444
// ConfigureTokenForTransfersSequence returns the sequence for configuring an EVM token with a 2.0.0 token pool.
4545
func (t *TokenAdapter) ConfigureTokenForTransfersSequence() *cldf_ops.Sequence[tokens.ConfigureTokenForTransfersInput, sequences.OnChainOutput, chain.BlockChains] {
4646
return evm_tokens.ConfigureTokenForTransfers
4747
}
4848

49-
// AddressRefToBytes returns an EVM address reference as an EVM address.
50-
func (t *TokenAdapter) AddressRefToBytes(ref datastore.AddressRef) ([]byte, error) {
51-
return common.HexToAddress(ref.Address).Bytes(), nil
52-
}
53-
5449
// DeriveTokenAddress derives the token address from a token pool reference, returning it as an EVM address.
5550
func (t *TokenAdapter) DeriveTokenAddress(e deployment.Environment, chainSelector uint64, poolRef datastore.AddressRef) ([]byte, error) {
5651
evmChain, ok := e.BlockChains.EVMChains()[chainSelector]
@@ -70,39 +65,6 @@ func (t *TokenAdapter) DeriveTokenAddress(e deployment.Environment, chainSelecto
7065
})
7166
}
7267

73-
func (t *TokenAdapter) DeployToken() *cldf_ops.Sequence[tokens.DeployTokenInput, sequences.OnChainOutput, chain.BlockChains] {
74-
return evm16seq.DeployToken
75-
}
76-
77-
func (t *TokenAdapter) DeployTokenVerify(e deployment.Environment, input tokens.DeployTokenInput) error {
78-
tokenAddr, err := datastore_utils.FindAndFormatRef(input.ExistingDataStore, datastore.AddressRef{
79-
ChainSelector: input.ChainSelector,
80-
Type: datastore.ContractType(input.Type),
81-
Qualifier: input.Symbol,
82-
}, input.ChainSelector, datastore_utils.FullRef)
83-
if err == nil {
84-
e.OperationsBundle.Logger.Info("Token already deployed at address:", tokenAddr.Address)
85-
return nil
86-
}
87-
88-
if err := evmutils.ValidateEVMAddress(input.CCIPAdmin, "CCIPAdmin"); err != nil {
89-
return err
90-
}
91-
if err := evmutils.ValidateEVMAddress(input.ExternalAdmin, "ExternalAdmin"); err != nil {
92-
return err
93-
}
94-
95-
if input.Decimals > 18 {
96-
return fmt.Errorf("EVM tokens cannot have more than 18 decimals, got %d", input.Decimals)
97-
}
98-
99-
if input.PreMint != nil && input.Supply != nil && *input.Supply != 0 && *input.PreMint > *input.Supply {
100-
return fmt.Errorf("pre-mint amount cannot be greater than max supply, got pre-mint %d and supply %d", *input.PreMint, *input.Supply)
101-
}
102-
103-
return nil
104-
}
105-
10668
func (t *TokenAdapter) DeployTokenPoolForToken() *cldf_ops.Sequence[tokens.DeployTokenPoolInput, sequences.OnChainOutput, chain.BlockChains] {
10769
return cldf_ops.NewSequence(
10870
"evm-2.0-adapter:deploy-token-pool-for-token",
@@ -286,11 +248,6 @@ func (t *TokenAdapter) DeployTokenPoolForToken() *cldf_ops.Sequence[tokens.Deplo
286248
)
287249
}
288250

289-
func (t *TokenAdapter) SetPool() *cldf_ops.Sequence[tokens.TPRLRemotes, sequences.OnChainOutput, chain.BlockChains] {
290-
// TODO implement me
291-
return nil
292-
}
293-
294251
func (t *TokenAdapter) DeriveTokenDecimals(e deployment.Environment, chainSelector uint64, poolRef datastore.AddressRef, token []byte) (uint8, error) {
295252
evmChain, ok := e.BlockChains.EVMChains()[chainSelector]
296253
if !ok {
@@ -329,10 +286,6 @@ func (t *TokenAdapter) DeriveTokenDecimals(e deployment.Environment, chainSelect
329286
return decimals, nil
330287
}
331288

332-
func (t *TokenAdapter) DeriveTokenPoolCounterpart(e deployment.Environment, chainSelector uint64, tokenPool []byte, token []byte) ([]byte, error) {
333-
return tokenPool, nil
334-
}
335-
336289
func (t *TokenAdapter) SetTokenPoolRateLimits() *cldf_ops.Sequence[tokens.TPRLRemotes, sequences.OnChainOutput, chain.BlockChains] {
337290
return cldf_ops.NewSequence(
338291
"evm-2.0-adapter:set-token-pool-rate-limits",
@@ -481,55 +434,6 @@ func (t *TokenAdapter) ManualRegistration() *cldf_ops.Sequence[tokens.ManualRegi
481434
})
482435
}
483436

484-
func (t *TokenAdapter) UpdateAuthorities() *cldf_ops.Sequence[tokens.UpdateAuthoritiesInput, sequences.OnChainOutput, *deployment.Environment] {
485-
return cldf_ops.NewSequence(
486-
"evm-2.0-adapter:update-authorities",
487-
cciputils.Version_2_0_0,
488-
"Transfer token pool ownership to timelock on EVM chain",
489-
func(b cldf_ops.Bundle, e *deployment.Environment, input tokens.UpdateAuthoritiesInput) (sequences.OnChainOutput, error) {
490-
evmChain, ok := e.BlockChains.EVMChains()[input.ChainSelector]
491-
if !ok {
492-
return sequences.OnChainOutput{}, fmt.Errorf("chain with selector %d not found", input.ChainSelector)
493-
}
494-
495-
timelockRef, err := datastore_utils.FindAndFormatRef(e.DataStore, datastore.AddressRef{
496-
Type: datastore.ContractType(cciputils.RBACTimelock),
497-
ChainSelector: evmChain.Selector,
498-
Qualifier: cciputils.CLLQualifier,
499-
}, evmChain.Selector, datastore_utils.FullRef)
500-
if err != nil {
501-
return sequences.OnChainOutput{}, fmt.Errorf("failed to find timelock for chain %d: %w", input.ChainSelector, err)
502-
}
503-
504-
adapter := &ownershipAdapters.EVMTransferOwnershipAdapter{}
505-
if err := adapter.InitializeTimelockAddress(*e, mcms.Input{Qualifier: cciputils.CLLQualifier}); err != nil {
506-
return sequences.OnChainOutput{}, fmt.Errorf("failed to initialize timelock address: %w", err)
507-
}
508-
509-
ownershipInput := deployapi.TransferOwnershipPerChainInput{
510-
ChainSelector: evmChain.Selector,
511-
CurrentOwner: evmChain.DeployerKey.From.Hex(),
512-
ProposedOwner: timelockRef.Address,
513-
ContractRef: []datastore.AddressRef{input.TokenPoolRef},
514-
}
515-
516-
var result sequences.OnChainOutput
517-
result, err = sequences.RunAndMergeSequence(b, e.BlockChains,
518-
adapter.SequenceTransferOwnershipViaMCMS(), ownershipInput, result)
519-
if err != nil {
520-
return sequences.OnChainOutput{}, fmt.Errorf("failed to transfer ownership on chain %d: %w", input.ChainSelector, err)
521-
}
522-
523-
result, err = sequences.RunAndMergeSequence(b, e.BlockChains,
524-
adapter.SequenceAcceptOwnership(), ownershipInput, result)
525-
if err != nil {
526-
return sequences.OnChainOutput{}, fmt.Errorf("failed to accept ownership on chain %d: %w", input.ChainSelector, err)
527-
}
528-
529-
return result, nil
530-
})
531-
}
532-
533437
func (t *TokenAdapter) MigrateLockReleasePoolLiquiditySequence() *cldf_ops.Sequence[tokens.MigrateLockReleasePoolLiquidityInput, sequences.OnChainOutput, chain.BlockChains] {
534438
return evm_tokens.MigrateLockReleasePoolLiquidity
535439
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package adapters
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/ethereum/go-ethereum/common"
7+
8+
"github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/utils"
9+
v1_0_0_seq "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_0_0/sequences"
10+
deployops "github.com/smartcontractkit/chainlink-ccip/deployment/deploy"
11+
tokensapi "github.com/smartcontractkit/chainlink-ccip/deployment/tokens"
12+
cciputils "github.com/smartcontractkit/chainlink-ccip/deployment/utils"
13+
datastore_utils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore"
14+
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/mcms"
15+
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/sequences"
16+
cldf_chain "github.com/smartcontractkit/chainlink-deployments-framework/chain"
17+
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
18+
"github.com/smartcontractkit/chainlink-deployments-framework/deployment"
19+
cldf_ops "github.com/smartcontractkit/chainlink-deployments-framework/operations"
20+
)
21+
22+
// EVMTokenBase provides version-agnostic EVM token adapter methods that are
23+
// shared across all pool versions (v1.5.1, v1.6.0, v1.6.1, v2.0.0).
24+
type EVMTokenBase struct{}
25+
26+
func (a *EVMTokenBase) AddressRefToBytes(ref datastore.AddressRef) ([]byte, error) {
27+
if !common.IsHexAddress(ref.Address) {
28+
return nil, fmt.Errorf("address %q is not a valid hex address", ref.Address)
29+
}
30+
31+
return common.HexToAddress(ref.Address).Bytes(), nil
32+
}
33+
34+
func (a *EVMTokenBase) DeployToken() *cldf_ops.Sequence[tokensapi.DeployTokenInput, sequences.OnChainOutput, cldf_chain.BlockChains] {
35+
return v1_0_0_seq.DeployToken
36+
}
37+
38+
func (a *EVMTokenBase) DeployTokenVerify(e deployment.Environment, input tokensapi.DeployTokenInput) error {
39+
tokenAddr, err := datastore_utils.FindAndFormatRef(input.ExistingDataStore, datastore.AddressRef{
40+
ChainSelector: input.ChainSelector,
41+
Type: datastore.ContractType(input.Type),
42+
Qualifier: input.Symbol,
43+
}, input.ChainSelector, datastore_utils.FullRef)
44+
if err == nil {
45+
e.OperationsBundle.Logger.Info("Token already deployed at address:", tokenAddr.Address)
46+
return nil
47+
}
48+
49+
if err := utils.ValidateEVMAddress(input.CCIPAdmin, "CCIPAdmin"); err != nil {
50+
return err
51+
}
52+
if err := utils.ValidateEVMAddress(input.ExternalAdmin, "ExternalAdmin"); err != nil {
53+
return err
54+
}
55+
56+
if input.Decimals > 18 {
57+
return fmt.Errorf("EVM tokens cannot have more than 18 decimals, got %d", input.Decimals)
58+
}
59+
60+
if input.PreMint != nil && input.Supply != nil && *input.Supply != 0 && *input.PreMint > *input.Supply {
61+
return fmt.Errorf("pre-mint amount cannot be greater than max supply, got pre-mint %d and supply %d", *input.PreMint, *input.Supply)
62+
}
63+
64+
return nil
65+
}
66+
67+
func (a *EVMTokenBase) DeriveTokenPoolCounterpart(_ deployment.Environment, _ uint64, tokenPool []byte, _ []byte) ([]byte, error) {
68+
return tokenPool, nil
69+
}
70+
71+
// UpdateAuthorities transfers token pool ownership to the timelock via MCMS.
72+
// It creates a self-contained EVMTransferOwnershipAdapter within the sequence
73+
// closure so it works correctly regardless of how the embedding struct is initialized.
74+
func (a *EVMTokenBase) UpdateAuthorities() *cldf_ops.Sequence[tokensapi.UpdateAuthoritiesInput, sequences.OnChainOutput, *deployment.Environment] {
75+
return cldf_ops.NewSequence(
76+
"evm-base:update-authorities",
77+
cciputils.Version_1_0_0,
78+
"Transfer token pool ownership to timelock on EVM chain",
79+
func(b cldf_ops.Bundle, e *deployment.Environment, input tokensapi.UpdateAuthoritiesInput) (sequences.OnChainOutput, error) {
80+
chain, ok := e.BlockChains.EVMChains()[input.ChainSelector]
81+
if !ok {
82+
return sequences.OnChainOutput{}, fmt.Errorf("chain with selector %d not defined", input.ChainSelector)
83+
}
84+
85+
timelockRef, err := datastore_utils.FindAndFormatRef(
86+
e.DataStore,
87+
datastore.AddressRef{
88+
Type: datastore.ContractType(cciputils.RBACTimelock),
89+
ChainSelector: chain.Selector,
90+
Qualifier: cciputils.CLLQualifier,
91+
},
92+
chain.Selector,
93+
datastore_utils.FullRef,
94+
)
95+
if err != nil {
96+
return sequences.OnChainOutput{}, fmt.Errorf("failed to find timelock address for chain %d: %w", input.ChainSelector, err)
97+
}
98+
99+
adapter := &EVMTransferOwnershipAdapter{}
100+
if err := adapter.InitializeTimelockAddress(*e, mcms.Input{Qualifier: cciputils.CLLQualifier}); err != nil {
101+
return sequences.OnChainOutput{}, fmt.Errorf("failed to initialize timelock address for chain %d: %w", input.ChainSelector, err)
102+
}
103+
104+
ownershipInput := deployops.TransferOwnershipPerChainInput{
105+
ChainSelector: chain.Selector,
106+
CurrentOwner: chain.DeployerKey.From.Hex(),
107+
ProposedOwner: timelockRef.Address,
108+
ContractRef: []datastore.AddressRef{input.TokenPoolRef},
109+
}
110+
111+
var result sequences.OnChainOutput
112+
result, err = sequences.RunAndMergeSequence(b, e.BlockChains,
113+
adapter.SequenceTransferOwnershipViaMCMS(), ownershipInput, result)
114+
if err != nil {
115+
return sequences.OnChainOutput{}, fmt.Errorf("failed to transfer ownership on chain %d: %w", input.ChainSelector, err)
116+
}
117+
118+
result, err = sequences.RunAndMergeSequence(b, e.BlockChains,
119+
adapter.SequenceAcceptOwnership(), ownershipInput, result)
120+
if err != nil {
121+
return sequences.OnChainOutput{}, fmt.Errorf("failed to accept ownership on chain %d: %w", input.ChainSelector, err)
122+
}
123+
124+
return result, nil
125+
})
126+
}
127+
128+
func (a *EVMTokenBase) MigrateLockReleasePoolLiquiditySequence() *cldf_ops.Sequence[tokensapi.MigrateLockReleasePoolLiquidityInput, sequences.OnChainOutput, cldf_chain.BlockChains] {
129+
return nil
130+
}

chains/evm/deployment/v1_6_0/sequences/token.go renamed to chains/evm/deployment/v1_0_0/sequences/token.go

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ import (
2424
bnm_erc20_bindings "github.com/smartcontractkit/chainlink-evm/gethwrappers/shared/generated/initial/burn_mint_erc20"
2525
)
2626

27-
// tokenSupportsAdminRole returns true if the token type supports AccessControl admin roles.
28-
// ERC20 is the basic token without role management.
29-
// BurnMint tokens inherit from AccessControl and support role management.
3027
func tokenSupportsAdminRole(tokenType deployment.ContractType) bool {
3128
switch tokenType {
3229
case burn_mint_erc20.ContractType,
@@ -37,8 +34,6 @@ func tokenSupportsAdminRole(tokenType deployment.ContractType) bool {
3734
}
3835
}
3936

40-
// tokenSupportsCCIPAdmin returns true if the token type supports AccessControl CCIP admin roles.
41-
// ERC20 is the basic token without role management.
4237
func tokenSupportsCCIPAdmin(tokenType deployment.ContractType) bool {
4338
switch tokenType {
4439
case burn_mint_erc20.ContractType,
@@ -49,8 +44,6 @@ func tokenSupportsCCIPAdmin(tokenType deployment.ContractType) bool {
4944
}
5045
}
5146

52-
// tokenSupportsPreMint returns true if the token type supports pre-minting tokens to the deployer
53-
// address during deployment.
5447
func tokenSupportsPreMint(tokenType deployment.ContractType) bool {
5548
switch tokenType {
5649
case burn_mint_erc20.ContractType, burn_mint_erc20_with_drip.ContractType:
@@ -72,13 +65,11 @@ var DeployToken = cldf_ops.NewSequence(
7265
var tokenRef datastore.AddressRef
7366
qualifier := input.Symbol
7467

75-
// Default max supply is 0 (i.e. unlimited supply)
7668
maxSupply := big.NewInt(0)
7769
if input.Supply != nil {
7870
maxSupply = tokenapi.ScaleTokenAmount(new(big.Int).SetUint64(*input.Supply), input.Decimals)
7971
}
8072

81-
// Default pre-mint amount is 0 (i.e. don't pre mint any tokens)
8273
preMint := big.NewInt(0)
8374
if input.PreMint != nil {
8475
preMint = tokenapi.ScaleTokenAmount(new(big.Int).SetUint64(*input.PreMint), input.Decimals)
@@ -108,7 +99,7 @@ var DeployToken = cldf_ops.NewSequence(
10899
Symbol: input.Symbol,
109100
Decimals: input.Decimals,
110101
MaxSupply: maxSupply,
111-
PreMint: preMint, // pre-mint given amount to deployer address. Not advised to use against mainnet.
102+
PreMint: preMint,
112103
},
113104
Qualifier: &qualifier,
114105
}, nil)
@@ -125,7 +116,7 @@ var DeployToken = cldf_ops.NewSequence(
125116
Symbol: input.Symbol,
126117
Decimals: input.Decimals,
127118
MaxSupply: maxSupply,
128-
PreMint: preMint, // pre-mint given amount to deployer address. Not advised to use against mainnet.
119+
PreMint: preMint,
129120
},
130121
Qualifier: &qualifier,
131122
}, nil)
@@ -140,7 +131,6 @@ var DeployToken = cldf_ops.NewSequence(
140131
tokenAddr := common.HexToAddress(tokenRef.Address)
141132
addresses = append(addresses, tokenRef)
142133

143-
// If senders are provided and token supports pre-minting, transfer the pre-minted tokens from the deployer to the first sender in the list
144134
if tokenSupportsPreMint(input.Type) && preMint.Cmp(big.NewInt(0)) > 0 && len(input.Senders) > 0 {
145135
firstSender := input.Senders[0]
146136
if !common.IsHexAddress(firstSender) {
@@ -167,7 +157,6 @@ var DeployToken = cldf_ops.NewSequence(
167157
writes = append(writes, transferReport.Output)
168158
}
169159

170-
// set CCIP admin to the provided address
171160
if input.CCIPAdmin != "" && tokenSupportsCCIPAdmin(input.Type) {
172161
setCCIPAdminReport, err := cldf_ops.ExecuteOperation(b, burn_mint_erc20.SetCCIPAdmin, chain, contract.FunctionInput[string]{
173162
ChainSelector: chain.Selector,
@@ -180,9 +169,7 @@ var DeployToken = cldf_ops.NewSequence(
180169
writes = append(writes, setCCIPAdminReport.Output)
181170
}
182171

183-
// Grant admin role to external admin if provided and token supports it
184172
if input.ExternalAdmin != "" && tokenSupportsAdminRole(input.Type) {
185-
// Read the default admin role
186173
token, err := bnm_erc20_bindings.NewBurnMintERC20(tokenAddr, chain.Client)
187174
if err != nil {
188175
return sequences.OnChainOutput{}, fmt.Errorf("failed to instantiate BurnMintERC20 contract: %w", err)
@@ -192,7 +179,6 @@ var DeployToken = cldf_ops.NewSequence(
192179
return sequences.OnChainOutput{}, fmt.Errorf("failed to get default admin role constant: %w", err)
193180
}
194181

195-
// Grant admin role to the external admin
196182
grantReport, err := cldf_ops.ExecuteOperation(b, burn_mint_erc20.GrantAdminRole, chain, contract.FunctionInput[burn_mint_erc20.RoleAssignment]{
197183
ChainSelector: chain.Selector,
198184
Address: tokenAddr,

chains/evm/deployment/v1_6_0/sequences/adapter.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func init() {
4646
}
4747

4848
type EVMAdapter struct {
49+
evm1_0_0.EVMTokenBase
4950
// transferOwnershipAdapter is shared so InitializeTimelockAddress populates the same instance
5051
// used by SequenceTransferOwnershipViaMCMS / SequenceAcceptOwnership.
5152
transferOwnershipAdapter *evm1_0_0.EVMTransferOwnershipAdapter

0 commit comments

Comments
 (0)