# Fiefdom Dev Documentation

Get started building your app or experience on Fiefdom with the official developer documentation.

Welcome to the official developer documentation for Fiefdom, a cutting-edge blockchain ecosystem dedicated to gaming and trading in the metaverse.

Here, you'll find comprehensive resources to guide you through developing on both the Fiefdom Mainnet (coming soon) and the Fiefdom Playground Testnet.

### Who Should Use These Docs?

Our documentation serves a wide array of users within the blockchain space:

* **Blockchain Developers**: Whether you're aiming to deploy smart contracts, develop DApps, or explore blockchain protocols, these docs provide the tools and knowledge you need to succeed in the Fiefdom ecosystem.
* **NFT Creators**: For artists and creators looking to mint, manage, and innovate with NFTs, our guides cover everything from digital art and gaming assets to unique digital collectibles.
* **DeFi Enthusiasts**: Explore the world of decentralized finance on Fiefdom, including creating tokens, setting up liquidity pools, and implementing yield farming strategies.
* **Innovators and Experimenters**: Anyone curious about blockchain's potential and eager to contribute to the next wave of decentralized technology will find valuable insights and opportunities here.

### Getting Started

To begin your development journey on Fiefdom, follow these initial steps:

1. **Choose Your Environment**: Decide whether to start on the Playground Testnet for experimentation and testing, or prepare for the upcoming Mainnet launch for live deployments.
2. **Set Up Your Development Tools**: Install necessary tools such as Node.js, Hardhat, or Truffle Suite, and configure your environment for Fiefdom development.
3. **Connect Your Wallet**: Set up MetaMask or another Ethereum-compatible wallet and connect it to the Fiefdom network.
4. **Explore Tutorials and Guides**: Dive into our tutorials for deploying smart contracts, creating NFTs, developing DApps, and more.

Whether you're new to blockchain development or looking to expand your skills in the Fiefdom ecosystem, these documents are designed to support your growth and success every step of the way. Welcome to Fiefdom – let's build the future of the metaverse together.


# Overview of Fiefdom

<figure><img src="/files/J9Nz41Ae6Nm6UaxQBUJO" alt=""><figcaption></figcaption></figure>

Fiefdom emerges as a pioneering Layer 3 blockchain network, strategically developed to serve the burgeoning demands of the gaming and trading sectors within the expansive metaverse. As an Arbitrum Orbit Chain, Fiefdom is designed from the ground up to harness the full potential of decentralized technologies, offering a tailored ecosystem that caters specifically to the dynamic needs of metaverse interactions and transactions.

At its core, Fiefdom is a testament to innovation and scalability, offering a permissionless platform where developers, game studios, and creators can freely build, deploy, and manage their metaverse projects. From fully on-chain games to intricate NFT-based experiences and DeFi/NFTfi integrations, Fiefdom provides a versatile foundation that supports a wide array of applications.

**Designed for the Metaverse**

Fiefdom's architecture is meticulously crafted to address the unique challenges and opportunities within the metaverse. It is not merely a blockchain network but a comprehensive ecosystem that facilitates fully immersive, on-chain gaming experiences, seamless trading of metaverse assets, and the development of NFT projects. By focusing on the metaverse, Fiefdom positions itself as a crucial infrastructure layer that enables a new tier of accessibility, utility, and interactivity within digital realms.

**A Permissionless Network**

The permissionless nature of Fiefdom underscores its commitment to open innovation and inclusivity. By allowing game studios, developers, and creators to build on top of the network without restrictions, Fiefdom fosters a vibrant, decentralized community of builders. This approach not only accelerates the development of diverse and innovative applications but also ensures that Fiefdom remains at the forefront of metaverse technology.

**Integration with Fief Ecosystem**

Fiefdom is an integral part of the broader Fief ecosystem, which includes the Fiefverse — a voxel game universe, and the Fief Protocol — a multi-chain platform for trading and earning rewards on metaverse assets. The introduction of Fiefdom enhances the Fief ecosystem by migrating game-related assets and functionalities onto a blockchain network optimized for speed, cost-efficiency, and scalability. This strategic integration ensures a seamless user experience across the Fief ecosystem, enhancing the value and utility of metaverse assets and interactions.

**Economic Model and Tokenomics**

At the heart of Fiefdom's economic model is the FIEF token, which serves as the primary medium of exchange, governance, and utility within the network. Fiefdom introduces innovative mechanisms such as deflationary transactions, where fees collected from transaction activity are permanently removed from circulation, and Influence Point (IP) Rebates, which reward on-chain activity with in-game currency. These features create a unique economic environment that incentivizes participation, rewards users, and sustains the network's growth.

**Technical Excellence and Security**

Built on the Arbitrum Orbit Chain and leveraging the Arbitrum Anytrust Protocol, Fiefdom benefits from the cutting-edge technology of Arbitrum's public Layer 2 network, Nova. This foundation provides Fiefdom with low-latency, ultra-low-cost transactions while maintaining a secure and decentralized network. The choice of Arbitrum's technology ensures that Fiefdom benefits from continuous improvements, scalability, and compatibility with Ethereum's ecosystem.

#### Conclusion

Fiefdom is more than just a blockchain network; it is a visionary platform that paves the way for the next generation of gaming and trading in the metaverse. By offering a permissionless, scalable, and economically robust ecosystem, Fiefdom invites developers, gamers, and creators to explore new horizons of digital interaction and innovation. With its unique blend of technical sophistication, community-driven development, and a focus on the metaverse, Fiefdom stands poised to redefine the landscape of blockchain gaming and metaverse commerce.


# Benefits of Building on Fiefdom

As an integral part of the growing ecosystem of Arbitrum Orbit Chains, Fiefdom distinguishes itself by offering a specialized platform for gaming and trading within the metaverse. This unique positioning as a Layer 3 solution on the Arbitrum network provides developers with several compelling advantages for building decentralized applications. Here are the core benefits of choosing Fiefdom for your development projects:

**Tailored for Gaming and Trading in the Metaverse**

Fiefdom's design is meticulously aligned with the needs of the metaverse, specifically focusing on gaming and trading applications. This specialized focus ensures that the network is optimized for the high throughput, low latency, and interactive experiences crucial for metaverse ecosystems. Developers can leverage this tailored environment to create immersive, engaging, and complex virtual worlds and marketplaces with ease.

**Seamless Integration with Arbitrum and Ethereum Ecosystems**

Being an Arbitrum Orbit Chain, Fiefdom benefits from seamless integration with both the Arbitrum Layer 2 solutions and the broader Ethereum ecosystem. This integration facilitates smooth asset transfers, interoperability, and access to a wide range of tools and services available within the Ethereum landscape. Developers building on Fiefdom can easily expand their applications and leverage the security, liquidity, and user base of Ethereum.

**Enhanced Performance and Cost Efficiency**

Fiefdom utilizes the Arbitrum Anytrust Protocol, inheriting Arbitrum's advanced scaling technologies that ensure low-latency and ultra-low-cost transactions. This performance optimization is crucial for developing scalable metaverse applications where fast response times and minimal transaction costs can significantly enhance user experience and facilitate more complex on-chain interactions.

**Permissionless Innovation**

As a permissionless network, Fiefdom encourages open innovation and development. Developers, from indie creators to established game studios, can build and deploy their applications without needing approval or facing restrictive barriers. This openness fosters a diverse and vibrant ecosystem of applications, driving innovation and creativity in the metaverse space.

**Economic Incentives and Token Utility**

Fiefdom introduces a unique economic model with the FIEF token serving multiple roles, including transaction fees, governance, and incentives. The network's design includes deflationary mechanisms and reward systems, such as Influence Point (IP) Rebates, which align the interests of developers, players, and token holders. Building on Fiefdom means participating in an ecosystem where economic incentives are structured to support and reward all stakeholders.

Grants are available for developers building applications on Fiefdom. More information will be available soon.

**Robust Security and Decentralization**

By leveraging the proven security and scalability features of the Arbitrum technology stack, Fiefdom offers developers a robust and decentralized platform for building their applications. The network's architecture ensures that applications benefit from the security assumptions of Ethereum while operating in a more scalable and cost-effective environment.

**Developer-friendly Tools and Resources**

Fiefdom provides developers with a comprehensive suite of tools, documentation, and resources designed to streamline the development process.

#### Conclusion

