Cointime

  • BTC $16834.19 -0.05 %
  • ETH $1232.77 -0.13 %
  • BCH $109.30 0.00 %
  • SOL $13.69 -0.22 %
  • XRP $0.38 -0.23 %
  • BNB $283.50 -0.04 %

Token Delegation with Lock-Ups

Jump Crypto· 9 min read

TL;DR

  • Token delegation programs enable robust governance, but they cannot fully deliver independent governance since token holders can revoke delegation rights instantaneously.
  • For token holders who care about that independence (e.g. institutional ones), we propose that token delegation contracts embed explicit lock-up periods.
  • We demonstrate with the Maker contracts, and we add additional features, such as the ability to bypass the lock-up period if the decision is mutual or if the token holder triggers an emergency channel.

Introduction

In the last two years, the concept of token delegation — where token holders give their voting rights on-chain to others — has become increasingly popular. Many major protocols, including MakerCompound, and Uniswap, have enabled it and built thriving communities of delegates that include student groups, nonprofits, and community leaders. These programs improve governance quality, and we at Jump Crypto believe strongly in token delegation ourselves.

There are two particular virtues of delegating tokens. The original one is to make governance more efficient. Without delegation programs, thousands of stakeholders — some with tiny stakes and others with scant time — have to comb through dozens of proposals. With delegation programs, a few experts can make more informed, consistent, and consequential decisions. In many settings, representative democracy has advantages over direct democracy, and delegation brings those benefits to crypto.

But in the last year, a second motivation has risen: neutrality. Some token holders have extremely large stakes, and may have stakes in competitor protocols. Those holders may want to credibly commit to building a decentralized and unbiased community. Delegating away voting rights is one way to ensure they are seen as neutral parties.

But that second motivation does not come automatically from the existing Token Delegation programs. It requires the special ingredient of independence of the delegate from the token holder. For instance, in his article laying out principles around token delegation, Jeff Amico of a16z specifically calls out the importance of “empower[ing] each delegate to vote independently from the token holder, in whatever way they see fit.” Unfortunately, most existing Token Delegation contracts do not enforce this independence, and there have been episodes where that independence was deliberately undermined ahead of key governance proposals.

In this article, we offer a simple, code-based solution: lock-up periods, where the token holder cannot revoke governance rights from the delegate. Moreover, we actually created a reference implementation of this concept, along with some optional mutual non-emergency and unilateral emergency bypass features, compatible with Maker's set of contracts.

Lock-up periods are not for all holder-delegate relationships. Small token holders, who primarily use the delegation program for the first reason (efficiency), should continue to have the ability to revoke voting rights at any time. But they can reshape the relationship between large holders and protocols, by credibly separating the two. Holders can enjoy the goodwill of robust delegation, and delegates enjoy insulation from their pressure.

Paradise Lost: Revoking Delegations

The token delegation program, while generally seen as having high potential, has not been free of criticism. Both in theory and in practice, norms around delegation can be ignored when convenient. This undercuts its aspirations towards building robust governance.

For instance, Chris Blec at DeFi Watch has been especially active in insisting upon clarity in the selection and interactions from a16z's delegation program. Blec has similarly pointed out that several votes are often ratified entirely by one or two holders' delegates. This raises questions about the closeness between delegates and token holders.

Moreover, these risks are not always hypothetical. In particular, consider the case of Maker's Poll 819, better known as the LOVE vote. This vote — around an oversight body for lending, and the broader values of decentralization versus efficiency — became unusually contentious and intense (In fact, it set the participation record for a Maker vote and this record still holds as of writing.). The broader blow-by-blow account is well-documented by Luca Prosperi, but the actions around token delegations are particularly relevant.

