Skip to content

Commit f76eec3

Browse files
feat: address normalizer (#2041)
* feat: normalize addresses WIP * fix: wrap error * docs: update method call Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 7a9a58b commit f76eec3

12 files changed

Lines changed: 302 additions & 19 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package adapters
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/ethereum/go-ethereum/common"
7+
8+
deployapi "github.com/smartcontractkit/chainlink-ccip/deployment/deploy"
9+
)
10+
11+
var _ deployapi.AddressNormalizer = (*EVMAddressNormalizer)(nil)
12+
13+
// EVMAddressNormalizer provides EIP-55 checksummed hex for datastore-aligned EVM lookups.
14+
type EVMAddressNormalizer struct{}
15+
16+
func (EVMAddressNormalizer) NormalizeAddress(addr string) (string, error) {
17+
if !common.IsHexAddress(addr) {
18+
return "", fmt.Errorf("address %q is not a valid hex address", addr)
19+
}
20+
return common.HexToAddress(addr).Hex(), nil
21+
}

chains/evm/deployment/v1_0_0/adapters/init.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ func init() {
1818
mcmsreaderapi.GetRegistry().RegisterMCMSReader(chain_selectors.FamilyEVM, &EVMMCMSReader{})
1919
tokensapi.GetTokenAdapterRegistry().RegisterTokenAdapter(chain_selectors.FamilyEVM, v, &EVMTokenBase{})
2020
feesapi.GetRegistry().RegisterFeeResolver(chain_selectors.FamilyEVM, &EVMFeeResolver{})
21+
deployapi.GetAddressNormalizerRegistry().RegisterAddressNormalizer(chain_selectors.FamilyEVM, &EVMAddressNormalizer{})
2122
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package adapters
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/gagliardetto/solana-go"
7+
8+
deployapi "github.com/smartcontractkit/chainlink-ccip/deployment/deploy"
9+
)
10+
11+
var _ deployapi.AddressNormalizer = (*SolanaAddressNormalizer)(nil)
12+
13+
// SolanaAddressNormalizer provides canonical base58 for datastore-aligned SVM lookups.
14+
type SolanaAddressNormalizer struct{}
15+
16+
func (SolanaAddressNormalizer) NormalizeAddress(addr string) (string, error) {
17+
pubKey, err := solana.PublicKeyFromBase58(addr)
18+
if err != nil {
19+
return "", fmt.Errorf("failed to parse address '%s' as base58 Solana public key: %w", addr, err)
20+
}
21+
return pubKey.String(), nil
22+
}

chains/solana/deployment/v1_0_0/adapters/init.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ package adapters
33
import (
44
chainsel "github.com/smartcontractkit/chain-selectors"
55

6+
deployapi "github.com/smartcontractkit/chainlink-ccip/deployment/deploy"
67
"github.com/smartcontractkit/chainlink-ccip/deployment/fees"
78
)
89

910
func init() {
1011
fees.GetRegistry().RegisterFeeResolver(chainsel.FamilySolana, &SolanaFeeResolver{})
12+
deployapi.GetAddressNormalizerRegistry().RegisterAddressNormalizer(chainsel.FamilySolana, &SolanaAddressNormalizer{})
1113
}

chains/solana/deployment/v1_6_0/sequences/tokens.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ import (
2222
"github.com/smartcontractkit/chainlink-deployments-framework/deployment"
2323
"github.com/smartcontractkit/chainlink-deployments-framework/operations"
2424
cldf_ops "github.com/smartcontractkit/chainlink-deployments-framework/operations"
25-
26-
tokensapi "github.com/smartcontractkit/chainlink-ccip/deployment/tokens"
2725
)
2826

