On-chain philanthropy
Cryptocurrencies are programmable money: they allow specifying rules and conditions around how funds are transmitted directly in the monetary system itself. Instead of relying on contracts and attorneys, blockchains can encode policies that were previously written in legalese. For example one can earmark a pool of funds to be locked until at a certain date, require two signatures to withdraw and only sent to a specific recipient (The last one is only possible with Ethereum and similarly expressive blockchains. Such covenants are not expressible in the rudimentary scripting language of Bitcoin yet, although extensions are known that would make it possible.) While the recent rise of ransomware and incidents such as the Colonial Pipeline closure have put the spotlight on corrosive uses of cryptocurrency— irreversible payments for criminal activity— the same capabilities can also be put to more beneficial uses. Here we explore an example of implementing a philanthropic campaign using Ethereum or Bitcoin.
Quick primer on matching gifts. “Gift” in this context refers to donations made to a charitable organization. A matching campaign is a commitment by an entity to make additional contributions using its own funds, in some proportion to every donation received by the nonprofit, subject to some limits and qualifications. For example it is very common for large companies in America to offer 1:1 matching for donations to 501c3 organizations. (510c3 is a reference to the section of US tax code granting special recognition to nonprofits that meet specific criteria, and allowing their donors to receive favorable tax treatment.) As a data-point: in the early 2000s MSFT offered dollar-for-dollar matching up to $12,000 per year per full-time employee.2 Such corporate matching policies are continuous. Other campaigns may be one time. For example a philanthropist may issue a one-time challenge to the leadership of a nonprofit organization, offering to double the impact of any funds received during a specific time window.
Hard-coded, immutable generosity
Blockchains are good at codifying this type of conditional logic— “I will contribute when someone else does.” To better illustrate how such commitments can be implemented, we will consider two different blockchains. First up is Ethereum, which is the easy case thanks to its Turing-complete programming language. Second one is Bitcoin where the implementation gets tricky and somewhat kludgy.
In both cases there are some simplifying assumptions to make the problem more tractable for a blog post:
- This is a one-time campaign focused on one specific charitable organization. That side-steps certain problems, including the reverse-mapping blockchain addresses to 501c3 organization and trying to decide whether a given transfer qualifies for the campaign.
- The nonprofit in question has a well-known blockchain address for receiving donations. This applies to more and more organizations as they partner with intermediaries for accepting cryptocurrency donations or directly publish such addresses on their website. For example Heifer International advertises addresses for Bitcoin, Ethereum, Litecoin, Stellar and Ripple.
- There is a cap on total funds available for matching but no per-donor quotas. Otherwise we would have a difficult problem trying to decide when a given participant has reached their quota. It is trivial to create an unbounded number of blockchain addresses, and there is no easy way to infer whether two seemingly independent donations originating from different addresses were in fact associated with the same entity.
Easy case: Ethereum
Recall that the objective is a matching campaign enforced by blockchain rules. Specifically we want to move beyond solutions that involve continuous monitoring and active intervention. For example, an outside observer could watch for all transactions to the nonprofit donation address and publish additional transactions of equivalent amount corresponding to each one. That would be a direct translation of how matching campaigns work off-chain: the donor makes a contribution and then proves to the campaign sponsor that they made a donation of so many dollars, usually by means of a receipt issued by the nonprofit. After verifying the evidence, the sponsor writes out a check of their own to the same organization.
While there is nothing wrong with carrying the same arrangement over into a blockchain, we can do better: in particular, the sponsor can make a commitment once such that they have no way to renege on the promise, neither by outright defection or inadvertent failure to keep up their end of the bargain when it comes to writing checks in a timely manner. With Ethereum, the sponsor can create a smart-contract once and fund it with the maximum amount they are willing to watch. Once the contract is launched, the remainder of the campaign runs on auto-pilot: immutable contract logic enforced by blockchain rules sees to it that every qualifying donation is properly matched.
This is hardly a novel observation; in fact there is at least one example of such a contract announced on Reddit and launched on-chain. Unfortunately the campaign does not seem to have gotten much traction since launch and not a single Wei has been passed over to the intended nonprofit recipient. Part of the problem is a design choice in the contract to set an all-or-nothing threshold. Similar to crowd-funding campaigns such as KickStarter, matching is conditioned on a threshold of donations being reached, after which the entire amount is matched. Here is an alternative design premised on processing and matching donations immediately as they arrive:
- As before, the sponsor launches a smart-contract on Ethereum and funds it with the maximum amount of ETH pledged. It could be also be funded by an ERC-20 token or stablecoin such as GUSD to avoid price volatility associated with cryptocurrencies.
- Donors interested in taking advantage of the campaign send funds to the contract, not directly to the charitable organization. (This raises an important trust question that will be addressed later: how can they be confident the contract is going to work as promised instead of embezzling the funds?)
- When incoming funds are received, either the “receive” or “fallback” function for the contract is invoked. That code will inspect the incoming amount and use one of the send/transfer/call functions to transfer twice the amount to the well-known address of the nonprofit. Note that each donation is processed individually and delivered immediately to the recipient. There is no waiting on fulfillment of some global conditions around total funds raised.
- There is one edge case to address in processing incoming funds: what if the contract does not have sufficient funds left to process the full amount? The naive logic sketched above will fail and depending on the attempted transfer mechanism, cause the entire transaction to be reverted, resulting in no changes other than wasted gas. An alternative is to match up to maximum amount possible and still forward the entire donation. But one could argue that fails on fairness criteria: the sender was promised one-for-one amplification on their donation. Perhaps they would have redirected their funds elsewhere had they known 100% match was no longer available. (This can happen due to contention between multiple donations, through no fault of either party. Suppose the contract has 3 ETH left for matching, and two people send 2 ETH contributions in the same Ethereum block. Depending on the order those transactions are mined into a block, one will be fully matched while the other will run into this edge-case.)
A better solution is to match contributions up to the remaining amount in the contract and return any unmatched portion back to the caller to reconsider their options. They can always resend funds directly to the nonprofit with the understanding that no match will be forthcoming, or they can wait for another opportunity. This means that once the contract runs out of funds, all incoming donations bounce back to senders. (Of course the sponsor can always resuscitate the campaign with a fresh injection of capital, to accommodate higher than expected demand. But the arrival of such additional funding can not be enforced by the contract.) - Finally the smart-contract can also impose a deadline such as 1 month for the campaign to avoid sponsor funds being locked up indefinitely. The end-date for the campaign must be specified when the contract is created and remain immutable, to prevent the sponsor from bailing out earlier. Once the deadline has elapsed, the sponsor can call a function on the contract to withdraw remaining funds. After that point, all donation attempts will bounce. This is preferable to simply destroying the contract using the Ethereum self-destruct operation; if the contract were to disappear altogether, incoming donations would be black-holed and irretrievably lost.
The next post in this series will tackle the problem of establishing trust in such a smart-contract and the challenges of replicating the same arrangement using more primitive bitcoin scripts.
[continued – part II]
CP
[2] That may appear extremely generous or fiscally irresponsible, depending on your perspective: a public company with fifty-thousand blue-badge employees effectively signed up a six-billion dollar liability in the worst-case scenario. Given human nature and lackluster reputation of tech community for giving, actual expenditures never amounted to more than a small fraction of this upper bound— an ironic commentary for a company founded by the preeminent philanthropist of our generation.