@@ -41,6 +41,23 @@ func newStorageSlotsByEntity(stakes EntityStakes, keccak []string) storageSlotsB
41
41
return storageSlotsByEntity
42
42
}
43
43
44
+ type storageSlotsValidator struct {
45
+ // Global parameters
46
+ Op * userop.UserOperation
47
+ EntryPoint common.Address
48
+
49
+ // Parameters of specific entities required for all validation
50
+ SenderSlots storageSlots
51
+ FactoryIsStaked bool
52
+
53
+ // Parameters of the entity under validation
54
+ EntityName string
55
+ EntityAddr common.Address
56
+ EntityAccess tracer.AccessMap
57
+ EntitySlots storageSlots
58
+ EntityIsStaked bool
59
+ }
60
+
44
61
func isAssociatedWith (slots storageSlots , slot string ) bool {
45
62
slotN , _ := big .NewInt (0 ).SetString (fmt .Sprintf ("0x%s" , slot ), 0 )
46
63
for _ , k := range slots .ToSlice () {
@@ -53,26 +70,18 @@ func isAssociatedWith(slots storageSlots, slot string) bool {
53
70
return false
54
71
}
55
72
56
- func validateStorageSlotsForEntity (
57
- entityName string ,
58
- op * userop.UserOperation ,
59
- entryPoint common.Address ,
60
- slotsByEntity storageSlotsByEntity ,
61
- entityAccess tracer.AccessMap ,
62
- entityAddr common.Address ,
63
- entityIsStaked bool ,
64
- ) error {
65
- senderSlots , senderSlotOk := slotsByEntity [op .Sender ]
66
- if ! senderSlotOk {
73
+ func (v * storageSlotsValidator ) Process () error {
74
+ senderSlots := v .SenderSlots
75
+ if senderSlots == nil {
67
76
senderSlots = mapset .NewSet [string ]()
68
77
}
69
- storageSlots , entitySlotOk := slotsByEntity [ entityAddr ]
70
- if ! entitySlotOk {
71
- storageSlots = mapset .NewSet [string ]()
78
+ entitySlots := v . EntitySlots
79
+ if entitySlots == nil {
80
+ entitySlots = mapset .NewSet [string ]()
72
81
}
73
82
74
- for addr , access := range entityAccess {
75
- if addr == op . Sender || addr == entryPoint {
83
+ for addr , access := range v . EntityAccess {
84
+ if addr == v . Op . Sender || addr == v . EntryPoint {
76
85
continue
77
86
}
78
87
@@ -84,24 +93,25 @@ func validateStorageSlotsForEntity(
84
93
for key , slotCount := range accessTypes {
85
94
for slot := range slotCount {
86
95
if isAssociatedWith (senderSlots , slot ) {
87
- if len (op .InitCode ) > 0 {
96
+ if (len (v .Op .InitCode ) > 0 && ! v .FactoryIsStaked ) ||
97
+ (len (v .Op .InitCode ) > 0 && v .FactoryIsStaked && v .EntityAddr != v .Op .Sender ) {
88
98
mustStakeSlot = slot
89
99
} else {
90
100
continue
91
101
}
92
- } else if isAssociatedWith (storageSlots , slot ) || addr == entityAddr {
102
+ } else if isAssociatedWith (entitySlots , slot ) || addr == v . EntityAddr {
93
103
mustStakeSlot = slot
94
104
} else {
95
- return fmt .Errorf ("%s has forbidden %s to %s slot %s" , entityName , key , addr2KnownEntity (op , addr ), slot )
105
+ return fmt .Errorf ("%s has forbidden %s to %s slot %s" , v . EntityName , key , addr2KnownEntity (v . Op , addr ), slot )
96
106
}
97
107
}
98
108
}
99
109
100
- if mustStakeSlot != "" && ! entityIsStaked {
110
+ if mustStakeSlot != "" && ! v . EntityIsStaked {
101
111
return fmt .Errorf (
102
112
"unstaked %s accessed %s slot %s" ,
103
- entityName ,
104
- addr2KnownEntity (op , addr ),
113
+ v . EntityName ,
114
+ addr2KnownEntity (v . Op , addr ),
105
115
mustStakeSlot ,
106
116
)
107
117
}
0 commit comments