Skip to content

Latest commit

 

History

History
100 lines (74 loc) · 3 KB

README.md

File metadata and controls

100 lines (74 loc) · 3 KB

Instructions

Instructions and its twin Instruction are perhaps the most complex objects in Glider, with the most methods, because they represent the never-ending combinations of Solidity calls, calculations, variable assignments, conditions, etc.

From Instructions, you can filter out:

  • Calls by type (external, delegate, static, low-level, internal...)
  • Calls by name (exact, negative, signature, prefix, suffix)
  • Assembly
  • Entry points
  • Other common types of instructions (conditions, loops, variable assignments...)

Example

from glider import *


def query():
    instructions = (
        Functions()
        .with_one_property([MethodProp.PUBLIC, MethodProp.EXTERNAL])
        .instructions()
        .external_calls()
        .with_callee_function_name("transferFrom")
        .exec(10)
    )

    result = []
    for instruction in instructions:
        # arbitrary logic
        result.append(instruction)

    return result

The glide above filters out only high-level functions and returns all instructions that contain an external call to tranferFrom(), such as this one:

function transferFromERC20(IERC20 _token,uint256 _amount)
    public
    payable
    returns (uint256)
{
    uint256 erc20balance = _token.balanceOf(msg.sender);
    require(_amount <= erc20balance,"Balance is to low");
    _token.transferFrom(msg.sender,payable(address(this)),_amount);
    return erc20balance;
}

I have no idea what this example is supposed to do, why they use payable, or why there's a redundant balance check :D But we can try to get the contract's source code; it's quite easy even without Etherscan (Kovan is deprecated).

Remember the Debug Technique? Well, our contract is located on offset 1, so we have to change the .exec(), plus add a print() to the arbitrary part where we will first step up to the parent function and then to the contract, getting its source code:

from glider import *


def query():
    instructions = (
        Functions()
        .with_one_property([MethodProp.PUBLIC, MethodProp.EXTERNAL])
        .instructions()
        .external_calls()
        .with_callee_function_name("transferFrom")
        .exec(1, 1)
    )

    result = []
    for instruction in instructions:
        # arbitrary logic
        print(instruction.get_parent().get_contract().source_code())
        result.append(instruction)

    return result

And the result is here: https://gist.github.com/ustas-eth/5f84201b12c1556df2c0316ac3455870

Looks like its purpose is to accept payments for tours! Is this cypherpunk?

There's an unprotected transfer function, too:

function transferERC20(
    IERC20 _token,address _to,uint256 _amount
) public {
    uint256 erc20balance = _token.balanceOf(address(this));
    require(_amount <= erc20balance,"Balance is to low");
    _token.transfer(_to,_amount);

}

And now I want to find them on the mainnet! UPD. Couldn't find them, mystery solved :(

Read next: Contracts