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

Module extension.
  Module transfer_fee.
    Module instruction.
      (*
      Enum TransferFeeInstruction
      {
        ty_params := [];
        variants :=
          [
            {
              name := "InitializeTransferFeeConfig";
              item :=
                StructRecord
                  [
                    ("transfer_fee_config_authority",
                      Ty.apply
                        (Ty.path "solana_program::program_option::COption")
                        [ Ty.path "solana_program::pubkey::Pubkey" ]);
                    ("withdraw_withheld_authority",
                      Ty.apply
                        (Ty.path "solana_program::program_option::COption")
                        [ Ty.path "solana_program::pubkey::Pubkey" ]);
                    ("transfer_fee_basis_points", Ty.path "u16");
                    ("maximum_fee", Ty.path "u64")
                  ];
              discriminant := None;
            };
            {
              name := "TransferCheckedWithFee";
              item :=
                StructRecord
                  [ ("amount", Ty.path "u64"); ("decimals", Ty.path "u8"); ("fee", Ty.path "u64") ];
              discriminant := None;
            };
            {
              name := "WithdrawWithheldTokensFromMint";
              item := StructTuple [];
              discriminant := None;
            };
            {
              name := "WithdrawWithheldTokensFromAccounts";
              item := StructRecord [ ("num_token_accounts", Ty.path "u8") ];
              discriminant := None;
            };
            {
              name := "HarvestWithheldTokensToMint";
              item := StructTuple [];
              discriminant := None;
            };
            {
              name := "SetTransferFee";
              item :=
                StructRecord
                  [ ("transfer_fee_basis_points", Ty.path "u16"); ("maximum_fee", Ty.path "u64") ];
              discriminant := None;
            }
          ];
      }
      *)
      
      Module Impl_core_clone_Clone_for_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
        Definition Self : Ty.t :=
          Ty.path "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction".
        
        (* Clone *)
        Definition clone (τ : list Ty.t) (α : list Value.t) : M :=
          match τ, α with
          | [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.read (|
                M.match_operator (|
                  Value.DeclaredButUndefined,
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (M.match_operator (|
                          Value.DeclaredButUndefined,
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  Value.DeclaredButUndefined,
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (M.match_operator (|
                                          Value.DeclaredButUndefined,
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (M.match_operator (|
                                                  Value.DeclaredButUndefined,
                                                  [ fun γ => ltac:(M.monadic (M.read (| self |))) ]
                                                |)))
                                          ]
                                        |)))
                                  ]
                                |)))
                          ]
                        |)))
                  ]
                |)
              |)))
          | _, _ => M.impossible
          end.
        
        Axiom Implements :
          M.IsTraitInstance
            "core::clone::Clone"
            Self
            (* Trait polymorphic types *) []
            (* Instance *) [ ("clone", InstanceField.Method clone) ].
      End Impl_core_clone_Clone_for_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
      
      Module Impl_core_marker_Copy_for_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
        Definition Self : Ty.t :=
          Ty.path "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction".
        
        Axiom Implements :
          M.IsTraitInstance
            "core::marker::Copy"
            Self
            (* Trait polymorphic types *) []
            (* Instance *) [].
      End Impl_core_marker_Copy_for_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
      
      Module Impl_core_fmt_Debug_for_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
        Definition Self : Ty.t :=
          Ty.path "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction".
        
        (* Debug *)
        Definition fmt (τ : list Ty.t) (α : list Value.t) : M :=
          match τ, α with
          | [], [ self; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let f := M.alloc (| f |) in
              M.read (|
                M.match_operator (|
                  self,
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let γ1_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                            "transfer_fee_config_authority"
                          |) in
                        let γ1_1 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                            "withdraw_withheld_authority"
                          |) in
                        let γ1_2 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                            "transfer_fee_basis_points"
                          |) in
                        let γ1_3 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                            "maximum_fee"
                          |) in
                        let __self_0 := M.alloc (| γ1_0 |) in
                        let __self_1 := M.alloc (| γ1_1 |) in
                        let __self_2 := M.alloc (| γ1_2 |) in
                        let __self_3 := M.alloc (| γ1_3 |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::Formatter",
                              "debug_struct_field4_finish",
                              []
                            |),
                            [
                              M.read (| f |);
                              M.read (| Value.String "InitializeTransferFeeConfig" |);
                              M.read (| Value.String "transfer_fee_config_authority" |);
                              (* Unsize *) M.pointer_coercion (M.read (| __self_0 |));
                              M.read (| Value.String "withdraw_withheld_authority" |);
                              (* Unsize *) M.pointer_coercion (M.read (| __self_1 |));
                              M.read (| Value.String "transfer_fee_basis_points" |);
                              (* Unsize *) M.pointer_coercion (M.read (| __self_2 |));
                              M.read (| Value.String "maximum_fee" |);
                              (* Unsize *) M.pointer_coercion __self_3
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let γ1_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                            "amount"
                          |) in
                        let γ1_1 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                            "decimals"
                          |) in
                        let γ1_2 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                            "fee"
                          |) in
                        let __self_0 := M.alloc (| γ1_0 |) in
                        let __self_1 := M.alloc (| γ1_1 |) in
                        let __self_2 := M.alloc (| γ1_2 |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::Formatter",
                              "debug_struct_field3_finish",
                              []
                            |),
                            [
                              M.read (| f |);
                              M.read (| Value.String "TransferCheckedWithFee" |);
                              M.read (| Value.String "amount" |);
                              (* Unsize *) M.pointer_coercion (M.read (| __self_0 |));
                              M.read (| Value.String "decimals" |);
                              (* Unsize *) M.pointer_coercion (M.read (| __self_1 |));
                              M.read (| Value.String "fee" |);
                              (* Unsize *) M.pointer_coercion __self_2
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::Formatter",
                              "write_str",
                              []
                            |),
                            [
                              M.read (| f |);
                              M.read (| Value.String "WithdrawWithheldTokensFromMint" |)
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let γ1_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::WithdrawWithheldTokensFromAccounts",
                            "num_token_accounts"
                          |) in
                        let __self_0 := M.alloc (| γ1_0 |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::Formatter",
                              "debug_struct_field1_finish",
                              []
                            |),
                            [
                              M.read (| f |);
                              M.read (| Value.String "WithdrawWithheldTokensFromAccounts" |);
                              M.read (| Value.String "num_token_accounts" |);
                              (* Unsize *) M.pointer_coercion __self_0
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::Formatter",
                              "write_str",
                              []
                            |),
                            [
                              M.read (| f |);
                              M.read (| Value.String "HarvestWithheldTokensToMint" |)
                            ]
                          |)
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let γ1_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::SetTransferFee",
                            "transfer_fee_basis_points"
                          |) in
                        let γ1_1 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::SetTransferFee",
                            "maximum_fee"
                          |) in
                        let __self_0 := M.alloc (| γ1_0 |) in
                        let __self_1 := M.alloc (| γ1_1 |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::Formatter",
                              "debug_struct_field2_finish",
                              []
                            |),
                            [
                              M.read (| f |);
                              M.read (| Value.String "SetTransferFee" |);
                              M.read (| Value.String "transfer_fee_basis_points" |);
                              (* Unsize *) M.pointer_coercion (M.read (| __self_0 |));
                              M.read (| Value.String "maximum_fee" |);
                              (* Unsize *) M.pointer_coercion __self_1
                            ]
                          |)
                        |)))
                  ]
                |)
              |)))
          | _, _ => M.impossible
          end.
        
        Axiom Implements :
          M.IsTraitInstance
            "core::fmt::Debug"
            Self
            (* Trait polymorphic types *) []
            (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
      End Impl_core_fmt_Debug_for_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
      
      Module Impl_core_marker_StructuralPartialEq_for_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
        Definition Self : Ty.t :=
          Ty.path "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction".
        
        Axiom Implements :
          M.IsTraitInstance
            "core::marker::StructuralPartialEq"
            Self
            (* Trait polymorphic types *) []
            (* Instance *) [].
      End Impl_core_marker_StructuralPartialEq_for_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
      
      Module Impl_core_cmp_PartialEq_for_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
        Definition Self : Ty.t :=
          Ty.path "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction".
        
        (* PartialEq *)
        Definition eq (τ : list Ty.t) (α : list Value.t) : M :=
          match τ, α with
          | [], [ self; other ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let other := M.alloc (| other |) in
              M.read (|
                let __self_tag :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (|
                        "core::intrinsics::discriminant_value",
                        [
                          Ty.path
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction"
                        ]
                      |),
                      [ M.read (| self |) ]
                    |)
                  |) in
                let __arg1_tag :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (|
                        "core::intrinsics::discriminant_value",
                        [
                          Ty.path
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction"
                        ]
                      |),
                      [ M.read (| other |) ]
                    |)
                  |) in
                M.alloc (|
                  LogicalOp.and (|
                    BinOp.Pure.eq (M.read (| __self_tag |)) (M.read (| __arg1_tag |)),
                    ltac:(M.monadic
                      (M.read (|
                        M.match_operator (|
                          M.alloc (| Value.Tuple [ M.read (| self |); M.read (| other |) ] |),
                          [
                            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 γ0_0 := M.read (| γ0_0 |) in
                                let γ2_0 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_0,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                                    "transfer_fee_config_authority"
                                  |) in
                                let γ2_1 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_0,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                                    "withdraw_withheld_authority"
                                  |) in
                                let γ2_2 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_0,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                                    "transfer_fee_basis_points"
                                  |) in
                                let γ2_3 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_0,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                                    "maximum_fee"
                                  |) in
                                let __self_0 := M.alloc (| γ2_0 |) in
                                let __self_1 := M.alloc (| γ2_1 |) in
                                let __self_2 := M.alloc (| γ2_2 |) in
                                let __self_3 := M.alloc (| γ2_3 |) in
                                let γ0_1 := M.read (| γ0_1 |) in
                                let γ2_0 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_1,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                                    "transfer_fee_config_authority"
                                  |) in
                                let γ2_1 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_1,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                                    "withdraw_withheld_authority"
                                  |) in
                                let γ2_2 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_1,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                                    "transfer_fee_basis_points"
                                  |) in
                                let γ2_3 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_1,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                                    "maximum_fee"
                                  |) in
                                let __arg1_0 := M.alloc (| γ2_0 |) in
                                let __arg1_1 := M.alloc (| γ2_1 |) in
                                let __arg1_2 := M.alloc (| γ2_2 |) in
                                let __arg1_3 := M.alloc (| γ2_3 |) in
                                M.alloc (|
                                  LogicalOp.and (|
                                    LogicalOp.and (|
                                      LogicalOp.and (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::cmp::PartialEq",
                                            Ty.apply
                                              (Ty.path "solana_program::program_option::COption")
                                              [ Ty.path "solana_program::pubkey::Pubkey" ],
                                            [
                                              Ty.apply
                                                (Ty.path "solana_program::program_option::COption")
                                                [ Ty.path "solana_program::pubkey::Pubkey" ]
                                            ],
                                            "eq",
                                            []
                                          |),
                                          [ M.read (| __self_0 |); M.read (| __arg1_0 |) ]
                                        |),
                                        ltac:(M.monadic
                                          (M.call_closure (|
                                            M.get_trait_method (|
                                              "core::cmp::PartialEq",
                                              Ty.apply
                                                (Ty.path "solana_program::program_option::COption")
                                                [ Ty.path "solana_program::pubkey::Pubkey" ],
                                              [
                                                Ty.apply
                                                  (Ty.path
                                                    "solana_program::program_option::COption")
                                                  [ Ty.path "solana_program::pubkey::Pubkey" ]
                                              ],
                                              "eq",
                                              []
                                            |),
                                            [ M.read (| __self_1 |); M.read (| __arg1_1 |) ]
                                          |)))
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.Pure.eq
                                          (M.read (| M.read (| __self_2 |) |))
                                          (M.read (| M.read (| __arg1_2 |) |))))
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.Pure.eq
                                        (M.read (| M.read (| __self_3 |) |))
                                        (M.read (| M.read (| __arg1_3 |) |))))
                                  |)
                                |)));
                            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 γ0_0 := M.read (| γ0_0 |) in
                                let γ2_0 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_0,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                                    "amount"
                                  |) in
                                let γ2_1 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_0,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                                    "decimals"
                                  |) in
                                let γ2_2 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_0,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                                    "fee"
                                  |) in
                                let __self_0 := M.alloc (| γ2_0 |) in
                                let __self_1 := M.alloc (| γ2_1 |) in
                                let __self_2 := M.alloc (| γ2_2 |) in
                                let γ0_1 := M.read (| γ0_1 |) in
                                let γ2_0 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_1,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                                    "amount"
                                  |) in
                                let γ2_1 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_1,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                                    "decimals"
                                  |) in
                                let γ2_2 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_1,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                                    "fee"
                                  |) in
                                let __arg1_0 := M.alloc (| γ2_0 |) in
                                let __arg1_1 := M.alloc (| γ2_1 |) in
                                let __arg1_2 := M.alloc (| γ2_2 |) in
                                M.alloc (|
                                  LogicalOp.and (|
                                    LogicalOp.and (|
                                      BinOp.Pure.eq
                                        (M.read (| M.read (| __self_0 |) |))
                                        (M.read (| M.read (| __arg1_0 |) |)),
                                      ltac:(M.monadic
                                        (BinOp.Pure.eq
                                          (M.read (| M.read (| __self_1 |) |))
                                          (M.read (| M.read (| __arg1_1 |) |))))
                                    |),
                                    ltac:(M.monadic
                                      (BinOp.Pure.eq
                                        (M.read (| M.read (| __self_2 |) |))
                                        (M.read (| M.read (| __arg1_2 |) |))))
                                  |)
                                |)));
                            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 γ0_0 := M.read (| γ0_0 |) in
                                let γ2_0 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_0,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::WithdrawWithheldTokensFromAccounts",
                                    "num_token_accounts"
                                  |) in
                                let __self_0 := M.alloc (| γ2_0 |) in
                                let γ0_1 := M.read (| γ0_1 |) in
                                let γ2_0 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_1,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::WithdrawWithheldTokensFromAccounts",
                                    "num_token_accounts"
                                  |) in
                                let __arg1_0 := M.alloc (| γ2_0 |) in
                                M.alloc (|
                                  BinOp.Pure.eq
                                    (M.read (| M.read (| __self_0 |) |))
                                    (M.read (| M.read (| __arg1_0 |) |))
                                |)));
                            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 γ0_0 := M.read (| γ0_0 |) in
                                let γ2_0 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_0,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::SetTransferFee",
                                    "transfer_fee_basis_points"
                                  |) in
                                let γ2_1 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_0,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::SetTransferFee",
                                    "maximum_fee"
                                  |) in
                                let __self_0 := M.alloc (| γ2_0 |) in
                                let __self_1 := M.alloc (| γ2_1 |) in
                                let γ0_1 := M.read (| γ0_1 |) in
                                let γ2_0 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_1,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::SetTransferFee",
                                    "transfer_fee_basis_points"
                                  |) in
                                let γ2_1 :=
                                  M.SubPointer.get_struct_record_field (|
                                    γ0_1,
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::SetTransferFee",
                                    "maximum_fee"
                                  |) in
                                let __arg1_0 := M.alloc (| γ2_0 |) in
                                let __arg1_1 := M.alloc (| γ2_1 |) in
                                M.alloc (|
                                  LogicalOp.and (|
                                    BinOp.Pure.eq
                                      (M.read (| M.read (| __self_0 |) |))
                                      (M.read (| M.read (| __arg1_0 |) |)),
                                    ltac:(M.monadic
                                      (BinOp.Pure.eq
                                        (M.read (| M.read (| __self_1 |) |))
                                        (M.read (| M.read (| __arg1_1 |) |))))
                                  |)
                                |)));
                            fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)))
                          ]
                        |)
                      |)))
                  |)
                |)
              |)))
          | _, _ => M.impossible
          end.
        
        Axiom Implements :
          M.IsTraitInstance
            "core::cmp::PartialEq"
            Self
            (* Trait polymorphic types *) []
            (* Instance *) [ ("eq", InstanceField.Method eq) ].
      End Impl_core_cmp_PartialEq_for_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
      
      Module Impl_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
        Definition Self : Ty.t :=
          Ty.path "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction".
        
        (*
            pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
                use TokenError::InvalidInstruction;
        
                let (&tag, rest) = input.split_first().ok_or(InvalidInstruction)?;
                Ok(match tag {
                    0 => {
                        let (transfer_fee_config_authority, rest) =
                            TokenInstruction::unpack_pubkey_option(rest)?;
                        let (withdraw_withheld_authority, rest) =
                            TokenInstruction::unpack_pubkey_option(rest)?;
                        let (transfer_fee_basis_points, rest) = TokenInstruction::unpack_u16(rest)?;
                        let (maximum_fee, _) = TokenInstruction::unpack_u64(rest)?;
                        Self::InitializeTransferFeeConfig {
                            transfer_fee_config_authority,
                            withdraw_withheld_authority,
                            transfer_fee_basis_points,
                            maximum_fee,
                        }
                    }
                    1 => {
                        let (amount, decimals, rest) = TokenInstruction::unpack_amount_decimals(rest)?;
                        let (fee, _) = TokenInstruction::unpack_u64(rest)?;
                        Self::TransferCheckedWithFee {
                            amount,
                            decimals,
                            fee,
                        }
                    }
                    2 => Self::WithdrawWithheldTokensFromMint,
                    3 => {
                        let (&num_token_accounts, _) = rest.split_first().ok_or(InvalidInstruction)?;
                        Self::WithdrawWithheldTokensFromAccounts { num_token_accounts }
                    }
                    4 => Self::HarvestWithheldTokensToMint,
                    5 => {
                        let (transfer_fee_basis_points, rest) = TokenInstruction::unpack_u16(rest)?;
                        let (maximum_fee, _) = TokenInstruction::unpack_u64(rest)?;
                        Self::SetTransferFee {
                            transfer_fee_basis_points,
                            maximum_fee,
                        }
                    }
                    _ => return Err(TokenError::InvalidInstruction.into()),
                })
            }
        *)
        Definition unpack (τ : list Ty.t) (α : list Value.t) : M :=
          match τ, α with
          | [], [ input ] =>
            ltac:(M.monadic
              (let input := M.alloc (| input |) in
              M.catch_return (|
                ltac:(M.monadic
                  (M.read (|
                    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 "&") [ Ty.path "u8" ];
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.apply (Ty.path "slice") [ Ty.path "u8" ] ]
                                    ];
                                  Ty.path "spl_token_2022::error::TokenError"
                                ],
                              [],
                              "branch",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "core::option::Option")
                                    [
                                      Ty.tuple
                                        [
                                          Ty.apply (Ty.path "&") [ Ty.path "u8" ];
                                          Ty.apply
                                            (Ty.path "&")
                                            [ Ty.apply (Ty.path "slice") [ Ty.path "u8" ] ]
                                        ]
                                    ],
                                  "ok_or",
                                  [ Ty.path "spl_token_2022::error::TokenError" ]
                                |),
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply (Ty.path "slice") [ Ty.path "u8" ],
                                      "split_first",
                                      []
                                    |),
                                    [ M.read (| input |) ]
                                  |);
                                  Value.StructTuple
                                    "spl_token_2022::error::TokenError::InvalidInstruction"
                                    []
                                ]
                              |)
                            ]
                          |)
                        |),
                        [
                          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
                                                "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction";
                                              Ty.path "solana_program::program_error::ProgramError"
                                            ],
                                          [
                                            Ty.apply
                                              (Ty.path "core::result::Result")
                                              [
                                                Ty.path "core::convert::Infallible";
                                                Ty.path "spl_token_2022::error::TokenError"
                                              ]
                                          ],
                                          "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 γ0_0 := M.read (| γ0_0 |) in
                            let tag := M.copy (| γ0_0 |) in
                            let rest := M.copy (| γ0_1 |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::result::Result::Ok"
                                [
                                  M.read (|
                                    M.match_operator (|
                                      tag,
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Integer 0
                                              |) 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
                                                                  "solana_program::program_option::COption")
                                                                [
                                                                  Ty.path
                                                                    "solana_program::pubkey::Pubkey"
                                                                ];
                                                              Ty.apply
                                                                (Ty.path "&")
                                                                [
                                                                  Ty.apply
                                                                    (Ty.path "slice")
                                                                    [ Ty.path "u8" ]
                                                                ]
                                                            ];
                                                          Ty.path
                                                            "solana_program::program_error::ProgramError"
                                                        ],
                                                      [],
                                                      "branch",
                                                      []
                                                    |),
                                                    [
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.path
                                                            "spl_token_2022::instruction::TokenInstruction",
                                                          "unpack_pubkey_option",
                                                          []
                                                        |),
                                                        [ M.read (| rest |) ]
                                                      |)
                                                    ]
                                                  |)
                                                |),
                                                [
                                                  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
                                                                        "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction";
                                                                      Ty.path
                                                                        "solana_program::program_error::ProgramError"
                                                                    ],
                                                                  [
                                                                    Ty.apply
                                                                      (Ty.path
                                                                        "core::result::Result")
                                                                      [
                                                                        Ty.path
                                                                          "core::convert::Infallible";
                                                                        Ty.path
                                                                          "solana_program::program_error::ProgramError"
                                                                      ]
                                                                  ],
                                                                  "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 transfer_fee_config_authority :=
                                                      M.copy (| γ0_0 |) in
                                                    let rest := M.copy (| γ0_1 |) 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
                                                                          "solana_program::program_option::COption")
                                                                        [
                                                                          Ty.path
                                                                            "solana_program::pubkey::Pubkey"
                                                                        ];
                                                                      Ty.apply
                                                                        (Ty.path "&")
                                                                        [
                                                                          Ty.apply
                                                                            (Ty.path "slice")
                                                                            [ Ty.path "u8" ]
                                                                        ]
                                                                    ];
                                                                  Ty.path
                                                                    "solana_program::program_error::ProgramError"
                                                                ],
                                                              [],
                                                              "branch",
                                                              []
                                                            |),
                                                            [
                                                              M.call_closure (|
                                                                M.get_associated_function (|
                                                                  Ty.path
                                                                    "spl_token_2022::instruction::TokenInstruction",
                                                                  "unpack_pubkey_option",
                                                                  []
                                                                |),
                                                                [ M.read (| rest |) ]
                                                              |)
                                                            ]
                                                          |)
                                                        |),
                                                        [
                                                          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
                                                                                "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction";
                                                                              Ty.path
                                                                                "solana_program::program_error::ProgramError"
                                                                            ],
                                                                          [
                                                                            Ty.apply
                                                                              (Ty.path
                                                                                "core::result::Result")
                                                                              [
                                                                                Ty.path
                                                                                  "core::convert::Infallible";
                                                                                Ty.path
                                                                                  "solana_program::program_error::ProgramError"
                                                                              ]
                                                                          ],
                                                                          "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 withdraw_withheld_authority :=
                                                              M.copy (| γ0_0 |) in
                                                            let rest := M.copy (| γ0_1 |) 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.path "u16";
                                                                              Ty.apply
                                                                                (Ty.path "&")
                                                                                [
                                                                                  Ty.apply
                                                                                    (Ty.path
                                                                                      "slice")
                                                                                    [ Ty.path "u8" ]
                                                                                ]
                                                                            ];
                                                                          Ty.path
                                                                            "solana_program::program_error::ProgramError"
                                                                        ],
                                                                      [],
                                                                      "branch",
                                                                      []
                                                                    |),
                                                                    [
                                                                      M.call_closure (|
                                                                        M.get_associated_function (|
                                                                          Ty.path
                                                                            "spl_token_2022::instruction::TokenInstruction",
                                                                          "unpack_u16",
                                                                          []
                                                                        |),
                                                                        [ M.read (| rest |) ]
                                                                      |)
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  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
                                                                                        "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction";
                                                                                      Ty.path
                                                                                        "solana_program::program_error::ProgramError"
                                                                                    ],
                                                                                  [
                                                                                    Ty.apply
                                                                                      (Ty.path
                                                                                        "core::result::Result")
                                                                                      [
                                                                                        Ty.path
                                                                                          "core::convert::Infallible";
                                                                                        Ty.path
                                                                                          "solana_program::program_error::ProgramError"
                                                                                      ]
                                                                                  ],
                                                                                  "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 transfer_fee_basis_points :=
                                                                      M.copy (| γ0_0 |) in
                                                                    let rest := M.copy (| γ0_1 |) 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.path "u64";
                                                                                      Ty.apply
                                                                                        (Ty.path
                                                                                          "&")
                                                                                        [
                                                                                          Ty.apply
                                                                                            (Ty.path
                                                                                              "slice")
                                                                                            [
                                                                                              Ty.path
                                                                                                "u8"
                                                                                            ]
                                                                                        ]
                                                                                    ];
                                                                                  Ty.path
                                                                                    "solana_program::program_error::ProgramError"
                                                                                ],
                                                                              [],
                                                                              "branch",
                                                                              []
                                                                            |),
                                                                            [
                                                                              M.call_closure (|
                                                                                M.get_associated_function (|
                                                                                  Ty.path
                                                                                    "spl_token_2022::instruction::TokenInstruction",
                                                                                  "unpack_u64",
                                                                                  []
                                                                                |),
                                                                                [ M.read (| rest |)
                                                                                ]
                                                                              |)
                                                                            ]
                                                                          |)
                                                                        |),
                                                                        [
                                                                          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
                                                                                                "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction";
                                                                                              Ty.path
                                                                                                "solana_program::program_error::ProgramError"
                                                                                            ],
                                                                                          [
                                                                                            Ty.apply
                                                                                              (Ty.path
                                                                                                "core::result::Result")
                                                                                              [
                                                                                                Ty.path
                                                                                                  "core::convert::Infallible";
                                                                                                Ty.path
                                                                                                  "solana_program::program_error::ProgramError"
                                                                                              ]
                                                                                          ],
                                                                                          "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 maximum_fee :=
                                                                              M.copy (| γ0_0 |) in
                                                                            M.alloc (|
                                                                              Value.StructRecord
                                                                                "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig"
                                                                                [
                                                                                  ("transfer_fee_config_authority",
                                                                                    M.read (|
                                                                                      transfer_fee_config_authority
                                                                                    |));
                                                                                  ("withdraw_withheld_authority",
                                                                                    M.read (|
                                                                                      withdraw_withheld_authority
                                                                                    |));
                                                                                  ("transfer_fee_basis_points",
                                                                                    M.read (|
                                                                                      transfer_fee_basis_points
                                                                                    |));
                                                                                  ("maximum_fee",
                                                                                    M.read (|
                                                                                      maximum_fee
                                                                                    |))
                                                                                ]
                                                                            |)))
                                                                      ]
                                                                    |)))
                                                              ]
                                                            |)))
                                                      ]
                                                    |)))
                                              ]
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Integer 1
                                              |) 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.path "u64";
                                                              Ty.path "u8";
                                                              Ty.apply
                                                                (Ty.path "&")
                                                                [
                                                                  Ty.apply
                                                                    (Ty.path "slice")
                                                                    [ Ty.path "u8" ]
                                                                ]
                                                            ];
                                                          Ty.path
                                                            "solana_program::program_error::ProgramError"
                                                        ],
                                                      [],
                                                      "branch",
                                                      []
                                                    |),
                                                    [
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.path
                                                            "spl_token_2022::instruction::TokenInstruction",
                                                          "unpack_amount_decimals",
                                                          []
                                                        |),
                                                        [ M.read (| rest |) ]
                                                      |)
                                                    ]
                                                  |)
                                                |),
                                                [
                                                  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
                                                                        "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction";
                                                                      Ty.path
                                                                        "solana_program::program_error::ProgramError"
                                                                    ],
                                                                  [
                                                                    Ty.apply
                                                                      (Ty.path
                                                                        "core::result::Result")
                                                                      [
                                                                        Ty.path
                                                                          "core::convert::Infallible";
                                                                        Ty.path
                                                                          "solana_program::program_error::ProgramError"
                                                                      ]
                                                                  ],
                                                                  "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 γ0_2 :=
                                                      M.SubPointer.get_tuple_field (| γ, 2 |) in
                                                    let amount := M.copy (| γ0_0 |) in
                                                    let decimals := M.copy (| γ0_1 |) in
                                                    let rest := M.copy (| γ0_2 |) 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.path "u64";
                                                                      Ty.apply
                                                                        (Ty.path "&")
                                                                        [
                                                                          Ty.apply
                                                                            (Ty.path "slice")
                                                                            [ Ty.path "u8" ]
                                                                        ]
                                                                    ];
                                                                  Ty.path
                                                                    "solana_program::program_error::ProgramError"
                                                                ],
                                                              [],
                                                              "branch",
                                                              []
                                                            |),
                                                            [
                                                              M.call_closure (|
                                                                M.get_associated_function (|
                                                                  Ty.path
                                                                    "spl_token_2022::instruction::TokenInstruction",
                                                                  "unpack_u64",
                                                                  []
                                                                |),
                                                                [ M.read (| rest |) ]
                                                              |)
                                                            ]
                                                          |)
                                                        |),
                                                        [
                                                          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
                                                                                "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction";
                                                                              Ty.path
                                                                                "solana_program::program_error::ProgramError"
                                                                            ],
                                                                          [
                                                                            Ty.apply
                                                                              (Ty.path
                                                                                "core::result::Result")
                                                                              [
                                                                                Ty.path
                                                                                  "core::convert::Infallible";
                                                                                Ty.path
                                                                                  "solana_program::program_error::ProgramError"
                                                                              ]
                                                                          ],
                                                                          "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 fee := M.copy (| γ0_0 |) in
                                                            M.alloc (|
                                                              Value.StructRecord
                                                                "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee"
                                                                [
                                                                  ("amount", M.read (| amount |));
                                                                  ("decimals",
                                                                    M.read (| decimals |));
                                                                  ("fee", M.read (| fee |))
                                                                ]
                                                            |)))
                                                      ]
                                                    |)))
                                              ]
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Integer 2
                                              |) in
                                            M.alloc (|
                                              Value.StructTuple
                                                "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::WithdrawWithheldTokensFromMint"
                                                []
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Integer 3
                                              |) 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 "&")
                                                                [ Ty.path "u8" ];
                                                              Ty.apply
                                                                (Ty.path "&")
                                                                [
                                                                  Ty.apply
                                                                    (Ty.path "slice")
                                                                    [ Ty.path "u8" ]
                                                                ]
                                                            ];
                                                          Ty.path
                                                            "spl_token_2022::error::TokenError"
                                                        ],
                                                      [],
                                                      "branch",
                                                      []
                                                    |),
                                                    [
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.apply
                                                            (Ty.path "core::option::Option")
                                                            [
                                                              Ty.tuple
                                                                [
                                                                  Ty.apply
                                                                    (Ty.path "&")
                                                                    [ Ty.path "u8" ];
                                                                  Ty.apply
                                                                    (Ty.path "&")
                                                                    [
                                                                      Ty.apply
                                                                        (Ty.path "slice")
                                                                        [ Ty.path "u8" ]
                                                                    ]
                                                                ]
                                                            ],
                                                          "ok_or",
                                                          [
                                                            Ty.path
                                                              "spl_token_2022::error::TokenError"
                                                          ]
                                                        |),
                                                        [
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path "slice")
                                                                [ Ty.path "u8" ],
                                                              "split_first",
                                                              []
                                                            |),
                                                            [ M.read (| rest |) ]
                                                          |);
                                                          Value.StructTuple
                                                            "spl_token_2022::error::TokenError::InvalidInstruction"
                                                            []
                                                        ]
                                                      |)
                                                    ]
                                                  |)
                                                |),
                                                [
                                                  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
                                                                        "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction";
                                                                      Ty.path
                                                                        "solana_program::program_error::ProgramError"
                                                                    ],
                                                                  [
                                                                    Ty.apply
                                                                      (Ty.path
                                                                        "core::result::Result")
                                                                      [
                                                                        Ty.path
                                                                          "core::convert::Infallible";
                                                                        Ty.path
                                                                          "spl_token_2022::error::TokenError"
                                                                      ]
                                                                  ],
                                                                  "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 γ0_0 := M.read (| γ0_0 |) in
                                                    let num_token_accounts := M.copy (| γ0_0 |) in
                                                    M.alloc (|
                                                      Value.StructRecord
                                                        "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::WithdrawWithheldTokensFromAccounts"
                                                        [
                                                          ("num_token_accounts",
                                                            M.read (| num_token_accounts |))
                                                        ]
                                                    |)))
                                              ]
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Integer 4
                                              |) in
                                            M.alloc (|
                                              Value.StructTuple
                                                "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::HarvestWithheldTokensToMint"
                                                []
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Integer 5
                                              |) 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.path "u16";
                                                              Ty.apply
                                                                (Ty.path "&")
                                                                [
                                                                  Ty.apply
                                                                    (Ty.path "slice")
                                                                    [ Ty.path "u8" ]
                                                                ]
                                                            ];
                                                          Ty.path
                                                            "solana_program::program_error::ProgramError"
                                                        ],
                                                      [],
                                                      "branch",
                                                      []
                                                    |),
                                                    [
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.path
                                                            "spl_token_2022::instruction::TokenInstruction",
                                                          "unpack_u16",
                                                          []
                                                        |),
                                                        [ M.read (| rest |) ]
                                                      |)
                                                    ]
                                                  |)
                                                |),
                                                [
                                                  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
                                                                        "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction";
                                                                      Ty.path
                                                                        "solana_program::program_error::ProgramError"
                                                                    ],
                                                                  [
                                                                    Ty.apply
                                                                      (Ty.path
                                                                        "core::result::Result")
                                                                      [
                                                                        Ty.path
                                                                          "core::convert::Infallible";
                                                                        Ty.path
                                                                          "solana_program::program_error::ProgramError"
                                                                      ]
                                                                  ],
                                                                  "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 transfer_fee_basis_points :=
                                                      M.copy (| γ0_0 |) in
                                                    let rest := M.copy (| γ0_1 |) 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.path "u64";
                                                                      Ty.apply
                                                                        (Ty.path "&")
                                                                        [
                                                                          Ty.apply
                                                                            (Ty.path "slice")
                                                                            [ Ty.path "u8" ]
                                                                        ]
                                                                    ];
                                                                  Ty.path
                                                                    "solana_program::program_error::ProgramError"
                                                                ],
                                                              [],
                                                              "branch",
                                                              []
                                                            |),
                                                            [
                                                              M.call_closure (|
                                                                M.get_associated_function (|
                                                                  Ty.path
                                                                    "spl_token_2022::instruction::TokenInstruction",
                                                                  "unpack_u64",
                                                                  []
                                                                |),
                                                                [ M.read (| rest |) ]
                                                              |)
                                                            ]
                                                          |)
                                                        |),
                                                        [
                                                          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
                                                                                "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction";
                                                                              Ty.path
                                                                                "solana_program::program_error::ProgramError"
                                                                            ],
                                                                          [
                                                                            Ty.apply
                                                                              (Ty.path
                                                                                "core::result::Result")
                                                                              [
                                                                                Ty.path
                                                                                  "core::convert::Infallible";
                                                                                Ty.path
                                                                                  "solana_program::program_error::ProgramError"
                                                                              ]
                                                                          ],
                                                                          "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 maximum_fee := M.copy (| γ0_0 |) in
                                                            M.alloc (|
                                                              Value.StructRecord
                                                                "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::SetTransferFee"
                                                                [
                                                                  ("transfer_fee_basis_points",
                                                                    M.read (|
                                                                      transfer_fee_basis_points
                                                                    |));
                                                                  ("maximum_fee",
                                                                    M.read (| maximum_fee |))
                                                                ]
                                                            |)))
                                                      ]
                                                    |)))
                                              ]
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              M.never_to_any (|
                                                M.read (|
                                                  M.return_ (|
                                                    Value.StructTuple
                                                      "core::result::Result::Err"
                                                      [
                                                        M.call_closure (|
                                                          M.get_trait_method (|
                                                            "core::convert::Into",
                                                            Ty.path
                                                              "spl_token_2022::error::TokenError",
                                                            [
                                                              Ty.path
                                                                "solana_program::program_error::ProgramError"
                                                            ],
                                                            "into",
                                                            []
                                                          |),
                                                          [
                                                            Value.StructTuple
                                                              "spl_token_2022::error::TokenError::InvalidInstruction"
                                                              []
                                                          ]
                                                        |)
                                                      ]
                                                  |)
                                                |)
                                              |)
                                            |)))
                                      ]
                                    |)
                                  |)
                                ]
                            |)))
                      ]
                    |)
                  |)))
              |)))
          | _, _ => M.impossible
          end.
        
        Axiom AssociatedFunction_unpack : M.IsAssociatedFunction Self "unpack" unpack.
        
        (*
            pub fn pack(&self, buffer: &mut Vec<u8>) {
                match *self {
                    Self::InitializeTransferFeeConfig {
                        ref transfer_fee_config_authority,
                        ref withdraw_withheld_authority,
                        transfer_fee_basis_points,
                        maximum_fee,
                    } => {
                        buffer.push(0);
                        TokenInstruction::pack_pubkey_option(transfer_fee_config_authority, buffer);
                        TokenInstruction::pack_pubkey_option(withdraw_withheld_authority, buffer);
                        buffer.extend_from_slice(&transfer_fee_basis_points.to_le_bytes());
                        buffer.extend_from_slice(&maximum_fee.to_le_bytes());
                    }
                    Self::TransferCheckedWithFee {
                        amount,
                        decimals,
                        fee,
                    } => {
                        buffer.push(1);
                        buffer.extend_from_slice(&amount.to_le_bytes());
                        buffer.extend_from_slice(&decimals.to_le_bytes());
                        buffer.extend_from_slice(&fee.to_le_bytes());
                    }
                    Self::WithdrawWithheldTokensFromMint => {
                        buffer.push(2);
                    }
                    Self::WithdrawWithheldTokensFromAccounts { num_token_accounts } => {
                        buffer.push(3);
                        buffer.push(num_token_accounts);
                    }
                    Self::HarvestWithheldTokensToMint => {
                        buffer.push(4);
                    }
                    Self::SetTransferFee {
                        transfer_fee_basis_points,
                        maximum_fee,
                    } => {
                        buffer.push(5);
                        buffer.extend_from_slice(&transfer_fee_basis_points.to_le_bytes());
                        buffer.extend_from_slice(&maximum_fee.to_le_bytes());
                    }
                }
            }
        *)
        Definition pack (τ : list Ty.t) (α : list Value.t) : M :=
          match τ, α with
          | [], [ self; buffer ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let buffer := M.alloc (| buffer |) in
              M.read (|
                M.match_operator (|
                  M.read (| self |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                            "transfer_fee_config_authority"
                          |) in
                        let γ0_1 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                            "withdraw_withheld_authority"
                          |) in
                        let γ0_2 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                            "transfer_fee_basis_points"
                          |) in
                        let γ0_3 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig",
                            "maximum_fee"
                          |) in
                        let transfer_fee_config_authority := M.alloc (| γ0_0 |) in
                        let withdraw_withheld_authority := M.alloc (| γ0_1 |) in
                        let transfer_fee_basis_points := M.copy (| γ0_2 |) in
                        let maximum_fee := M.copy (| γ0_3 |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "push",
                                []
                              |),
                              [ M.read (| buffer |); Value.Integer 0 ]
                            |)
                          |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "spl_token_2022::instruction::TokenInstruction",
                                "pack_pubkey_option",
                                []
                              |),
                              [ M.read (| transfer_fee_config_authority |); M.read (| buffer |) ]
                            |)
                          |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "spl_token_2022::instruction::TokenInstruction",
                                "pack_pubkey_option",
                                []
                              |),
                              [ M.read (| withdraw_withheld_authority |); M.read (| buffer |) ]
                            |)
                          |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "extend_from_slice",
                                []
                              |),
                              [
                                M.read (| buffer |);
                                (* Unsize *)
                                M.pointer_coercion
                                  (M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u16",
                                        "to_le_bytes",
                                        []
                                      |),
                                      [ M.read (| transfer_fee_basis_points |) ]
                                    |)
                                  |))
                              ]
                            |)
                          |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "extend_from_slice",
                                []
                              |),
                              [
                                M.read (| buffer |);
                                (* Unsize *)
                                M.pointer_coercion
                                  (M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u64",
                                        "to_le_bytes",
                                        []
                                      |),
                                      [ M.read (| maximum_fee |) ]
                                    |)
                                  |))
                              ]
                            |)
                          |) in
                        M.alloc (| Value.Tuple [] |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                            "amount"
                          |) in
                        let γ0_1 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                            "decimals"
                          |) in
                        let γ0_2 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee",
                            "fee"
                          |) in
                        let amount := M.copy (| γ0_0 |) in
                        let decimals := M.copy (| γ0_1 |) in
                        let fee := M.copy (| γ0_2 |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "push",
                                []
                              |),
                              [ M.read (| buffer |); Value.Integer 1 ]
                            |)
                          |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "extend_from_slice",
                                []
                              |),
                              [
                                M.read (| buffer |);
                                (* Unsize *)
                                M.pointer_coercion
                                  (M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u64",
                                        "to_le_bytes",
                                        []
                                      |),
                                      [ M.read (| amount |) ]
                                    |)
                                  |))
                              ]
                            |)
                          |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "extend_from_slice",
                                []
                              |),
                              [
                                M.read (| buffer |);
                                (* Unsize *)
                                M.pointer_coercion
                                  (M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u8",
                                        "to_le_bytes",
                                        []
                                      |),
                                      [ M.read (| decimals |) ]
                                    |)
                                  |))
                              ]
                            |)
                          |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "extend_from_slice",
                                []
                              |),
                              [
                                M.read (| buffer |);
                                (* Unsize *)
                                M.pointer_coercion
                                  (M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u64",
                                        "to_le_bytes",
                                        []
                                      |),
                                      [ M.read (| fee |) ]
                                    |)
                                  |))
                              ]
                            |)
                          |) in
                        M.alloc (| Value.Tuple [] |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "push",
                                []
                              |),
                              [ M.read (| buffer |); Value.Integer 2 ]
                            |)
                          |) in
                        M.alloc (| Value.Tuple [] |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::WithdrawWithheldTokensFromAccounts",
                            "num_token_accounts"
                          |) in
                        let num_token_accounts := M.copy (| γ0_0 |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "push",
                                []
                              |),
                              [ M.read (| buffer |); Value.Integer 3 ]
                            |)
                          |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "push",
                                []
                              |),
                              [ M.read (| buffer |); M.read (| num_token_accounts |) ]
                            |)
                          |) in
                        M.alloc (| Value.Tuple [] |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "push",
                                []
                              |),
                              [ M.read (| buffer |); Value.Integer 4 ]
                            |)
                          |) in
                        M.alloc (| Value.Tuple [] |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::SetTransferFee",
                            "transfer_fee_basis_points"
                          |) in
                        let γ0_1 :=
                          M.SubPointer.get_struct_record_field (|
                            γ,
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::SetTransferFee",
                            "maximum_fee"
                          |) in
                        let transfer_fee_basis_points := M.copy (| γ0_0 |) in
                        let maximum_fee := M.copy (| γ0_1 |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "push",
                                []
                              |),
                              [ M.read (| buffer |); Value.Integer 5 ]
                            |)
                          |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "extend_from_slice",
                                []
                              |),
                              [
                                M.read (| buffer |);
                                (* Unsize *)
                                M.pointer_coercion
                                  (M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u16",
                                        "to_le_bytes",
                                        []
                                      |),
                                      [ M.read (| transfer_fee_basis_points |) ]
                                    |)
                                  |))
                              ]
                            |)
                          |) in
                        let _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                "extend_from_slice",
                                []
                              |),
                              [
                                M.read (| buffer |);
                                (* Unsize *)
                                M.pointer_coercion
                                  (M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "u64",
                                        "to_le_bytes",
                                        []
                                      |),
                                      [ M.read (| maximum_fee |) ]
                                    |)
                                  |))
                              ]
                            |)
                          |) in
                        M.alloc (| Value.Tuple [] |)))
                  ]
                |)
              |)))
          | _, _ => M.impossible
          end.
        
        Axiom AssociatedFunction_pack : M.IsAssociatedFunction Self "pack" pack.
      End Impl_spl_token_2022_extension_transfer_fee_instruction_TransferFeeInstruction.
      
      (*
      fn encode_instruction_data(transfer_fee_instruction: TransferFeeInstruction) -> Vec<u8> {
          let mut data = TokenInstruction::TransferFeeExtension.pack();
          transfer_fee_instruction.pack(&mut data);
          data
      }
      *)
      Definition encode_instruction_data (τ : list Ty.t) (α : list Value.t) : M :=
        match τ, α with
        | [], [ transfer_fee_instruction ] =>
          ltac:(M.monadic
            (let transfer_fee_instruction := M.alloc (| transfer_fee_instruction |) in
            M.read (|
              let data :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "spl_token_2022::instruction::TokenInstruction",
                      "pack",
                      []
                    |),
                    [
                      M.alloc (|
                        Value.StructTuple
                          "spl_token_2022::instruction::TokenInstruction::TransferFeeExtension"
                          []
                      |)
                    ]
                  |)
                |) in
              let _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path
                        "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction",
                      "pack",
                      []
                    |),
                    [ transfer_fee_instruction; data ]
                  |)
                |) in
              data
            |)))
        | _, _ => M.impossible
        end.
      
      (*
      pub fn initialize_transfer_fee_config(
          token_program_id: &Pubkey,
          mint: &Pubkey,
          transfer_fee_config_authority: Option<&Pubkey>,
          withdraw_withheld_authority: Option<&Pubkey>,
          transfer_fee_basis_points: u16,
          maximum_fee: u64,
      ) -> Result<Instruction, ProgramError> {
          check_program_account(token_program_id)?;
          let transfer_fee_config_authority = transfer_fee_config_authority.cloned().into();
          let withdraw_withheld_authority = withdraw_withheld_authority.cloned().into();
          let data = encode_instruction_data(TransferFeeInstruction::InitializeTransferFeeConfig {
              transfer_fee_config_authority,
              withdraw_withheld_authority,
              transfer_fee_basis_points,
              maximum_fee,
          });
      
          Ok(Instruction {
              program_id: *token_program_id,
              accounts: vec![AccountMeta::new( *mint, false)],
              data,
          })
      }
      *)
      Definition initialize_transfer_fee_config (τ : list Ty.t) (α : list Value.t) : M :=
        match τ, α with
        | [],
            [
              token_program_id;
              mint;
              transfer_fee_config_authority;
              withdraw_withheld_authority;
              transfer_fee_basis_points;
              maximum_fee
            ] =>
          ltac:(M.monadic
            (let token_program_id := M.alloc (| token_program_id |) in
            let mint := M.alloc (| mint |) in
            let transfer_fee_config_authority := M.alloc (| transfer_fee_config_authority |) in
            let withdraw_withheld_authority := M.alloc (| withdraw_withheld_authority |) in
            let transfer_fee_basis_points := M.alloc (| transfer_fee_basis_points |) in
            let maximum_fee := M.alloc (| maximum_fee |) 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.path "solana_program::program_error::ProgramError"
                              ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_function (| "spl_token_2022::check_program_account", [] |),
                              [ M.read (| token_program_id |) ]
                            |)
                          ]
                        |)
                      |),
                      [
                        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 "solana_program::instruction::Instruction";
                                            Ty.path "solana_program::program_error::ProgramError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "solana_program::program_error::ProgramError"
                                            ]
                                        ],
                                        "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 transfer_fee_config_authority :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::convert::Into",
                          Ty.apply
                            (Ty.path "core::option::Option")
                            [ Ty.path "solana_program::pubkey::Pubkey" ],
                          [
                            Ty.apply
                              (Ty.path "solana_program::program_option::COption")
                              [ Ty.path "solana_program::pubkey::Pubkey" ]
                          ],
                          "into",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "core::option::Option")
                                [
                                  Ty.apply
                                    (Ty.path "&")
                                    [ Ty.path "solana_program::pubkey::Pubkey" ]
                                ],
                              "cloned",
                              []
                            |),
                            [ M.read (| transfer_fee_config_authority |) ]
                          |)
                        ]
                      |)
                    |) in
                  let withdraw_withheld_authority :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::convert::Into",
                          Ty.apply
                            (Ty.path "core::option::Option")
                            [ Ty.path "solana_program::pubkey::Pubkey" ],
                          [
                            Ty.apply
                              (Ty.path "solana_program::program_option::COption")
                              [ Ty.path "solana_program::pubkey::Pubkey" ]
                          ],
                          "into",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "core::option::Option")
                                [
                                  Ty.apply
                                    (Ty.path "&")
                                    [ Ty.path "solana_program::pubkey::Pubkey" ]
                                ],
                              "cloned",
                              []
                            |),
                            [ M.read (| withdraw_withheld_authority |) ]
                          |)
                        ]
                      |)
                    |) in
                  let data :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_function (|
                          "spl_token_2022::extension::transfer_fee::instruction::encode_instruction_data",
                          []
                        |),
                        [
                          Value.StructRecord
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::InitializeTransferFeeConfig"
                            [
                              ("transfer_fee_config_authority",
                                M.read (| transfer_fee_config_authority |));
                              ("withdraw_withheld_authority",
                                M.read (| withdraw_withheld_authority |));
                              ("transfer_fee_basis_points", M.read (| transfer_fee_basis_points |));
                              ("maximum_fee", M.read (| maximum_fee |))
                            ]
                        ]
                      |)
                    |) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructRecord
                          "solana_program::instruction::Instruction"
                          [
                            ("program_id", M.read (| M.read (| token_program_id |) |));
                            ("accounts",
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [ Ty.path "solana_program::instruction::AccountMeta" ],
                                  "into_vec",
                                  [ Ty.path "alloc::alloc::Global" ]
                                |),
                                [
                                  (* Unsize *)
                                  M.pointer_coercion
                                    (M.read (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "alloc::boxed::Box")
                                            [
                                              Ty.apply
                                                (Ty.path "array")
                                                [ Ty.path "solana_program::instruction::AccountMeta"
                                                ];
                                              Ty.path "alloc::alloc::Global"
                                            ],
                                          "new",
                                          []
                                        |),
                                        [
                                          M.alloc (|
                                            Value.Array
                                              [
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.path
                                                      "solana_program::instruction::AccountMeta",
                                                    "new",
                                                    []
                                                  |),
                                                  [ M.read (| M.read (| mint |) |); Value.Bool false
                                                  ]
                                                |)
                                              ]
                                          |)
                                        ]
                                      |)
                                    |))
                                ]
                              |));
                            ("data", M.read (| data |))
                          ]
                      ]
                  |)
                |)))
            |)))
        | _, _ => M.impossible
        end.
      
      (*
      pub fn transfer_checked_with_fee(
          token_program_id: &Pubkey,
          source: &Pubkey,
          mint: &Pubkey,
          destination: &Pubkey,
          authority: &Pubkey,
          signers: &[&Pubkey],
          amount: u64,
          decimals: u8,
          fee: u64,
      ) -> Result<Instruction, ProgramError> {
          check_program_account(token_program_id)?;
          let data = encode_instruction_data(TransferFeeInstruction::TransferCheckedWithFee {
              amount,
              decimals,
              fee,
          });
      
          let mut accounts = Vec::with_capacity(4 + signers.len());
          accounts.push(AccountMeta::new( *source, false));
          accounts.push(AccountMeta::new_readonly( *mint, false));
          accounts.push(AccountMeta::new( *destination, false));
          accounts.push(AccountMeta::new_readonly( *authority, signers.is_empty()));
          for signer in signers.iter() {
              accounts.push(AccountMeta::new_readonly( **signer, true));
          }
      
          Ok(Instruction {
              program_id: *token_program_id,
              accounts,
              data,
          })
      }
      *)
      Definition transfer_checked_with_fee (τ : list Ty.t) (α : list Value.t) : M :=
        match τ, α with
        | [],
            [ token_program_id; source; mint; destination; authority; signers; amount; decimals; fee
            ] =>
          ltac:(M.monadic
            (let token_program_id := M.alloc (| token_program_id |) in
            let source := M.alloc (| source |) in
            let mint := M.alloc (| mint |) in
            let destination := M.alloc (| destination |) in
            let authority := M.alloc (| authority |) in
            let signers := M.alloc (| signers |) in
            let amount := M.alloc (| amount |) in
            let decimals := M.alloc (| decimals |) in
            let fee := M.alloc (| fee |) 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.path "solana_program::program_error::ProgramError"
                              ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_function (| "spl_token_2022::check_program_account", [] |),
                              [ M.read (| token_program_id |) ]
                            |)
                          ]
                        |)
                      |),
                      [
                        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 "solana_program::instruction::Instruction";
                                            Ty.path "solana_program::program_error::ProgramError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "solana_program::program_error::ProgramError"
                                            ]
                                        ],
                                        "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 data :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_function (|
                          "spl_token_2022::extension::transfer_fee::instruction::encode_instruction_data",
                          []
                        |),
                        [
                          Value.StructRecord
                            "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::TransferCheckedWithFee"
                            [
                              ("amount", M.read (| amount |));
                              ("decimals", M.read (| decimals |));
                              ("fee", M.read (| fee |))
                            ]
                        ]
                      |)
                    |) in
                  let accounts :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "with_capacity",
                          []
                        |),
                        [
                          BinOp.Panic.add (|
                            Integer.Usize,
                            Value.Integer 4,
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "slice")
                                  [
                                    Ty.apply
                                      (Ty.path "&")
                                      [ Ty.path "solana_program::pubkey::Pubkey" ]
                                  ],
                                "len",
                                []
                              |),
                              [ M.read (| signers |) ]
                            |)
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new",
                              []
                            |),
                            [ M.read (| M.read (| source |) |); Value.Bool false ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new_readonly",
                              []
                            |),
                            [ M.read (| M.read (| mint |) |); Value.Bool false ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new",
                              []
                            |),
                            [ M.read (| M.read (| destination |) |); Value.Bool false ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new_readonly",
                              []
                            |),
                            [
                              M.read (| M.read (| authority |) |);
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "is_empty",
                                  []
                                |),
                                [ M.read (| signers |) ]
                              |)
                            ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                [
                                  Ty.apply
                                    (Ty.path "&")
                                    [ Ty.path "solana_program::pubkey::Pubkey" ]
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "iter",
                                  []
                                |),
                                [ M.read (| signers |) ]
                              |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "core::slice::iter::Iter")
                                              [
                                                Ty.apply
                                                  (Ty.path "&")
                                                  [ Ty.path "solana_program::pubkey::Pubkey" ]
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let signer := M.copy (| γ0_0 |) in
                                            let _ :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path "alloc::vec::Vec")
                                                      [
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta";
                                                        Ty.path "alloc::alloc::Global"
                                                      ],
                                                    "push",
                                                    []
                                                  |),
                                                  [
                                                    accounts;
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta",
                                                        "new_readonly",
                                                        []
                                                      |),
                                                      [
                                                        M.read (|
                                                          M.read (| M.read (| signer |) |)
                                                        |);
                                                        Value.Bool true
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructRecord
                          "solana_program::instruction::Instruction"
                          [
                            ("program_id", M.read (| M.read (| token_program_id |) |));
                            ("accounts", M.read (| accounts |));
                            ("data", M.read (| data |))
                          ]
                      ]
                  |)
                |)))
            |)))
        | _, _ => M.impossible
        end.
      
      (*
      pub fn withdraw_withheld_tokens_from_mint(
          token_program_id: &Pubkey,
          mint: &Pubkey,
          destination: &Pubkey,
          authority: &Pubkey,
          signers: &[&Pubkey],
      ) -> Result<Instruction, ProgramError> {
          check_program_account(token_program_id)?;
          let mut accounts = Vec::with_capacity(3 + signers.len());
          accounts.push(AccountMeta::new( *mint, false));
          accounts.push(AccountMeta::new( *destination, false));
          accounts.push(AccountMeta::new_readonly( *authority, signers.is_empty()));
          for signer in signers.iter() {
              accounts.push(AccountMeta::new_readonly( **signer, true));
          }
      
          Ok(Instruction {
              program_id: *token_program_id,
              accounts,
              data: encode_instruction_data(TransferFeeInstruction::WithdrawWithheldTokensFromMint),
          })
      }
      *)
      Definition withdraw_withheld_tokens_from_mint (τ : list Ty.t) (α : list Value.t) : M :=
        match τ, α with
        | [], [ token_program_id; mint; destination; authority; signers ] =>
          ltac:(M.monadic
            (let token_program_id := M.alloc (| token_program_id |) in
            let mint := M.alloc (| mint |) in
            let destination := M.alloc (| destination |) in
            let authority := M.alloc (| authority |) in
            let signers := M.alloc (| signers |) 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.path "solana_program::program_error::ProgramError"
                              ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_function (| "spl_token_2022::check_program_account", [] |),
                              [ M.read (| token_program_id |) ]
                            |)
                          ]
                        |)
                      |),
                      [
                        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 "solana_program::instruction::Instruction";
                                            Ty.path "solana_program::program_error::ProgramError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "solana_program::program_error::ProgramError"
                                            ]
                                        ],
                                        "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 accounts :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "with_capacity",
                          []
                        |),
                        [
                          BinOp.Panic.add (|
                            Integer.Usize,
                            Value.Integer 3,
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "slice")
                                  [
                                    Ty.apply
                                      (Ty.path "&")
                                      [ Ty.path "solana_program::pubkey::Pubkey" ]
                                  ],
                                "len",
                                []
                              |),
                              [ M.read (| signers |) ]
                            |)
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new",
                              []
                            |),
                            [ M.read (| M.read (| mint |) |); Value.Bool false ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new",
                              []
                            |),
                            [ M.read (| M.read (| destination |) |); Value.Bool false ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new_readonly",
                              []
                            |),
                            [
                              M.read (| M.read (| authority |) |);
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "is_empty",
                                  []
                                |),
                                [ M.read (| signers |) ]
                              |)
                            ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                [
                                  Ty.apply
                                    (Ty.path "&")
                                    [ Ty.path "solana_program::pubkey::Pubkey" ]
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "iter",
                                  []
                                |),
                                [ M.read (| signers |) ]
                              |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "core::slice::iter::Iter")
                                              [
                                                Ty.apply
                                                  (Ty.path "&")
                                                  [ Ty.path "solana_program::pubkey::Pubkey" ]
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let signer := M.copy (| γ0_0 |) in
                                            let _ :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path "alloc::vec::Vec")
                                                      [
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta";
                                                        Ty.path "alloc::alloc::Global"
                                                      ],
                                                    "push",
                                                    []
                                                  |),
                                                  [
                                                    accounts;
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta",
                                                        "new_readonly",
                                                        []
                                                      |),
                                                      [
                                                        M.read (|
                                                          M.read (| M.read (| signer |) |)
                                                        |);
                                                        Value.Bool true
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructRecord
                          "solana_program::instruction::Instruction"
                          [
                            ("program_id", M.read (| M.read (| token_program_id |) |));
                            ("accounts", M.read (| accounts |));
                            ("data",
                              M.call_closure (|
                                M.get_function (|
                                  "spl_token_2022::extension::transfer_fee::instruction::encode_instruction_data",
                                  []
                                |),
                                [
                                  Value.StructTuple
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::WithdrawWithheldTokensFromMint"
                                    []
                                ]
                              |))
                          ]
                      ]
                  |)
                |)))
            |)))
        | _, _ => M.impossible
        end.
      
      (*
      pub fn withdraw_withheld_tokens_from_accounts(
          token_program_id: &Pubkey,
          mint: &Pubkey,
          destination: &Pubkey,
          authority: &Pubkey,
          signers: &[&Pubkey],
          sources: &[&Pubkey],
      ) -> Result<Instruction, ProgramError> {
          check_program_account(token_program_id)?;
          let num_token_accounts =
              u8::try_from(sources.len()).map_err(|_| ProgramError::InvalidInstructionData)?;
          let mut accounts = Vec::with_capacity(3 + signers.len() + sources.len());
          accounts.push(AccountMeta::new_readonly( *mint, false));
          accounts.push(AccountMeta::new( *destination, false));
          accounts.push(AccountMeta::new_readonly( *authority, signers.is_empty()));
          for signer in signers.iter() {
              accounts.push(AccountMeta::new_readonly( **signer, true));
          }
          for source in sources.iter() {
              accounts.push(AccountMeta::new( **source, false));
          }
      
          Ok(Instruction {
              program_id: *token_program_id,
              accounts,
              data: encode_instruction_data(TransferFeeInstruction::WithdrawWithheldTokensFromAccounts {
                  num_token_accounts,
              }),
          })
      }
      *)
      Definition withdraw_withheld_tokens_from_accounts (τ : list Ty.t) (α : list Value.t) : M :=
        match τ, α with
        | [], [ token_program_id; mint; destination; authority; signers; sources ] =>
          ltac:(M.monadic
            (let token_program_id := M.alloc (| token_program_id |) in
            let mint := M.alloc (| mint |) in
            let destination := M.alloc (| destination |) in
            let authority := M.alloc (| authority |) in
            let signers := M.alloc (| signers |) in
            let sources := M.alloc (| sources |) 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.path "solana_program::program_error::ProgramError"
                              ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_function (| "spl_token_2022::check_program_account", [] |),
                              [ M.read (| token_program_id |) ]
                            |)
                          ]
                        |)
                      |),
                      [
                        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 "solana_program::instruction::Instruction";
                                            Ty.path "solana_program::program_error::ProgramError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "solana_program::program_error::ProgramError"
                                            ]
                                        ],
                                        "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 num_token_accounts :=
                    M.copy (|
                      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.path "u8";
                                  Ty.path "solana_program::program_error::ProgramError"
                                ],
                              [],
                              "branch",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "core::result::Result")
                                    [ Ty.path "u8"; Ty.path "core::num::error::TryFromIntError" ],
                                  "map_err",
                                  [
                                    Ty.path "solana_program::program_error::ProgramError";
                                    Ty.function
                                      [ Ty.tuple [ Ty.path "core::num::error::TryFromIntError" ] ]
                                      (Ty.path "solana_program::program_error::ProgramError")
                                  ]
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::convert::TryFrom",
                                      Ty.path "u8",
                                      [ Ty.path "usize" ],
                                      "try_from",
                                      []
                                    |),
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "slice")
                                            [
                                              Ty.apply
                                                (Ty.path "&")
                                                [ Ty.path "solana_program::pubkey::Pubkey" ]
                                            ],
                                          "len",
                                          []
                                        |),
                                        [ M.read (| sources |) ]
                                      |)
                                    ]
                                  |);
                                  M.closure
                                    (fun γ =>
                                      ltac:(M.monadic
                                        match γ with
                                        | [ α0 ] =>
                                          M.match_operator (|
                                            M.alloc (| α0 |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (Value.StructTuple
                                                    "solana_program::program_error::ProgramError::InvalidInstructionData"
                                                    []))
                                            ]
                                          |)
                                        | _ => M.impossible (||)
                                        end))
                                ]
                              |)
                            ]
                          |)
                        |),
                        [
                          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 "solana_program::instruction::Instruction";
                                              Ty.path "solana_program::program_error::ProgramError"
                                            ],
                                          [
                                            Ty.apply
                                              (Ty.path "core::result::Result")
                                              [
                                                Ty.path "core::convert::Infallible";
                                                Ty.path
                                                  "solana_program::program_error::ProgramError"
                                              ]
                                          ],
                                          "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 accounts :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "with_capacity",
                          []
                        |),
                        [
                          BinOp.Panic.add (|
                            Integer.Usize,
                            BinOp.Panic.add (|
                              Integer.Usize,
                              Value.Integer 3,
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "len",
                                  []
                                |),
                                [ M.read (| signers |) ]
                              |)
                            |),
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "slice")
                                  [
                                    Ty.apply
                                      (Ty.path "&")
                                      [ Ty.path "solana_program::pubkey::Pubkey" ]
                                  ],
                                "len",
                                []
                              |),
                              [ M.read (| sources |) ]
                            |)
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new_readonly",
                              []
                            |),
                            [ M.read (| M.read (| mint |) |); Value.Bool false ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new",
                              []
                            |),
                            [ M.read (| M.read (| destination |) |); Value.Bool false ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new_readonly",
                              []
                            |),
                            [
                              M.read (| M.read (| authority |) |);
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "is_empty",
                                  []
                                |),
                                [ M.read (| signers |) ]
                              |)
                            ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                [
                                  Ty.apply
                                    (Ty.path "&")
                                    [ Ty.path "solana_program::pubkey::Pubkey" ]
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "iter",
                                  []
                                |),
                                [ M.read (| signers |) ]
                              |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "core::slice::iter::Iter")
                                              [
                                                Ty.apply
                                                  (Ty.path "&")
                                                  [ Ty.path "solana_program::pubkey::Pubkey" ]
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let signer := M.copy (| γ0_0 |) in
                                            let _ :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path "alloc::vec::Vec")
                                                      [
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta";
                                                        Ty.path "alloc::alloc::Global"
                                                      ],
                                                    "push",
                                                    []
                                                  |),
                                                  [
                                                    accounts;
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta",
                                                        "new_readonly",
                                                        []
                                                      |),
                                                      [
                                                        M.read (|
                                                          M.read (| M.read (| signer |) |)
                                                        |);
                                                        Value.Bool true
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  let _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                [
                                  Ty.apply
                                    (Ty.path "&")
                                    [ Ty.path "solana_program::pubkey::Pubkey" ]
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "iter",
                                  []
                                |),
                                [ M.read (| sources |) ]
                              |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "core::slice::iter::Iter")
                                              [
                                                Ty.apply
                                                  (Ty.path "&")
                                                  [ Ty.path "solana_program::pubkey::Pubkey" ]
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let source := M.copy (| γ0_0 |) in
                                            let _ :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path "alloc::vec::Vec")
                                                      [
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta";
                                                        Ty.path "alloc::alloc::Global"
                                                      ],
                                                    "push",
                                                    []
                                                  |),
                                                  [
                                                    accounts;
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta",
                                                        "new",
                                                        []
                                                      |),
                                                      [
                                                        M.read (|
                                                          M.read (| M.read (| source |) |)
                                                        |);
                                                        Value.Bool false
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructRecord
                          "solana_program::instruction::Instruction"
                          [
                            ("program_id", M.read (| M.read (| token_program_id |) |));
                            ("accounts", M.read (| accounts |));
                            ("data",
                              M.call_closure (|
                                M.get_function (|
                                  "spl_token_2022::extension::transfer_fee::instruction::encode_instruction_data",
                                  []
                                |),
                                [
                                  Value.StructRecord
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::WithdrawWithheldTokensFromAccounts"
                                    [ ("num_token_accounts", M.read (| num_token_accounts |)) ]
                                ]
                              |))
                          ]
                      ]
                  |)
                |)))
            |)))
        | _, _ => M.impossible
        end.
      
      (*
      pub fn harvest_withheld_tokens_to_mint(
          token_program_id: &Pubkey,
          mint: &Pubkey,
          sources: &[&Pubkey],
      ) -> Result<Instruction, ProgramError> {
          check_program_account(token_program_id)?;
          let mut accounts = Vec::with_capacity(1 + sources.len());
          accounts.push(AccountMeta::new( *mint, false));
          for source in sources.iter() {
              accounts.push(AccountMeta::new( **source, false));
          }
          Ok(Instruction {
              program_id: *token_program_id,
              accounts,
              data: encode_instruction_data(TransferFeeInstruction::HarvestWithheldTokensToMint),
          })
      }
      *)
      Definition harvest_withheld_tokens_to_mint (τ : list Ty.t) (α : list Value.t) : M :=
        match τ, α with
        | [], [ token_program_id; mint; sources ] =>
          ltac:(M.monadic
            (let token_program_id := M.alloc (| token_program_id |) in
            let mint := M.alloc (| mint |) in
            let sources := M.alloc (| sources |) 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.path "solana_program::program_error::ProgramError"
                              ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_function (| "spl_token_2022::check_program_account", [] |),
                              [ M.read (| token_program_id |) ]
                            |)
                          ]
                        |)
                      |),
                      [
                        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 "solana_program::instruction::Instruction";
                                            Ty.path "solana_program::program_error::ProgramError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "solana_program::program_error::ProgramError"
                                            ]
                                        ],
                                        "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 accounts :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "with_capacity",
                          []
                        |),
                        [
                          BinOp.Panic.add (|
                            Integer.Usize,
                            Value.Integer 1,
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "slice")
                                  [
                                    Ty.apply
                                      (Ty.path "&")
                                      [ Ty.path "solana_program::pubkey::Pubkey" ]
                                  ],
                                "len",
                                []
                              |),
                              [ M.read (| sources |) ]
                            |)
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new",
                              []
                            |),
                            [ M.read (| M.read (| mint |) |); Value.Bool false ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                [
                                  Ty.apply
                                    (Ty.path "&")
                                    [ Ty.path "solana_program::pubkey::Pubkey" ]
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "iter",
                                  []
                                |),
                                [ M.read (| sources |) ]
                              |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "core::slice::iter::Iter")
                                              [
                                                Ty.apply
                                                  (Ty.path "&")
                                                  [ Ty.path "solana_program::pubkey::Pubkey" ]
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let source := M.copy (| γ0_0 |) in
                                            let _ :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path "alloc::vec::Vec")
                                                      [
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta";
                                                        Ty.path "alloc::alloc::Global"
                                                      ],
                                                    "push",
                                                    []
                                                  |),
                                                  [
                                                    accounts;
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta",
                                                        "new",
                                                        []
                                                      |),
                                                      [
                                                        M.read (|
                                                          M.read (| M.read (| source |) |)
                                                        |);
                                                        Value.Bool false
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructRecord
                          "solana_program::instruction::Instruction"
                          [
                            ("program_id", M.read (| M.read (| token_program_id |) |));
                            ("accounts", M.read (| accounts |));
                            ("data",
                              M.call_closure (|
                                M.get_function (|
                                  "spl_token_2022::extension::transfer_fee::instruction::encode_instruction_data",
                                  []
                                |),
                                [
                                  Value.StructTuple
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::HarvestWithheldTokensToMint"
                                    []
                                ]
                              |))
                          ]
                      ]
                  |)
                |)))
            |)))
        | _, _ => M.impossible
        end.
      
      (*
      pub fn set_transfer_fee(
          token_program_id: &Pubkey,
          mint: &Pubkey,
          authority: &Pubkey,
          signers: &[&Pubkey],
          transfer_fee_basis_points: u16,
          maximum_fee: u64,
      ) -> Result<Instruction, ProgramError> {
          check_program_account(token_program_id)?;
          let mut accounts = Vec::with_capacity(2 + signers.len());
          accounts.push(AccountMeta::new( *mint, false));
          accounts.push(AccountMeta::new_readonly( *authority, signers.is_empty()));
          for signer in signers.iter() {
              accounts.push(AccountMeta::new_readonly( **signer, true));
          }
      
          Ok(Instruction {
              program_id: *token_program_id,
              accounts,
              data: encode_instruction_data(TransferFeeInstruction::SetTransferFee {
                  transfer_fee_basis_points,
                  maximum_fee,
              }),
          })
      }
      *)
      Definition set_transfer_fee (τ : list Ty.t) (α : list Value.t) : M :=
        match τ, α with
        | [],
            [ token_program_id; mint; authority; signers; transfer_fee_basis_points; maximum_fee
            ] =>
          ltac:(M.monadic
            (let token_program_id := M.alloc (| token_program_id |) in
            let mint := M.alloc (| mint |) in
            let authority := M.alloc (| authority |) in
            let signers := M.alloc (| signers |) in
            let transfer_fee_basis_points := M.alloc (| transfer_fee_basis_points |) in
            let maximum_fee := M.alloc (| maximum_fee |) 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.path "solana_program::program_error::ProgramError"
                              ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_function (| "spl_token_2022::check_program_account", [] |),
                              [ M.read (| token_program_id |) ]
                            |)
                          ]
                        |)
                      |),
                      [
                        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 "solana_program::instruction::Instruction";
                                            Ty.path "solana_program::program_error::ProgramError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "solana_program::program_error::ProgramError"
                                            ]
                                        ],
                                        "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 accounts :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "with_capacity",
                          []
                        |),
                        [
                          BinOp.Panic.add (|
                            Integer.Usize,
                            Value.Integer 2,
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "slice")
                                  [
                                    Ty.apply
                                      (Ty.path "&")
                                      [ Ty.path "solana_program::pubkey::Pubkey" ]
                                  ],
                                "len",
                                []
                              |),
                              [ M.read (| signers |) ]
                            |)
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new",
                              []
                            |),
                            [ M.read (| M.read (| mint |) |); Value.Bool false ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            [
                              Ty.path "solana_program::instruction::AccountMeta";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "push",
                          []
                        |),
                        [
                          accounts;
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "solana_program::instruction::AccountMeta",
                              "new_readonly",
                              []
                            |),
                            [
                              M.read (| M.read (| authority |) |);
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "is_empty",
                                  []
                                |),
                                [ M.read (| signers |) ]
                              |)
                            ]
                          |)
                        ]
                      |)
                    |) in
                  let _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                [
                                  Ty.apply
                                    (Ty.path "&")
                                    [ Ty.path "solana_program::pubkey::Pubkey" ]
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        [ Ty.path "solana_program::pubkey::Pubkey" ]
                                    ],
                                  "iter",
                                  []
                                |),
                                [ M.read (| signers |) ]
                              |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "core::slice::iter::Iter")
                                              [
                                                Ty.apply
                                                  (Ty.path "&")
                                                  [ Ty.path "solana_program::pubkey::Pubkey" ]
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let signer := M.copy (| γ0_0 |) in
                                            let _ :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path "alloc::vec::Vec")
                                                      [
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta";
                                                        Ty.path "alloc::alloc::Global"
                                                      ],
                                                    "push",
                                                    []
                                                  |),
                                                  [
                                                    accounts;
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path
                                                          "solana_program::instruction::AccountMeta",
                                                        "new_readonly",
                                                        []
                                                      |),
                                                      [
                                                        M.read (|
                                                          M.read (| M.read (| signer |) |)
                                                        |);
                                                        Value.Bool true
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructRecord
                          "solana_program::instruction::Instruction"
                          [
                            ("program_id", M.read (| M.read (| token_program_id |) |));
                            ("accounts", M.read (| accounts |));
                            ("data",
                              M.call_closure (|
                                M.get_function (|
                                  "spl_token_2022::extension::transfer_fee::instruction::encode_instruction_data",
                                  []
                                |),
                                [
                                  Value.StructRecord
                                    "spl_token_2022::extension::transfer_fee::instruction::TransferFeeInstruction::SetTransferFee"
                                    [
                                      ("transfer_fee_basis_points",
                                        M.read (| transfer_fee_basis_points |));
                                      ("maximum_fee", M.read (| maximum_fee |))
                                    ]
                                ]
                              |))
                          ]
                      ]
                  |)
                |)))
            |)))
        | _, _ => M.impossible
        end.
    End instruction.
  End transfer_fee.
End extension.
