From df608adb135fa0fd0f254d65eec7e3e09c4e4284 Mon Sep 17 00:00:00 2001 From: martyall Date: Sat, 7 Oct 2023 20:34:59 -0700 Subject: [PATCH] use index as default label when absent --- abi-data/abis/EvilVerifier.json | 254 ++++++++++++++++++++++++++++++++ spago.dhall | 6 +- src/Data/AbiParser.purs | 36 ++++- src/Data/Generator.purs | 13 +- 4 files changed, 290 insertions(+), 19 deletions(-) create mode 100644 abi-data/abis/EvilVerifier.json diff --git a/abi-data/abis/EvilVerifier.json b/abi-data/abis/EvilVerifier.json new file mode 100644 index 0000000..4b11927 --- /dev/null +++ b/abi-data/abis/EvilVerifier.json @@ -0,0 +1,254 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "imageId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "input", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "address", + "name": "callbackContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "functionSelector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "gasLimit", + "type": "uint64" + } + ], + "name": "CallbackRequest", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "seal", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "postStateDigest", + "type": "bytes32" + } + ], + "internalType": "struct CallbackAuthorization", + "name": "auth", + "type": "tuple" + } + ], + "name": "callbackIsAuthorized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "bytes", + "name": "seal", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "postStateDigest", + "type": "bytes32" + } + ], + "internalType": "struct CallbackAuthorization", + "name": "auth", + "type": "tuple" + }, + { + "internalType": "address", + "name": "callbackContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "gasLimit", + "type": "uint64" + } + ], + "internalType": "struct Callback", + "name": "callback", + "type": "tuple" + } + ], + "name": "invokeCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "bytes", + "name": "seal", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "postStateDigest", + "type": "bytes32" + } + ], + "internalType": "struct CallbackAuthorization", + "name": "auth", + "type": "tuple" + }, + { + "internalType": "address", + "name": "callbackContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "gasLimit", + "type": "uint64" + } + ], + "internalType": "struct Callback[]", + "name": "callbacks", + "type": "tuple[]" + } + ], + "name": "invokeCallbacks", + "outputs": [ + { + "internalType": "bool[]", + "name": "invocationResults", + "type": "bool[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "parsePayload", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "imageId", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "input", + "type": "bytes" + }, + { + "internalType": "address", + "name": "callbackContract", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "functionSelector", + "type": "bytes4" + }, + { + "internalType": "uint64", + "name": "gasLimit", + "type": "uint64" + } + ], + "name": "requestCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/spago.dhall b/spago.dhall index b757b55..1493af8 100644 --- a/spago.dhall +++ b/spago.dhall @@ -19,10 +19,9 @@ , "foldable-traversable" , "identity" , "integers" + , "language-cst-parser" , "lists" , "maybe" - , "language-cst-parser" - , "tidy-codegen" , "mkdirp" , "newtype" , "node-buffer" @@ -30,13 +29,14 @@ , "node-fs-aff" , "node-path" , "node-process" - , "ordered-collections" , "optparse" + , "ordered-collections" , "partial" , "prelude" , "profunctor-lenses" , "string-parsers" , "strings" + , "tidy-codegen" , "transformers" , "tuples" , "web3" diff --git a/src/Data/AbiParser.purs b/src/Data/AbiParser.purs index 4cb8f8f..aef8369 100644 --- a/src/Data/AbiParser.purs +++ b/src/Data/AbiParser.purs @@ -11,7 +11,7 @@ import Data.Argonaut.Decode ((.:)) import Data.Argonaut.Decode.Class (class DecodeJson, decodeJson) import Data.Argonaut.Decode.Error (JsonDecodeError(..), printJsonDecodeError) import Data.Argonaut.Encode.Class (encodeJson) -import Data.Array (fromFoldable, intercalate) +import Data.Array (fromFoldable, intercalate, length, zip, (..)) import Data.Bifunctor (lmap) import Data.Either (Either(..), either) import Data.Foldable (foldr) @@ -24,6 +24,7 @@ import Data.Show.Generic (genericShow) import Data.String.CodeUnits (fromCharArray) import Data.TacitString as TacitString import Data.Traversable (traverse) +import Data.Tuple (Tuple(..)) import StringParser (Parser, fail, runParser, try) import StringParser.CodePoints (anyDigit, string, char, eof) import StringParser.Combinators (choice, manyTill, many1, optionMaybe) @@ -108,7 +109,7 @@ instance DecodeJson SolidityType where Right solidityTuple -> do components <- obj .: "components" factors <- traverse decodeJson components - pure $ solidityTuple factors + pure $ solidityTuple $ withMissingLabels factors instance Format SolidityType where format s = case s of @@ -287,8 +288,8 @@ instance DecodeJson SolidityFunction where cp <- parseStateMutability <|> parseConstantPayableFields <|> fallback pure $ SolidityFunction { name: nm - , inputs: is - , outputs: os + , inputs: withMissingLabels is + , outputs: withMissingLabels os , constant: cp.constant , payable: cp.payable , isConstructor: false @@ -342,7 +343,7 @@ instance DecodeJson SolidityEvent where a <- obj .: "anonymous" pure $ SolidityEvent { name: nm - , inputs: is + , inputs: withMissingLabels' is , anonymous: a } @@ -372,7 +373,7 @@ instance DecodeJson SolidityConstructor where obj <- decodeJson json is <- obj .: "inputs" pure $ SolidityConstructor - { inputs: is } + { inputs: withMissingLabels is } -------------------------------------------------------------------------------- -- | ABI @@ -426,3 +427,26 @@ instance instance Show AbiDecodeError where show (AbiDecodeError r) = "(AbiDecodeError " <> show r <> ")" + +withMissingLabels + :: Array NamedSolidityType + -> Array NamedSolidityType +withMissingLabels as = flip map (zip (1 .. length as) as) \(Tuple n f@(NamedSolidityType { name, type: _t })) -> + case name of + Nothing -> NamedSolidityType { name: Just ("_" <> show n), type: _t } + Just _ -> f + +withMissingLabels' + :: Array IndexedSolidityValue + -> Array IndexedSolidityValue +withMissingLabels' as = flip map (zip (1 .. length as) as) \(Tuple n f@(IndexedSolidityValue { type: t, indexed })) -> + let + NamedSolidityType { name, type: _t } = t + in + case name of + Nothing -> + let + nt' = NamedSolidityType { name: Just ("_" <> show n), type: _t } + in + IndexedSolidityValue { type: nt', indexed } + Just _ -> f diff --git a/src/Data/Generator.purs b/src/Data/Generator.purs index 53723db..3ceaff4 100644 --- a/src/Data/Generator.purs +++ b/src/Data/Generator.purs @@ -3,7 +3,7 @@ module Data.Generator where import Prelude import Data.AbiParser (Abi(..), AbiType(..), BasicSolidityType(..), IndexedSolidityValue(..), NamedSolidityType(..), SolidityConstructor(..), SolidityEvent(..), SolidityFunction(..), SolidityType(..), format) -import Data.Array (concat, filter, head, length, null, replicate, snoc, zip, (..), (:)) +import Data.Array (concat, filter, length, null, replicate, snoc, (:)) import Data.Identity (Identity(..)) import Data.Maybe (Maybe(..), fromJust, fromMaybe, isJust, isNothing, maybe) import Data.Newtype (un) @@ -13,7 +13,7 @@ import Data.Tuple (Tuple(..)) import Network.Ethereum.Core.HexString (fromByteString) import Network.Ethereum.Core.Keccak256 (keccak256) import Network.Ethereum.Web3.Types (HexString, unHex) -import Partial.Unsafe (unsafePartial) +import Partial.Unsafe (unsafeCrashWith, unsafePartial) import PureScript.CST.Types as CST import Tidy.Codegen as Gen import Tidy.Codegen.Monad as TidyM @@ -63,14 +63,7 @@ basicToPSType opts a = case a of tup@(SolidityTuple factors) -> unsafePartial $ maybeWrap opts (noRecordsAtOrBelow $ BasicType tup) do if null factors then Gen.typeCtor <$> TidyM.importFrom "Network.Ethereum.Web3.Solidity" (TidyM.importType "Tuple0") else case for_ factors \(NamedSolidityType { name }) -> name of - Nothing -> - let - namedFactors = flip map (zip (1 .. length factors) factors) \(Tuple n f@(NamedSolidityType { name, type: t })) -> - case name of - Nothing -> NamedSolidityType { name: Just ("_" <> show n), type: t } - Just _ -> f - in - basicToPSType opts (SolidityTuple namedFactors) + Nothing -> unsafeCrashWith "Names should have been proved by fallback method which uses coordinates" _ | opts.onlyTuples -> do let tupleType = "Tuple" <> show (length factors) tuple <- Gen.typeCtor <$> TidyM.importFrom "Network.Ethereum.Web3.Solidity" (TidyM.importType tupleType)