@@ -639,20 +639,26 @@ readStorage w st = go (simplifyNoLitToKeccak w) (simplifyNoLitToKeccak st)
639639 (a, b) | surelyEqual a b -> Just val
640640 (a, b) | surelyNotEqual a b -> go slot prev
641641
642- -- slot is for a map + map -> skip write
643- (MappingSlot idA _ , MappingSlot idB _ ) | isMap' idB, isMap' idA, idsDontMatch idA idB -> go slot prev
644- (MappingSlot idA keyA, MappingSlot idB keyB) | isMap' idB, isMap' idA, surelyNotEqual keyA keyB -> go slot prev
642+ ( MappingSlot idA _, MappingSlot idB _) | isMap' idB, isMap' idA, idsDontMatch idA idB -> go slot prev
643+ (MappingSlot idA keyA , MappingSlot idB keyB ) | isMap' idB, isMap' idA, idA == idB, surelyNotEqual keyA keyB -> go slot prev
644+ (MappingSlot idA _, ArraySlotZero idB) | isMap' idA, isArray idB -> go slot prev
645645
646- -- special case of array + map -> skip write
647- (ArraySlotWithOffs idA _, Keccak k) | isMap k, isArray idA -> go slot prev
648- (ArraySlotWithOffs2 idA _ _, Keccak k) | isMap k, isArray idA -> go slot prev
649- (ArraySlotZero idA, Keccak k) | isMap k, isArray idA -> go slot prev
650-
651- -- special case of map + array -> skip write
652- (Keccak k, ArraySlotWithOffs idA _) | isMap k, isArray idA -> go slot prev
653- (Keccak k, ArraySlotWithOffs2 idA _ _) | isMap k, isArray idA -> go slot prev
654- (ArraySlotWithOffs idA _, Keccak k) | isMap k, isArray idA -> go slot prev
655- (ArraySlotWithOffs2 idA _ _, Keccak k) | isMap k, isArray idA -> go slot prev
646+ (ArraySlotZero idA, ArraySlotZero idB) | isArray idA, isArray idB, idA /= idB -> go slot prev
647+ (ArraySlotZero idA, ArraySlotWithOffs idB (Lit off)) | isArray idA, isArray idB, idA /= idB, off < 256 , off /= 0 -> go slot prev
648+ (ArraySlotZero idA, ArraySlotWithOffs idB (Lit off)) | isArray idA, idA == idB, off /= 0 -> go slot prev
649+ (ArraySlotZero idA, MappingSlot idB _) | isArray idA, isMap' idB -> go slot prev
650+ (ArraySlotZero idA, Keccak idB) | isArray idA, isMap idB -> go slot prev
651+
652+ (ArraySlotWithOffs idA (Lit off), ArraySlotZero idB) | isArray idA, isArray idB, idA /= idB, off < 256 -> go slot prev
653+ (ArraySlotWithOffs idA (Lit off), ArraySlotZero idB) | isArray idA, idA == idB, off /= 0 -> go slot prev
654+ (ArraySlotWithOffs idA (Lit offA), ArraySlotWithOffs idB (Lit offB)) | isArray idA, isArray idB, idA /= idB, offA < 256 , offB < 256 -> go slot prev
655+ (ArraySlotWithOffs idA offA, ArraySlotWithOffs idB offB) | isArray idA, idA == idB, surelyNotEqual offA offB -> go slot prev
656+ (ArraySlotWithOffs idB offB2, ArraySlotWithOffs2 idA offA1 offA2) | isArray idA, idA == idB, surelyNotEqual (Add (Lit offA1) offA2) offB2 -> go slot prev
657+ (ArraySlotWithOffs idA (Lit off), Keccak idB) | isArray idA, isMap idB, off < 256 -> go slot prev
658+ (ArraySlotWithOffs idA (Lit off), MappingSlot idB _) | isArray idA, isMap' idB, off < 256 -> go slot prev
659+
660+ (Keccak idA, ArraySlotZero idB) | isMap idA, isArray idB -> go slot prev
661+ (Keccak idA, ArraySlotWithOffs idB (Lit offs)) | isMap idA, isArray idB, offs < 256 -> go slot prev
656662
657663 -- Fixed SMALL value will never match Keccak (well, it might, but that's VERY low chance)
658664 (Lit a, Keccak _) | a < 256 -> go slot prev
@@ -663,40 +669,27 @@ readStorage w st = go (simplifyNoLitToKeccak w) (simplifyNoLitToKeccak st)
663669 -- occurring here is 2^32/2^256 = 2^-224, which is close enough to zero
664670 -- for our purposes. This lets us completely simplify reads from write
665671 -- chains involving writes to arrays at literal offsets.
666- (Lit a, Add (Lit b ) (Keccak _)) | a < 256 , b < maxW32 -> go slot prev
667- (Add (Lit a ) (Keccak _) , Lit b) | b < 256 , a < maxW32 -> go slot prev
672+ (Lit a, Add (Lit offB ) (Keccak _)) | a < 256 , offB < maxW32 -> go slot prev
673+ (Add (Lit offA ) (Keccak _), Lit b) | b < 256 , offA < maxW32 -> go slot prev
668674
669675 -- Finding two Keccaks that are < 256 away from each other should be VERY hard
670676 -- This simplification allows us to deal with maps of structs
671- (Add (Lit a2) (Keccak _), Add (Lit b2) (Keccak _)) | a2 /= b2, abs (a2- b2) < 256 -> go slot prev
672- (Add (Lit a2) (Keccak _), (Keccak _)) | a2 > 0 , a2 < 256 -> go slot prev
673- ((Keccak _), Add (Lit b2) (Keccak _)) | b2 > 0 , b2 < 256 -> go slot prev
674-
675- -- zero offs vs zero offs
676- (ArraySlotZero idA, ArraySlotZero idB) | isArray idA, isArray idB, idA /= idB -> go slot prev
677-
678- -- zero offs vs non-zero offs
679- (ArraySlotZero idA, ArraySlotWithOffs idB _) | isArray idA, isArray idB, idA /= idB -> go slot prev
680- (ArraySlotZero idA, ArraySlotWithOffs idB (Lit offB)) | isArray idA, idA == idB, offB /= 0 -> go slot prev
681- (ArraySlotZero idA, ArraySlotWithOffs2 idB _ _) | isArray idA, isArray idB, idA /= idB -> go slot prev
677+ (Add (Lit a) (Keccak _), Add (Lit b) (Keccak _)) | a /= b, abs (a- b) < 256 -> go slot prev
678+ (Add (Lit a) (Keccak _), (Keccak _)) | a > 0 , a < 256 -> go slot prev
679+ ((Keccak _), Add (Lit b) (Keccak _)) | b > 0 , b < 256 -> go slot prev
682680
683- -- non-zero offs vs zero offs
684- (ArraySlotWithOffs idA _, ArraySlotZero idB) | isArray idA, isArray idB, idA /= idB -> go slot prev
685- (ArraySlotWithOffs idA (Lit offA), ArraySlotZero idB) | isArray idA, idA == idB, offA /= 0 -> go slot prev
686-
687- -- non-zero offs vs non-zero offs, different ids
688- (ArraySlotWithOffs idA _, ArraySlotWithOffs idB _) | isArray idA, isArray idB, idA /= idB -> go slot prev
689-
690- -- non-zero offs vs non-zero offs, same ids
691- (ArraySlotWithOffs idA a, ArraySlotWithOffs idB b) | isArray idA, idA == idB,
692- surelyNotEqual a b -> go slot prev
693- (ArraySlotWithOffs idB offB2, ArraySlotWithOffs2 idA offA1 offA2) | isArray idA, idA == idB,
694- surelyNotEqual (Add (Lit offA1) offA2) offB2 -> go slot prev
695681 (ArraySlotWithOffs2 idA offA1 offA2, ArraySlotWithOffs idB offB2) | isArray idA, idA == idB,
696682 surelyNotEqual (Add (Lit offA1) offA2) offB2 -> go slot prev
697683 (ArraySlotWithOffs2 idA offA1 offA2, ArraySlotWithOffs2 idB offB1 offB2) | isArray idA, idA == idB,
698684 surelyNotEqual (Add (Lit offA1) offA2) (Add (Lit offB1) offB2) -> go slot prev
699685
686+ -- DANGEROUS: offset could possibly be VERY large and SPECIFIC in order to make them clash
687+ -- This would constitute a hack, and would require a specifically badly written code
688+ (MappingSlot idA _, ArraySlotWithOffs idB _) | isMap' idA, isArray idB -> go slot prev
689+ (MappingSlot idA _, ArraySlotWithOffs2 idB _ _) | isMap' idA, isArray idB -> go slot prev
690+ (ArraySlotWithOffs idA _, MappingSlot idB _) | isArray idA, isMap' idB -> go slot prev
691+ (ArraySlotWithOffs2 idA _ _, MappingSlot idB _) | isArray idA, isMap' idB -> go slot prev
692+
700693 -- we are unable to determine statically whether or not we can safely move deeper in the write chain, so return an abstract term
701694 _ -> Just $ SLoad slot s
702695
@@ -731,6 +724,7 @@ pattern ArraySlotWithOffs2 id offs1 offs2 = Add (Lit offs1) (Add offs2 (Keccak (
731724-- special pattern to match the 0th element because the `Add` term gets simplified out
732725pattern ArraySlotZero :: ByteString -> Expr EWord
733726pattern ArraySlotZero id = Keccak (ConcreteBuf id )
727+
734728-- checks if two mapping ids match or not
735729idsDontMatch :: ByteString -> ByteString -> Bool
736730idsDontMatch a b = BS. length a >= 64 && BS. length b >= 64 && diff32to64Byte a b
0 commit comments