Experiment: Auto-Rotating NFT | Pooly “Magic” PFP

The Pooly “Magic” PFP bounty is an experiment to test auto-rotating NFT images using completely on-chain logic. It should be possible to automatically rotate to a different Artist submission after X amount of time has passed.

What: Auto-rotating profile picture

Why: Showcase community artists

How: On-chain ERC721 metadata generation

Example: Every 7 days a new PFP submission will be used with no additional on-chain transaction.



The Auto-Rotating NFT experiment will test rotating on-chain NFT metadata descriptors.


Highlight Artist in the Friends of Pooly community.

Experiment with the intersection of community Art and NFTs.

The Friends of Pooly recently had a PFP contest. Several amazing artists contributed. It would be great to showcase these Artist.

In short, the experiment is perfect for any intermediate solidity developers who want to level-up their skills and positively contribute to the Friends of Pooly community.


NFTs can generate item metadata completely on-chain; compared to the more commonly IPFS or centralized server approach to store the information.

By generating the NFT metadata on-chain it’s possible to rotate the image using blocknumber and/or timestamps.

Getting Involved

Experiments are an opportunity for the Friends of Pooly community to get involved, learn and have some fun.

Step 1: Join the Discord Step 2: Find the #birb-headquarters channel Step 3: Introduce Yourself to friends of Pooly

Contributors will be highlighted across the Friends of Pooly communication channels.

App Design Example

The app design below is a simple sketch of what the rotating UI could look like. Coding the user interface is not required right now, but is included as an example for what it might look like in the future.

Code Example:

The code snippets below provide a rough outline for having automatically rotating images in an NFT.

function tokenURI(uint256 tokenId) public view override returns (string memory) {
  return constructTokenURI(tokenId);

function constructTokenURI(uint256 _tokenId) public view returns (string memory) {
  string memory name = string(abi.encodePacked("Pooly Rotating"));
  string memory description = string(abi.encodePacked("#", _tokenId.toString()));

   * The generateImage function could return a different image URI depending
   * on the tokenId and blocknumber. A timestamp could also work.
  string memory image = generateImage(_tokenId, block.number);

              '", "description":"',
              '", "image": "',

function generateImage(uint256 _tokenId, uint256 blockNumber) public view returns (string memory) {}


Install the repo and dependencies by running: yarn


These contracts can be deployed to a network by running: yarn deploy <networkName>


These contracts can be verified on Etherscan, or an Etherscan clone, for example (Polygonscan) by running: yarn etherscan-verify <ethereum network name> or yarn etherscan-verify-polygon matic


Run the unit tests locally with: yarn test


Generate the test coverage report with: yarn coverage


View Github