Building on Fiefdom presents a unique opportunity for developers aiming to pioneer the next generation of gaming and trading applications within the metaverse. By leveraging the network's metaverse-focused design, seamless integration with the Arbitrum and Ethereum ecosystems, enhanced performance, permissionless innovation, economic incentives, and robust security, developers can create immersive and interactive experiences that push the boundaries of what's possible in the digital world. Fiefdom stands not just as a platform but as a gateway to the future of decentralized applications in the metaverse.


# Prerequisites for Developers Building on Fiefdom

Building on Fiefdom, an Arbitrum Orbit Chain optimized for gaming and trading in the metaverse, requires developers to have a certain level of preparedness. While Fiefdom itself does not introduce proprietary development tools, its compatibility with the Ethereum Virtual Machine (EVM) allows developers to utilize a wide range of existing tools and libraries common in Ethereum development.&#x20;

Here's a breakdown of the prerequisites for developers interested in building on Fiefdom:

**Familiarity with Ethereum and Smart Contract Development**

* **Solid Understanding of Ethereum**: Knowledge of how Ethereum works, including its architecture, transaction lifecycle, and gas mechanics, is crucial. Since Fiefdom is an EVM-compatible chain, the core concepts of Ethereum apply directly to development on Fiefdom.
* **Smart Contract Development**: Proficiency in writing smart contracts using Solidity or Vyper is essential. Developers should be comfortable with smart contract development processes, including writing, testing, deploying, and interacting with contracts.

**Development Tools and Environments**

* **Integrated Development Environment (IDE)**: Familiarity with development environments such as Remix, Hardhat, or Truffle is necessary for efficient coding, testing, and deploying of smart contracts.
* **Node.js and npm**: Many Ethereum development tools and libraries are Node.js-based. Having Node.js and npm (Node Package Manager) installed enables developers to manage dependencies and run development scripts easily.
* **Ethereum Wallet**: A wallet that supports the Ethereum network, like MetaMask or WalletConnect, is required for interacting with the blockchain, deploying contracts, and testing transactions. Developers should ensure their wallet is compatible with Arbitrum and can be configured for the Fiefdom network.

**Understanding of Layer 2 Solutions and Arbitrum**

* **Layer 2 Scaling Solutions**: A general understanding of Layer 2 scaling solutions, particularly how they work and their benefits, is beneficial. Since Fiefdom operates as a Layer 3 solution on top of Arbitrum, knowledge of rollups and sidechains will help developers design more efficient and scalable applications.
* **Arbitrum and Its Ecosystem**: Familiarity with Arbitrum, including its tooling, network configuration, and specific features like its AnyTrust technology, will aid developers in leveraging the full potential of Fiefdom. Understanding how to bridge assets between Ethereum, Arbitrum, and Fiefdom, and how transaction finality works in this context, is also important.

**Basic Knowledge of Cryptography and Blockchain Security**

* **Cryptography**: A basic understanding of cryptographic principles that underlie blockchain technology, including hashing, digital signatures, and public-key cryptography.
* **Security Practices**: Awareness of common security concerns in smart contract development, such as reentrancy attacks, overflow and underflow, and the importance of audits and formal verification processes.

**Community Engagement and Resources**

* **Active Participation in Developer Communities**: Engaging with Fiefdom's developer community, Ethereum forums, and Arbitrum discussions can provide valuable insights, support, and updates on best practices and new developments.
* **Continuous Learning**: Given the rapidly evolving nature of blockchain technology, a commitment to continuous learning and staying updated with the latest tools, protocols, and security practices is crucial for success.


# Setting Up a Development Environment for Fiefdom

Setting up a development environment for building on Fiefdom is a crucial step for developers. This process involves first configuring your development tools to interact with the Fiefdom Playground testnet network, allowing you to deploy and test smart contracts effectively.&#x20;

Below is a guide to help you establish a development environment tailored for Fiefdom Playground, utilizing its Chain ID, RPC URL, and other network specifics.

**Step 1: Install Node.js and npm**

