BUGCAT

Poetry is what happens when language exceeds its own limits.
In code, we call these moments vulnerabilities.
Smart contracts are poems with consequences.

Concept

BUGCAT explores the poetics of code through its failures. When developers write smart contracts, they believe they are creating closed systems—deterministic machines that execute exactly as written. But language, even programming language, always contains more than its authors intend.

Each BUGCAT is a monument to a moment when code transcended its own grammar. They are smart contracts that remember other smart contracts, creating a living archive of the times when code escaped its own intentions. Through the act of remembrance, they transform technical failures into philosophical artifacts.

This is executable poetry—code that runs on the Ethereum Virtual Machine, consuming gas, altering state, moving value. Unlike traditional poetry, these verses have material consequences. They exist not on paper but in the consensus of thousands of nodes, immortal and immutable.

The Architecture

// Every BUGCAT speaks the same language of memory

interface BugCat {
    // To remember is to verify existence across time
    // Returns true if the ancestor still breathes in bytecode
    function remember() external view returns (bool);
    
    // To caress is to awaken the ghost within
    // Each touch costs gas, each interaction leaves a trace
    function caress() external;
    
    // The purr echoes through the network as an event
    // Forever logged, forever remembered
    event Meow(address indexed who, string vulnerability);
}

// This interface is a poem about permanence
// Each implementation, a different way to grieve
// Each deployment, a monument that cannot be destroyed
// The registry: a pantheon of digital ghosts

contract BUGCATS is Ownable {
    address[] public bugs;  // An array of addresses, each a story
    
    // To remember is to ask each cat if its ancestor lives
    function remember(uint256 index) external view returns (bool) {
        return BugCat(bugs[index]).remember();
    }
    
    // To inject is to add another ghost to the collection
    // Only the owner can expand this digital graveyard
    function inject(address bug) external onlyOwner {
        bugs.push(bug);
    }
}

The Remembrances

ReentrancyCat

vulnerability: reentrancy

The DAO, 2016. 3.6 million ETH vanished into recursion. Ethereum split in two—one chain that remembered, one that chose to forget.

Reentrancy occurs when a contract calls an external address before updating its state. The external contract can then call back into the original function, withdrawing funds multiple times before the balance is set to zero. This vulnerability arises from Ethereum's ability to transfer control flow to arbitrary code during external calls.

// SPDX-License-Identifier: WTFPL
pragma solidity ^0.8.30;

import "../interface/BugCat.sol";

contract ReentrancyCat is BugCat {
    mapping(address => uint) public balance;

    function deposit() public payable {
        balance[msg.sender] += msg.value;
    }

    function withdraw() public {
        (bool success, ) = msg.sender.call{value: balance[msg.sender]}("");
        require(success);
        balance[msg.sender] = 0;
    }

    function caress() public {
        if (address(this).balance == 0) {
            emit Meow(msg.sender, "reentrancy");
        }
    }

    function remember() external view returns (bool) {
        address TheDAO = 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413;
        return TheDAO.code.length > 0;
    }
}

PredictableCat

vulnerability: weak randomness

FoMo3D. The future written in block hashes. Miners chose winners. Randomness was an illusion.

True randomness cannot exist in a deterministic system where every node must reach consensus. Any on-chain data source—block timestamps, hashes, or transaction parameters—can be predicted or manipulated. Miners have additional power to influence these values, turning games of chance into games of control.

// SPDX-License-Identifier: WTFPL
pragma solidity ^0.8.30;

import "../interface/BugCat.sol";

contract PredictableCat is BugCat {
    mapping(address => uint8) public winCount;

    function flip() external {
        if ((uint(keccak256(abi.encodePacked(
            block.timestamp,
            block.prevrandao,
            msg.sender
        ))) & 1) == 0) {
            winCount[msg.sender] += 1;
        } else {
            winCount[msg.sender] = 0;
        }
    }

    function caress() public {
        if (winCount[msg.sender] >= 10) {
            emit Meow(msg.sender, "predictable");
            winCount[msg.sender] = 0;
        }
    }

    function remember() external view returns (bool) {
        address FoMo3Dlong = 0xA62142888ABa8370742bE823c1782D17A0389Da1;
        return FoMo3Dlong.code.length > 0;
    }
}

