@@ -10,6 +10,7 @@ import Data.Type.Equality
1010import Act.Syntax
1111import Act.Syntax.TypedExplicit
1212import Act.Type (globalEnv )
13+ import Debug.Trace
1314
1415
1516{-|
@@ -30,7 +31,7 @@ addBounds (Act store contracts) = Act store (addBoundsContract <$> contracts)
3031-- | Adds type bounds for calldata, environment vars, and external storage vars
3132-- as preconditions
3233addBoundsConstructor :: Constructor -> Constructor
33- addBoundsConstructor ctor@ (Constructor _ (Interface _ decls) _ pre post invs stateUpdates) =
34+ addBoundsConstructor ctor@ (Constructor _ (Interface _ decls) pre post invs stateUpdates) =
3435 ctor { _cpreconditions = pre'
3536 , _cpostconditions = post'
3637 , _invariants = invs' }
@@ -41,7 +42,7 @@ addBoundsConstructor ctor@(Constructor _ (Interface _ decls) _ pre post invs sta
4142 -- The following is sound as values of locations outside local storage
4243 -- already exist as the constructor starts executing,
4344 -- and the constructor cannot modify non-local locations.
44- <> mkLocationBounds nonlocalLocs
45+ <> mkLocationBounds (toPrestate stateUpdates <$> nonlocalLocs)
4546 invs' = addBoundsInvariant ctor <$> invs
4647 post' = post <> mkStorageBounds stateUpdates Post
4748
@@ -50,15 +51,48 @@ addBoundsConstructor ctor@(Constructor _ (Interface _ decls) _ pre post invs sta
5051 <> concatMap locsFromUpdate stateUpdates
5152 nonlocalLocs = filter (not . isLocalLoc) locs
5253
54+
55+ changeBase :: Location -> StorageUpdate -> Maybe Location
56+ changeBase _ (Update _ (Item _ _ _) e) | isCreate e = Nothing
57+ -- TODO: suppport!
58+ where
59+ isCreate :: Exp a -> Bool
60+ isCreate (Address _ (Create _ _ _)) = True
61+ isCreate (Create _ _ _) = True
62+ isCreate _ = False
63+ changeBase (Loc st SStorage (Item _ vt baseref)) (Update _ (Item _ _ updatedRef) (VarRef _ _ sk' (Item _ _ ru'))) =
64+ Loc st sk' . Item st vt <$> hasBase baseref ru'
65+ where
66+ hasBase :: Ref Storage -> Ref k -> Maybe (Ref k )
67+ hasBase r''@ (SVar _ _ _) ru =
68+ if updatedRef == r'' then Just ru else Nothing
69+ hasBase r''@ (SArray pn r' vt' ixs) ru =
70+ if updatedRef == r'' then Just ru
71+ else (\ _r -> SArray pn _r vt' ixs) <$> hasBase r' ru
72+ hasBase r''@ (SMapping pn r' vt' ixs) ru =
73+ if updatedRef == r'' then Just ru
74+ else (\ _r -> SMapping pn _r vt' ixs) <$> hasBase r' ru
75+ hasBase r''@ (SField pn r' id' id'') ru =
76+ if updatedRef == r'' then Just ru
77+ else (\ _r -> SField pn _r id' id'') <$> hasBase r' ru
78+ changeBase _ _ = Nothing
79+
80+ toPrestate :: [StorageUpdate ] -> Location -> Location
81+ toPrestate _ loc@ (Loc _ SCalldata _) = loc
82+ toPrestate updates loc@ (Loc _ SStorage _) =
83+ case mapMaybe (changeBase loc) updates of
84+ [] -> loc
85+ l -> last l
86+
5387-- | Adds type bounds for calldata, environment vars, and storage vars as preconditions
5488addBoundsBehaviour :: Behaviour -> Behaviour
55- addBoundsBehaviour behv@ (Behaviour _ _ (Interface _ decls) _ pre cases post stateUpdates ret) =
89+ addBoundsBehaviour behv@ (Behaviour _ _ (Interface _ decls) pre cases post stateUpdates ret) =
5690 behv { _preconditions = pre', _postconditions = post' }
5791 where
5892 pre' = nub $ pre
5993 <> mkCallDataBounds decls
6094 <> mkStorageBounds stateUpdates Pre
61- <> mkLocationBounds locs
95+ <> mkLocationBounds (toPrestate stateUpdates <$> locs)
6296 <> mkEthEnvBounds (ethEnvFromBehaviour behv)
6397 post' = post
6498 <> mkStorageBounds stateUpdates Post
@@ -69,7 +103,7 @@ addBoundsBehaviour behv@(Behaviour _ _ (Interface _ decls) _ pre cases post stat
69103
70104-- | Adds type bounds for calldata, environment vars, and storage vars
71105addBoundsInvariant :: Constructor -> Invariant -> Invariant
72- addBoundsInvariant (Constructor _ (Interface _ decls) _ _ _ _ _ ) inv@ (Invariant _ preconds storagebounds (PredTimed predicate _)) =
106+ addBoundsInvariant (Constructor _ (Interface _ decls) _ _ _ _) inv@ (Invariant _ preconds storagebounds (PredTimed predicate _)) =
73107 inv { _ipreconditions = preconds', _istoragebounds = storagebounds' }
74108 where
75109 preconds' = nub $ preconds
@@ -139,9 +173,12 @@ mkLocationBounds refs = concatMap mkBound refs
139173 mkItemBounds SCalldata = mkCItemBounds
140174
141175mkCallDataBounds :: [Decl ] -> [Exp ABoolean ]
142- mkCallDataBounds = concatMap $ \ (Decl typ name) -> case typ of
143- -- Array element bounds are applied lazily when needed in mkCalldataLocationBounds
144- (AbiArrayType _ _) -> []
145- _ -> case fromAbiType typ of
146- AInteger -> [bound typ (_Var typ name)]
147- _ -> []
176+ mkCallDataBounds = concatMap $ \ (Decl argtyp name) -> case argtyp of
177+ (AbiArg typ) ->
178+ case typ of
179+ -- Array element bounds are applied lazily when needed in mkCalldataLocationBounds
180+ (AbiArrayType _ _) -> []
181+ _ -> case fromAbiType typ of
182+ AInteger -> [bound typ (_Var typ name)]
183+ _ -> []
184+ (ContractArg _ cid) -> [bound AbiAddressType (Address cid (_Var AbiAddressType name))]
0 commit comments