Skip to content

Commit a33b4af

Browse files
Merge pull request #200 from lefterislazar/static_arrays
Support for static arrays in contract storage and constructor/behavior arguments
2 parents 4b2a581 + be96791 commit a33b4af

File tree

137 files changed

+31330
-4245
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+31330
-4245
lines changed

.github/workflows/build.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,18 @@ jobs:
1717
fail-fast: false
1818
runs-on: ${{ matrix.os }}
1919
steps:
20-
- uses: actions/checkout@v2
21-
- uses: cachix/install-nix-action@v22
20+
- uses: actions/checkout@v4
21+
- uses: cachix/install-nix-action@v31
2222
with:
23-
skip_adding_nixpkgs_channel: false
24-
- uses: cachix/cachix-action@v12
23+
extra_nix_config: |
24+
experimental-features = nix-command flakes
25+
accept-flake-config = true
26+
- uses: cachix/cachix-action@v16
2527
with:
2628
name: dapp
2729
skipPush: true
2830
signingKey: ''
2931
- name: test
30-
run: nix develop --ignore-environment --command bash -c "cabal update && make test-ci"
32+
run: nix develop --ignore-environment --accept-flake-config --command bash -lc "cabal update && make test-ci"
3133
- name: build
32-
run: nix build -L .#act
34+
run: nix build -L .#act --accept-flake-config

.gitignore

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ src/dist/
1818
*.vok
1919
*.vos
2020
*.glob
21-
**/CoqMakefile
22-
**/CoqMakefile.conf
23-
**/.CoqMakefile.d
21+
**/RocqMakefile
22+
**/RocqMakefile.conf
23+
**/.RocqMakefile.d
2424
**/.lia.cache
2525
*.aux
2626
**/.coqdeps.d
@@ -32,4 +32,4 @@ doc/book
3232
.direnv/
3333

3434
*~
35-
*#
35+
*#

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ hevm_slow=tests/hevm/pass/amm/amm.act tests/hevm/pass/amm-2/amm-2.act
5353
hevm_fast=$(filter-out $(hevm_slow), $(hevm_pass))
5454

5555
# supposed to pass
56-
failing_typing=tests/frontend/pass/array/array.act tests/frontend/pass/dss/vat.act tests/frontend/pass/creation/createMultiple.act tests/frontend/pass/staticstore/staticstore.act
56+
failing_typing=tests/frontend/pass/dss/vat.act tests/frontend/pass/creation/createMultiple.act tests/frontend/pass/staticstore/staticstore.act
5757

5858

5959
coq-examples = tests/coq/transitions tests/coq/safemath tests/coq/exponent tests/coq/token tests/coq/ERC20-simple tests/coq/ERC20 tests/coq/multi

src/Act/Bounds.hs

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
module Act.Bounds (addBounds) where
55

66
import Data.Maybe
7-
import Data.List (nub)
7+
import Data.List (nub, partition)
8+
import Data.Type.Equality
89

