Yos Riady software craftsman 🌱

Harberger Taxes on Ethereum

Harberger Taxes

Cryptoeconomics utilizes cryptography and economic incentives in designing decentralized protocols and applications. We write smart contracts that define the rules of an economic game, a game which incentivize rational actors to behave in desirable ways. This idea is similar to mechanism design in economics. Decentralized protocols lets us define trustworthy rules - inscribed on the blockchain - that we can all understand upfront and aligns individual incentives to achieve a common goal.

Harberger Taxes is an economic abstraction (highlighted in the book Radical Markets) in which asset owners self-assesses the value of their asset and pay a tax rate of X% of that value per year. Whatever value they specify for their asset, the owner has to be willing to sell it to anyone at that price.

Blockchains offer a testing ground for experimenting with economic abstractions such as Harberger Taxes, where rules can be enforced using only smart contracts. Harberger Taxes promises to democratize the control of assets by striking a balance between private and commons ownership. While I’m skeptical that this new form of taxation can be easily applied to the real world, I think it’s worth exploring its use in greenfield domains such as decentralized communities.

In this article, let’s look at Harberger Taxes and how we can use it in decentralized applications.

Harberger Taxes

Every citizen and corporation would self-assess the value of assets they possess, pay a roughly 7% tax on these values, and is required to sell the assets to anyone willing to purchase them at this self-assessed price.

Harberger Taxes consists of two main ideas:

  • Asset owners self-assess the value of their asset, and pay taxes on that self-assessed price.
  • Anyone, at any time, can purchase an asset from you at that self-assessed price, thereby taking ownership of the asset. The new owner then sets their own price.

An asset owner is incentivized to set a low price to minimize the amount taxes they have to pay. At the same time, the asset owner wants to set a price high enough to discourage someone else from buying it away easily.

Asset owners can’t set impossibly high prices nor refuse valid offers, allowing the market to allocate assets more efficiently. Thus, the incentive is for owners to price an asset at the value they are willing to pay to keep it.

Contract Code

Harberger taxes are proportional to an asset’s price and the duration that the asset is held. We’ll write a smart contract that collect taxes on demand from prepaid balances maintained by asset holders.

Taxed Assets

First, we define a marketplace of assets that users will own and trade with each other. Each Asset has a bytes32 assetId, an owner address if any, and a price.

contract Marketplace {
  struct Asset {
      address owner;
      uint price;
  }

  mapping(bytes32 => Asset) public assets;

  // Returns the price of an asset
  function getPrice(bytes32 assetId) public view returns (uint) {
    Asset storage a = assets[assetId];
    return a.price;
  }

  // New asset creation and buy functions omitted for clarity
  function addAsset(bytes32 assetId, uint price) public;
  function buyAsset(bytes32 assetId) public payable;
}

The price of an asset determines the amount of tax the owner will have to pay.

Tax Balances

Taxes are collected by a separate TaxCollector contract:

contract TaxCollector {
    struct TaxBalance { // Prepaid asset tax information
      uint balance; // Amount in ether
      uint lastCollectedAt; // Timestamp of last collection date
    }
    mapping(bytes32 => TaxBalance) public taxBalances;

    // Address where collected taxes are sent to
    address public taxRecipient;

    // Daily tax rate (there are no floats in solidity)
    uint32 public taxNumerator;
    uint32 public taxDenominator;

    constructor(
        address _taxRecipient,
        uint32 _taxNumerator,
        uint32 _taxDenominator
    ) public {
        taxRecipient = _taxRecipient;
        taxNumerator = _taxNumerator;
        taxDenominator = _taxDenominator;
    }
}

This TaxCollector contract maintains balances of prepaid tax payments for each Asset in the marketplace.

Asset owners calls deposit() to top up their tax payment balance with Ether:

// Asset owners calls this with Ether to deposit tax payments for a particular asset
function deposit(bytes32 assetId) public payable {
    taxBalances[assetId].balance += msg.value;
}

// Withdraw tax payments, omitted for simplicity
function withdraw(bytes32 assetId, uint256 amount) public;

Note that whenever an Asset is created by the Marketplace contract, a corresponding TaxBalance should be created for that asset, with zero balance and lastCollectedAt set to the asset creation date. This keeps track of tax payments of each asset. For simplicity, this step is omitted from the sample code.

Tax Collection

We will collect() taxes in batches on demand. If during tax collection the asset owner has insufficient advance tax balance for the tax period between the last collection date and the present time, the asset owner will have failed to pay their tax. It’s the responsibility of the asset owner to ensure that they have set aside enough tax payments for their asset.

Let’s first define a function for calculating the taxes owed for an asset:

Marketplace public marketplace; // Address of asset marketplace contract

function taxOwed(bytes32 assetId) public view returns (uint256) {
    uint assetPrice = marketplace.getPrice(assetId); // External contract call

    return assetPrice * (now - a.lastCollectedAt) * taxNumerator
        / taxDenominator / 1 days;
}

