Instruction.extended_previous_instructions() Returns the set of all instructions preceding the current node in the control flow graph.
extended_previous_instructions() → Set[
Instruction
]
The function returns all instructions that are previous to the instruction in the CFG (control flow graph).
The difference between the extended_previous_instructions() function and previous_instructions() is that the former works in an inter-procedural manner.
The function is inter-procedural, and follows function calls; for the intra -procedural variant of this function, use previous_instructions() .
For example, in the function:
Copy function mul ( uint256 a , uint256 b) internal pure returns ( uint256 ) {
if (a == 0 ) {
return 0 ;
}
uint256 c = a * b;
require (c / a == b , "SafeMath: multiplication overflow" );
return c;
}
for the instruction:
Copy require (c / a == b , "SafeMath: multiplication overflow" )
having that the mul() is being called inside the function:
Copy function _transfer ( address from , address to , uint256 amount) private {
uint256 taxAmount = 0 ;
if ( ! _isExcludedFromFee[from] && ! _isExcludedFromFee[to]) {
require (tradeOpen , "Trading not open" );
taxAmount = amount. mul ((_buyCount > _reduceBuyTaxAt) ? _finalBuyTax : _initialBuyTax). div ( 100 );
if (from == uniswapV2Pair && to != address (uniswapV2Router)) {
require ( balanceOf (to) + amount <= _maxWalletSize , "Exceeds the limit" );
_buyCount ++ ;
}
if (to != uniswapV2Pair) {
require ( balanceOf (to) + amount <= _maxWalletSize , "Exceeds the limit" );
}
if (to == uniswapV2Pair && from != address ( this ) ){
taxAmount = amount. mul ((_buyCount > _reduceSellTaxAt) ? _finalSellTax : _initialSellTax). div ( 100 );
}
//....
}
the function will return previous instructions from mul():
Copy if (a == 0 ) {
return 0 ;
}
uint256 c = a * b;
as well as from _transfer():
Copy uint256 taxAmount = 0 ;
if ( ! _isExcludedFromFee[from] && ! _isExcludedFromFee[to]) {
require (tradeOpen , "Trading not open" );
taxAmount = amount. mul ((_buyCount > _reduceBuyTaxAt) ? _finalBuyTax : _initialBuyTax). div ( 100 );
if (from == uniswapV2Pair && to != address (uniswapV2Router)) {
require ( balanceOf (to) + amount <= _maxWalletSize , "Exceeds the limit" );
_buyCount ++ ;
}
if (to != uniswapV2Pair) {
require ( balanceOf (to) + amount <= _maxWalletSize , "Exceeds the limit" );
}
if (to == uniswapV2Pair && from != address ( this ) ){
taxAmount = amount. mul ((_buyCount > _reduceSellTaxAt) ? _finalSellTax : _initialSellTax). div ( 100 );
}
Furthermore, it will also return instructions from transferFrom() function as the _transfer() is being called from there as well:
Copy function transferFrom ( address sender , address recipient , uint256 amount) public override returns ( bool ) {
_transfer (sender , recipient , amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true ;
}
Query Example
Copy from glider import *
def query ():
instructions = Functions().with_all_properties([MethodProp.INTERNAL]).instructions().with_callee_function_name('require').exec(1,2)
return instructions + list (instructions[ 0 ]. extended_previous_instructions ())
Output
Copy "root" : { 4 items
"contract" : string "0xd705c24267ed3c55458160104994c55c6492dfcf"
"contract_name" : string "SafeMath"
"sol_function" : solidity
function mul ( uint256 a , uint256 b) internal pure returns ( uint256 ) {
if (a == 0 ) {
return 0 ;
}
uint256 c = a * b;
require (c / a == b , "SafeMath: multiplication overflow" );
return c;
}
"sol_instruction" : solidity
require (c / a == b , "SafeMath: multiplication overflow" )
} ,
...
"root" : { 4 items
"contract" : string "0xd705c24267ed3c55458160104994c55c6492dfcf"
"contract_name" : string "Token"
"sol_function" : solidity
function _transfer ( address from , address to , uint256 amount) private {
uint256 taxAmount = 0 ;
if ( ! _isExcludedFromFee[from] && ! _isExcludedFromFee[to]) {
require (tradeOpen , "Trading not open" );
taxAmount = amount. mul ((_buyCount > _reduceBuyTaxAt) ? _finalBuyTax : _initialBuyTax). div ( 100 );
if (from == uniswapV2Pair && to != address (uniswapV2Router)) {
require ( balanceOf (to) + amount <= _maxWalletSize , "Exceeds the limit" );
_buyCount ++ ;
}
if (to != uniswapV2Pair) {
require ( balanceOf (to) + amount <= _maxWalletSize , "Exceeds the limit" );
}
if (to == uniswapV2Pair && from != address ( this ) ){
taxAmount = amount. mul ((_buyCount > _reduceSellTaxAt) ? _finalSellTax : _initialSellTax). div ( 100 );
}
uint256 contractTokenBalance = balanceOf ( address ( this ));
if ( ! inSwap && to == uniswapV2Pair && swapEnabled && contractTokenBalance > _taxSwapThreshold) {
swapTokensForEth ( min (amount , min (contractTokenBalance , _maxTaxSwap)));
uint256 contractETHBalance = address ( this ).balance;
if (contractETHBalance > 0 ) {
sendETHToFee ( address ( this ).balance);
}
}
}
if (taxAmount > 0 ){
_balances[ address ( this )] = _balances[ address ( this )]. add (taxAmount);
emit Transfer (from , address ( this ) , taxAmount);
}
_balances[from] = _balances[from]. sub (amount);
_balances[to] = _balances[to]. add (amount. sub (taxAmount));
emit Transfer (from , to , amount. sub (taxAmount));
}
"sol_instruction" : solidity
taxAmount = amount. mul ((_buyCount > _reduceSellTaxAt) ? _finalSellTax : _initialSellTax). div ( 100 )
}
...
"root" : { 4 items
"contract" : string "0xd705c24267ed3c55458160104994c55c6492dfcf"
"contract_name" : string "Token"
"sol_function" : solidity
function transferFrom ( address sender , address recipient , uint256 amount) public override returns ( bool ) {
_transfer (sender , recipient , amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true ;
}
"sol_instruction" : solidity
_transfer (sender , recipient , amount)
}
Last updated 7 months ago