Climatecoin

MIT's Center for Collective Intelligence has a project called ClimateColab, which attempts to crowdsource solutions to climate change via an annual contest. I just made finalist with a proposal I call Climatecoin.

Climate change is a public goods problem, which is generally thought near-impossible to solve on a purely voluntary basis. But here's another public good, which we do provide at large scale on a purely voluntary basis: cryptocurrency consensus. Satoshi figured out he could pay for all the required work by inflating the money supply.

So my basic idea is to make a currency on Ethereum which is "mined" by offsetting carbon. There are already organizations that let you pay for voluntary carbon offsets, with third-party auditing and certification. We simply get them to publish addresses for ether donations, and mint new coins to anyone who donates ether to the offsetters via our contract. Then, like any coin, we encourage merchants to accept them as payment, starting with the sort of merchants interested in showing off their "green" credentials.

The offsetters set an ether price per ton of carbon, and we mint a certain number of coins per ton. We also give the donor a certain number of votes per ton, and store the total number of actual tons carbon the donor has offset. (The donor can use the tonnage number for "bragging rights," which in itself helps a bit for solving public goods problems.)

function mint(address offsetter) {
    Offsetter off = offsetters[offsetter];
    uint tons = msg.value / off.price;
    if (msg.value == 0
       || off.active != true
       || off.donated + tons >= off.max) return;

    uint coins = tons * coinsPerTon();
    uint votes = tons * votesPerTon();
    users[msg.sender].balance += coins;
    users[msg.sender].tons += tons;
    users[msg.sender].voteweight += votes;
    totalvotes += votes;
    totaltons += tons;
    totalcoins += coins;
    if (!offsetter.call.value(msg.value)()) throw;
}

Since the sooner you reduce carbon, the more effective it is, we have the coins per ton decrease over time. This also means early donors get more reward, which is good for speculative value. And exponential decay seems appropriate, but I don't think it has to be exact; one way to approximate it with cheap gas costs is an linear interpolation between each halving of the reward. Something like this:

//given current multipliers, get the next multipliers
function nextCoinmult() returns(uint) {
    if (coinmult == 1) {
        return coinmult;
    } else {
        return coinmult / 2;
    }
}

//update our multpliers if it's past time to do so
function updateMult() {
    if (block.timestamp < lastMultUpdateTimestamp + 365 days
        || coinmult == 1) return;

    lastMultUpdateTimestamp = block.timestamp;
    coinmult = nextCoinmult();
}

//get coins per ton by interpolating between current multiplier and next 
function coinsPerTon() returns (uint) {
    //linear change, prefer exponential
    //return 1000 - (1000 * (totaltons/maxtons));

    updateMult();
    uint currmult = coinmult;
    uint nextmult = nextCoinmult();
    if (nextmult != coinmult) {
        uint oneday = 1 days;
        uint numdays = (block.timestamp - lastMultUpdateTimestamp) / oneday;
        uint changePerDay = (coinmult - nextmult) / 365;
        currmult = coinmult - (numdays * changePerDay);
    }
    return currmult;
}

A tricky part is maintaining the list of approved offsetters. A central adminstrator could do it, but that'd require a lot of trust; a corrupt adminstrator could approve his own address and mint climatecoins for free. A set of admins in a multisig, if they're well-trusted climate experts, might be viable.

But can we decentralize the decision? This is a tricky problem; it's similar to the problem of making a friendly AI with a stable goal system; i.e. if we make a superintelligent AI and give it a value system that makes it want to keep humans happy, but it's able to modify its own value system, how do we know it will keep placing a high value on human happiness?

One answer is just to observe that if you were able to modify your own brain to turn yourself into a serial killer, you probably wouldn't do that, because under your current value system you don't like the idea of being a serial killer. Similarly, in Climatecoin if we start with a set of voters who place a high value on a healthy climate, then we can have some confidence that they'll keep voting accordingly.