Before you begin, ensure you have Node.js and npm (Node Package Manager) installed on your computer. These tools are essential for managing project dependencies and running development scripts. You can download Node.js, which includes npm, from [nodejs.org](https://nodejs.org/).

**Step 2: Set Up Your Ethereum Wallet**

* **MetaMask Configuration**: Install MetaMask, a popular Ethereum wallet, as a browser extension from [metamask.io](https://metamask.io/). After setting up MetaMask, you'll need to configure it to connect to the Fiefdom Playground testnet network.
  * Note: Any other major EVM-compatibles wallet provider will work.
* **Add Fiefdom Network to MetaMask**:
  * Open MetaMask and go to Settings > Networks > Add Network.
  * Enter the following details for the Fiefdom network:
    * **Network Name**: Fiefdom Playground
    * **New RPC URL**: `https://fiefdom-playground.calderachain.xyz/http`
    * **Chain ID**: `712`
    * **Currency Symbol**: FIEF
    * **Block Explorer URL**: <https://explorer.playground.fiefdom.gg/>
  * Save the configuration. Your wallet is now connected to the Fiefdom Playground testnet network.

**Step 3: Choose and Set Up Your Development Environment**

* **Hardhat or Truffle Suite**: These are popular development environments for Ethereum smart contract development. For Fiefdom, either can be used as they both support custom network configurations.
  * **Hardhat**: Install Hardhat using npm with `npm install --save-dev hardhat`. Initialize a new Hardhat project by running `npx hardhat` in your project directory and follow the setup instructions.
  * **Truffle Suite**: Install Truffle using npm with `npm install -g truffle`. Initialize a new Truffle project by running `truffle init` in your project directory.

**Step 4: Configure Your Development Environment for Fiefdom**

* For **Hardhat**, edit the `hardhat.config.js` file to include the Fiefdom network configuration:

  ```javascript
  module.exports = {
    networks: {
      fiefdomPlayground: {
        url: "https://fiefdom-playground.calderachain.xyz/http",
        chainId: 712,
        accounts: [/* Your private keys here */],
        gas: "auto",
        gasPrice: "auto"
      }
    },
    solidity: "0.8.4", // or any other version you prefer
  };
  ```
* For **Truffle**, edit the `truffle-config.js` file to add the Fiefdom network:

  ```javascript
  module.exports = {
    networks: {
      fiefdomPlayground: {
        provider: () => new HDWalletProvider(/* Your mnemonic or private keys */, "https://fiefdom-playground.calderachain.xyz/http"),
        network_id: 712,
        gas: "auto",
        gasPrice: "auto"
      }
    },
    compilers: {
      solc: {
        version: "0.8.4", // or any other version you prefer
      }
    }
  };
  ```

**Step 5: Web3 Provider Setup**

For interacting with the Fiefdom Playground network programmatically (e.g., deploying contracts, sending transactions), configure a Web3 provider in your project:

* **Web3.js or Ethers.js**: Both libraries are widely used in Ethereum development. Install your choice of library using npm, for example, `npm install web3` or `npm install ethers`.
* Use the RPC URL (`https://fiefdom-playground.calderachain.xyz/http`) when initializing your Web3 or Ethers provider to connect to the Fiefdom network.


# Introduction

The Fiefdom Playground Testnet serves as the cornerstone for developers embarking on their journey within the Fiefdom ecosystem. In the broader landscape of blockchain development, testnets play a pivotal role, offering a sandbox environment where developers can experiment, test, and refine their applications without the stakes of real-value transactions.&#x20;

Fiefdom's Playground Testnet is designed to embody this philosophy fully, providing a robust and versatile platform that caters to developers of all stages and sizes—from individual hobbyists to large-scale enterprise teams.

**The Purpose of Testnets**

Testnets are essential for several reasons in the blockchain development lifecycle. They offer a risk-free environment for developers to:

* **Deploy and Test Smart Contracts**: Before any code is deployed on the mainnet, where mistakes can be costly, testnets provide a safe space for deployment and interaction testing.
* **Experiment with Blockchain Functionality**: Developers can explore the full suite of blockchain features, including transactions, smart contract interactions, and consensus mechanisms, without financial risk.
* **Understand Gas Economics**: Even though transactions on testnets do not carry real value, they simulate the gas economics of the mainnet, helping developers optimize their applications for cost-efficiency.
* **Engage with the Community**: Testnets allow developers to collaborate, share insights, and collectively troubleshoot issues, fostering a strong community of practice. You can join our Discord now.

**Why Fiefdom Playground Testnet Stands Out**

The Fiefdom Playground Testnet is not just any testnet; it's a tailored environment that amplifies the potential for innovation within the metaverse domain. Here’s why it stands out:

* **Optimized for the Metaverse**: With Fiefdom's focus on gaming and trading, the Playground Testnet is specifically optimized for applications in the metaverse, offering unique tools and features that align with the needs of metaverse developers.
* **EVM Compatibility**: As an EVM-compatible chain, Fiefdom allows developers to use existing Ethereum development tools and libraries, lowering the barrier to entry and facilitating a smooth transition for those familiar with Ethereum's ecosystem.
* **Rich Tooling and Resources**: The Playground Testnet comes equipped with comprehensive documentation, developer tools, and resources, making it easier for developers to get started and continue their development journey on Fiefdom.
* **Realistic Environment**: Despite being a testnet, Playground aims to replicate the mainnet environment as closely as possible, ensuring that developers can accurately gauge the performance and behavior of their applications under real-world conditions.

**Getting Started on the Playground Testnet**

Starting your development journey on the Fiefdom Playground Testnet is straightforward. With tools and documentation readily available, developers can quickly set up their environment, connect their wallets, and begin deploying and testing their applications.&#x20;

The testnet is designed to be accessible and user-friendly, ensuring that developers can focus on what truly matters—building innovative, scalable, and engaging applications for the metaverse


# Hub

<figure><img src="/files/DkWaqKGLo4RLKLEK0dce" alt=""><figcaption></figcaption></figure>

The Fiefdom Playground Testnet Hub is a comprehensive portal designed to streamline your development journey on the Fiefdom blockchain. Accessible at <https://playground.fiefdom.gg/>, the Hub provides centralized access to essential tools and resources, including the FIEF Faucet, Bridge, and Explorer. T

his integrated approach ensures developers have everything they need at their fingertips, facilitating an efficient and productive development process. Here’s how to make the most out of the Hub’s features:

**FIEF Faucet: Fueling Your Testnet Activities**

<figure><img src="/files/eVDHbeMv2hSUb2tP3afC" alt=""><figcaption></figcaption></figure>

The FIEF Faucet is a critical tool for developers beginning their journey on the Fiefdom Playground Testnet. It provides free FIEF tokens, which are used to pay for transaction fees on the testnet, simulating the economic model of the mainnet without the need for real funds.

* **Accessing the Faucet**: Navigate to the Hub and locate the FIEF Faucet section. With a simple interface, obtaining FIEF tokens is just a few clicks away.
* **Usage**: Enter your wallet address and request your testnet FIEF tokens. These tokens enable you to deploy smart contracts, execute transactions, and test the functionalities of your applications under realistic economic conditions.

**Bridge: Seamlessly Connect Fiefdom with Arbitrum**

<figure><img src="/files/HMiCNwcVt4EAnHk0DGeb" alt=""><figcaption></figcaption></figure>

The Bridge functionality within the Hub serves as a conduit between the Fiefdom testnet and the Arbitrum Sepolia testnet, showcasing Fiefdom's interoperability and the seamless experience of asset transfer across layers.

* **Functionality**: The Bridge allows developers to transfer tokens back and forth between the Fiefdom and Arbitrum testnets, enabling a multi-layered testing environment that mirrors the interconnected nature of the mainnet ecosystem.
* **Applications**: This feature is particularly useful for testing cross-chain applications, dApps that rely on asset mobility, and ensuring compatibility with broader ecosystem standards.

**Explorer: Insight into Fiefdom's On-chain Activity**

<figure><img src="/files/4HQxLwB0Mtx9ZYmcjFBD" alt=""><figcaption></figcaption></figure>

The Explorer component of the Hub is an invaluable resource for developers seeking a transparent view into the testnet's blockchain activity. It provides detailed information on transactions, smart contracts, and blockchain state, among others.

* **Features**: With the Explorer, you can track transaction histories, inspect smart contract code, and monitor the overall health and activity on the Fiefdom testnet. This visibility is essential for debugging, performance optimization, and understanding the dynamics of your application in a live environment.
* **Accessibility**: Directly accessible from the Hub, the Explorer ensures that detailed blockchain analytics are readily available to support your development process.

The Fiefdom Playground block explorer is built on top of BlockScout. If you have specific questions regarding the interaction with the explorer API, contract verification, etc., please see the BlockScout documentation: <https://docs.blockscout.com/>


# Basics

Smart contracts are the backbone of applications on the Fiefdom network, enabling the creation of decentralized applications (DApps), tokens, and complex blockchain interactions within the gaming and trading metaverse. Developing smart contracts on Fiefdom, thanks to its EVM compatibility, is a process familiar to those who have worked with Ethereum. This guide outlines the essential steps and best practices for developing, deploying, and interacting with smart contracts on Fiefdom.

**Understanding Smart Contract Development**

Smart contracts are self-executing contracts with the terms of the agreement directly written into code. On Fiefdom, these contracts govern the rules of interactions, transactions, and functionality within DApps, ensuring a decentralized and trustless execution of operations.

**Prerequisites**

Before diving into smart contract development on Fiefdom, ensure you have:

* A solid understanding of Solidity, the programming language for writing smart contracts on Ethereum and EVM-compatible chains.
* Familiarity with the development tools and environments such as Remix, Hardhat, or Truffle, which facilitate smart contract development, testing, and deployment.
* An Ethereum wallet compatible with Fiefdom, configured with testnet FIEF for deploying contracts and interacting with the network.

See [Setting Up a Development Environment for Fiefdom](/getting-started/setting-up-a-development-environment-for-fiefdom)for more in depth information on getting you system setup.

**Step 1: Setting Up Your Development Environment**

Choose a development environment that suits your project needs:

* **Remix IDE**: A web-based IDE for Solidity development, perfect for quick prototyping and beginner developers.
* **Hardhat or Truffle**: Node.js-based frameworks for Ethereum development that offer a comprehensive suite of development tools for compiling, deploying, and testing smart contracts.

**Step 2: Writing Your First Smart Contract**

Create a simple smart contract. Here's an example of a basic contract written in Solidity that stores and retrieves a value:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorage {
    uint256 private storedData;

    function set(uint256 x) public {
        storedData = x;
    }

    function get() public view returns (uint256) {
        return storedData;
    }
}
```

**Step 3: Compiling Your Contract**

* **Remix IDE**: Compile your contract directly in the IDE by selecting the Solidity compiler version matching your pragma statement and clicking the "Compile" button.
* **Hardhat/Truffle**: Use the command `npx hardhat compile` or `truffle compile` in your project directory to compile your contract. Ensure your configuration files (`hardhat.config.js` or `truffle-config.js`) are set up correctly for Fiefdom.

**Step 4: Deploying to Fiefdom**

Deploy your compiled contract to the Fiefdom network:

* **Remix IDE**: Connect Remix to your MetaMask wallet configured for Fiefdom, and use the "Deploy" tab to deploy your contract.
* **Hardhat/Truffle**: Use the deployment scripts provided by these frameworks, ensuring your scripts target the Fiefdom network configuration in your project setup.

**Step 5: Interacting with Your Smart Contract**

Once deployed, interact with your contract to test its functionality:

* **Via Remix or Web3.js/Ethers.js**: Call the contract's methods using Remix or through a script using Web3.js or Ethers.js. Ensure you're connected to the Fiefdom network.

**Best Practices for Smart Contract Development**

* **Security**: Follow best practices for smart contract security, including code audits, testing, and leveraging known security patterns.
* **Gas Optimization**: Optimize your contract code to minimize gas usage, especially important for functions that will be called frequently.
* **Upgradability**: Consider implementing upgradable smart contracts, especially for complex DApps, to allow for future improvements and fixes without losing state or funds.


# Interacting With Fiefdom Smart Contracts

Interacting with smart contracts is a fundamental aspect of developing decentralized applications (DApps) on the Fiefdom network. This guide provides an overview of the methods and tools you can use to interact with deployed smart contracts, enabling you to create dynamic and responsive applications within the Fiefdom ecosystem.

**Preparing for Interaction**

Before interacting with smart contracts on Fiefdom, ensure you have:

* Deployed a smart contract on the Fiefdom network or have the address of an existing contract you wish to interact with.
* Access to a Fiefdom-compatible wallet, such as MetaMask, configured with the Fiefdom network and funded with testnet FIEF for transactions.
* Chosen a development tool or library, like Web3.js, Ethers.js, or a frontend framework integrated with these libraries, for interacting with the blockchain.

**Web3.js and Ethers.js Libraries**

Web3.js and Ethers.js are JavaScript libraries that enable interaction with the Ethereum blockchain and are fully compatible with Fiefdom due to its EVM-compatibility. These libraries can be used in Node.js applications or integrated into web applications to interact with smart contracts.

* **Web3.js**: A collection of modules that contain specific functionalities for the ethereum ecosystem.
* **Ethers.js**: A compact library that aims to be a complete and compact library for interacting with the Ethereum Blockchain and its ecosystem.

**Interacting from a Script**

To interact with a smart contract using a script, follow these steps:

1. **Initialize Your Web3 or Ethers Provider**: Connect to the Fiefdom network using the RPC URL provided by Fiefdom.
   * For Web3.js:

     ```javascript
     const Web3 = require('web3');
     const web3 = new Web3('https://fiefdom-playground.calderachain.xyz/http');
     ```
   * For Ethers.js:

     ```javascript
     const { ethers } = require('ethers');
     const provider = new ethers.providers.JsonRpcProvider('https://fiefdom-playground.calderachain.xyz/http');
     ```
2. **Create a Contract Instance**: Use the ABI (Application Binary Interface) and the address of your deployed contract to create an instance.
   * For Web3.js:

     ```javascript
     const contract = new web3.eth.Contract(abi, contractAddress);
     ```
   * For Ethers.js:

     ```javascript
     const contract = new ethers.Contract(contractAddress, abi, provider);
     ```
3. **Call Contract Methods**: Use the contract instance to call methods. You can call view methods directly, but for state-changing methods, you'll need to send a transaction.
   * For view methods in Web3.js:

     ```javascript
     contract.methods.yourMethodName().call().then(console.log);
     ```
   * For state-changing methods in Web3.js, you'll need to sign the transaction:

     ```javascript
     contract.methods.yourMethodName().send({ from: senderAddress }).then(console.log);
     ```
   * For Ethers.js, interacting is similar, but you'll use a signer for transactions:

     ```javascript
     // For view methods
     contract.yourMethodName().then(console.log);

     // For state-changing methods
     const signer = provider.getSigner();
     const contractWithSigner = contract.connect(signer);
     contractWithSigner.yourMethodName().then(console.log);
     ```

**Interacting through a Web Interface**

Integrating Web3.js or Ethers.js into a web application allows users to interact with smart contracts through a user-friendly interface. Frameworks like React or Vue can be used to create dynamic DApp interfaces that communicate with smart contracts on Fiefdom.

* **Connect Wallet**: Use libraries like `@web3-react/core` or `ethers`' built-in wallet connection functionalities to connect users' wallets to your DApp.
* **Read and Display Data**: Call view functions from your contract to display data in your DApp.
* **Send Transactions**: Create forms and buttons that allow users to send transactions to your smart contract, modifying the blockchain state.


# Create ERC-20 Token

This tutorial guides you through the process of deploying an ERC-20 token on the Fiefdom Playground testnet blockchain.&#x20;

ERC-20 tokens are a standard for creating fungible tokens on the Ethereum blockchain, and thanks to Fiefdom's EVM compatibility, the process is similar to deploying on Ethereum. By following these steps, you'll learn how to create and deploy your own ERC-20 token.

**Prerequisites**

* Ensure you have Node.js and npm installed.
* A text editor or IDE for writing and editing your smart contract code.
* MetaMask or another Ethereum-compatible wallet, set up and configured for the Fiefdom network.
* Some testnet FIEF in your wallet for deploying the contract.

**Step 1: Setting Up Your Project**

1. Create a new directory for your project and navigate into it.
2. Initialize a new Node.js project by running `npm init -y` in your terminal.
3. Install Hardhat, a popular development environment for compiling, deploying, and testing Ethereum software. Install it using npm:

   ```css
   npm install --save-dev hardhat
   ```

**Step 2: Initializing Your Hardhat Project**

1. Run `npx hardhat` in your project directory. Select “Create an empty hardhat.config.js” when prompted.
2. Install the OpenZeppelin Contracts library, which provides a secure and community-audited ERC-20 implementation:

   ```bash
   npm install @openzeppelin/contracts
   ```

**Step 3: Writing Your ERC-20 Token Contract**

1. Create a `contracts` folder in your project root.
2. Inside `contracts`, create a new file named `MyToken.sol`.
3. Open `MyToken.sol` in your editor and define your ERC-20 token by extending OpenZeppelin’s `ERC20` contract. Here is a simple example:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
        _mint(msg.sender, initialSupply);
    }
}
```

This contract creates an ERC-20 token named "MyToken" with the symbol "MTK". The `constructor` sets the initial token supply and assigns it to the deployer's address.

**Step 4: Compiling Your Contract**

1. Create a `hardhat.config.js` file in your project root if it’s not already there from the Hardhat setup.
2. Configure Hardhat to use the Solidity version installed by OpenZeppelin Contracts and set up the Fiefdom Playground network configuration:

```javascript
require("@nomiclabs/hardhat-waffle");

module.exports = {
  solidity: "0.8.0",
  networks: {
    fiefdomPlayground: {
      url: "https://fiefdom-playground.calderachain.xyz/http",
      accounts: [/* Your private key here */],
      chainId: 712,
    }
  }
};
```

Replace `/* Your private key here */` with your own private key. Be careful with your private key and consider using environment variables to keep it secure.

3. Compile your contract by running `npx hardhat compile`.

**Step 5: Deploying Your ERC-20 Token**

1. Create a `scripts` folder in your project root.
2. Inside `scripts`, create a new file named `deploy.js`.
3. Write a deployment script in `deploy.js`:

```javascript
async function main() {
    const [deployer] = await ethers.getSigners();

    console.log("Deploying contracts with the account:", deployer.address);

    const MyToken = await ethers.getContractFactory("MyToken");
    const token = await MyToken.deploy(1000000); // Deploy with 1,000,000 initial supply

    console.log("Token address:", token.address);
}

main().then(() => process.exit(0)).catch(error => {
    console.error(error);
    process.exit(1);
});
```

This script deploys your `MyToken` contract with an initial supply of 1,000,000 tokens (adjust the supply as needed).

4. Deploy your token to the Fiefdom network by running:

   ```arduino
   npx hardhat run scripts/deploy.js --network fiefdomPlayground
   ```


# Create ERC-721 NFT

This tutorial will walk you through the steps to create and deploy an ERC-721 token on the Fiefdom Playground Testnet.&#x20;

ERC-721 tokens, known for their non-fungible characteristics, are perfect for representing unique assets such as game items or digital art for Profile Picture (PFP) projects. This guide is tailored specifically for developers looking to explore and innovate on the Fiefdom Playground Testnet before the mainnet becomes available.

**Prerequisites**

* Node.js and npm installed on your development machine.
* A crypto wallet compatible with Ethereum and Fiefdom, such as MetaMask, configured for the Fiefdom Playground Testnet.
* Familiarity with Solidity and the basics of smart contract development.

**Step 1: Project Setup**

1. **Create a Project Directory**: Make a new directory for your project and navigate into it.
2. **Initialize a Node.js Project**: Run `npm init -y` to create a `package.json` file.
3. **Install Hardhat**: Execute `npm install --save-dev hardhat` to add Hardhat to your project.

**Step 2: Hardhat Project Configuration**

1. **Initialize Hardhat**: In your project directory, run `npx hardhat`. Opt for "Create an empty hardhat.config.js" when prompted.
2. **Install OpenZeppelin Contracts**: Run `npm install @openzeppelin/contracts` to get secure ERC-721 implementations.

**Step 3: Crafting Your ERC-721 Token Contract**

1. **Create a Contracts Directory**: Inside your project, make a `contracts` folder.
2. **Write Your ERC-721 Contract**: In `contracts`, create a file named `GameItem.sol` or `PFPProject.sol`. Insert your ERC-721 code, extending OpenZeppelin’s `ERC721URIStorage` for easy metadata management:

<pre class="language-solidity"><code class="lang-solidity"><strong>// SPDX-License-Identifier: MIT
</strong>pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract GameItem is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("GameItem", "GMIT") {}

    function mintItem(address player, string memory tokenURI)
        public
        returns (uint256)
    {
        _tokenIds.increment();
        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        _setTokenURI(newItemId, tokenURI);
        return newItemId;
    }
}
</code></pre>