This episode showed that the token delegation program could be bypassed in critical moments. In particular, several commentators — including GFX Labs — pointed out that Rune Christensen, the founder of Maker, changed his delegation rights during the vote. Christensen was vocally against the proposal, but he had delegated almost his entire stake of MKR tokens. These delegates originally represented a mix of yes, abstention, and no votes. But during the two-week voting window, he revoked delegation rights from delegates who voted yes or abstained, and re-delegated those stakes to other delegates who cast no votes. This reallocation seems to have been only a tactical measure, and did not seem to reflect some fundamental rift between Christensen and delegates who voted yes. As evidence, note that in the three days following the vote's conclusion, Christensen once again shifted delegation rights back towards delegates who had voted yes during the previous election (with other stakes). This pattern is depicted below.

Legal Solutions

The token delegation program needs to be made more robust. One solution to do so is to pair delegations with strong legal contracts that enforce independence. In particular, a16z's delegation program promises minimum periods of time for delegates to hold governance rights. This mitigates the risk of a token holder recalling governance rights if the delegate votes against her interests, and more generally, it limits the pressure that a token holder can apply to their delegates.

This principle is enforced by a legal contract that they place in a public Github repository. The key line in the legal contract comes in Section 6, where they state: “The initial term of this Agreement shall be [NUMBER] months from the Effective Date… Tokenholder may only terminate this Agreement prior to the expiration of the Term in the event that Delegate materially fails to satisfy its Protocol governance duties.”

But a legal mechanism is a suboptimal choice. To be clear, we do not doubt a16z's intentions. But those who follow in its footsteps may not be so high-minded. Legal contracts are costly to enforce, embed asymmetrical power dynamics, and represent opaque negotiations. In the hands of a less savory token holder, the legal contract imposes few meaningful checks.

As such, a legal contract may be the wrong mechanism to scale and enhance the token delegation program universally. They rely on too many assumptions around transparency and enforceability.

Proposal: Code, Not Law

But there is a simple solution: smart contracts, rather than legal contracts. In other words, we recommend protecting delegate independence by embedding lock-up periods directly into the smart contract. This is highly transparent up front and easily enforceable after the fact. Best of all, it is typically a straightforward technical implementation.

We demonstrate with the Maker contracts. Most of the core delegation logic lives in VoteDelegate.sol contract. In particular, we draw attention to the lock and free functions, which do exactly what they claim. The token holder uses the lock function to tie up tokens and distribute their governance rights, and uses the free function to reclaim those tokens and the associated governance rights.

function lock(uint256 wad) external live {
    stake[msg.sender] = add(stake[msg.sender], wad);
    gov.pull(msg.sender, wad);
    chief.lock(wad);
    iou.push(msg.sender, wad);

    emit Lock(msg.sender, wad);
}

function free(uint256 wad) external {
    require(stake[msg.sender] >= wad, "VoteDelegate/insufficient-stake");

    stake[msg.sender] -= wad;
    iou.pull(msg.sender, wad);
    chief.free(wad);
    gov.push(msg.sender, wad);

    emit Free(msg.sender, wad);
}

We can make a few simple modifications. First, when the contract constructor is called, a variable called _lockupPeriod is defined. Second, the token holder calls the initiateUnlock function to trigger the unlock countdown. Third, the free function must be slightly modified to check that the lock-up period has been respected.

mapping(address => uint256) public principalToUnlockTime;

function _setUnlock(address principal, uint256 unlockTime) internal {
    principalToUnlockTime[principal] = unlockTime;
    emit UnlockBlockTime(principal, unlockTime);
}

function initiateUnlock() external {
    require(
        stake[msg.sender] > 0,
        "VoteDelegate/must-have-stake-to-initiate-free"
    );
    _setUnlock(msg.sender, block.timestamp + lockupPeriod);
}

function free(uint256 wad) external {
    require(stake[msg.sender] >= wad, "VoteDelegate/insufficient-stake");
    uint256 unlockTime = principalToUnlockTime[msg.sender];
    require(
        unlockTime > 0 && unlockTime <= block.timestamp,
        "VoteDelegate/cannot-free-within-lockup"
    );

    stake[msg.sender] -= wad;
    iou.pull(msg.sender, wad);
    chief.free(wad);
    gov.push(msg.sender, wad);

    delete principalToUnlockTime[msg.sender];
    emit Free(msg.sender, wad);
}

