The scaffold generators carried Solidity types as raw strings and matched
them with `ends_with("[]")` / `starts_with("uint")`, while codegen carries
alloy `DynSolType` and matches on variants. Every scaffold bug found while
reviewing tuple support was a string-matching bug in this half.
Resolve each event input to `DynSolType` once at the ABI boundary and carry
the typed value through `InputLeaf`, the schema generator and the mapping
cast. `solidity_to_graphql`/`int_to_graphql` become `graphql_type`, an
exhaustive match on the type; `needs_bytes_array_cast` matches
`Array(Address)` instead of the `"address[]"` string.
Typing the schema side also fixes fixed-size arrays of scalar elements
(`uint256[3]`, `bool[2]`, `bytes32[4]`, ...), which `ends_with("[]")` could
not see and which scaffolded to a non-building scalar field. `address[3]`
still needs the cast and is handled in the next commit.
Scaffolding runs on hand-written ABIs alloy accepts but cannot fully resolve
(a component-less `tuple`), so a fallible resolver falls back to a `Bytes`
field with a warning instead of panicking like codegen's resolver does.
Stacked on #6693 (which is stacked on #6661) — both should land first.
The scaffold decided GraphQL types by string-matching Solidity type names, in parallel with codegen's already-typed path. This parses the type once at the ABI boundary and carries the resolved DynSolType through the manifest, schema, and mapping generators, so a schema/codegen disagreement is unrepresentable rather than a string the two sides match differently.