Glider gitbook
GliderRVSS Calculator Ask the Community
  • Glider introduction
  • 🏄Writing Queries
  • ✍️Glider and Declarative Query Writing
  • 🎓Glider: The Basics
    • Intro to Python
      • Basic Python
      • Advanced Python
    • Intro to Glider
    • Instructions
      • Learning Instructions
      • Exercises
    • Functions
      • Learning Functions
      • Exercises
    • Contracts
      • Learning Contracts
      • Exercises
    • Bonus Challenges
  • 📙API
    • 📌Main concepts
    • Iterables
      • APISet
      • APIList
    • Argument
      • Argument.backward_df()
      • Argument.data
      • Argument.df_reaches_from_functions_arguments()
      • Argument.df_reaching_functions_arguments()
      • Argument.forward_df()
      • Argument.get_parent()
      • Argument.index
      • Argument.memory_type
      • Argument.name
      • Argument.procedure_graph_node
      • Argument.source_code()
      • Argument.type
    • Arguments
      • Arguments.list()
      • Arguments.with_memory_type()
      • Arguments.with_name()
      • Arguments.with_type()
      • Arguments.with_type_convertible()
      • Convertor
        • Convertor.add()
        • Convertor.can_convert()
        • Convertor.set_conversions()
    • Contract
      • Contract.address()
      • Contract.base_contracts()
      • Contract.chain_id()
      • Contract.constructor()
      • Contract.derived_contracts()
      • Contract.enums()
      • Contract.errors()
      • Contract.events()
      • Contract.functions()
      • Contract.is_lib()
      • Contract.is_main()
      • Contract.modifiers()
      • Contract.name
      • Contract.parent_contracts()
      • Contract.pragmas()
      • Contract.source_code()
      • Contract.state_variables()
      • Contract.structs()
    • Contracts
      • Contracts.exec()
      • Contracts.functions()
      • Contracts.interface_contracts()
      • Contracts.mains()
      • Contracts.with_name_prefix()
      • Contracts.with_name_regex()
      • Contracts.with_name_suffix()
      • Contracts.non_interface_contracts()
      • Contracts.with_all_function_names()
      • Contracts.with_compiler_range()
      • Contracts.with_compiler_range_not()
      • Contracts.with_error_name()
      • Contracts.with_error_prefix()
      • Contracts.with_error_regex()
      • Contracts.with_error_signature()
      • Contracts.with_error_suffix()
      • Contracts.with_event_name()
      • Contracts.with_event_prefix()
      • Contracts.with_event_regex()
      • Contracts.with_event_signature()
      • Contracts.with_event_suffix()
      • Contracts.with_function_name()
      • Contracts.with_function_name_not()
      • Contracts.with_one_of_the_function_names()
      • Contracts.with_name()
      • Contracts.with_name_not()
      • Contracts.with_struct_field_name()
      • Contracts.with_struct_field_type()
      • Contracts.with_struct_fields_count()
      • Contracts.with_struct_name()
    • Enum
      • Enum.data
      • Enum.max
      • Enum.min
      • Enum.name
      • Enum.values
    • Enums
      • Enums.exec()
    • Error
      • Error.args
      • Error.name
      • Error.signature
    • Errors
      • Errors.exec()
    • Event
      • Event.arg_list()
      • Event.name
      • Event.signature
    • Function
      • Function.caller_functions()
      • Function.extended_caller_functions()
      • Function.has_modifiers()
      • Function.is_constructor()
      • Function.is_external()
      • Function.is_global()
      • Function.is_internal()
      • Function.is_payable()
      • Function.is_private()
      • Function.is_public()
      • Function.is_pure()
      • Function.is_view()
      • Function.modifiers()
      • Function.properties()
      • Function.return_instructions()
      • Function.return_tuple()
    • Functions
      • Functions.constructors()
      • Functions.exec()
      • Functions.extended_caller_functions()
      • Functions.extended_caller_modifiers()
      • Functions.with_all_properties()
      • Functions.with_declarer_contract_name()
      • Functions.with_modifier_name()
      • Functions.without_modifier_name()
      • Functions.with_modifier_name_regex()
      • Functions.with_modifier_signature()
      • Functions.with_one_of_the_modifier_names()
      • Functions.without_modifier_names()
      • Functions.with_one_of_the_modifier_name_regexes()
      • Functions.with_one_property()
      • Functions.without_properties()
      • Functions.with_all_modifier_names()
      • Functions.without_modifiers()
      • Functions.with_declarer_contract_name()
    • Modifier
      • Modifier.functions()
      • Modifier.placer_instructions()
      • Modifier.properties()
    • Modifiers
      • Modifiers.exec()
      • Modifiers.placer_instructions()
    • Callable
      • Callable.address()
      • Callable.arguments()
      • Callable.break_instructions()
      • Callable.callee_functions()
      • Callable.callee_values()
      • Callable.calls_instructions()
      • Callable.catch_instructions()
      • Callable.continue_instructions()
      • Callable.end_asm_instructions()
      • Callable.end_if_instructions()
      • Callable.end_loop_instructions()
      • Callable.entry_point_instructions()
      • Callable.expression_instructions()
      • Callable.extended_callee_functions()
      • Callable.extended_instructions()
      • Callable.get_contract()
      • Callable.get_reachable_instructions()
      • Callable.hashed_signature()
      • Callable.if_instructions()
      • Callable.if_loop_instructions()
      • Callable.instructions()
      • Callable.local_variables()
      • Callable.name
      • Callable.new_contract_instructions()
      • Callable.signature()
      • Callable.source_code()
      • Callable.start_asm_instructions()
      • Callable.start_loop_instructions()
      • Callable.throw_instructions()
      • Callable.try_instructions()
    • Callables
      • Callables.contracts()
      • Callables.extended_callee_functions()
      • Callables.instructions()
      • Callables.with_name_prefix()
      • Callables.with_name_prefixes()
      • Callables.with_name_regex()
      • Callables.with_name_regexes()
      • Callables.with_name_suffix()
      • Callables.with_name_suffixes()
      • Callables.with_arg_count()
      • Callables.with_arg_memory_type()
      • Callables.with_arg_name()
      • Callables.with_arg_type()
      • Callables.with_arg_types()
      • Callables.with_hashed_signature()
      • Callables.with_name()
      • Callables.without_name()
      • Callables.with_one_of_the_names()
      • Callables.without_names()
      • Callables.with_signature()
      • Callables.with_signatures()
      • Callables.with_callee_names()
      • Callables.with_declarer_contract_name()
      • MethodProp
        • MethodProp.EXTERNAL
        • MethodProp.HAS_ARGS
        • MethodProp.HAS_CALLEES
        • MethodProp.HAS_ERRORS
        • MethodProp.HAS_MODIFIERS
        • MethodProp.HAS_STATE_VARIABLES_READ
        • MethodProp.HAS_STATE_VARIABLES_WRITTEN
        • MethodProp.INTERNAL
        • MethodProp.IS_CONSTRUCTOR
        • MethodProp.IS_GLOBAL
        • MethodProp.IS_PAYABLE
        • MethodProp.IS_PURE
        • MethodProp.IS_VIEW
        • MethodProp.PRIVATE
        • MethodProp.PUBLIC
    • Instruction
      • Instruction.backward_df()
      • Instruction.callee_names()
      • Instruction.extended_previous_instructions()
      • Instruction.forward_df()
      • Instruction.get_callees()
      • Instruction.get_component()
      • Instruction.get_components()
      • Instruction.get_dest()
      • Instruction.get_parent()
      • Instruction.get_value()
      • Instruction.is_break()
      • Instruction.is_call()
      • Instruction.is_catch()
      • Instruction.is_cmp()
      • Instruction.is_continue()
      • Instruction.is_end_assembly()
      • Instruction.is_end_if()
      • Instruction.is_end_loop()
      • Instruction.is_entry_point()
      • Instruction.is_expression()
      • Instruction.is_from_assembly()
      • Instruction.is_if()
      • Instruction.is_if_loop()
      • Instruction.is_new_contract()
      • Instruction.is_placer()
      • Instruction.is_return()
      • Instruction.is_start_assembly()
      • Instruction.is_start_loop()
      • Instruction.is_storage_read()
      • Instruction.is_storage_write()
      • Instruction.is_throw()
      • Instruction.is_try()
      • Instruction.next_block()
      • Instruction.next_instruction()
      • Instruction.next_instructions()
      • Instruction.extended_next_instructions()
      • Instruction.previous_instruction()
      • Instruction.previous_instructions()
      • Instruction.extended_previous_instructions()
      • Instruction.solidity_callee_names()
      • Instruction.source_code()
      • BreakInstruction
      • CatchInstruction
        • CatchInstruction.get_block_instructions()
      • ContinueInstruction
      • EndAssemblyInstruction
      • EndIfInstruction
      • EndLoopInstruction
      • EntryPointInstruction
      • ExpressionInstruction
      • IfInstruction
        • IfInstruction.first_false_instruction()
        • IfInstruction.first_true_instruction()
        • IfInstruction.get_condition()
        • Condition
          • Condition.is_eq()
          • Condition.is_geq()
          • Condition.is_gr()
          • Condition.is_le()
          • Condition.is_leq()
      • IfLoopInstruction
      • NewVariableInstruction
      • PlaceholderInstruction
      • ReturnInstruction
      • StartAssemblyInstruction
        • StartAssemblyInstruction.get_block_instructions()
      • StartLoopInstruction
      • ThrowInstruction
      • TryInstruction
        • TryInstruction.get_block_instructions()
      • CatchInstruction
        • CatchInstruction.get_block_instructions()
    • Instructions
      • Instructions.asm_block_instructions()
      • Instructions.break_instructions()
      • Instructions.calls()
      • Instruction.catch_instructions()
      • Instructions.continue_instructions()
      • Instructions.delegate_calls()
      • Instructions.delegate_calls_from_assembly()
      • Instructions.delegate_calls_non_assembly()
      • Instructions.end_asm_instructions()
      • Instructions.end_if_instructions()
      • Instructions.end_loop_instructions()
      • Instructions.entry_point_instructions()
      • Instructions.exec()
      • Instructions.expression_instructions()
      • Instructions.external_calls()
      • Instructions.functions()
      • Instructions.high_level_static_calls()
      • Instructions.if_instructions()
      • Instructions.if_loop_instructions()
      • Instructions.internal_calls()
      • Instructions.library_calls()
      • Instructions.low_level_function_calls()
      • Instructions.low_level_static_calls()
      • Instructions.modifiers()
      • Instructions.new_contract_instructions()
      • Instructions.new_variable_instructions()
      • Instructions.placeholder_instructions()
      • Instructions.return_instructions()
      • Instructions.start_asm_instructions()
      • Instructions.start_loop_instructions()
      • Instructions.throw_instructions()
      • Instructions.try_instructions()
      • Instructions.with_all_callee_function_names()
      • Instructions.with_callee_function_name()
      • Instructions.with_callee_function_name_prefix()
      • Instructions.with_callee_function_name_suffix()
      • Instructions.with_callee_function_signature()
      • Instructions.with_one_of_callee_function_names()
      • Instructions.without_callee_function_name()
      • Instructions.without_callee_function_names()
    • Value
      • Value
        • Value.expression
        • Value.is_main_value()
        • Value.parent_value
        • Value.get_callee_values()
        • Value.get_state_vars()
        • Value.get_local_vars()
        • Value.get_global_vars()
        • Value.get_arg_vars()
        • Value.get_vars()
      • ValueExpression
        • ValueExpression.get_dest()
        • ValueExpression.get_component()
        • ValueExpression.get_components()
      • Var
        • Var.backward_df()
        • Var.forward_df()
        • Var.get_object_of_var()
        • Var.get_parent()
        • Var.procedure_graph_node
        • Var.type
      • Literal
        • Literal.get_type()
        • Literal.get_value()
      • Call
        • Call.signature
        • Call.name
        • Call.get_contract_name()
        • Call.get_args()
        • Call.get_arg()
        • Call.get_call_gas()
        • Call.get_call_qualifier()
        • Call.get_call_salt()
        • Call.get_call_type()
        • Call.get_call_value()
        • Call.get_function()
        • Call.get_special_params()
        • Call.kv_parameters()
        • CallType
          • CallType.EVENT
          • CallType.EXTERNAL
          • CallType.INTERNAL
          • CallType.LIBRARY
          • CallType.LOW_LEVEL
          • CallType.NEW_ARR
          • CallType.NEW_ELEMENTARY_TYPE:
          • CallType.NEW_STRUCT
          • CallType.PRIVATE
          • CallType.PUBLIC
          • CallType.SOLIDITY
          • CallType.TYPE_CONVERSION
    • Point
      • Point
        • Point.backward_df()
        • Point.forward_df()
        • Point.extended_backward_df()
        • Point.extended_forward_df()
        • Point.has_global_df()
        • Point.has_extended_global_df()
        • Point.get_parent()
        • Point.get_all_tainted_paths_affecting_point()
        • Point.get_tainted_path_affecting_point()
        • Point.get_tainted_sources_affecting_point()
        • Point.df_reaching_functions_arguments()
        • Point.df_reaches_from_functions_arguments()
      • ArgumentPoint
        • ArgumentPoint.get_variable()
      • ArgumentPoints
        • ArgumentsPoints.with_memory_type()
        • ArgumentPoints.with_name()
        • ArgumentPoints.with_type()
        • ArgumentPoints.list()
      • ExternalPoint
        • ExternalPoint.get_variable()
        • ExternalPoint.source_code()
      • GlobalPoint
        • GlobalPoint.get_variable()
      • StatePoint
        • StatePoint.get_variable()
      • VarValue
        • VarValue.backward_df()
        • VarValue.extended_backward_df()
        • VarValue.extended_forward_df()
        • VarValue.forward_df()
        • VarValue.get_defining_points()
        • VarValue.get_object_of_var()
        • VarValue.get_parent()
        • VarValue.type
    • Variables
      • Variable
        • Variable.canonical_name
        • Variable.data
        • Variable.name
        • Variable.source_code()
        • Variable.type
      • StateVariables
        • StateVariables
          • StateVariables.exec()
          • StateVariables.with_all_properties()
          • StateVariables.with_one_property()
          • StateVariables.with_type()
          • StateVariable.with_name()
        • StateVariableProp
        • StateVariable
          • StateVariable.contract()
          • StateVariable.is_accessible()
          • StateVariable.is_constant()
          • StateVariable.is_immutable()
          • StateVariable.is_internal()
          • StateVariable.is_private()
          • StateVariable.is_public()
          • StateVariable.properties()
          • StateVariable.source_code()
      • LocalVariables
        • LocalVariables
          • LocalVariables.with_memory_type()
          • LocalVariables.with_type()
        • LocalVariable
          • LocalVariable.get_parent()
          • LocalVariable.property
          • LocalVariable.source_code()
      • GlobalVariables
      • ArgumentVariable
        • ArgumentVariable.index
        • ArgumentVariable.data
        • ArgumentVariable.memory_type
        • ArgumentVariable.source_code()
    • Struct
      • Struct.data
      • Struct.fields
      • Struct.name
    • StructField
      • StructField.name
      • StructField.type
    • Structs
      • Structs.exec()
    • Internal
      • CallGraph
        • CallGraph.all_nodes()
        • CallGraph.get_corresponding_node_for_function()
        • CallGraph.nodes()
        • CallGraph.with_name()
        • CallGraph.with_name_not()
        • CallGraph.with_name_prefix()
        • CallGraph.with_name_suffix()
      • CallNode
        • CallNode.callable()
        • CallNode.callable_name()
        • CallNode.callee_functions()
        • CallNode.callee_modifiers()
        • CallNode.callees()
        • CallNode.caller_functions()
        • CallNode.caller_modifiers()
        • CallNode.callers()
        • CallNode.get_extended_callees()
        • CallNode.get_extended_callers()
        • CallNode.is_function
        • CallNode.is_modifier
      • Queryable
        • Queryable.query_aggregator
      • NoneObject
        • NoneObject.dump_into_json()
        • NoneObject.instructions()
        • NoneObject.name()
  • Changelog
  • 🚧Limitations
  • 🔧Glider Usage
  • 🗺️Roadmap
  • 👥Comparison with other tools
  • ⚖️Legal Notices
    • Privacy Notice
    • Terms and Conditions
