Good day to learn about the Function
methods, isn't it? Function
is the second of our fundamental trio. It can be used to:
- Check the corresponding function's properties
- Get different types of instructions belonging to this function
- Work with arguments
- ...
Don't forget about the
Callable
object,Function
inherit its methods!
From the most important methods, I can highlight the following:
- The group of property methods (
.is_internal()
,.is_public()
,.is_payable()
, etc.) - The group of
Instructions
getters (.if_instructions()
,.asm_instructions()
, etc.) .signature()
,.hashed_signature()
, and.name()
.get_contract()
to step up to the contract.arguments()
to get theArguments
object.modifiers()
to get theModifiers
object.dump_into_json()
, I'll make an additional article about it
There are about 50 methods in total, so make sure to check them all in the documentation 1 and 2.
I'll share one of my unfinished glides as an example where I use Function
to check the arguments:
from glider import *
def query():
instructions = (
Functions()
.with_one_property([MethodProp.EXTERNAL, MethodProp.PUBLIC])
.with_all_properties([MethodProp.HAS_CALLEES])
.with_arg_type("address")
.without_modifier_name(["onlyOwner", "onlyRole", "onlyAdmin"])
.instructions()
.external_calls()
.with_callee_function_name("transferFrom")
.exec(100)
)
result = []
for instruction in instructions:
function = instruction.get_parent()
addr_from = check_transfer_argument(instruction, function)
if not addr_from:
continue
if not check_requirements(instruction, function, addr_from):
continue
result.append(instruction)
return result
def check_transfer_argument(instruction, function):
function_addr_args = function.arguments().with_type("address")
calls = instruction.get_callee_values()
for call in calls:
if call.signature == "transferFrom(address,address,uint256)":
addr_from = call.get_args()[0]
for function_addr_arg in function_addr_args:
if addr_from.expression == function_addr_arg.name:
return function_addr_arg.name
def check_requirements(instruction, function, addr_from):
return True
As you can see, I use function = instruction.get_parent()
to step up from the instructions that contain transferFrom()
call to their corresponding functions.
Then, in the check_transfer_argument()
Python function, I query the function's arguments using function.arguments().with_type("address")
and try to match between them and transferFrom()
arguments to check whether the call uses arbitrary from
value.
The glide is unfinished because of the empty check_requirements()
in the end. There should be some algorithm to check whether the from
variable is used in a require
or if
.
You can try to modify it and finish the function, I don't mind, just show me what it looks like afterward :)