packages feed

ethereum-analyzer-2.0.0: test/Ethereum/Analyzer/Solidity/SimpleSpec.hs

module Ethereum.Analyzer.Solidity.SimpleSpec
  ( spec
  ) where

import Protolude hiding (show)

import Compiler.Hoopl

-- import Ethereum.Analyzer.Common
import Ethereum.Analyzer.Solidity
import Ethereum.Analyzer.TestData.DaoJson (simpleDaoJson)
import Ethereum.Analyzer.TestData.StorageJson (storageJson)

-- import GHC.Show (Show(..))
import Test.Hspec
import qualified Text.PrettyPrint.GenericPretty as GP

spec :: Spec
spec =
  describe "e2h" $
  parallel $ do
    it "parses storageJson" $ do
      let eitherContracts = do
            solNodes <- decodeSoleNodes (toS storageJson)
            let mContracts = mapM s2sContracts solNodes
            let contracts = concat $ runSimpleUniqueMonad mContracts
            return contracts
      GP.pp eitherContracts
      eitherContracts `shouldBe`
        Right
          [ Contract
            { cName = "SimpleStorage"
            , cStateVars =
                [VarDecl {vName = Idfr "storedData", vType = Unknown "uint256"}]
            , cFunctions =
                [ FunDefinition
                  { fName = Idfr "set"
                  , fParams =
                      [VarDecl {vName = Idfr "x", vType = Unknown "uint256"}]
                  , fReturns = []
                  , fBody =
                      [ StAssign
                          (JustId (Idfr "storedData"))
                          (ExpLval (JustId (Idfr "x")))
                      ]
                  }
                , FunDefinition
                  { fName = Idfr "get"
                  , fParams = []
                  , fReturns =
                      [VarDecl {vName = Idfr "", vType = Unknown "uint256"}]
                  , fBody = [StReturn [JustId (Idfr "storedData")]]
                  }
                ]
            }
          ]
    it "parses simpleDaoJson" $ do
      let eitherContracts = do
            solNodes <- decodeSoleNodes (toS simpleDaoJson)
            let mContracts = mapM s2sContracts solNodes
            let contracts = concat $ runSimpleUniqueMonad mContracts
            return contracts
      GP.pp eitherContracts
      eitherContracts `shouldBe`
        Right
          [ Contract
            { cName = "SimpleDAO"
            , cStateVars =
                [ VarDecl
                  { vName = Idfr "credit"
                  , vType = Unknown "mapping(address => uint256)"
                  }
                ]
            , cFunctions =
                [ FunDefinition
                  { fName = Idfr "donate"
                  , fParams =
                      [VarDecl {vName = Idfr "to", vType = Unknown "address"}]
                  , fReturns = []
                  , fBody =
                      [ StAssign
                          (Index
                           { iArray = JustId (Idfr "credit")
                           , iIndex =
                               Index
                               { iArray = JustId (Idfr "credit")
                               , iIndex = JustId (Idfr "to")
                               }
                           })
                          (ExpLval
                             (Member
                              { mObj = JustId (Idfr "msg")
                              , mField = Idfr "value"
                              }))
                      ]
                  }
                , FunDefinition
                  { fName = Idfr "withdraw"
                  , fParams =
                      [ VarDecl
                        {vName = Idfr "amount", vType = Unknown "uint256"}
                      ]
                  , fReturns = []
                  , fBody =
                      [ StAssign
                          (JustId (Idfr "v1"))
                          (ExpBin
                             ">="
                             (Index
                              { iArray = JustId (Idfr "credit")
                              , iIndex =
                                  Index
                                  { iArray = JustId (Idfr "credit")
                                  , iIndex =
                                      Member
                                      { mObj = JustId (Idfr "msg")
                                      , mField = Idfr "sender"
                                      }
                                  }
                              })
                             (JustId (Idfr "amount")))
                      , StIf
                          (JustId (Idfr "v1"))
                          [ StAssign
                              (JustId (Idfr "v2"))
                              (ExpCall
                                 (Member
                                  { mObj =
                                      Member
                                      { mObj =
                                          Member
                                          { mObj = JustId (Idfr "msg")
                                          , mField = Idfr "sender"
                                          }
                                      , mField = Idfr "call"
                                      }
                                  , mField = Idfr "value"
                                  })
                                 [JustId (Idfr "amount")])
                          , StAssign
                              (JustId (Idfr "v3"))
                              (ExpCall (JustId (Idfr "v2")) [])
                          , StLocalVarDecl
                              (VarDecl
                               {vName = Idfr "res", vType = Unknown "bool"})
                          , StAssign
                              (JustId (Idfr "res"))
                              (ExpLval (JustId (Idfr "v3")))
                          , StAssign
                              (Index
                               { iArray = JustId (Idfr "credit")
                               , iIndex =
                                   Index
                                   { iArray = JustId (Idfr "credit")
                                   , iIndex =
                                       Member
                                       { mObj = JustId (Idfr "msg")
                                       , mField = Idfr "sender"
                                       }
                                   }
                               })
                              (ExpLval (JustId (Idfr "amount")))
                          ]
                          []
                      ]
                  }
                , FunDefinition
                  { fName = Idfr "queryCredit"
                  , fParams =
                      [VarDecl {vName = Idfr "to", vType = Unknown "address"}]
                  , fReturns =
                      [VarDecl {vName = Idfr "", vType = Unknown "uint256"}]
                  , fBody =
                      [ StReturn
                          [ Index
                            { iArray = JustId (Idfr "credit")
                            , iIndex =
                                Index
                                { iArray = JustId (Idfr "credit")
                                , iIndex = JustId (Idfr "to")
                                }
                            }
                          ]
                      ]
                  }
                ]
            }
          , Contract
            { cName = "Mallory"
            , cStateVars =
                [ VarDecl
                  {vName = Idfr "dao", vType = Unknown "contract SimpleDAO"}
                , VarDecl {vName = Idfr "owner", vType = Unknown "address"}
                ]
            , cFunctions =
                [ FunDefinition
                  { fName = Idfr "Mallory"
                  , fParams =
                      [ VarDecl
                        { vName = Idfr "addr"
                        , vType = Unknown "contract SimpleDAO"
                        }
                      ]
                  , fReturns = []
                  , fBody =
                      [ StAssign
                          (JustId (Idfr "owner"))
                          (ExpLval
                             (Member
                              { mObj = JustId (Idfr "msg")
                              , mField = Idfr "sender"
                              }))
                      , StAssign
                          (JustId (Idfr "dao"))
                          (ExpLval (JustId (Idfr "addr")))
                      ]
                  }
                , FunDefinition
                  { fName = Idfr "getJackpot"
                  , fParams = []
                  , fReturns = []
                  , fBody =
                      [ StAssign
                          (JustId (Idfr "v6"))
                          (ExpCall
                             (Member
                              { mObj = JustId (Idfr "owner")
                              , mField = Idfr "send"
                              })
                             [ Member
                               { mObj = JustId (Idfr "this")
                               , mField = Idfr "balance"
                               }
                             ])
                      , StLocalVarDecl
                          (VarDecl {vName = Idfr "res", vType = Unknown "bool"})
                      , StAssign
                          (JustId (Idfr "res"))
                          (ExpLval (JustId (Idfr "v6")))
                      ]
                  }
                , FunDefinition
                  { fName = Idfr ""
                  , fParams = []
                  , fReturns = []
                  , fBody =
                      [ StAssign
                          (JustId (Idfr "v4"))
                          (ExpCall
                             (Member
                              { mObj = JustId (Idfr "dao")
                              , mField = Idfr "queryCredit"
                              })
                             [JustId (Idfr "this")])
                      , StAssign
                          (JustId (Idfr "v5"))
                          (ExpCall
                             (Member
                              { mObj = JustId (Idfr "dao")
                              , mField = Idfr "withdraw"
                              })
                             [JustId (Idfr "v4")])
                      , StAssign
                          (JustId (Idfr "_"))
                          (ExpLval (JustId (Idfr "v5")))
                      ]
                  }
                ]
            }
          , Contract
            { cName = "Mallory2"
            , cStateVars =
                [ VarDecl
                  {vName = Idfr "dao", vType = Unknown "contract SimpleDAO"}
                , VarDecl {vName = Idfr "owner", vType = Unknown "address"}
                , VarDecl {vName = Idfr "performAttack", vType = Unknown "bool"}
                ]
            , cFunctions =
                [ FunDefinition
                  { fName = Idfr "Mallory2"
                  , fParams =
                      [ VarDecl
                        { vName = Idfr "addr"
                        , vType = Unknown "contract SimpleDAO"
                        }
                      ]
                  , fReturns = []
                  , fBody =
                      [ StAssign
                          (JustId (Idfr "owner"))
                          (ExpLval
                             (Member
                              { mObj = JustId (Idfr "msg")
                              , mField = Idfr "sender"
                              }))
                      , StAssign
                          (JustId (Idfr "dao"))
                          (ExpLval (JustId (Idfr "addr")))
                      ]
                  }
                , FunDefinition
                  { fName = Idfr "attack"
                  , fParams = []
                  , fReturns = []
                  , fBody =
                      [ StAssign (JustId (Idfr "v13")) (ExpLiteral "1")
                      , StAssign
                          (JustId (Idfr "v14"))
                          (ExpCall
                             (Member
                              { mObj =
                                  Member
                                  { mObj = JustId (Idfr "dao")
                                  , mField = Idfr "donate"
                                  }
                              , mField = Idfr "value"
                              })
                             [JustId (Idfr "v13")])
                      , StAssign
                          (JustId (Idfr "v15"))
                          (ExpCall (JustId (Idfr "v14")) [JustId (Idfr "this")])
                      , StAssign
                          (JustId (Idfr "_"))
                          (ExpLval (JustId (Idfr "v15")))
                      , StAssign (JustId (Idfr "v16")) (ExpLiteral "1")
                      , StAssign
                          (JustId (Idfr "v17"))
                          (ExpCall
                             (Member
                              { mObj = JustId (Idfr "dao")
                              , mField = Idfr "withdraw"
                              })
                             [JustId (Idfr "v16")])
                      , StAssign
                          (JustId (Idfr "_"))
                          (ExpLval (JustId (Idfr "v17")))
                      ]
                  }
                , FunDefinition
                  { fName = Idfr "getJackpot"
                  , fParams = []
                  , fReturns = []
                  , fBody =
                      [ StAssign
                          (JustId (Idfr "v10"))
                          (ExpCall
                             (Member
                              { mObj = JustId (Idfr "dao")
                              , mField = Idfr "withdraw"
                              })
                             [ Member
                               { mObj = JustId (Idfr "dao")
                               , mField = Idfr "balance"
                               }
                             ])
                      , StAssign
                          (JustId (Idfr "_"))
                          (ExpLval (JustId (Idfr "v10")))
                      , StAssign
                          (JustId (Idfr "v11"))
                          (ExpCall
                             (Member
                              { mObj = JustId (Idfr "owner")
                              , mField = Idfr "send"
                              })
                             [ Member
                               { mObj = JustId (Idfr "this")
                               , mField = Idfr "balance"
                               }
                             ])
                      , StLocalVarDecl
                          (VarDecl {vName = Idfr "res", vType = Unknown "bool"})
                      , StAssign
                          (JustId (Idfr "res"))
                          (ExpLval (JustId (Idfr "v11")))
                      , StAssign (JustId (Idfr "v12")) (ExpLiteral "true")
                      , StAssign
                          (JustId (Idfr "performAttack"))
                          (ExpLval (JustId (Idfr "v12")))
                      ]
                  }
                , FunDefinition
                  { fName = Idfr ""
                  , fParams = []
                  , fReturns = []
                  , fBody =
                      [ StIf
                          (JustId (Idfr "performAttack"))
                          [ StAssign (JustId (Idfr "v7")) (ExpLiteral "false")
                          , StAssign
                              (JustId (Idfr "performAttack"))
                              (ExpLval (JustId (Idfr "v7")))
                          , StAssign (JustId (Idfr "v8")) (ExpLiteral "1")
                          , StAssign
                              (JustId (Idfr "v9"))
                              (ExpCall
                                 (Member
                                  { mObj = JustId (Idfr "dao")
                                  , mField = Idfr "withdraw"
                                  })
                                 [JustId (Idfr "v8")])
                          , StAssign
                              (JustId (Idfr "_"))
                              (ExpLval (JustId (Idfr "v9")))
                          ]
                          []
                      ]
                  }
                ]
            }
          ]