Powered by GitBook
On this page
  • Intro
  • Exercise #1 - Find external calls
  • Exercise #2 - Find the Instructions that Follow External Calls
  • Exercise #3 - Return instructions that Write to Storage
  • Exercise #4 - External Calls invoking abi.encode
  • Bonus Challenge
  1. Glider: The Basics
  2. Instructions

Exercises

PreviousLearning InstructionsNextFunctions

Last updated 22 days ago

Intro

In this section, we will present several exercises that will fortify your Instructions query skills. Each exercise provided comes along with a solution if you get stuck.

Exercise #1 - Find external calls

Now, let’s update this query to find instructions that make external calls to other contracts. To achieve this, we can reference the of the Glider API documentation to identify the function that queries for external calls.

Challenge: Update the following query such that it queries for external call instructions:

from glider import *

def query():
    # CHALLENGE: Update this query such that it looks for external call instructions.
    return Instructions().exec(10)
Click here for the solution

Stuck or want to confirm your answer? Visit the link below where you can view and run the solution inside of Glider IDE:

Exercise #2 - Find the Instructions that Follow External Calls

Now that we’ve identified external call instructions, let’s take it a step further and find the instructions executed immediately after those external calls.

To achieve this, we need to iterate over each instruction and check how many next instructions exist. If 1 or more instructions do exist, then we have a positive hit.