Here’s our tax collect() function:

function collect(bytes32 assetId) public onlyCollector returns (bool) {
    TaxBalance storage taxBalance = taxBalances[assetId];
    uint taxes = taxOwed(assetId);

    if (taxes <= taxBalance.balance) {
        taxBalance.lastCollectedAt = now;
        taxBalance.balance -= taxes;
        taxRecipient.transfer(taxes) += tax;
        return true;
    } else {
        taxBalance.lastCollectedAt = now;
        taxBalance.balance = 0;
        foreclose(bytes32 assetId); // foreclose asset
        return false;
    }
}

In the above code:

  • First, we retrieve the asset’s taxBalance by assetId.
  • We check if the asset owner has deposited sufficient advance taxOwed() for the asset.
  • If there is sufficient balance, we transfer the taxes owed to the taxRecipient address and update the asset’s advance tax balance and lastCollectedAt. The asset owner has successfully paid their Harberger Tax and continues to own it.
  • If there is insufficient balance, we foreclose the asset.

Note that the above function has an onlyCollector modifier that makes collect() only be callable only by whitelisted tax collector addresses.

Foreclosure

Failure to pay tax will result in an asset’s foreclosure. A foreclosed Asset has owner set to address(0) which means it is open for auction.

function foreclose(bytes32 assetId) internal {
    Asset storage a = assets[assetId];
    a.owner = address(0); // Asset is now open for auction
}

The sample code is simplified for clarity, but you can fill in the rest. The basic harberger tax calculation, deposits, and collection is implemented.

Use Cases

Let’s look at how Harberger Taxes can be used in real-life applications.

Continuous Auctions

With Harberger taxes, users will know what the going price is for any asset. This results in liquid markets where anyone can make an offer even if the owner is not actively selling. For example, NFT marketplaces such as Decentraland, OpenSea, and Harberger Ads can list digital goods that users can browse and purchase at any time.

Marketplace actors can not only earn from the transaction fees or spread of the exchange, but also from the taxes.

Arts Funding

In recent years, we’ve seen the proliferation of new forms of art funding from subscription patronage to crowdfunding works together, through the likes of Patreon and Kickstarter.

Likewise, the blockchain offers a platform to re-imagine how we fund and support creators and artists.

For example, Harberger taxes can be used to sell limited sponsorship seats which carry special privileges to fans. This is similar to a pay what you want model of self-assessed price discrimination.

Rare Patrons offers a radical market approach for fans to participate in supporting their favourite creators.

Given these concepts/ideas, I want to propose a variant on the usage of radical markets that combines collectibles with such funding schemes. It works as follows:

  • Every musician has a single patron seat.
  • Anyone can buy the patron seat (to become the singular patron & gain the privilege of being the patron).
  • Upon buying it they have to self-assess the value of this seat (being the patron).
  • During the tenure of being a patron, this patron has to pay a > percentage fee (say 5%) of the self-assessed seat value per year as their patronage to the musician.
  • At any point in time, someone else can buy this patron seat at this self-assessed value, changing ownership.
  • Upon being “dethroned” as the rare patron for a specific musician, that patron earns a collectible “Post-Patron” badge, signifying that they were a patron at a certain point in history. They just join the “Patrons Club”.
  • They can choose to sell this collectible if they no longer want it.

~ Simon de la Rouviere, Rare Patrons

These ideas offer new ways of funding for artists and creators.

Intellectual Property

Harberger Taxes can also be applied to intellectual property and open source. When a patent requires the active payment of a nonzero amount of tax, patent trolls have less of an incentive to ‘squat’ useless works that have no value beyond being useful in a suit in the future. It also makes the IP market much more liquid.

Bonded Communities

Cryptocommunities can use Harberger taxes to strike a balance between private and commons ownership. Given a community with scarce assets, how can we allocate it efficiently to productive members of the community?

Exclusive ownership of a community asset can be taxed, ensuring that those that value it the most have access. Failure to pay the tax will trigger a forced auction of the asset that all community members can participate in.

In addition, communities can direct how taxes are utilized. For example, taxes in a closed-loop community can go to a curved bond reserve via sponsored burning, increasing community members’ token values. This tax reserve can also be redistributed to the community as a universal basic income, or go to a community fund that is governed by a DAO.

Harberger taxes and other cryptoeconomic primitives offers us new ways for individuals to mass coordinate at scale in a decentralized network without centralized authority.

Summary

In this article, we’ve looked at Harberger Taxes and how we can use it in decentralized applications.

While it may be difficult to implement in the real world, the blockchain offers a testing ground for novel, experimental ways of coordinating individuals within a society.

Author

Yos is a software craftsman based in Singapore.

📬 Subscribe to my newsletter

Get notified of my latest articles by providing your email below.


Going Serverless book

Interested to find out more about serverless? Going Serverless teaches you how to build scalable applications with the Serverless framework and AWS Lambda. You'll learn how to design, develop, test, deploy, and secure Serverless applications from planning to production.

Learn More →