> ## Documentation Index
> Fetch the complete documentation index at: https://base-a060aa97-eb-mini-app-ia-overhaul.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Minimal Tokens Exercise

> Exercise - Create your own token!

Create a contract that adheres to the following specifications.

***

## Contract

Create a contract called `UnburnableToken`. Add the following in storage:

* A public mapping called `balances` to store how many tokens are owned by each address
* A `public uint` to hold `totalSupply`
* A `public uint` to hold `totalClaimed`
* Other variables as necessary to complete the task

Add the following functions.

### Constructor

Add a constructor that sets the total supply of tokens to 100,000,000.

### Claim

Add a `public` function called `claim`. When called, so long as a number of tokens equalling the `totalSupply` have not yet been distributed, any wallet *that has not made a claim previously* should be able to claim 1000 tokens. If a wallet tries to claim a second time, it should revert with `TokensClaimed`.

The `totalClaimed` should be incremented by the claim amount.

Once all tokens have been claimed, this function should revert with the error `AllTokensClaimed`. (We won't be able to test this, but you'll know if it's there!)

### Safe Transfer

Implement a `public` function called `safeTransfer` that accepts an address `_to` and an `_amount`. It should transfer tokens from the sender to the `_to` address, **only if**:

* That address is not the zero address
* That address has a balance of greater than zero Base Sepolia Eth

A failure of either of these checks should result in a revert with an `UnsafeTransfer` error, containing the address.

***

### Submit your Contract and Earn an NFT Badge! (BETA)

<Note>
  #### Hey, where'd my NFT go!?

  [Testnets](/learn/deployment-to-testnet/test-networks) are not permanent! Base Goerli [will soon be sunset](https://base.mirror.xyz/kkz1-KFdUwl0n23PdyBRtnFewvO48_m-fZNzPMJehM4), in favor of Base Sepolia.

  As these are separate networks with separate data, your NFTs **will not** transfer over.

  **Don't worry!** We've captured the addresses of all NFT owners on Base Goerli and will include them when we release the mechanism to transfer these NFTs to mainnet later this year! You can also redeploy on Sepolia and resubmit if you'd like!
</Note>

<Warning>
  The contract specification contains actions that can only be performed once by a given address. As a result, the unit tests for a passing contract will only be successful the **first** time you test.

  **You may need to submit a fresh deployment to pass**
</Warning>

{/* <CafeUnitTest nftNum={13}/> */}

<iframe src="https://684b5e62b1ff46bc5bf83966-aijszlfakk.chromatic.com/iframe.html?args=&id=components-cafeunittest--thirteen&viewMode=story&dark=true&hero=true" width="100%" height="auto" />