**Step 4: Compiling the Contract**

1. **Adjust `hardhat.config.js`**: Modify your Hardhat configuration to include the Fiefdom Playground Testnet details:

```javascript
require("@nomiclabs/hardhat-waffle");

module.exports = {
  solidity: "0.8.0",
  networks: {
    fiefdomPlayground: {
      url: "https://fiefdom-playground.calderachain.xyz/http",
      accounts: [/* Your private key */],
      chainId: 712,
    }
  }
};
```

Replace `/* Your private key */` with your wallet's private key, ensuring proper security practices to protect it.

2. **Compile Your Contract**: Run `npx hardhat compile`.

**Step 5: Deploying to the Fiefdom Playground Testnet**

1. **Script Creation**: In a new `scripts` directory, add a `deploy.js` file with deployment logic:

```javascript
async function main() {
    const [deployer] = await ethers.getSigners();
    console.log("Deploying contracts with the account:", deployer.address);

    const GameItem = await ethers.getContractFactory("GameItem");
    const gameItem = await GameItem.deploy();

    console.log("GameItem deployed to:", gameItem.address);
}

main().catch((error) => {
    console.error(error);
    process.exit(1);
});
```

2. **Execute Deployment**: Deploy your ERC-721 token by running:

   ```bash
   npx hardhat run scripts/deploy.js --network fiefdomPlayground
   ```