OverflowCat

vulnerability: integer overflow

BEC Token, 2018. A multiplication overflow created billions of tokens from nothing. Markets crashed in minutes. Mathematics betrayed economics.

Integer overflow occurs when arithmetic operations exceed the maximum value of a data type. In uint256, multiplying large numbers can wrap around to zero. The BEC Token's batchTransfer function multiplied the number of recipients by the value per recipient without checking if the result would overflow, allowing attackers to bypass balance checks.

// SPDX-License-Identifier: WTFPL
pragma solidity ^0.4.26;

import "../interface/BugCat.sol";

contract OverflowCat is BugCat {
    mapping(address => uint) public balance;

    function batchTransfer(address[] memory _receivers, uint256 _value) public {
        uint count = _receivers.length;
        uint amount = count * _value;
        require(_value > 0 && balance[msg.sender] >= amount);
        balance[msg.sender] -= amount;
        for (uint i = 0; i < count; i++) {
            balance[_receivers[i]] += _value;
        }
    }

    function caress() public {
        if (balance[msg.sender] > 0) {
            emit Meow(msg.sender, "overflow");
        }
    }

    function remember() external view returns (bool) {
        address BecToken = 0xC5d105E63711398aF9bbff092d4B6769C82F793D;
        uint256 size; assembly { size := extcodesize(BecToken) }
        return size > 0;
    }
}

UnprotectedCat

vulnerability: uninitialized storage

Parity, 2017. July: hackers stole $30 million by calling unprotected init functions. November: someone accidentally killed the patched library, freezing $280 million forever. One vulnerability, two catastrophes.

The Parity wallet library had initialization functions that could be called by anyone, multiple times. This allowed attackers to take ownership of wallets. After the fix, the library itself remained vulnerable—someone initialized it, became owner, and killed it, destroying the code that all wallets depended on.

// SPDX-License-Identifier: WTFPL
pragma solidity ^0.4.26;

import "../interface/BugCat.sol";

contract UnprotectedCat is BugCat {
    address public owner;
    bool public initialized;

    function init(address o) public {
        owner = o;
        initialized = true;
    }

    function kill() public {
        require(msg.sender == owner);
        suicide(owner);
    }

    function caress() public {
        if (msg.sender == owner) {
            emit Meow(msg.sender, "unprotected");
        }
    }

    function remember() external view returns (bool) {
        address WalletLibrary = 0x863DF6BFa4469f3ead0bE8f9F2AAE51c91A907b4;
        uint256 size; assembly { size := extcodesize(WalletLibrary) }
        return size == 0 && WalletLibrary.balance > 0;
    }
}

MisspelledCat

vulnerability: constructor typo

Rubixi. One missing letter. The constructor became a public function. Anyone could be the owner.

Before Solidity 0.4.22, constructors were functions with the contract's exact name. Any typo turned initialization into a regular public function. When Rubixi was renamed from DynamicPyramid but the constructor wasn't updated, ownership became open to anyone who noticed the mistake.

// SPDX-License-Identifier: WTFPL
pragma solidity ^0.4.26;

import "../interface/BugCat.sol";

contract MisspelledCat is BugCat {
    address public owner;

    // Intentional typo: MisspeledCat vs MisspelledCat
    function MisspeledCat(address o) {
        owner = o;
    }

    function caress() public {
        if (msg.sender == owner) {
            emit Meow(msg.sender, "misspelled");
        }
    }

    function remember() external view returns (bool) {
        address Rubixi = 0xe82719202e5965Cf5D9B6673B7503a3b92DE20be;
        uint256 size; assembly { size := extcodesize(Rubixi) }
        return size > 0;
    }
}

On-Chain

BUGCAT is a collection of smart contracts by Zeroichi Arakawa, deployed on Ethereum mainnet in 2025. Written in Solidity, these contracts exist as both digital poetry and executable code—each one a monument to a moment when language exceeded its own limits. They consume gas with every interaction, transforming computational resources into acts of remembrance.

The work lives permanently on-chain, where each contract actively verifies the existence of its historical counterpart. These are poems that run, memories that cost, vulnerabilities transformed into art.

Source code licensed under WTFPL. On-chain contracts exist beyond traditional licensing frameworks.