(* Generated by coq-of-rust *)
Require Import CoqOfRust.CoqOfRust.

Module handler.
  Module mainnet.
    Module post_execution.
      (*
      pub fn end<EXT, DB: Database>(
          _context: &mut Context<EXT, DB>,
          evm_output: Result<ResultAndState, EVMError<DB::Error>>,
      ) -> Result<ResultAndState, EVMError<DB::Error>> {
          evm_output
      }
      *)
      Definition end_ (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ EXT; DB ], [ _context; evm_output ] =>
          ltac:(M.monadic
            (let _context := M.alloc (| _context |) in
            let evm_output := M.alloc (| evm_output |) in
            M.read (| evm_output |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Function_end_ : M.IsFunction "revm::handler::mainnet::post_execution::end" end_.
      
      (*
      pub fn clear<EXT, DB: Database>(context: &mut Context<EXT, DB>) {
          // clear error and journaled state.
          let _ = context.evm.take_error();
          context.evm.inner.journaled_state.clear();
      }
      *)
      Definition clear (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ EXT; DB ], [ context ] =>
          ltac:(M.monadic
            (let context := M.alloc (| context |) in
            M.read (|
              M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "revm::context::inner_evm_context::InnerEvmContext")
                        []
                        [ DB ],
                      "take_error",
                      []
                    |),
                    [
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::ops::deref::DerefMut",
                          Ty.apply (Ty.path "revm::context::evm_context::EvmContext") [] [ DB ],
                          [],
                          "deref_mut",
                          []
                        |),
                        [
                          M.SubPointer.get_struct_record_field (|
                            M.read (| context |),
                            "revm::context::Context",
                            "evm"
                          |)
                        ]
                      |)
                    ]
                  |)
                |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let~ _ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "revm::journaled_state::JournaledState",
                              "clear",
                              []
                            |),
                            [
                              M.SubPointer.get_struct_record_field (|
                                M.SubPointer.get_struct_record_field (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| context |),
                                    "revm::context::Context",
                                    "evm"
                                  |),
                                  "revm::context::evm_context::EvmContext",
                                  "inner"
                                |),
                                "revm::context::inner_evm_context::InnerEvmContext",
                                "journaled_state"
                              |)
                            ]
                          |)
                        |) in
                      M.alloc (| Value.Tuple [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Function_clear : M.IsFunction "revm::handler::mainnet::post_execution::clear" clear.
      
      (*
      pub fn reward_beneficiary<SPEC: Spec, EXT, DB: Database>(
          context: &mut Context<EXT, DB>,
          gas: &Gas,
      ) -> Result<(), EVMError<DB::Error>> {
          let beneficiary = context.evm.env.block.coinbase;
          let effective_gas_price = context.evm.env.effective_gas_price();
      
          // transfer fee to coinbase/beneficiary.
          // EIP-1559 discard basefee for coinbase transfer. Basefee amount of gas is discarded.
          let coinbase_gas_price = if SPEC::enabled(LONDON) {
              effective_gas_price.saturating_sub(context.evm.env.block.basefee)
          } else {
              effective_gas_price
          };
      
          let (coinbase_account, _) = context
              .evm
              .inner
              .journaled_state
              .load_account(beneficiary, &mut context.evm.inner.db)?;
      
          coinbase_account.mark_touch();
          coinbase_account.info.balance = coinbase_account
              .info
              .balance
              .saturating_add(coinbase_gas_price * U256::from(gas.spent() - gas.refunded() as u64));
      
          Ok(())
      }
      *)
      Definition reward_beneficiary (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ SPEC; EXT; DB ], [ context; gas ] =>
          ltac:(M.monadic
            (let context := M.alloc (| context |) in
            let gas := M.alloc (| gas |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ beneficiary :=
                    M.copy (|
                      M.SubPointer.get_struct_record_field (|
                        M.SubPointer.get_struct_record_field (|
                          M.read (|
                            M.SubPointer.get_struct_record_field (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::ops::deref::Deref",
                                  Ty.apply
                                    (Ty.path "revm::context::evm_context::EvmContext")
                                    []
                                    [ DB ],
                                  [],
                                  "deref",
                                  []
                                |),
                                [
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| context |),
                                    "revm::context::Context",
                                    "evm"
                                  |)
                                ]
                              |),
                              "revm::context::inner_evm_context::InnerEvmContext",
                              "env"
                            |)
                          |),
                          "revm_primitives::env::Env",
                          "block"
                        |),
                        "revm_primitives::env::BlockEnv",
                        "coinbase"
                      |)
                    |) in
                  let~ effective_gas_price :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "revm_primitives::env::Env",
                          "effective_gas_price",
                          []
                        |),
                        [
                          M.read (|
                            M.SubPointer.get_struct_record_field (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::ops::deref::Deref",
                                  Ty.apply
                                    (Ty.path "revm::context::evm_context::EvmContext")
                                    []
                                    [ DB ],
                                  [],
                                  "deref",
                                  []
                                |),
                                [
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| context |),
                                    "revm::context::Context",
                                    "evm"
                                  |)
                                ]
                              |),
                              "revm::context::inner_evm_context::InnerEvmContext",
                              "env"
                            |)
                          |)
                        ]
                      |)
                    |) in
                  let~ coinbase_gas_price :=
                    M.copy (|
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "revm_primitives::specification::Spec",
                                        SPEC,
                                        [],
                                        "enabled",
                                        []
                                      |),
                                      [
                                        Value.StructTuple
                                          "revm_primitives::specification::SpecId::LONDON"
                                          []
                                      ]
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply
                                      (Ty.path "ruint::Uint")
                                      [
                                        Value.Integer IntegerKind.Usize 256;
                                        Value.Integer IntegerKind.Usize 4
                                      ]
                                      [],
                                    "saturating_sub",
                                    []
                                  |),
                                  [
                                    M.read (| effective_gas_price |);
                                    M.read (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (|
                                            M.SubPointer.get_struct_record_field (|
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "core::ops::deref::Deref",
                                                  Ty.apply
                                                    (Ty.path
                                                      "revm::context::evm_context::EvmContext")
                                                    []
                                                    [ DB ],
                                                  [],
                                                  "deref",
                                                  []
                                                |),
                                                [
                                                  M.SubPointer.get_struct_record_field (|
                                                    M.read (| context |),
                                                    "revm::context::Context",
                                                    "evm"
                                                  |)
                                                ]
                                              |),
                                              "revm::context::inner_evm_context::InnerEvmContext",
                                              "env"
                                            |)
                                          |),
                                          "revm_primitives::env::Env",
                                          "block"
                                        |),
                                        "revm_primitives::env::BlockEnv",
                                        "basefee"
                                      |)
                                    |)
                                  ]
                                |)
                              |)));
                          fun γ => ltac:(M.monadic effective_gas_price)
                        ]
                      |)
                    |) in
                  M.match_operator (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::ops::try_trait::Try",
                            Ty.apply
                              (Ty.path "core::result::Result")
                              []
                              [
                                Ty.tuple
                                  [
                                    Ty.apply
                                      (Ty.path "&mut")
                                      []
                                      [ Ty.path "revm_primitives::state::Account" ];
                                    Ty.path "bool"
                                  ];
                                Ty.apply
                                  (Ty.path "revm_primitives::result::EVMError")
                                  []
                                  [ Ty.associated ]
                              ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "revm::journaled_state::JournaledState",
                                "load_account",
                                [ DB ]
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| context |),
                                      "revm::context::Context",
                                      "evm"
                                    |),
                                    "revm::context::evm_context::EvmContext",
                                    "inner"
                                  |),
                                  "revm::context::inner_evm_context::InnerEvmContext",
                                  "journaled_state"
                                |);
                                M.read (| beneficiary |);
                                M.SubPointer.get_struct_record_field (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| context |),
                                      "revm::context::Context",
                                      "evm"
                                    |),
                                    "revm::context::evm_context::EvmContext",
                                    "inner"
                                  |),
                                  "revm::context::inner_evm_context::InnerEvmContext",
                                  "db"
                                |)
                              ]
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Break",
                                0
                              |) in
                            let residual := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::FromResidual",
                                        Ty.apply
                                          (Ty.path "core::result::Result")
                                          []
                                          [
                                            Ty.tuple [];
                                            Ty.apply
                                              (Ty.path "revm_primitives::result::EVMError")
                                              []
                                              [ Ty.associated ]
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            []
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.apply
                                                (Ty.path "revm_primitives::result::EVMError")
                                                []
                                                [ Ty.associated ]
                                            ]
                                        ],
                                        "from_residual",
                                        []
                                      |),
                                      [ M.read (| residual |) ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Continue",
                                0
                              |) in
                            let val := M.copy (| γ0_0 |) in
                            val))
                      ]
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                          let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                          let coinbase_account := M.copy (| γ0_0 |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "revm_primitives::state::Account",
                                  "mark_touch",
                                  []
                                |),
                                [ M.read (| coinbase_account |) ]
                              |)
                            |) in
                          let~ _ :=
                            M.write (|
                              M.SubPointer.get_struct_record_field (|
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| coinbase_account |),
                                  "revm_primitives::state::Account",
                                  "info"
                                |),
                                "revm_primitives::state::AccountInfo",
                                "balance"
                              |),
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "ruint::Uint")
                                    [
                                      Value.Integer IntegerKind.Usize 256;
                                      Value.Integer IntegerKind.Usize 4
                                    ]
                                    [],
                                  "saturating_add",
                                  []
                                |),
                                [
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| coinbase_account |),
                                        "revm_primitives::state::Account",
                                        "info"
                                      |),
                                      "revm_primitives::state::AccountInfo",
                                      "balance"
                                    |)
                                  |);
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::arith::Mul",
                                      Ty.apply
                                        (Ty.path "ruint::Uint")
                                        [
                                          Value.Integer IntegerKind.Usize 256;
                                          Value.Integer IntegerKind.Usize 4
                                        ]
                                        [],
                                      [
                                        Ty.apply
                                          (Ty.path "ruint::Uint")
                                          [
                                            Value.Integer IntegerKind.Usize 256;
                                            Value.Integer IntegerKind.Usize 4
                                          ]
                                          []
                                      ],
                                      "mul",
                                      []
                                    |),
                                    [
                                      M.read (| coinbase_gas_price |);
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "ruint::Uint")
                                            [
                                              Value.Integer IntegerKind.Usize 256;
                                              Value.Integer IntegerKind.Usize 4
                                            ]
                                            [],
                                          "from",
                                          [ Ty.path "u64" ]
                                        |),
                                        [
                                          BinOp.Wrap.sub (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "revm_interpreter::gas::Gas",
                                                "spent",
                                                []
                                              |),
                                              [ M.read (| gas |) ]
                                            |),
                                            M.rust_cast
                                              (M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "revm_interpreter::gas::Gas",
                                                  "refunded",
                                                  []
                                                |),
                                                [ M.read (| gas |) ]
                                              |))
                                          |)
                                        ]
                                      |)
                                    ]
                                  |)
                                ]
                              |)
                            |) in
                          M.alloc (|
                            Value.StructTuple "core::result::Result::Ok" [ Value.Tuple [] ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Function_reward_beneficiary :
        M.IsFunction
          "revm::handler::mainnet::post_execution::reward_beneficiary"
          reward_beneficiary.
      
      (*
      pub fn reimburse_caller<SPEC: Spec, EXT, DB: Database>(
          context: &mut Context<EXT, DB>,
          gas: &Gas,
      ) -> Result<(), EVMError<DB::Error>> {
          let caller = context.evm.env.tx.caller;
          let effective_gas_price = context.evm.env.effective_gas_price();
      
          // return balance of not spend gas.
          let (caller_account, _) = context
              .evm
              .inner
              .journaled_state
              .load_account(caller, &mut context.evm.inner.db)?;
      
          caller_account.info.balance = caller_account
              .info
              .balance
              .saturating_add(effective_gas_price * U256::from(gas.remaining() + gas.refunded() as u64));
      
          Ok(())
      }
      *)
      Definition reimburse_caller (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ SPEC; EXT; DB ], [ context; gas ] =>
          ltac:(M.monadic
            (let context := M.alloc (| context |) in
            let gas := M.alloc (| gas |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ caller :=
                    M.copy (|
                      M.SubPointer.get_struct_record_field (|
                        M.SubPointer.get_struct_record_field (|
                          M.read (|
                            M.SubPointer.get_struct_record_field (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::ops::deref::Deref",
                                  Ty.apply
                                    (Ty.path "revm::context::evm_context::EvmContext")
                                    []
                                    [ DB ],
                                  [],
                                  "deref",
                                  []
                                |),
                                [
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| context |),
                                    "revm::context::Context",
                                    "evm"
                                  |)
                                ]
                              |),
                              "revm::context::inner_evm_context::InnerEvmContext",
                              "env"
                            |)
                          |),
                          "revm_primitives::env::Env",
                          "tx"
                        |),
                        "revm_primitives::env::TxEnv",
                        "caller"
                      |)
                    |) in
                  let~ effective_gas_price :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "revm_primitives::env::Env",
                          "effective_gas_price",
                          []
                        |),
                        [
                          M.read (|
                            M.SubPointer.get_struct_record_field (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::ops::deref::Deref",
                                  Ty.apply
                                    (Ty.path "revm::context::evm_context::EvmContext")
                                    []
                                    [ DB ],
                                  [],
                                  "deref",
                                  []
                                |),
                                [
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| context |),
                                    "revm::context::Context",
                                    "evm"
                                  |)
                                ]
                              |),
                              "revm::context::inner_evm_context::InnerEvmContext",
                              "env"
                            |)
                          |)
                        ]
                      |)
                    |) in
                  M.match_operator (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::ops::try_trait::Try",
                            Ty.apply
                              (Ty.path "core::result::Result")
                              []
                              [
                                Ty.tuple
                                  [
                                    Ty.apply
                                      (Ty.path "&mut")
                                      []
                                      [ Ty.path "revm_primitives::state::Account" ];
                                    Ty.path "bool"
                                  ];
                                Ty.apply
                                  (Ty.path "revm_primitives::result::EVMError")
                                  []
                                  [ Ty.associated ]
                              ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "revm::journaled_state::JournaledState",
                                "load_account",
                                [ DB ]
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| context |),
                                      "revm::context::Context",
                                      "evm"
                                    |),
                                    "revm::context::evm_context::EvmContext",
                                    "inner"
                                  |),
                                  "revm::context::inner_evm_context::InnerEvmContext",
                                  "journaled_state"
                                |);
                                M.read (| caller |);
                                M.SubPointer.get_struct_record_field (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| context |),
                                      "revm::context::Context",
                                      "evm"
                                    |),
                                    "revm::context::evm_context::EvmContext",
                                    "inner"
                                  |),
                                  "revm::context::inner_evm_context::InnerEvmContext",
                                  "db"
                                |)
                              ]
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Break",
                                0
                              |) in
                            let residual := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::FromResidual",
                                        Ty.apply
                                          (Ty.path "core::result::Result")
                                          []
                                          [
                                            Ty.tuple [];
                                            Ty.apply
                                              (Ty.path "revm_primitives::result::EVMError")
                                              []
                                              [ Ty.associated ]
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            []
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.apply
                                                (Ty.path "revm_primitives::result::EVMError")
                                                []
                                                [ Ty.associated ]
                                            ]
                                        ],
                                        "from_residual",
                                        []
                                      |),
                                      [ M.read (| residual |) ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Continue",
                                0
                              |) in
                            let val := M.copy (| γ0_0 |) in
                            val))
                      ]
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                          let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                          let caller_account := M.copy (| γ0_0 |) in
                          let~ _ :=
                            M.write (|
                              M.SubPointer.get_struct_record_field (|
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| caller_account |),
                                  "revm_primitives::state::Account",
                                  "info"
                                |),
                                "revm_primitives::state::AccountInfo",
                                "balance"
                              |),
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "ruint::Uint")
                                    [
                                      Value.Integer IntegerKind.Usize 256;
                                      Value.Integer IntegerKind.Usize 4
                                    ]
                                    [],
                                  "saturating_add",
                                  []
                                |),
                                [
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| caller_account |),
                                        "revm_primitives::state::Account",
                                        "info"
                                      |),
                                      "revm_primitives::state::AccountInfo",
                                      "balance"
                                    |)
                                  |);
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::arith::Mul",
                                      Ty.apply
                                        (Ty.path "ruint::Uint")
                                        [
                                          Value.Integer IntegerKind.Usize 256;
                                          Value.Integer IntegerKind.Usize 4
                                        ]
                                        [],
                                      [
                                        Ty.apply
                                          (Ty.path "ruint::Uint")
                                          [
                                            Value.Integer IntegerKind.Usize 256;
                                            Value.Integer IntegerKind.Usize 4
                                          ]
                                          []
                                      ],
                                      "mul",
                                      []
                                    |),
                                    [
                                      M.read (| effective_gas_price |);
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "ruint::Uint")
                                            [
                                              Value.Integer IntegerKind.Usize 256;
                                              Value.Integer IntegerKind.Usize 4
                                            ]
                                            [],
                                          "from",
                                          [ Ty.path "u64" ]
                                        |),
                                        [
                                          BinOp.Wrap.add (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "revm_interpreter::gas::Gas",
                                                "remaining",
                                                []
                                              |),
                                              [ M.read (| gas |) ]
                                            |),
                                            M.rust_cast
                                              (M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "revm_interpreter::gas::Gas",
                                                  "refunded",
                                                  []
                                                |),
                                                [ M.read (| gas |) ]
                                              |))
                                          |)
                                        ]
                                      |)
                                    ]
                                  |)
                                ]
                              |)
                            |) in
                          M.alloc (|
                            Value.StructTuple "core::result::Result::Ok" [ Value.Tuple [] ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Function_reimburse_caller :
        M.IsFunction "revm::handler::mainnet::post_execution::reimburse_caller" reimburse_caller.
      
      (*
      pub fn output<EXT, DB: Database>(
          context: &mut Context<EXT, DB>,
          result: FrameResult,
      ) -> Result<ResultAndState, EVMError<DB::Error>> {
          context.evm.take_error()?;
          // used gas with refund calculated.
          let gas_refunded = result.gas().refunded() as u64;
          let final_gas_used = result.gas().spent() - gas_refunded;
          let output = result.output();
          let instruction_result = result.into_interpreter_result();
      
          // reset journal and return present state.
          let (state, logs) = context.evm.journaled_state.finalize();
      
          let result = match instruction_result.result.into() {
              SuccessOrHalt::Success(reason) => ExecutionResult::Success {
                  reason,
                  gas_used: final_gas_used,
                  gas_refunded,
                  logs,
                  output,
              },
              SuccessOrHalt::Revert => ExecutionResult::Revert {
                  gas_used: final_gas_used,
                  output: output.into_data(),
              },
              SuccessOrHalt::Halt(reason) => ExecutionResult::Halt {
                  reason,
                  gas_used: final_gas_used,
              },
              // Only two internal return flags.
              flag @ (SuccessOrHalt::FatalExternalError
              | SuccessOrHalt::InternalContinue
              | SuccessOrHalt::InternalCallOrCreate) => {
                  panic!(
                      "Encountered unexpected internal return flag: {:?} with instruction result: {:?}",
                      flag, instruction_result
                  )
              }
          };
      
          Ok(ResultAndState { result, state })
      }
      *)
      Definition output (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ EXT; DB ], [ context; result ] =>
          ltac:(M.monadic
            (let context := M.alloc (| context |) in
            let result := M.alloc (| result |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::ops::try_trait::Try",
                            Ty.apply
                              (Ty.path "core::result::Result")
                              []
                              [
                                Ty.tuple [];
                                Ty.apply
                                  (Ty.path "revm_primitives::result::EVMError")
                                  []
                                  [ Ty.associated ]
                              ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "revm::context::inner_evm_context::InnerEvmContext")
                                  []
                                  [ DB ],
                                "take_error",
                                []
                              |),
                              [
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::ops::deref::DerefMut",
                                    Ty.apply
                                      (Ty.path "revm::context::evm_context::EvmContext")
                                      []
                                      [ DB ],
                                    [],
                                    "deref_mut",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| context |),
                                      "revm::context::Context",
                                      "evm"
                                    |)
                                  ]
                                |)
                              ]
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Break",
                                0
                              |) in
                            let residual := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::FromResidual",
                                        Ty.apply
                                          (Ty.path "core::result::Result")
                                          []
                                          [
                                            Ty.path "revm_primitives::result::ResultAndState";
                                            Ty.apply
                                              (Ty.path "revm_primitives::result::EVMError")
                                              []
                                              [ Ty.associated ]
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            []
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.apply
                                                (Ty.path "revm_primitives::result::EVMError")
                                                []
                                                [ Ty.associated ]
                                            ]
                                        ],
                                        "from_residual",
                                        []
                                      |),
                                      [ M.read (| residual |) ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Continue",
                                0
                              |) in
                            let val := M.copy (| γ0_0 |) in
                            val))
                      ]
                    |) in
                  let~ gas_refunded :=
                    M.alloc (|
                      M.rust_cast
                        (M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "revm_interpreter::gas::Gas",
                            "refunded",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "revm::frame::FrameResult",
                                "gas",
                                []
                              |),
                              [ result ]
                            |)
                          ]
                        |))
                    |) in
                  let~ final_gas_used :=
                    M.alloc (|
                      BinOp.Wrap.sub (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "revm_interpreter::gas::Gas",
                            "spent",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "revm::frame::FrameResult",
                                "gas",
                                []
                              |),
                              [ result ]
                            |)
                          ]
                        |),
                        M.read (| gas_refunded |)
                      |)
                    |) in
                  let~ output :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "revm::frame::FrameResult",
                          "output",
                          []
                        |),
                        [ result ]
                      |)
                    |) in
                  let~ instruction_result :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "revm::frame::FrameResult",
                          "into_interpreter_result",
                          []
                        |),
                        [ M.read (| result |) ]
                      |)
                    |) in
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "revm::journaled_state::JournaledState",
                          "finalize",
                          []
                        |),
                        [
                          M.SubPointer.get_struct_record_field (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::ops::deref::DerefMut",
                                Ty.apply
                                  (Ty.path "revm::context::evm_context::EvmContext")
                                  []
                                  [ DB ],
                                [],
                                "deref_mut",
                                []
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| context |),
                                  "revm::context::Context",
                                  "evm"
                                |)
                              ]
                            |),
                            "revm::context::inner_evm_context::InnerEvmContext",
                            "journaled_state"
                          |)
                        ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                          let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                          let state := M.copy (| γ0_0 |) in
                          let logs := M.copy (| γ0_1 |) in
                          let~ result :=
                            M.copy (|
                              M.match_operator (|
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::convert::Into",
                                      Ty.path
                                        "revm_interpreter::instruction_result::InstructionResult",
                                      [
                                        Ty.path
                                          "revm_interpreter::instruction_result::SuccessOrHalt"
                                      ],
                                      "into",
                                      []
                                    |),
                                    [
                                      M.read (|
                                        M.SubPointer.get_struct_record_field (|
                                          instruction_result,
                                          "revm_interpreter::interpreter::InterpreterResult",
                                          "result"
                                        |)
                                      |)
                                    ]
                                  |)
                                |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ0_0 :=
                                        M.SubPointer.get_struct_tuple_field (|
                                          γ,
                                          "revm_interpreter::instruction_result::SuccessOrHalt::Success",
                                          0
                                        |) in
                                      let reason := M.copy (| γ0_0 |) in
                                      M.alloc (|
                                        Value.StructRecord
                                          "revm_primitives::result::ExecutionResult::Success"
                                          [
                                            ("reason", M.read (| reason |));
                                            ("gas_used", M.read (| final_gas_used |));
                                            ("gas_refunded", M.read (| gas_refunded |));
                                            ("logs", M.read (| logs |));
                                            ("output", M.read (| output |))
                                          ]
                                      |)));
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let _ :=
                                        M.is_struct_tuple (|
                                          γ,
                                          "revm_interpreter::instruction_result::SuccessOrHalt::Revert"
                                        |) in
                                      M.alloc (|
                                        Value.StructRecord
                                          "revm_primitives::result::ExecutionResult::Revert"
                                          [
                                            ("gas_used", M.read (| final_gas_used |));
                                            ("output",
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "revm_primitives::result::Output",
                                                  "into_data",
                                                  []
                                                |),
                                                [ M.read (| output |) ]
                                              |))
                                          ]
                                      |)));
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ0_0 :=
                                        M.SubPointer.get_struct_tuple_field (|
                                          γ,
                                          "revm_interpreter::instruction_result::SuccessOrHalt::Halt",
                                          0
                                        |) in
                                      let reason := M.copy (| γ0_0 |) in
                                      M.alloc (|
                                        Value.StructRecord
                                          "revm_primitives::result::ExecutionResult::Halt"
                                          [
                                            ("reason", M.read (| reason |));
                                            ("gas_used", M.read (| final_gas_used |))
                                          ]
                                      |)));
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let flag := M.copy (| γ |) in
                                      M.find_or_pattern (|
                                        γ,
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let _ :=
                                                M.is_struct_tuple (|
                                                  γ,
                                                  "revm_interpreter::instruction_result::SuccessOrHalt::FatalExternalError"
                                                |) in
                                              Value.Tuple []));
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let _ :=
                                                M.is_struct_tuple (|
                                                  γ,
                                                  "revm_interpreter::instruction_result::SuccessOrHalt::InternalContinue"
                                                |) in
                                              Value.Tuple []));
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let _ :=
                                                M.is_struct_tuple (|
                                                  γ,
                                                  "revm_interpreter::instruction_result::SuccessOrHalt::InternalCallOrCreate"
                                                |) in
                                              Value.Tuple []))
                                        ],
                                        M.closure
                                          (fun γ =>
                                            ltac:(M.monadic
                                              match γ with
                                              | [] =>
                                                ltac:(M.monadic
                                                  (M.alloc (|
                                                    M.never_to_any (|
                                                      M.call_closure (|
                                                        M.get_function (|
                                                          "core::panicking::panic_fmt",
                                                          []
                                                        |),
                                                        [
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.path "core::fmt::Arguments",
                                                              "new_v1",
                                                              []
                                                            |),
                                                            [
                                                              M.alloc (|
                                                                Value.Array
                                                                  [
                                                                    M.read (|
                                                                      Value.String
                                                                        "Encountered unexpected internal return flag: "
                                                                    |);
                                                                    M.read (|
                                                                      Value.String
                                                                        " with instruction result: "
                                                                    |)
                                                                  ]
                                                              |);
                                                              M.alloc (|
                                                                Value.Array
                                                                  [
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path
                                                                          "core::fmt::rt::Argument",
                                                                        "new_debug",
                                                                        [
                                                                          Ty.path
                                                                            "revm_interpreter::instruction_result::SuccessOrHalt"
                                                                        ]
                                                                      |),
                                                                      [ flag ]
                                                                    |);
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path
                                                                          "core::fmt::rt::Argument",
                                                                        "new_debug",
                                                                        [
                                                                          Ty.path
                                                                            "revm_interpreter::interpreter::InterpreterResult"
                                                                        ]
                                                                      |),
                                                                      [ instruction_result ]
                                                                    |)
                                                                  ]
                                                              |)
                                                            ]
                                                          |)
                                                        ]
                                                      |)
                                                    |)
                                                  |)))
                                              | _ => M.impossible "wrong number of arguments"
                                              end))
                                      |)))
                                ]
                              |)
                            |) in
                          M.alloc (|
                            Value.StructTuple
                              "core::result::Result::Ok"
                              [
                                Value.StructRecord
                                  "revm_primitives::result::ResultAndState"
                                  [ ("result", M.read (| result |)); ("state", M.read (| state |)) ]
                              ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Function_output : M.IsFunction "revm::handler::mainnet::post_execution::output" output.
    End post_execution.
  End mainnet.
End handler.