### Enhancing Your ERC-721 Tokens with IPFS for Metadata Storage

Integrating InterPlanetary File System (IPFS) for storing and referencing the metadata of your ERC-721 tokens on the Fiefdom Playground Testnet adds an extra layer of decentralization and permanence to your digital assets.&#x20;

This approach ensures that your NFTs are not just uniquely identifiable on the blockchain but also securely linked to immutable metadata and media files. Here's how to incorporate IPFS into your ERC-721 token deployment for game items or PFP projects.

**Understanding IPFS and Metadata**

IPFS is a peer-to-peer protocol for storing and sharing data in a distributed file system. In the context of NFTs, IPFS can host metadata and associated media files (images, videos, etc.), making them accessible through a unique hash known as a Content Identifier (CID). This method guarantees that once your NFT's metadata is on IPFS, it cannot be altered, ensuring the longevity and integrity of the asset's information.

**Preparing Your Metadata**

1. **Create Metadata JSON**: Each NFT should have a corresponding metadata file in JSON format that describes its attributes. For a game item or PFP, this might include name, description, image, and attributes specific to the asset:

```json
{
  "name": "Epic Sword of Truth",
  "description": "A legendary sword wielded by heroes of old.",
  "image": "ipfs://<YourImageCID>",
  "attributes": [
    {
      "trait_type": "Damage",
      "value": 100
    },
    {
      "trait_type": "Durability",
      "value": "High"
    }
  ]
}
```

2. **Upload to IPFS**: Use an IPFS client or service like Pinata, Infura, or IPFS Desktop to upload your metadata files. Each file will receive a unique CID.

**Integrating IPFS with Your ERC-721 Contract**

When deploying your `GameItem` or `PFPProject` contract, the `tokenURI` for each minted token should point to its metadata file stored on IPFS.

1. **Minting with IPFS Metadata**: In your smart contract's minting function, ensure the `tokenURI` parameter references the IPFS CID of your metadata JSON file. The `ipfs://` URI scheme followed by the CID constitutes the full token URI.

```solidity
function mintItem(address player, string memory tokenURI)
    public
    returns (uint256)
{
    _tokenIds.increment();
    uint256 newItemId = _tokenIds.current();
    _mint(player, newItemId);
    _setTokenURI(newItemId, tokenURI); // tokenURI is the IPFS link
    return newItemId;
}
```

2. **Example Token URI**: If your metadata file's CID on IPFS is `QmXkWfWGPxbQtjThvWEPXzNQHgHQ8Z8poL5ZbQmBL4Z7Rs`, the `tokenURI` would be `ipfs://QmXkWfWGPxbQtjThvWEPXzNQHgHQ8Z8poL5ZbQmBL4Z7Rs`.

**Deploying and Testing**

Follow the previously outlined steps to deploy your ERC-721 contract to the Fiefdom Playground Testnet, ensuring that when you mint NFTs, you provide the correct IPFS-based `tokenURI` for each. This setup not only secures your NFT metadata on a decentralized storage platform but also aligns with the best practices of NFT creation, ensuring asset integrity and accessibility.


# Create ERC-404 Token

This tutorial will guide you through creating and deploying an experimental ERC-404 token on the Fiefdom Playground Testnet.&#x20;

The ERC-404 standard is a novel implementation that mixes ERC-20 and ERC-721 standards to allow for native liquidity and fractionalization of non-fungible tokens (NFTs). This guide is designed for developers eager to explore innovative token standards on the Fiefdom Playground Testnet.

**Prerequisites**

* Node.js and npm installed on your development environment.
* A crypto wallet compatible with Ethereum and Fiefdom, configured for the Fiefdom Playground Testnet.
* Basic understanding of Solidity and smart contract development.

**Step 1: Project Setup**

1. **Create a Project Directory**: Initialize a new directory for your project and navigate into it.
2. **Initialize a Node.js Project**: Run `npm init -y` to create your `package.json` file.
3. **Install Hardhat**: Add Hardhat to your project with `npm install --save-dev hardhat`.

**Step 2: Hardhat Project Configuration**

1. **Initialize Hardhat**: In your project directory, execute `npx hardhat` and select "Create an empty hardhat.config.js" when prompted.
2. **Install OpenZeppelin Contracts**: Run `npm install @openzeppelin/contracts` for secure token implementations.

**Step 3: Crafting Your ERC-404 Token Contract**

1. **Create a Contracts Directory**: Make a `contracts` folder within your project.
2. **Write Your ERC-404 Contract**: In the `contracts` directory, create a file named `MyERC404Token.sol`. Use the provided ERC-404 abstract contract as a starting point to implement your token logic.
3. See Further Details below for a full example contract.

```solidity
solidityCopy code// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "./ERC404.sol";

contract MyERC404Token is ERC404 {
    constructor() ERC404("MyERC404Token", "M404", 18) {
        // Additional constructor logic here
    }

    // Implement required functions and overrides
    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        // Logic to return the metadata URI for tokenId
    }
}
```

**Step 4: Compiling Your Contract**

1. **Configure Hardhat for Fiefdom Playground**: Adjust your `hardhat.config.js` to include the Fiefdom Playground Testnet settings:

```javascript
javascriptCopy coderequire("@nomiclabs/hardhat-waffle");

module.exports = {
  solidity: "0.8.20",
  networks: {
    fiefdomPlayground: {
      url: "https://fiefdom-playground.calderachain.xyz/http",
      accounts: [/* Your private key here */],
      chainId: 712,
    }
  }
};
```

Replace `/* Your private key here */` with your wallet's private key, safeguarding it appropriately.

2. **Compile Your Contract**: Execute `npx hardhat compile` to compile your contract.

**Step 5: Deploying to the Fiefdom Playground Testnet**

1. **Create a Deployment Script**: In the `scripts` directory, add a `deploy.js` file with the deployment logic for your ERC-404 token:

```javascript
javascriptCopy codeasync function main() {
    const [deployer] = await ethers.getSigners();
    console.log("Deploying contracts with the account:", deployer.address);

    const MyERC404Token = await ethers.getContractFactory("MyERC404Token");
    const myERC404Token = await MyERC404Token.deploy();

    console.log("MyERC404Token deployed to:", myERC404Token.address);
}

main().catch((error) => {
    console.error(error);
    process.exit(1);
});
```

2. **Execute Deployment**: Deploy your ERC-404 token to the Fiefdom Playground Testnet by running:&#x20;

```
npx hardhat run scripts/deploy.js --network fiefdomPlayground
```

### Further Details

This example contract code provided is from the official GitHub of Pandora Labs, a primary group leading the development charge of ERC-404. - <https://github.com/Pandora-Labs-Org/erc404>.