With this, the token delegation program becomes more publicly credible. Delegates have well-defined and well-understood amounts of independence, enforced by code rather than law.

Mutual and Emergency Bypasses

Of course, lock-up periods may not always be desirable, and we can modify the smart contract accordingly.

First, delegates and token holders may mutually agree to end the delegation relationship. In this case, the lock-up period only inhibits utility and so we can provide a bypass function. This can be achieved with a simple function delegatorBypassLockup, that lets the delegate relinquish governance rights without any delay. (Note that there is a parameter, isDelegatorBypassEnabled, that enables this functionality when the contract is initiated.)

function delegatorBypassLockup(address principal) external delegate_auth {
    require(
        isDelegatorBypassEnabled,
        "VoteDelegate/delegator-bypass-not-enabled"
    );
    require(
        stake[principal] > 0,
        "VoteDelegate/must-have-stake-to-initiate-free"
    );
    _setUnlock(principal, block.timestamp);
}

Second, there may be emergency cases where the token holder should bypass the lock-up period unilaterally. This is important in case the delegate is acting in highly irresponsible or adversarial ways. But this should not be an easy or painless process, as otherwise token holders will use it routinely.

One powerful solution is to allow the token holder to bypass the lock-up period by irrevocably burning tokens.[1] This is straightforward to operationalize. When initializing the contract, the token owner sets an emergencyUnlockBurnPercent value (which could be as high as 100%). The free function is then modified to check whether the token holder elected the emergency route. If so, it only returns the unburned stake and burns the remainder. We present part of that logic here.

    stake[msg.sender] -= wad;
    iou.pull(msg.sender, wad);
    chief.free(wad);

    uint256 toBurn = 0;
    if (shouldBurn) {
        toBurn = mul(wad, emergencyUnlockBurnPercent) / 100;
    }
    gov.push(msg.sender, wad - toBurn);
    gov.burn(toBurn);

Complete Repository

The pull request that embeds all features and modifications discussed in this article can be found in the following public Github repository: link. This repo also includes all necessary changes to the Maker architecture. We welcome comments and suggestions, and believe the contract can already be deployed into production.

Future Aspirations: Composability

This is only the start, but we believe the token delegation program can get richer. In particular, we believe composability of the token delegation contracts will unlock the next wave of innovation. What if delegates could delegate their voting rights to other delegates?

These sorts of relationships could enable even more independence to delegates. For instance, a token holder could delegate their tokens to a student group. The student group, in turn, could delegate those rights to individual members on the list, without revealing exact identities to the token holder. Thus, if the token holder wanted to apply soft pressure, they wouldn't even know which individuals to target, and which individuals were voting for and against their interests.

Composability could also pair with richer contracts to allow for more creative interactions between token holders and delegates. For instance, token holders could be allowed to unilaterally withdraw tokens from a delegate, but not receive them until a minimum lock-up period has elapsed. This balances their ability to punish delegates with their inability to undo delegates' votes. Composable contracts would be one pathway towards this — and other — solutions.

Conclusion

Lock-ups are not for everyone. For instance, retail participants — particularly those who are drawn to the token delegation program for its original virtue of efficiency — will find lock-ups unnecessary. But lock-ups can be highly useful for a certain class of token holders (e.g. founders, institutional holders, etc), who are interested in maintaining their position of neutrality.

Above all, we want clarity. Some token holders genuinely want to give their delegates substantial independence. Other token holders want a more tightly-monitored relationship. The status quo forces all of these individuals into the same smart contract, and leaves them to express their true intentions through a patchwork of public statements and legal documents. This contract allows each token holder to pick the framework that best suits them — the desired lock-up period, the presence of a mutual bypass, and the emergency burn parameter. And it forces them to do it on the chain, where everyone can see and nobody need monitor.

All Comments