pragma solidity 0.8.18;

contract L2GasLimit {
    fallback() external {
        assembly {
            let success := staticcall(
                gas(),
                0x08,
                0x80,
                165504,
                0x0,
                0x0
            )
            if iszero(success) { revert(0, 0) }
        }
    }
}
func TestImpossiblePrecompileCallBug(t *testing.T) {
    /**********************************************************************
    1. General setup
    **********************************************************************/
    op_e2e.InitParallel(t, op_e2e.UsesCannon)

    ctx := context.Background()
    sys, _ := StartFaultDisputeSystem(t, WithBlobBatches())
    t.Cleanup(sys.Close)

    // NOTE: Flake prevention. Copied from other tests
    safeBlock, err := sys.Clients["sequencer"].BlockByNumber(ctx, big.NewInt(int64(rpc.SafeBlockNumber)))
    require.NoError(t, err)
    require.NoError(t, wait.ForSafeBlock(ctx, sys.RollupClient("sequencer"), safeBlock.NumberU64()+1))
    t.Logf("AUDIT: L2 block gas limit: %d", safeBlock.GasLimit())

    /**********************************************************************
    2. Create a contract that will call the 0x08 precompile efficiently
    **********************************************************************/
    deployReceipt := op_e2e.SendL2Tx(t, sys.Cfg, sys.Clients["sequencer"], sys.Cfg.Secrets.Alice, func(opts *op_e2e.TxOpts) {
        opts.Gas = 1_000_000
        opts.ToAddr = nil

        // Below is the initcode for the following contract:
        /**********************************************************************
        pragma solidity 0.8.18;

        contract L2GasLimit {
            fallback() external {
                assembly {
                    let success := staticcall(
                        gas(),
                        0x08,
                        0x80,
                        165504,
                        0x0,
                        0x0
                    )
                    if iszero(success) { revert(0, 0) }
                }
            }
        }
        **********************************************************************/
        initCodeHex := "6080604052348015600f57600080fd5b50605d80601d6000396000f3fe6080604052348015600f576"
        initCodeHex += "00080fd5b5060008062028680608060085afa602557600080fd5b00fea26469706673582212209e7bb"
        initCodeHex += "5e756d6686f69b47dc161cf0dc1ff83238b405d23bbc542328f68ed76c064736f6c63430008120033"
        initCode, err := hex.DecodeString(initCodeHex)
        require.NoError(t, err)
        opts.Data = initCode
    })

    t.Logf("AUDIT: Deploy tx gasUsed: %d", deployReceipt.GasUsed)
    t.Logf("AUDIT: Deploy tx block number: %d", deployReceipt.BlockNumber)
    t.Logf("AUDIT: Deploy tx contractAddress: %s", deployReceipt.ContractAddress.Hex())

    /**********************************************************************
    3. Call the contract, using nearly 30_000_000 gas
    **********************************************************************/
    precompileReceipt := op_e2e.SendL2Tx(t, sys.Cfg, sys.Clients["sequencer"], sys.Cfg.Secrets.Alice, func(opts *op_e2e.TxOpts) {
        // Note: the initial l1 attributes tx almost always uses less than 70k gas
        opts.Gas = 30_000_000 - 70_000
        opts.ToAddr = &deployReceipt.ContractAddress
        opts.Nonce = 1
        opts.Data = nil
    })

    // Not necessary, but this shows how much gas the initial l1 attributes tx used
    l1AttrTx, _ := sys.Clients["sequencer"].TransactionInBlock(ctx, precompileReceipt.BlockHash, 0)
    l1AttrTxReceipt, _ := sys.Clients["sequencer"].TransactionReceipt(ctx, l1AttrTx.Hash())
    t.Logf("AUDIT: Contract call initial tx gas used: %d", l1AttrTxReceipt.GasUsed)

    // Show that the precompile call succeeded
    t.Logf("AUDIT: Contract call block number: %d", precompileReceipt.BlockNumber)
    t.Logf("AUDIT: Contract call gas used: %d", precompileReceipt.GasUsed)
    t.Logf("AUDIT: Contract call status: %d", precompileReceipt.Status)
    t.Logf("AUDIT: Contract call cumulative gas used: %d", precompileReceipt.CumulativeGasUsed)

    /**********************************************************************
    4. Run a dispute game on the block of the precompile call. Notice that
    the challenger will fail because the gas required is too high for the
    PreimageOracle to ever succeed
    **********************************************************************/
    disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys)
    game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", precompileReceipt.BlockNumber.Uint64(), common.Hash{0x01, 0xaa})
    require.NotNil(t, game)
    outputRootClaim := game.DisputeBlock(ctx, precompileReceipt.BlockNumber.Uint64())
    game.LogGameData(ctx)

    game.StartChallenger(ctx, "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice))

    outputRootClaim = outputRootClaim.WaitForCounterClaim(ctx)

    preimageLoadCheck := game.CreateStepPreimageLoadCheck(ctx)
    game.ChallengeToPreimageLoad(ctx, outputRootClaim, sys.Cfg.Secrets.Alice, utils.FirstPrecompilePreimageLoad(), preimageLoadCheck, true)
}
    > grep "AUDIT:" test_output.txt; grep -B 3 "Failed to load preimage part" test_output.txt;
        output_cannon_test.go:409: AUDIT: L2 block gas limit: 30000000
        output_cannon_test.go:446: AUDIT: Deploy tx gasUsed: 73521
        output_cannon_test.go:447: AUDIT: Deploy tx block number: 9
        output_cannon_test.go:448: AUDIT: Deploy tx contractAddress: 0xbdEd0D2bf404bdcBa897a74E6657f1f12e5C6fb6
        output_cannon_test.go:464: AUDIT: Contract call initial tx gas used: 52182
        output_cannon_test.go:467: AUDIT: Contract call block number: 10
        output_cannon_test.go:468: AUDIT: Contract call gas used: 29442018
        output_cannon_test.go:469: AUDIT: Contract call status: 1
        output_cannon_test.go:470: AUDIT: Contract call cumulative gas used: 29494200
                    Error:          Received unexpected error:
                                    oversized data: transaction size 165754, limit 131072
                    Test:           TestImpossiblePrecompileCallBug
                    Messages:       Failed to load preimage part
- if data.IsLocal || uint64(len(data.GetPreimageWithoutSize())) < s.largePreimageSizeThreshold {
+ if data.OracleKey[0] != byte(2) || uint64(len(data.GetPreimageWithoutSize())) < s.largePreimageSizeThreshold {
      return s.directUploader.UploadPreimage(ctx, parent, data)
  } else {
      return s.largeUploader.UploadPreimage(ctx, parent, data)
  }
