The Harberger Pixel Map
One of us also read Radical Markets, talked about Harberger Taxes on a recent panel in HGK, and wanted to try building a demonstration of its use case.
Why this project matters
Harberger Taxes are one way to protect the commons and increase the general welfare of society.
This project demonstrates a functional use of a Harberger Tax on Ethereum to manage an array of limited assets. This implementation closely resembles - and could be reapplied to - real estate/city planning.
It could be extended to other ecosystems, as well. For example, the 2018 NIFTY Ethereum Hackathon Winner currently doesn't use a Harberger Tax, but could (and probably should) as a method to achieve their mission to "protect, preserve, and restore our world’s endangered wildlife and natural zones."
What it does
The Harberger Pixel Map allows users to set pixels on a communal canvas, similar to /r/place.
Users collectively discover the fair utility value of each pixel.
Values are taxed and fund the 'commons'. We've tentatively selected The Fellowship of Ethereum Magicians as the first commons project to receive funds.
Attributes & rules
- Harberger Pixel Map is a 1,000 x 1,000 pixel map
- Each pixel can be "purchased" by anyone at anytime
- Each person sets a price (tax) they're willing to pay per pixel
- Taxes are perpetual and must be repaid every 'n' blocks (variable)
- If someone is willing to pay more per pixel than the current "owner", they can "purchase" the pixel and select its new color
- If taxes aren't paid by the owner after 'n' blocks, the price drops to the minBid amount (price floor) & someone can "purchase" it for a lower price (and begin paying their taxes on it accordingly)
- All taxes are paid to a commons
How we built it
- We found an open source, web based clone of Microsoft Paint
- We wrote the Harberger Tax contract for how the economics should work (for two bid operations: per pixel & per set of pixels)
- We distilled the relevant information to an event that the contract would emit
- We created backend functions to watch the events and modify the Pixel Map in the publicly available Paint Clone
- We installed web3 hooks in the Paint Clone as the user interface to compile your transaction data after you draw and color the selected pixels you wish to "purchase"
- We made it compatible with MetaMask
Challenges we ran into
- It was a challenge to design a contract that allowed a person to bid on multiple pixels in a single transaction due to its relatively high cost and strict require arguments
- A better solution than a default minBid price floor would be to instead have a reverse dutch auction or DEX with stop limits per pixel, but it was out of the scope of this weekend to BUIDL such a mechanism
- Simon suggested that the taxes could support a communal bonding curve. However, we struggled to design a justifiable bonding curve (which Simon also identified as a challenge). Instead we set the 'commons' address to the Fellowship of Ethereum Magicians. This can be updated later.
Accomplishments that we're proud of
- We're proud of the fact that we took a highly abstract, inaccessible concept, like a Harberger Tax, and were able to distill it into a game that most people would understand, and even recognize if they're already familiar with /r/place.
- We're proud that although it might seem like the obvious solution, we independently recognized that using ERC721 as the deed per pixel would actually be quite inefficient and the wrong instrument altogether. After designing our own solution, we later corroborated this with some research done by Todd Proebsting.
What we learned
Solidity, how to watch for emitted events, how to run ganache
How to test contract functions efficiently, how to optimize contracts for gas consumption, how to torubleshoot issues as they came up (by getting a deeper familiarity with Ethereum)
How to use Git from the command line, how to debug solidity with Truffle, that there's such a thing as an experimental ABI encoder
What's next for Harberger Pixel Map
- We will add a pixel price heat map so a user can visualize the current cost of all the pixels
- We will add an improved price setting UX so users can more easily set individual pixels prior to submitting a bulk-pixel transaction
- We will replace the minBid price floor with a reverse dutch auction or DEX
- We created a Harberger Tax model that is specifically designed for the Pixel Map. However, what we would prefer to do is create a standardized contract interface that any project could use if they wanted to implement a Harberger Tax into their project to support a "Commons" address
- We designed a exit address for the Harberger Pixel Map that deposits all taxes paid to a "commons" address. For starters, we selected the Ethereum Magicians. However, we will move to build a tokenized bonding curve to decentralize the curation of "The Commons."
From PoC to MVP
It should be noted that in the pursuit of completing a PoC for this weekend our implementation of a Harberger Tax is in some respects currently incomplete. It is designed to simulate many aspects of a Harberger Tax model, such as:
- User sets the price
- User makes perpetual payments (pays taxes)
- Anyone can buy the pixel at any time
- A new buyer can set the new color
- If a user fails to pay taxes, their pixel value is reduced to a minimum for anyone to buy
- Taxes are distributed to a commons
However, to bring this PoC to an MVP, which demonstrates all possible operations within an unbounded Hargerber Tax, we will need to make sure:
- Users actually "own" their pixel // Currently, they only pay taxes on the right to change the color once
- Users set a pixel purchase price from which the tax is calculated // Currently, users are just setting their own tax rate, paying it, and skipping the pixel purchase (this functions more like the user is paying rent - at a rate they set - w/o equity)
- Tax payments are fluid and can be measured down to the day, hour, or even block // Currently: while pixels can be purchased anytime, the tax rates are capped to a fixed time allocation (temporarily set to 1 month)