an intermediate symbolic execution engine for EVM bytecode
16

Configure Feed

Select the types of activity you want to include in your feed.

symevm / src / Opcode.hs
6.1 kB 274 lines
1{-# LANGUAGE LambdaCase #-} 2 3module Opcode where 4 5import Data.Word 6import Data.ByteString (ByteString) 7import qualified Data.ByteString as BS 8import Prelude hiding (LT, GT, EQ) 9 10data Opcode 11 = STOP | ADD | MUL | SUB | DIV | SDIV | MOD | SMOD 12 | ADDMOD | MULMOD | EXP | SIGNEXTEND 13 | LT | GT | SLT | SGT | EQ | ISZERO 14 | AND | OR | XOR | NOT | BYTE | SHL | SHR | SAR 15 | SHA3 16 | ADDRESS | BALANCE | ORIGIN | CALLER | CALLVALUE 17 | CALLDATALOAD | CALLDATASIZE | CALLDATACOPY 18 | CODESIZE | CODECOPY 19 | GASPRICE | EXTCODESIZE | EXTCODECOPY | RETURNDATASIZE | RETURNDATACOPY 20 | EXTCODEHASH 21 | BLOCKHASH | COINBASE | TIMESTAMP | NUMBER | DIFFICULTY | GASLIMIT 22 | CHAINID | SELFBALANCE | BASEFEE 23 | POP | MLOAD | MSTORE | MSTORE8 | SLOAD | SSTORE | JUMP | JUMPI 24 | PC | MSIZE | GAS | JUMPDEST 25 | PUSH1 | PUSH2 | PUSH3 | PUSH4 | PUSH5 | PUSH6 | PUSH7 | PUSH8 26 | PUSH9 | PUSH10 | PUSH11 | PUSH12 | PUSH13 | PUSH14 | PUSH15 | PUSH16 27 | PUSH17 | PUSH18 | PUSH19 | PUSH20 | PUSH21 | PUSH22 | PUSH23 | PUSH24 28 | PUSH25 | PUSH26 | PUSH27 | PUSH28 | PUSH29 | PUSH30 | PUSH31 | PUSH32 29 | DUP1 | DUP2 | DUP3 | DUP4 | DUP5 | DUP6 | DUP7 | DUP8 30 | DUP9 | DUP10 | DUP11 | DUP12 | DUP13 | DUP14 | DUP15 | DUP16 31 | SWAP1 | SWAP2 | SWAP3 | SWAP4 | SWAP5 | SWAP6 | SWAP7 | SWAP8 32 | SWAP9 | SWAP10 | SWAP11 | SWAP12 | SWAP13 | SWAP14 | SWAP15 | SWAP16 33 | LOG0 | LOG1 | LOG2 | LOG3 | LOG4 34 | CREATE | CALL | CALLCODE | RETURN | DELEGATECALL | CREATE2 35 | STATICCALL | REVERT | INVALID | SELFDESTRUCT 36 | UNKNOWN Word8 37 deriving (Show, Eq) 38 39decodeOpcode :: Word8 -> Opcode 40decodeOpcode = \case 41 0x00 -> STOP 42 0x01 -> ADD 43 0x02 -> MUL 44 0x03 -> SUB 45 0x04 -> DIV 46 0x05 -> SDIV 47 0x06 -> MOD 48 0x07 -> SMOD 49 0x08 -> ADDMOD 50 0x09 -> MULMOD 51 0x0a -> EXP 52 0x0b -> SIGNEXTEND 53 0x10 -> LT 54 0x11 -> GT 55 0x12 -> SLT 56 0x13 -> SGT 57 0x14 -> EQ 58 0x15 -> ISZERO 59 0x16 -> AND 60 0x17 -> OR 61 0x18 -> XOR 62 0x19 -> NOT 63 0x1a -> BYTE 64 0x1b -> SHL 65 0x1c -> SHR 66 0x1d -> SAR 67 0x20 -> SHA3 68 0x30 -> ADDRESS 69 0x31 -> BALANCE 70 0x32 -> ORIGIN 71 0x33 -> CALLER 72 0x34 -> CALLVALUE 73 0x35 -> CALLDATALOAD 74 0x36 -> CALLDATASIZE 75 0x37 -> CALLDATACOPY 76 0x38 -> CODESIZE 77 0x39 -> CODECOPY 78 0x3a -> GASPRICE 79 0x3b -> EXTCODESIZE 80 0x3c -> EXTCODECOPY 81 0x3d -> RETURNDATASIZE 82 0x3e -> RETURNDATACOPY 83 0x3f -> EXTCODEHASH 84 0x40 -> BLOCKHASH 85 0x41 -> COINBASE 86 0x42 -> TIMESTAMP 87 0x43 -> NUMBER 88 0x44 -> DIFFICULTY 89 0x45 -> GASLIMIT 90 0x46 -> CHAINID 91 0x47 -> SELFBALANCE 92 0x48 -> BASEFEE 93 0x50 -> POP 94 0x51 -> MLOAD 95 0x52 -> MSTORE 96 0x53 -> MSTORE8 97 0x54 -> SLOAD 98 0x55 -> SSTORE 99 0x56 -> JUMP 100 0x57 -> JUMPI 101 0x58 -> PC 102 0x59 -> MSIZE 103 0x5a -> GAS 104 0x5b -> JUMPDEST 105 0x60 -> PUSH1 106 0x61 -> PUSH2 107 0x62 -> PUSH3 108 0x63 -> PUSH4 109 0x64 -> PUSH5 110 0x65 -> PUSH6 111 0x66 -> PUSH7 112 0x67 -> PUSH8 113 0x68 -> PUSH9 114 0x69 -> PUSH10 115 0x6a -> PUSH11 116 0x6b -> PUSH12 117 0x6c -> PUSH13 118 0x6d -> PUSH14 119 0x6e -> PUSH15 120 0x6f -> PUSH16 121 0x70 -> PUSH17 122 0x71 -> PUSH18 123 0x72 -> PUSH19 124 0x73 -> PUSH20 125 0x74 -> PUSH21 126 0x75 -> PUSH22 127 0x76 -> PUSH23 128 0x77 -> PUSH24 129 0x78 -> PUSH25 130 0x79 -> PUSH26 131 0x7a -> PUSH27 132 0x7b -> PUSH28 133 0x7c -> PUSH29 134 0x7d -> PUSH30 135 0x7e -> PUSH31 136 0x7f -> PUSH32 137 0x80 -> DUP1 138 0x81 -> DUP2 139 0x82 -> DUP3 140 0x83 -> DUP4 141 0x84 -> DUP5 142 0x85 -> DUP6 143 0x86 -> DUP7 144 0x87 -> DUP8 145 0x88 -> DUP9 146 0x89 -> DUP10 147 0x8a -> DUP11 148 0x8b -> DUP12 149 0x8c -> DUP13 150 0x8d -> DUP14 151 0x8e -> DUP15 152 0x8f -> DUP16 153 0x90 -> SWAP1 154 0x91 -> SWAP2 155 0x92 -> SWAP3 156 0x93 -> SWAP4 157 0x94 -> SWAP5 158 0x95 -> SWAP6 159 0x96 -> SWAP7 160 0x97 -> SWAP8 161 0x98 -> SWAP9 162 0x99 -> SWAP10 163 0x9a -> SWAP11 164 0x9b -> SWAP12 165 0x9c -> SWAP13 166 0x9d -> SWAP14 167 0x9e -> SWAP15 168 0x9f -> SWAP16 169 0xa0 -> LOG0 170 0xa1 -> LOG1 171 0xa2 -> LOG2 172 0xa3 -> LOG3 173 0xa4 -> LOG4 174 0xf0 -> CREATE 175 0xf1 -> CALL 176 0xf2 -> CALLCODE 177 0xf3 -> RETURN 178 0xf4 -> DELEGATECALL 179 0xf5 -> CREATE2 180 0xfa -> STATICCALL 181 0xfd -> REVERT 182 0xfe -> INVALID 183 0xff -> SELFDESTRUCT 184 b -> UNKNOWN b 185 186pushBytes :: Opcode -> Int 187pushBytes PUSH1 = 1 188pushBytes PUSH2 = 2 189pushBytes PUSH3 = 3 190pushBytes PUSH4 = 4 191pushBytes PUSH5 = 5 192pushBytes PUSH6 = 6 193pushBytes PUSH7 = 7 194pushBytes PUSH8 = 8 195pushBytes PUSH9 = 9 196pushBytes PUSH10 = 10 197pushBytes PUSH11 = 11 198pushBytes PUSH12 = 12 199pushBytes PUSH13 = 13 200pushBytes PUSH14 = 14 201pushBytes PUSH15 = 15 202pushBytes PUSH16 = 16 203pushBytes PUSH17 = 17 204pushBytes PUSH18 = 18 205pushBytes PUSH19 = 19 206pushBytes PUSH20 = 20 207pushBytes PUSH21 = 21 208pushBytes PUSH22 = 22 209pushBytes PUSH23 = 23 210pushBytes PUSH24 = 24 211pushBytes PUSH25 = 25 212pushBytes PUSH26 = 26 213pushBytes PUSH27 = 27 214pushBytes PUSH28 = 28 215pushBytes PUSH29 = 29 216pushBytes PUSH30 = 30 217pushBytes PUSH31 = 31 218pushBytes PUSH32 = 32 219pushBytes _ = 0 220 221isPush :: Opcode -> Bool 222isPush op = pushBytes op > 0 223 224dupDepth :: Opcode -> Maybe Int 225dupDepth DUP1 = Just 1 226dupDepth DUP2 = Just 2 227dupDepth DUP3 = Just 3 228dupDepth DUP4 = Just 4 229dupDepth DUP5 = Just 5 230dupDepth DUP6 = Just 6 231dupDepth DUP7 = Just 7 232dupDepth DUP8 = Just 8 233dupDepth DUP9 = Just 9 234dupDepth DUP10 = Just 10 235dupDepth DUP11 = Just 11 236dupDepth DUP12 = Just 12 237dupDepth DUP13 = Just 13 238dupDepth DUP14 = Just 14 239dupDepth DUP15 = Just 15 240dupDepth DUP16 = Just 16 241dupDepth _ = Nothing 242 243swapDepth :: Opcode -> Maybe Int 244swapDepth SWAP1 = Just 1 245swapDepth SWAP2 = Just 2 246swapDepth SWAP3 = Just 3 247swapDepth SWAP4 = Just 4 248swapDepth SWAP5 = Just 5 249swapDepth SWAP6 = Just 6 250swapDepth SWAP7 = Just 7 251swapDepth SWAP8 = Just 8 252swapDepth SWAP9 = Just 9 253swapDepth SWAP10 = Just 10 254swapDepth SWAP11 = Just 11 255swapDepth SWAP12 = Just 12 256swapDepth SWAP13 = Just 13 257swapDepth SWAP14 = Just 14 258swapDepth SWAP15 = Just 15 259swapDepth SWAP16 = Just 16 260swapDepth _ = Nothing 261 262readBytecode :: ByteString -> Int -> Maybe Word8 263readBytecode code pc 264 | pc >= 0 && pc < BS.length code = Just (BS.index code pc) 265 | otherwise = Nothing 266 267readBytes :: ByteString -> Int -> Int -> Integer 268readBytes code start n = go 0 0 269 where 270 go acc i 271 | i >= n = acc 272 | otherwise = case readBytecode code (start + i) of 273 Just b -> go (acc * 256 + fromIntegral b) (i + 1) 274 Nothing -> acc