To seed our climate-friendly voters we can use admins at first, who select reputable offsetters, and award votes based on the number of actual tons carbon people pay to offset. The voters presumably include lots of people who care enough about the climate to bother offsetting (although there's also some purely speculative interest). Once there's enough accumulated tonnage to prevent cheap attack, turn it over to the voters.

It might be a good idea to weight recent offsets more heavily. An easy method is to simply increase votesPerTon over time, the same way we decrease coinsPerTon. Unlike coins, the votes are not transferable; decisions are made by people who actually offset carbon. With luck, though our collective intelligence will have the ability to change its value system, it won't want to; it'll be like a stable-value FriendlyAI.

In the following code, an offsetter's status can change when a quorum votes with a 2/3 majority.

function passesQuorum(address offsetter) returns (bool) {
    uint quorum = totalvotes / 10;
    uint votes = totalVotesFor[offsetter] + totalVotesAgainst[offsetter];
    return votes > quorum;
}

//to change offsetter status, must meet quorum and win by 66% majority
function resolveVote(address offsetter) {
    if (!passesQuorum(offsetter)) return;

    uint vfor = totalVotesFor[offsetter];
    uint vagainst = totalVotesAgainst[offsetter];
    uint threshold = ((vfor + vagainst) * 2) / 3;
    if (vfor > threshold) {
        offsetters[offsetter].active = true;
    }
    if (vagainst > threshold) {
        offsetters[offsetter].active = false;
    }
}

We probably want the users to be able to change their votes. To do that we'll need to store the vote per user, so we can see how many votes to remove when we store the new vote.

We have a couple backstops in case voting fails to maintain legitimate offsetters. For one, donors can choose the offsetter when they donate; this helps but doesn't completely defend the overall legitimacy of Climatecoin. For extreme cases, another option is to fork the contract. Simply copy all the data to a new contract, but remove the bad offsetters and the voting power of everyone who voted for them. Then the market can determine which is more valuable. If Climatecoin is used by merchants to signal their "green credentials," the merchants are likely to switch to the more reputable fork.

It would be nice if a purely voluntary solution like this could completely solve climate change. Unfortunately, it would have to be absurdly successful to accomplish that. Even if Climatecoin attained a market cap of $1 trillion, and inflated 10% per year, it would only be spending $100 billion annually on carbon offsets. Carbon offsets are currently selling at $12 per ton CO2, so that'd be under 10 billion tons offset. Our current emissions are over 30 billion tons annually. And that price is on the low side because of low demand in the voluntary market. At scale, the cost could be significantly higher (depending on what sort of innovations people come up with). The offsets which are least vulnerable to manipulation are those that directly absorb CO2 from the atmosphere in measurable ways; at least some of those are relatively expensive.

But if, someday, government imposes a price on emissions, it may sometimes be more economical to offset the carbon you emit instead of paying the fee. To encourage this, the government could let you pay with climatecoins, which it burns, awarding you a tonnage credit based on the current coinsPerTon. A more direct method is to burn the coins yourself, and just provide a proof that you did it:

function burn(uint tons) {
    uint coins = coinsPerTon() * tons;
    if (users[msg.sender].balance < coins) throw;

    users[msg.sender].balance -= coins;
    users[msg.sender].burned += tons;
    Burn(msg.sender, tons); //write to log so it's easy to provide a proof
}

This way, we could reach a maximum number of Climatecoins, and only issue new coins when we dip below the maximum because people burned coins. Our total offsets would no longer be limited by inflation.

If we assume this is the endgame, and that its prospect is a major source of climatecoin value, then there's another voting method we could try: let people vote on offsetters by locking up their coins for some period of time, as suggested by /u/avsa for the DAO fork debate, and mentioned by Vitalik for more general use. The more coins and the longer the time, the more weight for the vote. The more reputable the offsetters, the more likely that governments will accept climatecoins; hence people will have more confidence in Climatecoin's long-term value if the offsetters are reputable.

Therefore, we could have users vote by vaulting their coins. We weight the votes and set the offsetter's active bits accordingly. The users' coins are locked only if the vote goes their way.

struct Vote {
    uint expiration;
    uint duration;
    uint amount;
    bool approve;
}

function makeVote(uint duration, uint amount, bool approve) private returns (Vote) {
    return Vote(block.timestamp + duration, duration, amount, approve);
}

function vote(address offsetter, uint duration, uint amount, bool approve) {
    if (amount > users[msg.sender].balance) return;

    users[msg.sender].votes[offsetter] = makeVote(duration, amount, approve);
    users[msg.sender].balance -= amount;
    uint votes = calculateVote(amount, duration);
    if (approve) {
        totalVotesFor[offsetter] += votes;
    } else {
        totalVotesAgainst[offsetter] += votes;
    }
}

function unvault(address offsetter) {
    Vote v = users[msg.sender].votes[offsetter];
    if (v.amount == 0
        || v.expiration < block.timestamp
        || v.approve != offsetters[offsetter].active) return;

    users[msg.sender].balance += v.amount;
    delete users[msg.sender].votes[offsetter];
    uint votes = calculateVote(v.amount, v.duration);
    if (v.approve) {
        totalVotesFor[offsetter] -= votes;
    } else {
        totalVotesAgainst[offsetter] -= votes;
    }
}

In this case we can easily let users change their votes; it's automatic whenever they unvault their funds.

This voting system doesn't give any particular weight to people who actually offset carbon, rather than just buying coins on the open market; it simply assumes that reliable offsetters will be thought best for coin value (due to potential government recognition). If we're not confident in that assumption, we could make a hybrid voting system, by changing the calculateVote function to also take the voters' accumulated tonnage into account.