Challenge: Update the query below to only return external call instructions that are followed by other instructions.

Extra Challenge: Use the filter() function to exclude instructions that don’t have any next instructions.

from glider import *

def query():
    return (
        Instructions()
        .external_calls()
        .exec(10)
        # CHALLENGE: Add your solution here.
    )

Exercise #3 - Return instructions that Write to Storage

Now that we’ve identified cases where additional instructions are executed after an external call, let’s take it further by examining these instructions to see if any of them write to the contract’s storage (i.e., update a state variable).

Challenge: Use the is_storage_write() method to filter instructions and return only external call instructions that are followed by instructions that update the contract’s storage.

Python provides a built-in function called any(). It takes a list, set, or array and returns True if at least one value in the data structure evaluates to True.

With Glider, you can call a method on a list of items, and that method will automatically be applied to each item in the list. This makes it easy to perform operations on multiple items at once. For example, the following code will return an array of function names:

func_names = Functions().exec(4).name
print(func_names)

Exercise #4 - External Calls invoking abi.encode

So far, our query identifies external calls and checks if any of the following instructions write to storage.

In this final exercise, we want to take it a step further by identifying external call instructions that also invoke abi.encode. To achieve this, you’ll need to add an additional filter to your query that checks for cases where the external call instruction includes a call to abi.encode.