From their documentation:

*`This is an extremely simple minimal version of an ERC-404 that mints the entire supply to the initial owner of the contract.`*

*`Generally the initial tokens minted to the deployer will be added to a DEX as liquidity. The DEX pool address should also be added to the whitelist to prevent minting NFTs to it and burning NFTs from it on transfer.`*

Note: WFIEF and FiefSwap DEX Contracts will be available for full proper testing of the ERC-404 standard on Fiefdom Playground soon.

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

import {IERC404} from "./interfaces/IERC404.sol";
import {ERC721Receiver} from "./lib/ERC721Receiver.sol";
import {DoubleEndedQueue} from "./lib/DoubleEndedQueue.sol";
import {IERC165} from "./lib/interfaces/IERC165.sol";

abstract contract ERC404 is IERC404 {
  using DoubleEndedQueue for DoubleEndedQueue.Uint256Deque;

  /// @dev The queue of ERC-721 tokens stored in the contract.
  DoubleEndedQueue.Uint256Deque private _storedERC721Ids;

  /// @dev Token name
  string public name;

  /// @dev Token symbol
  string public symbol;

  /// @dev Decimals for ERC-20 representation
  uint8 public immutable decimals;

  /// @dev Units for ERC-20 representation
  uint256 public immutable units;

  /// @dev Total supply in ERC-20 representation
  uint256 public totalSupply;

  /// @dev Current mint counter which also represents the highest
  ///      minted id, monotonically increasing to ensure accurate ownership
  uint256 internal _minted;

  /// @dev Initial chain id for EIP-2612 support
  uint256 internal immutable INITIAL_CHAIN_ID;

  /// @dev Initial domain separator for EIP-2612 support
  bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

  /// @dev Balance of user in ERC-20 representation
  mapping(address => uint256) public balanceOf;

  /// @dev Allowance of user in ERC-20 representation
  mapping(address => mapping(address => uint256)) public allowance;

  /// @dev Approval in ERC-721 representaion
  mapping(uint256 => address) public getApproved;

  /// @dev Approval for all in ERC-721 representation
  mapping(address => mapping(address => bool)) public isApprovedForAll;

  /// @dev Packed representation of ownerOf and owned indices
  mapping(uint256 => uint256) internal _ownedData;

  /// @dev Array of owned ids in ERC-721 representation
  mapping(address => uint256[]) internal _owned;

  /// @dev Addresses that are exempt from ERC-721 transfer, typically for gas savings (pairs, routers, etc)
  mapping(address => bool) public erc721TransferExempt;

  /// @dev EIP-2612 nonces
  mapping(address => uint256) public nonces;

  /// @dev Address bitmask for packed ownership data
  uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

  /// @dev Owned index bitmask for packed ownership data
  uint256 private constant _BITMASK_OWNED_INDEX = ((1 << 96) - 1) << 160;

  constructor(string memory name_, string memory symbol_, uint8 decimals_) {
    name = name_;
    symbol = symbol_;

    if (decimals_ < 18) {
      revert DecimalsTooLow();
    }

    decimals = decimals_;
    units = 10 ** decimals;

    // EIP-2612 initialization
    INITIAL_CHAIN_ID = block.chainid;
    INITIAL_DOMAIN_SEPARATOR = _computeDomainSeparator();
  }

  /// @notice Function to find owner of a given ERC-721 token
  function ownerOf(
    uint256 id_
  ) public view virtual returns (address erc721Owner) {
    erc721Owner = _getOwnerOf(id_);

    // If the id_ is beyond the range of minted tokens, is 0, or the token is not owned by anyone, revert.
    if (id_ > _minted || id_ == 0 || erc721Owner == address(0)) {
      revert NotFound();
    }
  }

  function owned(
    address owner_
  ) public view virtual returns (uint256[] memory) {
    return _owned[owner_];
  }

  function erc721BalanceOf(
    address owner_
  ) public view virtual returns (uint256) {
    return _owned[owner_].length;
  }

  function erc20BalanceOf(
    address owner_
  ) public view virtual returns (uint256) {
    return balanceOf[owner_];
  }

  function erc20TotalSupply() public view virtual returns (uint256) {
    return totalSupply;
  }

  function erc721TotalSupply() public view virtual returns (uint256) {
    return _minted;
  }

  function erc721TokensBankedInQueue() public view virtual returns (uint256) {
    return _storedERC721Ids.length();
  }

  /// @notice tokenURI must be implemented by child contract
  function tokenURI(uint256 id_) public view virtual returns (string memory);

  /// @notice Function for token approvals
  /// @dev This function assumes the operator is attempting to approve an ERC-721
  ///      if valueOrId is less than the minted count. Note: Unlike setApprovalForAll,
  ///      spender_ must be allowed to be 0x0 so that approval can be revoked.
  function approve(
    address spender_,
    uint256 valueOrId_
  ) public virtual returns (bool) {
    // The ERC-721 tokens are 1-indexed, so 0 is not a valid id and indicates that
    // operator is attempting to set the ERC-20 allowance to 0.
    if (valueOrId_ <= _minted && valueOrId_ > 0) {
      // Intention is to approve as ERC-721 token (id).
      uint256 id = valueOrId_;
      address erc721Owner = _getOwnerOf(id);

      if (
        msg.sender != erc721Owner && !isApprovedForAll[erc721Owner][msg.sender]
      ) {
        revert Unauthorized();
      }

      getApproved[id] = spender_;

      emit ERC721Approval(erc721Owner, spender_, id);
    } else {
      // Prevent granting 0x0 an ERC-20 allowance.
      if (spender_ == address(0)) {
        revert InvalidSpender();
      }

      // Intention is to approve as ERC-20 token (value).
      uint256 value = valueOrId_;
      allowance[msg.sender][spender_] = value;

      emit ERC20Approval(msg.sender, spender_, value);
    }

    return true;
  }

  /// @notice Function for ERC-721 approvals
  function setApprovalForAll(address operator_, bool approved_) public virtual {
    // Prevent approvals to 0x0.
    if (operator_ == address(0)) {
      revert InvalidOperator();
    }
    isApprovedForAll[msg.sender][operator_] = approved_;
    emit ApprovalForAll(msg.sender, operator_, approved_);
  }

  /// @notice Function for mixed transfers from an operator that may be different than 'from'.
  /// @dev This function assumes the operator is attempting to transfer an ERC-721
  ///      if valueOrId is less than or equal to current max id.
  function transferFrom(
    address from_,
    address to_,
    uint256 valueOrId_
  ) public virtual returns (bool) {
    // Prevent transferring tokens from 0x0.
    if (from_ == address(0)) {
      revert InvalidSender();
    }

    // Prevent burning tokens to 0x0.
    if (to_ == address(0)) {
      revert InvalidRecipient();
    }

    if (valueOrId_ <= _minted) {
      // Intention is to transfer as ERC-721 token (id).
      uint256 id = valueOrId_;

      if (from_ != _getOwnerOf(id)) {
        revert Unauthorized();
      }

      // Check that the operator is either the sender or approved for the transfer.
      if (
        msg.sender != from_ &&
        !isApprovedForAll[from_][msg.sender] &&
        msg.sender != getApproved[id]
      ) {
        revert Unauthorized();
      }

      // Neither the sender nor the recipient can be ERC-721 transfer exempt when transferring specific token ids.
      if (erc721TransferExempt[from_]) {
        revert SenderIsERC721TransferExempt();
      }

      if (erc721TransferExempt[to_]) {
        revert RecipientIsERC721TransferExempt();
      }

      // Transfer 1 * units ERC-20 and 1 ERC-721 token.
      // ERC-721 transfer exemptions handled above. Can't make it to this point if either is transfer exempt.
      _transferERC20(from_, to_, units);
      _transferERC721(from_, to_, id);
    } else {
      // Intention is to transfer as ERC-20 token (value).
      uint256 value = valueOrId_;
      uint256 allowed = allowance[from_][msg.sender];

      // Check that the operator has sufficient allowance.
      if (allowed != type(uint256).max) {
        allowance[from_][msg.sender] = allowed - value;
      }

      // Transferring ERC-20s directly requires the _transfer function.
      // Handles ERC-721 exemptions internally.
      _transferERC20WithERC721(from_, to_, value);
    }

    return true;
  }

  /// @notice Function for ERC-20 transfers.
  /// @dev This function assumes the operator is attempting to transfer as ERC-20
  ///      given this function is only supported on the ERC-20 interface. 
  ///      Treats even small amounts that are valid ERC-721 ids as ERC-20s.
  function transfer(address to_, uint256 value_) public virtual returns (bool) {
    // Prevent burning tokens to 0x0.
    if (to_ == address(0)) {
      revert InvalidRecipient();
    }

    // Transferring ERC-20s directly requires the _transfer function.
    // Handles ERC-721 exemptions internally.
    return _transferERC20WithERC721(msg.sender, to_, value_);
  }

  /// @notice Function for ERC-721 transfers with contract support.
  function safeTransferFrom(
    address from_,
    address to_,
    uint256 id_
  ) public virtual {
    transferFrom(from_, to_, id_);

    if (
      to_.code.length != 0 &&
      ERC721Receiver(to_).onERC721Received(msg.sender, from_, id_, "") !=
      ERC721Receiver.onERC721Received.selector
    ) {
      revert UnsafeRecipient();
    }
  }

  /// @notice Function for ERC-721 transfers with contract support and callback data.
  function safeTransferFrom(
    address from_,
    address to_,
    uint256 id_,
    bytes calldata data_
  ) public virtual {
    transferFrom(from_, to_, id_);

    if (
      to_.code.length != 0 &&
      ERC721Receiver(to_).onERC721Received(msg.sender, from_, id_, data_) !=
      ERC721Receiver.onERC721Received.selector
    ) {
      revert UnsafeRecipient();
    }
  }

  /// @notice Function for EIP-2612 permits
  function permit(
    address owner_,
    address spender_,
    uint256 value_,
    uint256 deadline_,
    uint8 v_,
    bytes32 r_,
    bytes32 s_
  ) public virtual {
    if (deadline_ < block.timestamp) {
      revert PermitDeadlineExpired();
    }

    if (value_ <= _minted && value_ > 0) {
      revert InvalidApproval();
    }

    if (spender_ == address(0)) {
      revert InvalidSpender();
    }

    unchecked {
      address recoveredAddress = ecrecover(
        keccak256(
          abi.encodePacked(
            "\x19\x01",
            DOMAIN_SEPARATOR(),
            keccak256(
              abi.encode(
                keccak256(
                  "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                ),
                owner_,
                spender_,
                value_,
                nonces[owner_]++,
                deadline_
              )
            )
          )
        ),
        v_,
        r_,
        s_
      );

      if (recoveredAddress == address(0) || recoveredAddress != owner_) {
        revert InvalidSigner();
      }

      allowance[recoveredAddress][spender_] = value_;
    }

    emit ERC20Approval(owner_, spender_, value_);
  }

  /// @notice Returns domain initial domain separator, or recomputes if chain id is not equal to initial chain id
  function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
    return
      block.chainid == INITIAL_CHAIN_ID
        ? INITIAL_DOMAIN_SEPARATOR
        : _computeDomainSeparator();
  }

  function supportsInterface(
    bytes4 interfaceId
  ) public view virtual returns (bool) {
    return
      interfaceId == type(IERC404).interfaceId ||
      interfaceId == type(IERC165).interfaceId;
  }

  /// @notice Internal function to compute domain separator for EIP-2612 permits
  function _computeDomainSeparator() internal view virtual returns (bytes32) {
    return
      keccak256(
        abi.encode(
          keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
          ),
          keccak256(bytes(name)),
          keccak256("1"),
          block.chainid,
          address(this)
        )
      );
  }

  /// @notice This is the lowest level ERC-20 transfer function, which
  ///         should be used for both normal ERC-20 transfers as well as minting.
  /// Note that this function allows transfers to and from 0x0.
  function _transferERC20(
    address from_,
    address to_,
    uint256 value_
  ) internal virtual {
    // Minting is a special case for which we should not check the balance of
    // the sender, and we should increase the total supply.
    if (from_ == address(0)) {
      totalSupply += value_;
    } else {
      // Deduct value from sender's balance.
      balanceOf[from_] -= value_;
    }

    // Update the recipient's balance.
    // Can be unchecked because on mint, adding to totalSupply is checked, and on transfer balance deduction is checked.
    unchecked {
      balanceOf[to_] += value_;
    }

    emit ERC20Transfer(from_, to_, value_);
  }

  /// @notice Consolidated record keeping function for transferring ERC-721s.
  /// @dev Assign the token to the new owner, and remove from the old owner.
  /// Note that this function allows transfers to and from 0x0.
  /// Does not handle ERC-721 exemptions.
  function _transferERC721(
    address from_,
    address to_,
    uint256 id_
  ) internal virtual {
    // If this is not a mint, handle record keeping for transfer from previous owner.
    if (from_ != address(0)) {
      // On transfer of an NFT, any previous approval is reset.
      delete getApproved[id_];

      uint256 updatedId = _owned[from_][_owned[from_].length - 1];
      if (updatedId != id_) {
        uint256 updatedIndex = _getOwnedIndex(id_);
        // update _owned for sender
        _owned[from_][updatedIndex] = updatedId;
        // update index for the moved id
        _setOwnedIndex(updatedId, updatedIndex);
      }

      // pop
      _owned[from_].pop();
    }

    if (to_ != address(0)) {
      // Update owner of the token to the new owner.
      _setOwnerOf(id_, to_);
      // Push token onto the new owner's stack.
      _owned[to_].push(id_);
      // Update index for new owner's stack.
      _setOwnedIndex(id_, _owned[to_].length - 1);
    } else {
      delete _ownedData[id_];
    }

    emit ERC721Transfer(from_, to_, id_);
  }

  /// @notice Internal function for ERC-20 transfers. Also handles any ERC-721 transfers that may be required.
  // Handles ERC-721 exemptions.
  function _transferERC20WithERC721(
    address from_,
    address to_,
    uint256 value_
  ) internal virtual returns (bool) {
    uint256 erc20BalanceOfSenderBefore = erc20BalanceOf(from_);
    uint256 erc20BalanceOfReceiverBefore = erc20BalanceOf(to_);

    _transferERC20(from_, to_, value_);

    // Preload for gas savings on branches
    bool isFromERC721TransferExempt = erc721TransferExempt[from_];
    bool isToERC721TransferExempt = erc721TransferExempt[to_];

    // Skip _withdrawAndStoreERC721 and/or _retrieveOrMintERC721 for ERC-721 transfer exempt addresses
    // 1) to save gas
    // 2) because ERC-721 transfer exempt addresses won't always have/need ERC-721s corresponding to their ERC20s.
    if (isFromERC721TransferExempt && isToERC721TransferExempt) {
      // Case 1) Both sender and recipient are ERC-721 transfer exempt. No ERC-721s need to be transferred.
      // NOOP.
    } else if (isFromERC721TransferExempt) {
      // Case 2) The sender is ERC-721 transfer exempt, but the recipient is not. Contract should not attempt
      //         to transfer ERC-721s from the sender, but the recipient should receive ERC-721s
      //         from the bank/minted for any whole number increase in their balance.
      // Only cares about whole number increments.
      uint256 tokensToRetrieveOrMint = (balanceOf[to_] / units) -
        (erc20BalanceOfReceiverBefore / units);
      for (uint256 i = 0; i < tokensToRetrieveOrMint;) {
        _retrieveOrMintERC721(to_);
        unchecked {
          i++;
        }
      }
    } else if (isToERC721TransferExempt) {
      // Case 3) The sender is not ERC-721 transfer exempt, but the recipient is. Contract should attempt
      //         to withdraw and store ERC-721s from the sender, but the recipient should not
      //         receive ERC-721s from the bank/minted.
      // Only cares about whole number increments.
      uint256 tokensToWithdrawAndStore = (erc20BalanceOfSenderBefore / units) -
        (balanceOf[from_] / units);
      for (uint256 i = 0; i < tokensToWithdrawAndStore;) {
        _withdrawAndStoreERC721(from_);
        unchecked {
          i++;
        }
      }
    } else {
      // Case 4) Neither the sender nor the recipient are ERC-721 transfer exempt.
      // Strategy:
      // 1. First deal with the whole tokens. These are easy and will just be transferred.
      // 2. Look at the fractional part of the value:
      //   a) If it causes the sender to lose a whole token that was represented by an NFT due to a
      //      fractional part being transferred, withdraw and store an additional NFT from the sender.
      //   b) If it causes the receiver to gain a whole new token that should be represented by an NFT
      //      due to receiving a fractional part that completes a whole token, retrieve or mint an NFT to the recevier.

      // Whole tokens worth of ERC-20s get transferred as ERC-721s without any burning/minting.
      uint256 nftsToTransfer = value_ / units;
      for (uint256 i = 0; i < nftsToTransfer;) {
        // Pop from sender's ERC-721 stack and transfer them (LIFO)
        uint256 indexOfLastToken = _owned[from_].length - 1;
        uint256 tokenId = _owned[from_][indexOfLastToken];
        _transferERC721(from_, to_, tokenId);
        unchecked {
          i++;
        }
      }

      // If the sender's transaction changes their holding from a fractional to a non-fractional
      // amount (or vice versa), adjust ERC-721s.
      //
      // Check if the send causes the sender to lose a whole token that was represented by an ERC-721
      // due to a fractional part being transferred.
      //
      // To check this, look if subtracting the fractional amount from the balance causes the balance to
      // drop below the original balance % units, which represents the number of whole tokens they started with.
      uint256 fractionalAmount = value_ % units;

      if (
        (erc20BalanceOfSenderBefore - fractionalAmount) / units <
        (erc20BalanceOfSenderBefore / units)
      ) {
        _withdrawAndStoreERC721(from_);
      }

      // Check if the receive causes the receiver to gain a whole new token that should be represented
      // by an NFT due to receiving a fractional part that completes a whole token.
      if (
        (erc20BalanceOfReceiverBefore + fractionalAmount) / units >
        (erc20BalanceOfReceiverBefore / units)
      ) {
        _retrieveOrMintERC721(to_);
      }
    }

    return true;
  }

  /// @notice Internal function for ERC20 minting
  /// @dev This function will allow minting of new ERC20s.
  ///      If mintCorrespondingERC721s_ is true, and the recipient is not ERC-721 exempt, it will also mint the corresponding ERC721s.
  function _mintERC20(
    address to_,
    uint256 value_,
    bool mintCorrespondingERC721s_
  ) internal virtual {
    /// You cannot mint to the zero address (you can't mint and immediately burn in the same transfer).
    if (to_ == address(0)) {
      revert InvalidRecipient();
    }

    _transferERC20(address(0), to_, value_);

    // If mintCorrespondingERC721s_ is true, and the recipient is not ERC-721 transfer exempt, mint the corresponding ERC721s.
    if (mintCorrespondingERC721s_ && !erc721TransferExempt[to_]) {
      uint256 nftsToRetrieveOrMint = value_ / units;
      for (uint256 i = 0; i < nftsToRetrieveOrMint;) {
        // ERC-721 exemptions handled above.
        _retrieveOrMintERC721(to_);
        unchecked {
          i++;
        }
      }
    }
  }

  /// @notice Internal function for ERC-721 minting and retrieval from the bank.
  /// @dev This function will allow minting of new ERC-721s up to the total fractional supply. It will
  ///      first try to pull from the bank, and if the bank is empty, it will mint a new token.
  /// Does not handle ERC-721 exemptions.
  function _retrieveOrMintERC721(address to_) internal virtual {
    if (to_ == address(0)) {
      revert InvalidRecipient();
    }

    uint256 id;

    if (!DoubleEndedQueue.empty(_storedERC721Ids)) {
      // If there are any tokens in the bank, use those first.
      // Pop off the end of the queue (FIFO).
      id = _storedERC721Ids.popBack();
    } else {
      // Otherwise, mint a new token, should not be able to go over the total fractional supply.
      _minted++;
      id = _minted;
    }

    address erc721Owner = _getOwnerOf(id);

    // The token should not already belong to anyone besides 0x0 or this contract.
    // If it does, something is wrong, as this should never happen.
    if (erc721Owner != address(0)) {
      revert AlreadyExists();
    }

    // Transfer the token to the recipient, either transferring from the contract's bank or minting.
    // Does not handle ERC-721 exemptions.
    _transferERC721(erc721Owner, to_, id);
  }

  /// @notice Internal function for ERC-721 deposits to bank (this contract).
  /// @dev This function will allow depositing of ERC-721s to the bank, which can be retrieved by future minters.
  // Does not handle ERC-721 exemptions.
  function _withdrawAndStoreERC721(address from_) internal virtual {
    if (from_ == address(0)) {
      revert InvalidSender();
    }

    // Retrieve the latest token added to the owner's stack (LIFO).
    uint256 id = _owned[from_][_owned[from_].length - 1];

    // Transfer the token to the contract.
    // Does not handle ERC-721 exemptions.
    _transferERC721(from_, address(0), id);

    // Record the token in the contract's bank queue.
    _storedERC721Ids.pushFront(id);
  }

  /// @notice Initialization function to set pairs / etc, saving gas by avoiding mint / burn on unnecessary targets
  function _setERC721TransferExempt(address target_, bool state_) internal virtual {
    // If the target has at least 1 full ERC-20 token, they should not be removed from the exempt list
    // because if they were and then they attempted to transfer, it would revert as they would not
    // necessarily have ehough ERC-721s to bank.
    if (erc20BalanceOf(target_) >= units && !state_) {
      revert CannotRemoveFromERC721TransferExempt();
    }
    erc721TransferExempt[target_] = state_;
  }

  function _getOwnerOf(
    uint256 id_
  ) internal view virtual returns (address ownerOf_) {
    uint256 data = _ownedData[id_];

    assembly {
      ownerOf_ := and(data, _BITMASK_ADDRESS)
    }
  }

  function _setOwnerOf(uint256 id_, address owner_) internal virtual {
    uint256 data = _ownedData[id_];

    assembly {
      data := add(
        and(data, _BITMASK_OWNED_INDEX),
        and(owner_, _BITMASK_ADDRESS)
      )
    }

    _ownedData[id_] = data;
  }

  function _getOwnedIndex(
    uint256 id_
  ) internal view virtual returns (uint256 ownedIndex_) {
    uint256 data = _ownedData[id_];

    assembly {
      ownedIndex_ := shr(160, data)
    }
  }

  function _setOwnedIndex(uint256 id_, uint256 index_) internal virtual {
    uint256 data = _ownedData[id_];

    if (index_ > _BITMASK_OWNED_INDEX >> 160) {
      revert OwnedIndexOverflow();
    }

    assembly {
      data := add(
        and(data, _BITMASK_ADDRESS),
        and(shl(160, index_), _BITMASK_OWNED_INDEX)
      )
    }

    _ownedData[id_] = data;
  }
}
```


# Dwarf Dash Example

<figure><img src="/files/FOL8TlP6cZ61XfPiSSIk" alt=""><figcaption></figcaption></figure>

Dwarf Dash is a play-to-earn runner that was designed to showcase the power of the Fiefdom network and its capacity to support on-chain gaming.

Dwarf Dash is currently live on the Fiefdom Playground testnet, where each game played can be logged instantly via smart contract on the network.

Play now: <https://dwarfdash.fief.gg/>


# FIEF <> WFIEF Wrapper

Convert between the network token FIEF and an ERC-20 version that can be used inside of Fiefdom smart contracts.

Coming Soon to Fiefdom Playground.


# FiefSwap

Robust trading platform for both fungible and non-fungible tokens. Includes a traditional DEX, NFT AMM, and more.

Coming Soon to Fiefdom Playground.


# Troves

<figure><img src="/files/C0kZJQT8AOSGiaQ6jadt" alt=""><figcaption></figcaption></figure>

### Visit Site: <https://troves.fiefdom.gg/>

***

What are Troves?

Troves are custom designed token indices that provide specialized insights into token categories.

#### What pain point does Troves solve?

Troves were born out of a frustration with current analytics platforms that design category trackers with limited granularity. This is compounded by the issue that most platforms build categories using requests from projects that are often not fully accurate.

#### Are Troves Tradable?

No, not currently. Troves are meant to provide curated information; however, tokenization via Fief Protocol or independent third party on the Fiefdom network is a potential path. This would require improvements to data oracles, among other considerations.

If you are a developer and want to contribute to the Troves project, or build your own app on top of it, reach out to the Fief team.