910
import Act.Syntax
1011
import Act.Syntax.TypedExplicit
@@ -37,10 +38,18 @@ addBoundsConstructor ctor@(Constructor _ (Interface _ decls) _ pre post invs sta
3738
pre' = pre
3839
<> mkCallDataBounds decls
3940
<> mkEthEnvBounds (ethEnvFromConstructor ctor)
40-
<> mkStorageBoundsLoc (nub $ concatMap locsFromExp pre <> concatMap locsFromUpdateRHS stateUpdates)
41+
-- The following is sound as values of locations outside local storage
42+
-- already exist as the constructor starts executing,
43+
-- and the constructor cannot modify non-local locations.
44+
<> mkLocationBounds nonlocalLocs
4145
invs' = addBoundsInvariant ctor <$> invs
4246
post' = post <> mkStorageBounds stateUpdates Post
4347

48+
locs = concatMap locsFromExp (pre <> post)
49+
<> concatMap locsFromInvariant invs
50+
<> concatMap locsFromUpdate stateUpdates
51+
nonlocalLocs = filter (not . isLocalLoc) locs
52+
4453
-- | Adds type bounds for calldata, environment vars, and storage vars as preconditions
4554
addBoundsBehaviour :: Behaviour -> Behaviour
4655
addBoundsBehaviour behv@(Behaviour _ _ (Interface _ decls) _ pre cases post stateUpdates _) =
@@ -49,11 +58,14 @@ addBoundsBehaviour behv@(Behaviour _ _ (Interface _ decls) _ pre cases post stat
4958
pre' = pre
5059
<> mkCallDataBounds decls
5160
<> mkStorageBounds stateUpdates Pre
52-
<> mkStorageBoundsLoc (nub $ concatMap locsFromExp (pre <> cases) <> concatMap locsFromUpdateRHS stateUpdates)
61+
<> mkLocationBounds locs
5362
<> mkEthEnvBounds (ethEnvFromBehaviour behv)
5463
post' = post
5564
<> mkStorageBounds stateUpdates Post
5665

66+
locs = concatMap locsFromExp (pre <> post <> cases)
67+
<> concatMap locsFromUpdate stateUpdates
68+
5769
-- | Adds type bounds for calldata, environment vars, and storage vars
5870
addBoundsInvariant :: Constructor -> Invariant -> Invariant
5971
addBoundsInvariant (Constructor _ (Interface _ decls) _ _ _ _ _) inv@(Invariant _ preconds storagebounds (PredTimed predicate _)) =
@@ -62,8 +74,13 @@ addBoundsInvariant (Constructor _ (Interface _ decls) _ _ _ _ _) inv@(Invariant
6274
preconds' = preconds
6375
<> mkCallDataBounds decls
6476
<> mkEthEnvBounds (ethEnvFromExp predicate)
77+
<> mkLocationBounds nonlocalLocs
6578
storagebounds' = storagebounds
66-
<> mkStorageBoundsLoc (locsFromExp predicate)
79+
<> mkLocationBounds localLocs
80+
81+
locs = concatMap locsFromExp (preconds <> storagebounds)
82+
<> locsFromExp predicate
83+
(nonlocalLocs, localLocs) = partition (not . isLocalLoc) locs
6784

6885
mkEthEnvBounds :: [EthEnv] -> [Exp ABoolean]
6986
mkEthEnvBounds vars = catMaybes $ mkBound <$> nub vars
@@ -94,21 +111,36 @@ mkStorageBounds :: [StorageUpdate] -> When -> [Exp ABoolean]
94111
mkStorageBounds refs t = concatMap mkBound refs
95112
where
96113
mkBound :: StorageUpdate -> [Exp ABoolean]
97-
mkBound (Update SInteger item _) = [mkItemBounds t item]
114+
mkBound (Update SInteger item _) = [mkSItemBounds t item]
115+
mkBound (Update typ item@(Item _ (PrimitiveType at) _) _) | isNothing $ flattenArrayAbiType at =
116+
maybe [] (\Refl -> mkSItemBounds t <$> expandItem item) $ testEquality (flattenSType typ) SInteger
98117
mkBound _ = []
99118

100-
mkItemBounds :: When -> TItem AInteger Storage -> Exp ABoolean
101-
mkItemBounds whn item@(Item _ (PrimitiveType vt) _) = bound vt (VarRef nowhere whn SStorage item)
102-
mkItemBounds _ (Item _ (ContractType _) _) = LitBool nowhere True
119+
mkSItemBounds :: When -> TItem AInteger Storage -> Exp ABoolean
120+
mkSItemBounds whn item@(Item _ (PrimitiveType vt) _) = bound vt (VarRef nowhere whn SStorage item)
121+
mkSItemBounds _ (Item _ (ContractType _) _) = LitBool nowhere True
103122

104-
mkStorageBoundsLoc :: [StorageLocation] -> [Exp ABoolean]
105-
mkStorageBoundsLoc refs = concatMap mkBound refs
123+
mkCItemBounds :: TItem AInteger Calldata -> Exp ABoolean
124+
mkCItemBounds item@(Item _ (PrimitiveType vt) _) = bound vt (VarRef nowhere Pre SCalldata item)
125+
mkCItemBounds (Item _ (ContractType _) _) = LitBool nowhere True
126+
127+
mkLocationBounds :: [Location] -> [Exp ABoolean]
128+
mkLocationBounds refs = concatMap mkBound refs
106129
where
107-
mkBound :: StorageLocation -> [Exp ABoolean]
108-
mkBound (Loc SInteger item) = [mkItemBounds Pre item]
130+
mkBound :: Location -> [Exp ABoolean]
131+
mkBound (Loc SInteger rk item) = [mkItemBounds rk item]
132+
mkBound (Loc typ rk item@(Item _ (PrimitiveType at) _)) | isNothing $ flattenArrayAbiType at =
133+
maybe [] (\Refl -> mkItemBounds rk <$> expandItem item) $ testEquality (flattenSType typ) SInteger
109134
mkBound _ = []
110135

136+
mkItemBounds :: SRefKind k -> TItem AInteger k -> Exp ABoolean
137+
mkItemBounds SStorage = mkSItemBounds Pre
138+
mkItemBounds SCalldata = mkCItemBounds
139+
111140
mkCallDataBounds :: [Decl] -> [Exp ABoolean]
112-
mkCallDataBounds = concatMap $ \(Decl typ name) -> case fromAbiType typ of
113-
AInteger -> [bound typ (_Var typ name)]
114-
_ -> []
141+
mkCallDataBounds = concatMap $ \(Decl typ name) -> case typ of
142+
-- Array element bounds are applied lazily when needed in mkCalldataLocationBounds
143+
(AbiArrayType _ _) -> []
144+
_ -> case fromAbiType typ of
145+
AInteger -> [bound typ (_Var typ name)]
146+
_ -> []

src/Act/CLI.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ type' :: FilePath -> Solvers.Solver -> Maybe Integer -> Bool -> IO ()
145145
type' f solver' smttimeout' debug' = do
146146
contents <- readFile f
147147
proceed contents (addBounds <$> compile contents) $ \claims -> do
148+
checkArrayBounds claims solver' smttimeout' debug'
148149
checkCases claims solver' smttimeout' debug'
150+
checkRewriteAliasing claims solver' smttimeout' debug'
149151
B.putStrLn $ encode claims
150152

151153
parseSolver :: Maybe Text -> IO Solvers.Solver
@@ -161,7 +163,9 @@ prove file' solver' smttimeout' debug' = do
161163
let config = SMT.SMTConfig solver' (fromMaybe 20000 smttimeout') debug'
162164
contents <- readFile file'
163165
proceed contents (addBounds <$> compile contents) $ \claims -> do
166+
checkArrayBounds claims solver' smttimeout' debug'
164167
checkCases claims solver' smttimeout' debug'
168+
checkRewriteAliasing claims solver' smttimeout' debug'
165169
let
166170
catModels results = [m | Sat m <- results]
167171
catErrors results = [e | e@SMT.Error {} <- results]
@@ -215,7 +219,9 @@ coq' :: FilePath -> Solvers.Solver -> Maybe Integer -> Bool -> IO ()
215219
coq' f solver' smttimeout' debug' = do
216220
contents <- readFile f
217221
proceed contents (addBounds <$> compile contents) $ \claims -> do
222+
checkArrayBounds claims solver' smttimeout' debug'
218223
checkCases claims solver' smttimeout' debug'
224+
checkRewriteAliasing claims solver' smttimeout' debug'
219225
TIO.putStr $ coq claims
220226

221227
decompile' :: FilePath -> Text -> Solvers.Solver -> Maybe Integer -> Bool -> IO ()

0 commit comments

Comments
 (0)