Bonus Challenge

Although we have not discussed what an instruction is yet, think of it as a line of code in a function.

We have a query that finds Solidity instructions:

from glider import *

def query():
    return (
        Instructions()
        .exec(10)
    )

We want to update this query to find delegatecall instructions.

Challenge: Identify the Glider function that, when called on Instructions(), will return only delegatecall instructions.

Refer to this to learn how to retrieve an instruction’s next instructions.

Click here for the solution

Stuck or want to confirm your answer? Visit the link below where you can view and run the solution inside of Glider IDE:

To check if an instruction is writing to contract storage, Glider provides a we can use. This function allows us to determine whether a given instruction performs a write operation on the contract’s state.

Click here for the solution

Stuck or want to confirm your answer? Visit the link below where you can view and run the solution inside of Glider IDE:

To retrieve all the calls made within an instruction, use the function.

Click here for the solution

Stuck or want to confirm your answer? Visit the link below where you can view and run the solution inside of Glider IDE:

Click here for the solution

Stuck or want to confirm your answer? Visit the link below where you can view and run the solution inside of Glider IDE:

🎓
💡
💡
💡
💡
💡
Instructions() section
https://glide.r.xyz/query/4aKXz8r5
Glider method
https://glide.r.xyz/query/BXFNHQyC
dedicated method named is_storage_write()
https://glide.r.xyz/query/NUSps4CL
callee_names()
https://glide.r.xyz/query/Y65j8PWM
https://glide.r.xyz/query/o3Q0dKq4
Instructions following an external call instruction are highlighted in blue