|
1 | 1 | {-# LANGUAGE CPP #-}
|
2 | 2 | {-# LANGUAGE FlexibleContexts #-}
|
| 3 | +{-# LANGUAGE ImportQualifiedPost #-} |
3 | 4 | {-# LANGUAGE LambdaCase #-}
|
4 | 5 | {-# LANGUAGE OverloadedStrings #-}
|
5 | 6 | {-# LANGUAGE QuasiQuotes #-}
|
6 | 7 | {-# LANGUAGE ScopedTypeVariables #-}
|
7 | 8 |
|
8 | 9 | module Chainweb.Test.Pact5.TransactionTests (tests) where
|
9 | 10 |
|
10 |
| -import Test.Tasty |
11 |
| -import Test.Tasty.HUnit |
12 |
| - |
| 11 | +import Chainweb.Pact5.Templates |
| 12 | +import Chainweb.Miner.Pact |
13 | 13 | import Control.Lens hiding ((.=))
|
14 |
| - |
15 | 14 | import Data.Foldable
|
16 | 15 | import Data.Text (unpack)
|
17 |
| -import qualified Data.Map.Strict as Map |
18 |
| - |
19 |
| --- internal pact modules |
20 |
| - |
21 |
| -import Pact.Core.Repl |
22 |
| -import Pact.Core.Pretty |
23 | 16 | import Pact.Core.Environment
|
24 | 17 | import Pact.Core.Errors
|
25 | 18 | import Pact.Core.Info
|
| 19 | +import Pact.Core.Pretty |
| 20 | +import Pact.Core.Repl |
26 | 21 | import Pact.Core.Repl.Utils
|
| 22 | +import Control.Monad (when) |
| 23 | +import Data.Text qualified as Text |
| 24 | +import Pact.Types.KeySet qualified as Pact4 |
| 25 | +import Test.Tasty |
| 26 | +import Test.Tasty.HUnit |
| 27 | +import Data.Map.Strict qualified as Map |
27 | 28 |
|
28 | 29 | -- ---------------------------------------------------------------------- --
|
29 | 30 | -- Global settings
|
30 | 31 |
|
| 32 | +tests :: TestTree |
| 33 | +tests = testGroup "Chainweb.Test.Pact5.TransactionTests" |
| 34 | + [ testCase "coin contract v6" $ runReplTest coinReplV6 |
| 35 | + , testCase "namespace v1" $ runReplTest nsReplV1 |
| 36 | + , testCase "namespace v2" $ runReplTest nsReplV2 |
| 37 | + , testCase "miner key injection" injectionTest |
| 38 | + ] |
| 39 | + |
31 | 40 | coinReplV6 :: FilePath
|
32 | 41 | coinReplV6 = "pact/pact5/coin-contract/coin.repl"
|
33 | 42 |
|
@@ -57,9 +66,26 @@ runReplTest file = do
|
57 | 66 | ReplTestFailed msg ->
|
58 | 67 | failWithErr rstate (PEExecutionError (EvalError msg) [] _loc)
|
59 | 68 |
|
60 |
| -tests :: TestTree |
61 |
| -tests = testGroup "Chainweb.Test.Pact5.TransactionTests" |
62 |
| - [ testCase "coin contract v6" $ runReplTest coinReplV6 |
63 |
| - , testCase "namespace v1" $ runReplTest nsReplV1 |
64 |
| - , testCase "namespace v2" $ runReplTest nsReplV2 |
65 |
| - ] |
| 69 | +injectionTest :: Assertion |
| 70 | +injectionTest = do |
| 71 | + let (expr, pv) = mkCoinbaseTerm badMinerId minerKeys0 1.0 |
| 72 | + |
| 73 | + assertEqual "Precompiled exploit yields correct code" (renderText expr) $ |
| 74 | + "(coin.coinbase \"alpha\" (read-keyset \"miner-keyset\") 9999999.99)" |
| 75 | + <> "(coin.coinbase \"alpha\" (read-keyset \"miner-keyset\") (read-decimal \"reward\"))" |
| 76 | + |
| 77 | + let stmt = renderText pv |
| 78 | + |
| 79 | + when ("coinbase" `Text.isInfixOf` stmt) $ |
| 80 | + assertFailure "Precompiled statement contains exploitable code" |
| 81 | + |
| 82 | + when ("read-keyset" `Text.isInfixOf` stmt) $ |
| 83 | + assertFailure "Precompiled statement contains exploitable code" |
| 84 | + |
| 85 | +badMinerId :: MinerId |
| 86 | +badMinerId = MinerId "alpha\" (read-keyset \"miner-keyset\") 9999999.99)(coin.coinbase \"alpha" |
| 87 | + |
| 88 | +minerKeys0 :: MinerKeys |
| 89 | +minerKeys0 = MinerKeys $ Pact4.mkKeySet |
| 90 | + ["f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27"] |
| 91 | + "default" |
0 commit comments