Files
zeekayandHanzo Dev dced1dcfb9 Publish under the org, not a person
Bylines, paper authorship, correspondence addresses and the founder blurb under
each post named an individual. They name the organisation that published the
work instead: the brand on posts and pages, the research byline on papers, and
research@ in place of a personal address. Both are what these repositories
already used elsewhere — nothing new was coined.

Co-authors are untouched. Where a paper named someone else alongside, they stay
named; only the one byline changed. Bibliography entries, running heads,
PDF metadata and affiliations move with it, so a citation still resolves to
whoever the cited paper names.

Sample and fixture data uses the placeholder name these tests already use
elsewhere, so no assertion changed meaning.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-01 08:55:40 -07:00

517 lines
20 KiB
TeX

\documentclass[11pt,letterpaper]{article}
\usepackage{shared/zoocover}
% Packages
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{amsmath,amssymb,amsthm}
\usepackage{algorithm}
\usepackage{algorithmic}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{booktabs}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows,positioning,calc}
\usepackage{listings}
\usepackage{caption}
\usepackage{subcaption}
% geometry loaded by zoocover
\input{shared/lstlang}
% Listing style
\lstset{
basicstyle=\ttfamily\footnotesize,
breaklines=true,
frame=single,
numbers=left,
numberstyle=\tiny,
captionpos=b,
xleftmargin=2em,
framexleftmargin=1.5em,
}
% Theorem environments
\newtheorem{theorem}{Theorem}[section]
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{proposition}[theorem]{Proposition}
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{definition}{Definition}[section]
\newtheorem{example}{Example}[section]
% Custom commands
\newcommand{\Zoo}{\textsc{Zoo}}
\newcommand{\NFT}{\textsc{nft}}
\newcommand{\ERC}{\textsc{erc}}
\newcommand{\DAO}{\textsc{dao}}
\newcommand{\ZOO}{\$\textsc{zoo}}
% Hyperref setup
\hypersetup{
colorlinks=true,
linkcolor=blue,
citecolor=blue,
urlcolor=blue
}
% Title and authors
\title{\textbf{ZRC-1155: Multi-Token Standard for Conservation Assets}}
\author{
Zoo Labs Foundation Research\thanks{[email protected]}\\
\textit{Zoo Labs Foundation}\\
\texttt{[email protected]}
}
\date{January 2025}
\begin{document}
\zoocoverpage
\begin{abstract}
We present ZRC-1155, the multi-token standard for the Zoo L2 chain. ZRC-1155 extends ERC-1155 and the Lux LRC-1155 standard (LP-2155) to support fungible, non-fungible, semi-fungible, and soulbound tokens within a single contract. The standard introduces token-level conservation categorization (species, habitat, research, impact, gaming), a structured token~ID encoding scheme that embeds category and type information in the 256-bit identifier, batch impact tracking across token types, and a collection-wide auto-donation mechanism. ZRC-1155 enables gas-efficient management of conservation badges, citizen science achievements, research data bundles, donor tier memberships, and in-game wildlife items---use cases that would require hundreds of separate ERC-20 or ERC-721 contracts under conventional standards.
\textbf{Keywords}: multi-token, ERC-1155, batch operations, soulbound, conservation badges, gas efficiency
\end{abstract}
\section{Introduction}
The Zoo ecosystem generates hundreds of distinct token types: conservation badges awarded for field work, citizen science achievements, donor tier memberships, in-game items for Zoo gaming experiences, protection credits traded in DeFi markets, and research data bundles for DeSci collaborations. Deploying individual ERC-20 or ERC-721 contracts for each type is economically infeasible: each deployment costs gas, each contract requires separate approval and management, and multi-token transfers require $O(n)$ transactions.
ERC-1155~\cite{erc1155} solves this by supporting multiple token types within a single contract. A single \texttt{safeBatchTransferFrom} call moves 50 different token types in one transaction, reducing gas cost by up to 90\% compared to 50 individual ERC-20 transfers.
ZRC-1155 extends ERC-1155 with conservation-specific features: token-level categorization, batch impact tracking, soulbound transfer restrictions for achievement badges, and a donation mechanism that operates across batch transfers.
\subsection{Use Cases}
\begin{enumerate}
\item \textbf{Conservation Badges}: Soulbound achievements for donations, field work, citizen science. Hundreds of badge types with varying supply.
\item \textbf{Protection Credits}: Fungible tokens representing verified conservation outcomes (hectares protected, species recovered). Traded in DeFi markets.
\item \textbf{Research Data Bundles}: Semi-fungible tokens representing satellite imagery, sensor data, and field observations. Identical within a dataset, unique across datasets.
\item \textbf{Donor Tiers}: Semi-fungible membership tokens (Bronze, Silver, Gold, Platinum) with per-tier benefits.
\item \textbf{GameFi Items}: In-game tools, habitats, consumables for Zoo gaming experiences (ZIP-0004).
\item \textbf{Conservation Portfolios}: Baskets of tokens representing diversified impact across species and regions.
\end{enumerate}
\subsection{Contributions}
\begin{enumerate}
\item The complete IZRC1155 interface with conservation categorization and batch impact tracking (Section~\ref{sec:interface}).
\item A structured token ID encoding that embeds conservation category and type in the 256-bit identifier (Section~\ref{sec:encoding}).
\item Soulbound token mechanics with burn-only revocation (Section~\ref{sec:soulbound}).
\item Batch donation mechanism operating across heterogeneous token types (Section~\ref{sec:donation}).
\item Gas cost analysis demonstrating 5--10$\times$ savings over individual contracts (Section~\ref{sec:gas}).
\end{enumerate}
\section{Background}
\subsection{ERC-1155}
ERC-1155~\cite{erc1155} defines a multi-token interface supporting:
\begin{itemize}
\item \textbf{Fungible tokens}: Supply $> 1$, interchangeable within type.
\item \textbf{Non-fungible tokens}: Supply $= 1$, unique.
\item \textbf{Semi-fungible}: Limited supply, interchangeable within type but distinct across types.
\end{itemize}
Key operations: \texttt{safeTransferFrom}, \texttt{safeBatchTransferFrom}, \texttt{balanceOf}, \texttt{balanceOfBatch}. The \texttt{uri(id)} function returns a template URI per token type.
\subsection{Soulbound Tokens}
Vitalik Buterin proposed soulbound tokens (SBTs)~\cite{sbt2022} as non-transferable credentials. ERC-5192~\cite{erc5192} formalizes a minimal SBT interface. ZRC-1155 implements soulbound semantics at the token-type level within the multi-token framework.
\section{Interface Specification}
\label{sec:interface}
\subsection{Enumerations}
\begin{lstlisting}[language=Solidity,caption=Token and conservation category enums]
enum TokenCategory {
FUNGIBLE, // Stackable, divisible
NON_FUNGIBLE, // Unique, supply of 1
SEMI_FUNGIBLE, // Fungible within type
SOULBOUND // Non-transferable
}
enum ConservationCategory {
NONE, // No classification
SPECIES, // Tied to a species
HABITAT, // Tied to a habitat
RESEARCH, // Scientific data
IMPACT, // Conservation proof
GAMING // In-game item
}
\end{lstlisting}
\subsection{Token Type Info}
\begin{lstlisting}[language=Solidity,caption=TokenTypeInfo struct]
struct TokenTypeInfo {
TokenCategory tokenCategory;
ConservationCategory conservationCategory;
uint256 maxSupply; // 0 = unlimited
uint256 currentSupply;
bool transferable; // false for SOULBOUND
string speciesId; // Empty if N/A
address conservationFund; // address(0) = default
uint16 donationBasisPoints; // 0 = default
}
\end{lstlisting}
\subsection{Core Interface}
\begin{lstlisting}[language=Solidity,caption=IZRC1155 interface]
interface IZRC1155 is IERC1155,
IERC1155MetadataURI {
// Token Type Management
function tokenTypeInfo(uint256 id)
external view returns (TokenTypeInfo memory);
function createTokenType(
uint256 id,
TokenCategory tokenCategory,
ConservationCategory conservationCategory,
uint256 maxSupply,
bool transferable,
string calldata speciesId
) external;
event TokenTypeCreated(
uint256 indexed id,
TokenCategory tokenCategory,
ConservationCategory conservationCategory,
uint256 maxSupply
);
// Batch Impact Tracking
function totalCollectionImpact()
external view returns (uint256);
function tokenTypeImpact(uint256 id)
external view returns (uint256);
function accountImpact(address account)
external view returns (uint256);
event ImpactRecorded(
uint256 indexed tokenId,
address indexed account,
uint256 creditsAdded,
uint256 totalCredits
);
// Collection-Wide Donation
function defaultConservationFund()
external view returns (address);
function defaultDonationBasisPoints()
external view returns (uint16);
function setDefaultConservationFund(
address fund
) external;
function setDefaultDonationBasisPoints(
uint16 bps
) external;
event CollectionDonation(
address indexed from,
uint256[] ids,
uint256[] amounts,
uint256 totalDonationValue
);
// Batch Minting
function mintBatch(
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
function mintSoulbound(
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
}
\end{lstlisting}
\section{Token ID Encoding}
\label{sec:encoding}
ZRC-1155 uses a structured 256-bit token ID:
\begin{verbatim}
Token ID (uint256):
+------------------+----------------+------------------+
| Category (8 bits)| Type (48 bits) | Serial (200 bits)|
+------------------+----------------+------------------+
Bits 255-248 Bits 247-200 Bits 199-0
\end{verbatim}
\begin{lstlisting}[language=Solidity,caption=ZRC1155TokenId library]
library ZRC1155TokenId {
function encode(
ConservationCategory category,
uint48 typeId,
uint200 serial
) internal pure returns (uint256) {
return (uint256(category) << 248)
| (uint256(typeId) << 200)
| uint256(serial);
}
function category(uint256 id)
internal pure returns (
ConservationCategory) {
return ConservationCategory(
uint8(id >> 248));
}
function typeId(uint256 id)
internal pure returns (uint48) {
return uint48(id >> 200);
}
function serial(uint256 id)
internal pure returns (uint200) {
return uint200(id);
}
}
\end{lstlisting}
\begin{definition}[Token ID Uniqueness]
For any two token IDs $a$ and $b$, if $\text{category}(a) = \text{category}(b)$ and $\text{typeId}(a) = \text{typeId}(b)$ and $\text{serial}(a) = \text{serial}(b)$, then $a = b$. The encoding is bijective.
\end{definition}
The structured encoding enables efficient on-chain filtering. Indexers and subgraphs decode the conservation category directly from the token ID without additional storage reads.
\begin{table}[t]
\centering
\begin{tabular}{lccc}
\toprule
\textbf{Token} & \textbf{Category} & \textbf{Type} & \textbf{Serial} \\
\midrule
Species badge & SPECIES (1) & 0x000001 & 0 \\
Habitat credit & HABITAT (2) & 0x000042 & 0 \\
Research dataset & RESEARCH (3) & 0x000100 & 17 \\
Impact proof & IMPACT (4) & 0x000200 & 0 \\
Game sword & GAMING (5) & 0x001000 & 99 \\
\bottomrule
\end{tabular}
\caption{Example token ID encoding for various conservation asset types.}
\label{tab:encoding}
\end{table}
\section{Soulbound Mechanics}
\label{sec:soulbound}
Tokens with \texttt{transferable = false} enforce:
\begin{enumerate}
\item \texttt{safeTransferFrom} and \texttt{safeBatchTransferFrom} MUST revert for soulbound token IDs.
\item \texttt{setApprovalForAll} grants no transfer rights for soulbound tokens.
\item Soulbound tokens CAN be burned by the holder (voluntary credential revocation).
\item Standard \texttt{TransferSingle}/\texttt{TransferBatch} events are emitted on mint and burn for indexer compatibility.
\end{enumerate}
\begin{lstlisting}[language=Solidity,caption=Soulbound enforcement in \_beforeTokenTransfer]
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal override {
super._beforeTokenTransfer(
operator, from, to, ids, amounts, data);
// Allow mints (from == 0) and burns (to == 0)
if (from != address(0)
&& to != address(0)) {
for (uint256 i = 0; i < ids.length; i++) {
require(
_tokenTypes[ids[i]].transferable,
"ZRC1155: soulbound"
);
}
}
}
\end{lstlisting}
\section{Batch Donation Mechanism}
\label{sec:donation}
When \texttt{safeBatchTransferFrom} is called with fungible token types that have \texttt{donationBasisPoints > 0}:
\begin{enumerate}
\item For each token ID in the batch, compute the donation amount using the token-specific or collection-default rate.
\item Transfer donation amounts to the respective conservation fund.
\item Transfer remaining amounts to the recipient.
\item Emit a single \texttt{CollectionDonation} event with aggregated data.
\end{enumerate}
Soulbound and non-fungible tokens are exempt from donation deduction.
\begin{proposition}[Batch Donation Gas Cost]
Let $n$ be the number of token IDs in a batch transfer, $k \leq n$ be the number with nonzero donation rate. The donation overhead is $O(k)$ additional storage writes (one per conservation fund) plus $O(1)$ for the event emission. For $k = 0$, the batch transfer has zero donation overhead.
\end{proposition}
\section{Metadata URI Schema}
The \texttt{uri(id)} function returns a template URI:
\begin{verbatim}
https://api.zoo.ngo/metadata/1155/{id}.json
\end{verbatim}
\begin{lstlisting}[language=JSON,caption=ZRC-1155 metadata example]
{
"name": "Rainforest Guardian Badge",
"description": "Awarded for protecting 100
hectares of tropical rainforest.",
"image": "ipfs://Qm.../rainforest-badge.png",
"properties": {
"tokenCategory": "SEMI_FUNGIBLE",
"conservationCategory": "HABITAT",
"transferable": false,
"maxSupply": 10000,
"speciesId": "",
"habitatType": "Tropical Rainforest",
"impactCreditsPerUnit": 100,
"requirements": "Donate >= 1000 ZOO to
rainforest conservation fund"
}
}
\end{lstlisting}
\section{Gas Cost Analysis}
\label{sec:gas}
\begin{table}[t]
\centering
\begin{tabular}{lcc}
\toprule
\textbf{Operation} & \textbf{Individual Contracts} & \textbf{ZRC-1155 Batch} \\
\midrule
Transfer 1 type & 65,000 gas & 52,000 gas \\
Transfer 10 types & 650,000 gas & 98,000 gas \\
Transfer 50 types & 3,250,000 gas & 290,000 gas \\
Mint 10 types & 1,500,000 gas & 180,000 gas \\
\bottomrule
\end{tabular}
\caption{Gas cost comparison: individual ERC-20/721 contracts vs. ZRC-1155 batch operations.}
\label{tab:gas}
\end{table}
The gas savings come from two sources: (1)~reduced base transaction overhead (one transaction instead of $n$), and (2)~reduced storage reads (single contract state instead of $n$ contract states). For batch transfers of 50~types, ZRC-1155 uses 91\% less gas.
\section{Security Analysis}
\subsection{Supply Overflow}
\texttt{mintBatch} MUST check \texttt{currentSupply + amount <= maxSupply} for each capped token type and revert atomically if any type overflows.
\subsection{Soulbound Bypass}
Transfer restrictions are enforced in \texttt{\_beforeTokenTransfer}, not in external wrappers. This prevents bypass via \texttt{delegatecall} or proxy contracts.
\subsection{Batch Gas Limits}
Extremely large batch operations may exceed block gas limits. Implementations SHOULD set a maximum batch size (e.g., 100 token IDs per call).
\subsection{Token ID Collisions}
\texttt{createTokenType} MUST revert if a token type ID already exists. The encoding scheme guarantees uniqueness when the \texttt{ZRC1155TokenId} library is used.
\subsection{Reentrancy}
\texttt{safeTransferFrom} calls \texttt{onERC1155Received} on the recipient. Implementations MUST use reentrancy guards.
\subsection{Donation Griefing}
An attacker could create many small transfers where the donation rounds to zero. Implementations SHOULD skip donation for amounts below a minimum threshold.
\section{Related Work}
ERC-1155~\cite{erc1155} defines the base multi-token standard. Enjin~\cite{enjin2019} pioneered ERC-1155 for gaming assets. ERC-5192~\cite{erc5192} defines minimal soulbound token interfaces; ZRC-1155 integrates soulbound mechanics within the multi-token framework. OpenSea's Wyvern protocol~\cite{opensea2018} handles ERC-1155 marketplace listings. Thirdweb~\cite{thirdweb2023} provides ERC-1155 drop contracts for batch minting.
In conservation, Reef Conservation Tokens~\cite{reef2022} use ERC-1155 for coral reef protection credits. ZRC-1155 generalizes this pattern with formal conservation categorization, structured token IDs, and soulbound badge support.
POAP (Proof of Attendance Protocol)~\cite{poap2019} uses ERC-721 for event attendance badges; ZRC-1155's soulbound SEMI\_FUNGIBLE category achieves the same goal with significantly lower gas cost for batch issuance.
\section{Conclusion}
ZRC-1155 provides a gas-efficient, conservation-aware multi-token standard for the Zoo ecosystem. The structured token ID encoding enables efficient on-chain categorization without additional storage. Soulbound mechanics ensure that achievement badges represent genuine participation. The batch donation mechanism extends conservation funding to every multi-token transfer. Together, these features make ZRC-1155 the practical foundation for the hundreds of token types the Zoo conservation ecosystem requires.
\section*{Acknowledgments}
This work was supported by Zoo Labs Foundation. We thank the Enjin team for pioneering the ERC-1155 standard and OpenZeppelin for the reference implementation.
\bibliographystyle{plain}
\begin{thebibliography}{20}
\bibitem{erc1155}
W.~Radomski et al., ``EIP-1155: Multi Token Standard,'' Ethereum Improvement Proposals, 2018.
\bibitem{sbt2022}
V.~Buterin, E.~Weyl, and P.~Ohlhaver, ``Decentralized Society: Finding Web3's Soul,'' 2022.
\bibitem{erc5192}
T.~Wilson et al., ``EIP-5192: Minimal Soulbound NFTs,'' Ethereum Improvement Proposals, 2022.
\bibitem{enjin2019}
Enjin, ``Enjin: Blockchain Game Development Platform,'' Technical Documentation, 2019.
\bibitem{opensea2018}
D.~Finzer and A.~Atallah, ``OpenSea: Decentralized Marketplace for Crypto Collectibles,'' Technical Documentation, 2018.
\bibitem{thirdweb2023}
thirdweb, ``ERC-1155 Drop: Batch Minting and Claiming,'' Technical Documentation, 2023.
\bibitem{lrc1155}
Lux Industries Inc ``LP-2155: LRC-1155 Multi-Token Standard,'' Lux Protocol Standards, 2022.
\bibitem{zip0004}
Zoo Labs Foundation, ``ZIP-0004: Gaming Standards for Zoo Ecosystem,'' Zoo Improvement Proposals, 2024.
\bibitem{zip0100}
Zoo Labs Foundation, ``ZIP-0100: Zoo Contract Registry,'' Zoo Improvement Proposals, 2024.
\bibitem{zip0500}
Zoo Labs Foundation, ``ZIP-0500: ESG Principles for Conservation Impact,'' Zoo Improvement Proposals, 2024.
\bibitem{zip0700}
Zoo Labs Foundation, ``ZIP-0700: ZRC-20 Fungible Token Standard,'' Zoo Improvement Proposals, 2025.
\bibitem{zip0701}
Zoo Labs Foundation, ``ZIP-0701: ZRC-721 NFT Standard,'' Zoo Improvement Proposals, 2025.
\bibitem{poap2019}
POAP, ``Proof of Attendance Protocol,'' \url{https://poap.xyz}, 2019.
\bibitem{reef2022}
Reef Conservation, ``Reef Conservation Tokens: ERC-1155 for Marine Protection,'' Technical Report, 2022.
\bibitem{openzeppelin}
OpenZeppelin, ``OpenZeppelin Contracts,'' \url{https://openzeppelin.com/contracts}, 2023.
\bibitem{erc165}
C.~Reitwie{\ss}ner et al., ``EIP-165: Standard Interface Detection,'' Ethereum Improvement Proposals, 2018.
\bibitem{erc20}
F.~Vogelsteller and V.~Buterin, ``EIP-20: Token Standard,'' Ethereum Improvement Proposals, 2015.
\bibitem{erc721}
W.~Entriken et al., ``EIP-721: Non-Fungible Token Standard,'' Ethereum Improvement Proposals, 2018.
\bibitem{zip0015}
Zoo Labs Foundation, ``ZIP-0015: Zoo L2 Chain Architecture,'' Zoo Improvement Proposals, 2024.
\bibitem{erc2981}
Z.~Leibowitz et al., ``EIP-2981: NFT Royalty Standard,'' Ethereum Improvement Proposals, 2020.
\end{thebibliography}
\end{document}