diff --git a/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validation_test.go b/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validation_test.go index 5a2f0ba892..f9a965ee08 100644 --- a/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validation_test.go +++ b/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validation_test.go @@ -2788,3 +2788,54 @@ func TestContractUpgradeIsRepresentable(t *testing.T) { test(true) test(false) } + +func TestContractUpgrade(t *testing.T) { + + t.Parallel() + + const oldCode = ` + access(all) + contract Test { + + access(all) + resource A { + + access(self) + // NOTE: undefined type + let cap: Capability<&B{Undefined}> + } + + access(all) + resource B {} + } + ` + + const newCode = ` + access(all) + contract Test { + + access(all) + entitlement E + + access(all) + resource A { + + access(self) + let cap: Capability + + init(cap: Capability) { + self.cap = cap + } + } + + access(all) + resource B {} + } + ` + + err := testContractUpdate(t, oldCode, newCode) + require.Error(t, err) + + cause := getSingleContractUpdateErrorCause(t, err, "Test") + assertFieldAuthorizationMismatchError(t, cause, "A", "cap", "all", "E") +} diff --git a/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validator.go b/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validator.go index 7cc5870309..1a9a0d1658 100644 --- a/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validator.go +++ b/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validator.go @@ -241,8 +241,12 @@ func (validator *CadenceV042ToV1ContractUpdateValidator) getInterfaceType(intf * func (validator *CadenceV042ToV1ContractUpdateValidator) getIntersectedInterfaces( intersection []*ast.NominalType, ) (interfaceTypes []*sema.InterfaceType) { - for _, interfaceType := range intersection { - interfaceTypes = append(interfaceTypes, validator.getInterfaceType(interfaceType)) + for _, astInterfaceType := range intersection { + interfaceType := validator.getInterfaceType(astInterfaceType) + if interfaceType == nil { + continue + } + interfaceTypes = append(interfaceTypes, interfaceType) } return } @@ -289,6 +293,10 @@ func (validator *CadenceV042ToV1ContractUpdateValidator) expectedAuthorizationOf // been a restricted type with no legacy type interfaces := validator.getIntersectedInterfaces(intersectionTypes) + if len(interfaces) == 0 { + return sema.UnauthorizedAccess + } + intersectionType := sema.NewIntersectionType(nil, nil, interfaces) return intersectionType.SupportedEntitlements().Access()