2927
func (a *SolanaAdapter) ConfigureTokenForTransfersSequence() *cldf_ops.Sequence[tokenapi.ConfigureTokenForTransfersInput, sequences.OnChainOutput, cldf_chain.BlockChains] {
@@ -470,7 +468,7 @@ func (a *SolanaAdapter) DeployToken() *cldf_ops.Sequence[tokenapi.DeployTokenInp
470468
}
471469
var premint uint64 = 0
472470
if input.PreMint != nil {
473-
value := tokensapi.ScaleTokenAmount(new(big.Int).SetUint64(*input.PreMint), input.Decimals)
471+
value := tokenapi.ScaleTokenAmount(new(big.Int).SetUint64(*input.PreMint), input.Decimals)
474472
if !value.IsUint64() {
475473
return sequences.OnChainOutput{}, fmt.Errorf("pre-mint amount is too large after scaling by decimals: %s", value.String())
476474
}

deployment/deploy/product.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,61 @@ type LaneVersionResolver interface {
112112
IsSupportedChain(e cldf.Environment, chainSel uint64) bool
113113
DeriveLaneVersionsForChain(e cldf.Environment, chainSel uint64) (map[uint64]*semver.Version, []*semver.Version, error)
114114
}
115+
116+
// AddressNormalizer canonicalizes VM-specific address strings so datastore lookups
117+
// and config parsing behave consistently across deployments (same role as versioning
118+
// of pool contracts is orthogonal).
119+
type AddressNormalizer interface {
120+
NormalizeAddress(address string) (string, error)
121+
}
122+
123+
type addressNormalizerID string
124+
125+
func newAddressNormalizerID(chainFamily string) addressNormalizerID {
126+
return addressNormalizerID(chainFamily)
127+
}
128+
129+
// AddressNormalizerRegistry maps chain family strings to address normalizers.
130+
// It is analogous to FeeAdapterRegistry's family-keyed FeeResolver slot.
131+
type AddressNormalizerRegistry struct {
132+
mu sync.Mutex
133+
m map[addressNormalizerID]AddressNormalizer
134+
}
135+
136+
func newAddressNormalizerRegistry() *AddressNormalizerRegistry {
137+
return &AddressNormalizerRegistry{
138+
m: make(map[addressNormalizerID]AddressNormalizer),
139+
}
140+
}
141+
142+
var (
143+
addressNormalizerSingleton *AddressNormalizerRegistry
144+
addressNormalizerOnce sync.Once
145+
)
146+
147+
// GetAddressNormalizerRegistry returns the singleton address normalizer registry.
148+
func GetAddressNormalizerRegistry() *AddressNormalizerRegistry {
149+
addressNormalizerOnce.Do(func() {
150+
addressNormalizerSingleton = newAddressNormalizerRegistry()
151+
})
152+
return addressNormalizerSingleton
153+
}
154+
155+
// RegisterAddressNormalizer registers normalizer for chainFamily if not already set.
156+
func (r *AddressNormalizerRegistry) RegisterAddressNormalizer(chainFamily string, n AddressNormalizer) {
157+
id := newAddressNormalizerID(chainFamily)
158+
r.mu.Lock()
159+
defer r.mu.Unlock()
160+
if _, exists := r.m[id]; !exists {
161+
r.m[id] = n
162+
}
163+
}
164+
165+
// GetAddressNormalizer returns the AddressNormalizer registered for chainFamily.
166+
func (r *AddressNormalizerRegistry) GetAddressNormalizer(chainFamily string) (AddressNormalizer, bool) {
167+
id := newAddressNormalizerID(chainFamily)
168+
r.mu.Lock()
169+
defer r.mu.Unlock()
170+
a, ok := r.m[id]
171+
return a, ok
172+
}

deployment/docs/implementing-adapters.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ func (a *MyChainAdapter) DeriveTokenPoolCounterpart(e Environment, chainSelector
167167
}
168168
```
169169

170+
#### AddressNormalizer (config and datastore addresses)
171+
172+
Some changesets normalize user-supplied address strings before datastore lookups. That logic lives on **`deploy.AddressNormalizer`** in **`deployment/deploy`**, registered on **`deploy.GetAddressNormalizerRegistry()`** and keyed **only by chain family** (not by token adapter semver).
173+
174+
- Implement the interface in **`chains/<family>/deployment/v1_0_0/adapters/address_normalizer.go`** (see EVM and Solana in this repo).
175+
- Register once from that package’s **`init()`** with **`deploy.GetAddressNormalizerRegistry().RegisterAddressNormalizer(chain_selectors.Family..., &MyAddressNormalizer{})`** (first registration wins).
176+
- Optionally embed the normalizer on your **`TokenAdapter`** so the type still satisfies **`AddressNormalizer`** when useful; cross-package callers that only have a chain selector should use the family-keyed registry (as **`deployment/tokens`** does via **`chain_selectors.GetSelectorFamily`**).
177+
170178
#### 4.4 FeeAdapter, MCMSReader, TransferOwnershipAdapter, CurseAdapter, CurseSubjectAdapter
171179

172180
Follow the same pattern -- see [Interfaces Reference](interfaces.md) for the full method signatures.

deployment/tokens/configure_tokens_for_transfers.go

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,22 @@ func processTokenConfigForChain(e deployment.Environment, mcmsRegistry *changese
9595
reports := make([]cldf_ops.Report[any, any], 0)
9696
ds := datastore.NewMemoryDataStore()
9797

98+
var err error
9899
for selector, token := range cfg {
100+
token.TokenPoolRef, err = TryNormalizeAddressRef(selector, token.TokenPoolRef)
101+
if err != nil {
102+
return nil, nil, nil, fmt.Errorf("failed to normalize token pool ref address for chain selector %d: %w", selector, err)
103+
}
104+
token.TokenRef, err = TryNormalizeAddressRef(selector, token.TokenRef)
105+
if err != nil {
106+
return nil, nil, nil, fmt.Errorf("failed to normalize token ref address for chain selector %d: %w", selector, err)
107+
}
108+
token.RegistryRef, err = TryNormalizeAddressRef(selector, token.RegistryRef)
109+
if err != nil {
110+
return nil, nil, nil, fmt.Errorf("failed to normalize registry ref address for chain selector %d: %w", selector, err)
111+
}
112+
cfg[selector] = token
113+
99114
tokenPool, err := datastore_utils.FindAndFormatRef(e.DataStore, token.TokenPoolRef, selector, datastore_utils.FullRef)
100115
if err != nil {
101116
return nil, nil, nil, fmt.Errorf("failed to resolve token pool ref on chain with selector %d: %w", selector, err)
@@ -201,7 +216,11 @@ func convertRemoteChainConfig(
201216
}
202217

203218
if inCfg.RemotePool != nil {
204-
fullRemotePoolRef, err := datastore_utils.FindAndFormatRef(e.DataStore, *inCfg.RemotePool, remoteChainSelector, datastore_utils.FullRef)
219+
remotePoolRef, err := TryNormalizeAddressRef(remoteChainSelector, *inCfg.RemotePool)
220+
if err != nil {
221+
return outCfg, fmt.Errorf("failed to normalize remote pool ref address for remote chain selector %d: %w", remoteChainSelector, err)
222+
}
223+
fullRemotePoolRef, err := datastore_utils.FindAndFormatRef(e.DataStore, remotePoolRef, remoteChainSelector, datastore_utils.FullRef)
205224
if err != nil {
206225
return outCfg, fmt.Errorf("failed to resolve remote pool ref %s: %w", datastore_utils.SprintRef(*inCfg.RemotePool), err)
207226
}
@@ -215,7 +234,11 @@ func convertRemoteChainConfig(
215234
}
216235
// Can either provide the token reference directly or derive it from the pool reference.
217236
if inCfg.RemoteToken != nil {
218-
outCfg.RemoteToken, err = datastore_utils.FindAndFormatRef(e.DataStore, *inCfg.RemoteToken, remoteChainSelector, remoteAdapter.AddressRefToBytes)
237+
remoteTokenRef, normErr := TryNormalizeAddressRef(remoteChainSelector, *inCfg.RemoteToken)
238+
if normErr != nil {
239+
return outCfg, fmt.Errorf("failed to normalize remote token ref address for remote chain selector %d: %w", remoteChainSelector, normErr)
240+
}
241+
outCfg.RemoteToken, err = datastore_utils.FindAndFormatRef(e.DataStore, remoteTokenRef, remoteChainSelector, remoteAdapter.AddressRefToBytes)
219242
if err != nil {
220243
e.Logger.Warnf("failed to resolve remote token ref %s: %v. Will attempt to derive remote token address from pool reference", datastore_utils.SprintRef(*inCfg.RemoteToken), err)
221244
outCfg.RemoteToken, err = remoteAdapter.DeriveTokenAddress(e, remoteChainSelector, fullRemotePoolRef)
@@ -240,30 +263,46 @@ func convertRemoteChainConfig(
240263
}
241264
}
242265
for _, ccvRef := range inCfg.OutboundCCVs {
243-
fullCCVRef, err := datastore_utils.FindAndFormatRef(e.DataStore, ccvRef, chainSelector, datastore_utils.FullRef)
266+
ref, err := TryNormalizeAddressRef(chainSelector, ccvRef)
267+
if err != nil {
268+
return outCfg, fmt.Errorf("failed to normalize outbound CCV ref address for chain selector %d: %w", chainSelector, err)
269+
}
270+
fullCCVRef, err := datastore_utils.FindAndFormatRef(e.DataStore, ref, chainSelector, datastore_utils.FullRef)
244271
if err != nil {
245-
return outCfg, fmt.Errorf("failed to resolve outbound CCV ref %s: %w", datastore_utils.SprintRef(ccvRef), err)
272+
return outCfg, fmt.Errorf("failed to resolve outbound CCV ref %s: %w", datastore_utils.SprintRef(ref), err)
246273
}
247274
outCfg.OutboundCCVs = append(outCfg.OutboundCCVs, fullCCVRef.Address)
248275
}
249276
for _, ccvRef := range inCfg.InboundCCVs {
250-
fullCCVRef, err := datastore_utils.FindAndFormatRef(e.DataStore, ccvRef, chainSelector, datastore_utils.FullRef)
277+
ref, err := TryNormalizeAddressRef(chainSelector, ccvRef)
278+
if err != nil {
279+
return outCfg, fmt.Errorf("failed to normalize inbound CCV ref address for chain selector %d: %w", chainSelector, err)
280+
}
281+
fullCCVRef, err := datastore_utils.FindAndFormatRef(e.DataStore, ref, chainSelector, datastore_utils.FullRef)
251282
if err != nil {
252-
return outCfg, fmt.Errorf("failed to resolve inbound CCV ref %s: %w", datastore_utils.SprintRef(ccvRef), err)
283+
return outCfg, fmt.Errorf("failed to resolve inbound CCV ref %s: %w", datastore_utils.SprintRef(ref), err)
253284
}
254285
outCfg.InboundCCVs = append(outCfg.InboundCCVs, fullCCVRef.Address)
255286
}
256287
for _, ccvRef := range inCfg.OutboundCCVsToAddAboveThreshold {
257-
fullCCVRef, err := datastore_utils.FindAndFormatRef(e.DataStore, ccvRef, chainSelector, datastore_utils.FullRef)
288+
ref, err := TryNormalizeAddressRef(chainSelector, ccvRef)
258289
if err != nil {
259-
return outCfg, fmt.Errorf("failed to resolve outbound CCV to add above threshold ref %s: %w", datastore_utils.SprintRef(ccvRef), err)
290+
return outCfg, fmt.Errorf("failed to normalize outbound CCV-above-threshold ref address for chain selector %d: %w", chainSelector, err)
291+
}
292+
fullCCVRef, err := datastore_utils.FindAndFormatRef(e.DataStore, ref, chainSelector, datastore_utils.FullRef)
293+
if err != nil {
294+
return outCfg, fmt.Errorf("failed to resolve outbound CCV to add above threshold ref %s: %w", datastore_utils.SprintRef(ref), err)
260295
}
261296
outCfg.OutboundCCVsToAddAboveThreshold = append(outCfg.OutboundCCVsToAddAboveThreshold, fullCCVRef.Address)
262297
}
263298
for _, ccvRef := range inCfg.InboundCCVsToAddAboveThreshold {
264-
fullCCVRef, err := datastore_utils.FindAndFormatRef(e.DataStore, ccvRef, chainSelector, datastore_utils.FullRef)
299+
ref, err := TryNormalizeAddressRef(chainSelector, ccvRef)
300+
if err != nil {
301+
return outCfg, fmt.Errorf("failed to normalize inbound CCV-above-threshold ref address for chain selector %d: %w", chainSelector, err)
302+
}
303+
fullCCVRef, err := datastore_utils.FindAndFormatRef(e.DataStore, ref, chainSelector, datastore_utils.FullRef)
265304
if err != nil {
266-
return outCfg, fmt.Errorf("failed to resolve inbound CCV to add above threshold ref %s: %w", datastore_utils.SprintRef(ccvRef), err)
305+
return outCfg, fmt.Errorf("failed to resolve inbound CCV to add above threshold ref %s: %w", datastore_utils.SprintRef(ref), err)
267306
}
268307
outCfg.InboundCCVsToAddAboveThreshold = append(outCfg.InboundCCVsToAddAboveThreshold, fullCCVRef.Address)
269308
}

deployment/tokens/migrate_lock_release_pool_liquidity.go

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,20 @@ func makeMigrationApply(_ *TokenAdapterRegistry, mcmsRegistry *changesets.MCMSRe
7575
return cldf.ChangesetOutput{}, fmt.Errorf("migration[%d]: adapter for family '%s' version '%s' does not support liquidity migration", i, family, migration.NewPoolRef.Version)
7676
}
7777

78-
oldPoolRef, err := datastore_utils.FindAndFormatRef(e.DataStore, migration.OldPoolRef, migration.ChainSelector, datastore_utils.FullRef)
78+
oldRef, err := TryNormalizeAddressRef(migration.ChainSelector, migration.OldPoolRef)
79+
if err != nil {
80+
return cldf.ChangesetOutput{}, fmt.Errorf("migration[%d]: failed to normalize old pool ref address: %w", i, err)
81+
}
82+
newRef, err := TryNormalizeAddressRef(migration.ChainSelector, migration.NewPoolRef)
83+
if err != nil {
84+
return cldf.ChangesetOutput{}, fmt.Errorf("migration[%d]: failed to normalize new pool ref address: %w", i, err)
85+
}
86+
87+
oldPoolRef, err := datastore_utils.FindAndFormatRef(e.DataStore, oldRef, migration.ChainSelector, datastore_utils.FullRef)
7988
if err != nil {
8089
return cldf.ChangesetOutput{}, fmt.Errorf("migration[%d]: failed to resolve old pool ref: %w", i, err)
8190
}
82-
newPoolRef, err := datastore_utils.FindAndFormatRef(e.DataStore, migration.NewPoolRef, migration.ChainSelector, datastore_utils.FullRef)
91+
newPoolRef, err := datastore_utils.FindAndFormatRef(e.DataStore, newRef, migration.ChainSelector, datastore_utils.FullRef)
8392
if err != nil {
8493
return cldf.ChangesetOutput{}, fmt.Errorf("migration[%d]: failed to resolve new pool ref: %w", i, err)
8594
}
@@ -96,11 +105,19 @@ func makeMigrationApply(_ *TokenAdapterRegistry, mcmsRegistry *changesets.MCMSRe
96105

97106
var setPoolConfig *MigrationSetPoolConfig
98107
if migration.RegistryRef != nil && migration.TokenRef != nil {
99-
registryRef, err := datastore_utils.FindAndFormatRef(e.DataStore, *migration.RegistryRef, migration.ChainSelector, datastore_utils.FullRef)
108+
regRef, err := TryNormalizeAddressRef(migration.ChainSelector, *migration.RegistryRef)
109+
if err != nil {
110+
return cldf.ChangesetOutput{}, fmt.Errorf("migration[%d]: failed to normalize registry ref address: %w", i, err)
111+
}
112+
tokRef, err := TryNormalizeAddressRef(migration.ChainSelector, *migration.TokenRef)
113+
if err != nil {
114+
return cldf.ChangesetOutput{}, fmt.Errorf("migration[%d]: failed to normalize token ref address for setPool: %w", i, err)
115+
}
116+
registryRef, err := datastore_utils.FindAndFormatRef(e.DataStore, regRef, migration.ChainSelector, datastore_utils.FullRef)
100117
if err != nil {
101118
return cldf.ChangesetOutput{}, fmt.Errorf("migration[%d]: failed to resolve registry ref: %w", i, err)
102119
}
103-
tokenRef, err := datastore_utils.FindAndFormatRef(e.DataStore, *migration.TokenRef, migration.ChainSelector, datastore_utils.FullRef)
120+
tokenRef, err := datastore_utils.FindAndFormatRef(e.DataStore, tokRef, migration.ChainSelector, datastore_utils.FullRef)
104121
if err != nil {
105122
return cldf.ChangesetOutput{}, fmt.Errorf("migration[%d]: failed to resolve token ref: %w", i, err)
106123
}

deployment/tokens/rate_limits.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ func setTokenPoolRateLimitsApply() func(cldf.Environment, TPRLInput) (cldf.Chang
104104
if !exists {
105105
return cldf.ChangesetOutput{}, fmt.Errorf("no TokenPoolAdapter registered for chain family '%s'", family)
106106
}
107+
config.TokenPoolRef, err = TryNormalizeAddressRef(selector, config.TokenPoolRef)
108+
if err != nil {
109+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to normalize token pool ref address on chain selector %d: %w", selector, err)
110+
}
111+
config.TokenRef, err = TryNormalizeAddressRef(selector, config.TokenRef)
112+
if err != nil {
113+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to normalize token ref address on chain selector %d: %w", selector, err)
114+
}
107115
tokenPool, err := datastore_utils.FindAndFormatRef(e.DataStore, config.TokenPoolRef, selector, datastore_utils.FullRef)
108116
if err != nil {
109117
return cldf.ChangesetOutput{}, fmt.Errorf("failed to resolve token pool ref on chain with selector %d: %w", selector, err)
@@ -151,17 +159,26 @@ func setTokenPoolRateLimitsApply() func(cldf.Environment, TPRLInput) (cldf.Chang
151159
return cldf.ChangesetOutput{}, fmt.Errorf("no inputs provided for remote chain with selector %d to chain with selector %d", selector, remoteSelector)
152160
}
153161

162+
counterpart.TokenPoolRef, err = TryNormalizeAddressRef(remoteSelector, counterpart.TokenPoolRef)
163+
if err != nil {
164+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to normalize counterpart token pool ref address on chain selector %d: %w", remoteSelector, err)
165+
}
166+
counterpart.TokenRef, err = TryNormalizeAddressRef(remoteSelector, counterpart.TokenRef)
167+
if err != nil {
168+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to normalize counterpart token ref address on chain selector %d: %w", remoteSelector, err)
169+
}
170+
154171
remoteTokenPool, err := datastore_utils.FindAndFormatRef(e.DataStore, counterpart.TokenPoolRef, remoteSelector, datastore_utils.FullRef)
155172
if err != nil {
156173
return cldf.ChangesetOutput{}, fmt.Errorf("failed to resolve token pool ref on chain with selector %d: %w", remoteSelector, err)
157174
}
158175
remoteTokenBytes, err := datastore_utils.FindAndFormatRef(e.DataStore, counterpart.TokenRef, remoteSelector, counterPartAdapter.AddressRefToBytes)
159176
if err != nil {
160-
return cldf.ChangesetOutput{}, fmt.Errorf("failed to resolve token ref on chain with selector %d: %w", selector, err)
177+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to resolve token ref on chain with selector %d: %w", remoteSelector, err)
161178
}
162179
remoteDecimals, err := counterPartAdapter.DeriveTokenDecimals(e, remoteSelector, remoteTokenPool, remoteTokenBytes)
163180
if err != nil {
164-
return cldf.ChangesetOutput{}, fmt.Errorf("failed to get token decimals for token on chain with selector %d: %w", selector, err)
181+
return cldf.ChangesetOutput{}, fmt.Errorf("failed to get token decimals for token on chain with selector %d: %w", remoteSelector, err)
165182
}
166183
tprlRemote.OutboundRateLimiterConfig, tprlRemote.InboundRateLimiterConfig = GenerateTPRLConfigs(inputs.RateLimit, remoteInputs.RateLimit, decimals, remoteDecimals, family, tokenPool.Version)
167184
rateLimitReport, err := cldf_ops.ExecuteSequence(

0 commit comments

Comments
 (0)