MIP 54: DssVest

MIP 54: DssVest

Preamble

MIP#: 54
Title: DssVest
Author(s): Derek Flossman, Brian McMichael
Contributors: None
Tags:
Type: Technical
Status: Formal Submission
Date Proposed: 2021-05-12
Date Ratified: n/a
Dependencies: n/a
Replaces: n/a
License: AGPL3+

Sentence Summary

DssVest is a module that automates token vesting once the vesting plan has been approved by Governance.

Paragraph Summary

This module allows scheduling, cliff vesting, specification of vesting period as well as third-party revocation. The plan variables must be specified by the party submitting their proposal to Governance. Once the vesting cliff has been reached it puts the user in control of redeeming their tokens without any third-party interaction. DssVest also supports a number of vesting variants, including; minting MKR, minting DAI via vat.suck as well as paying out pre-deposited tokens.

Motivation

  • A safe and secure mechanism to provide protocol contributors with MKR incentives
  • Reduce future Governance overhead to a minimum
  • Enable team facilitators to manage/remove token bonuses themselves when team members leave
  • Promote transparency by making it easier to keep track of outstanding MKR mint amounts
  • Enable independent user control once cliff dates have been reached

The following gives an explanation of the module interactions and functionality:

DssVest Specifications:

DssVest Setup and Variables:

  • DssVest allows a recipient to have a vesting start date and an end date
  • DssVest will be initiated in a governance executive
  • The starting date for a DssVest Award can be back-dated if necessary
  • Variables in DssVest include:
    • _usr : The plan beneficiary/recipient
    • _tot : The total amount of the vesting plan, in token units
      • Ex 100 MKR = 100 * 10**18
    • _bgn : A unix-timestamp of the plan start date
    • _tau : The duration of the vesting plan (in seconds)
    • _clf : The cliff period, in which tokens are accrued but not payable. (in seconds)
    • _mgr : (Optional) The address of an authorized manager. This address has permission to remove the vesting plan when the contributor leaves the project
      • Note: auth users on this contract always have the ability to yank a vesting contract

DssVest Interaction:

  • The following user interactions are possible with DssVest:
    • vest(_id): The vesting plan participant calls vest(id) after the cliff period to pay out accrued and unpaid tokens
    • move(_id, _dst) : The vesting plan participant can transfer their contract _id control and ownership to another address _dst
    • unpaid(_id) returns (amt) : Returns the amount of accrued, vested, unpaid tokens
    • accrued(_id) returns (amt) : Returns the amount of tokens that have accrued from the beginning of the plan to the current block
    • valid(_id) returns (bool) : Returns true if the plan id is valid and has not been claimed or yanked before the cliff
    • yank(_id) : An authorized user (ex. governance) of the vesting contract, or an optional plan manager, can yank a vesting contract. If the contract is yanked prior to the plan cliff, no funds will be paid out. If a plan is yanked after the contract cliff period has ended, new accruals will cease and the participant will be able to call vest to claim any vested funds
    • yank(_id, _end) : Allows governance to schedule a point in the future to end the vest. Used for planned offboarding of contributors

Optional Vesting Cliff:

  • If a cliff is included, it will not be possible for the recipient to receive any award until the timestamp of the cliff is reached
  • Once the cliff date is reached, only the recipient can call vest through a UI or Etherscan

Authorization:

  • DssVest will be managed by an operator
  • The operator will include the core unit multisig and Governance
  • There is a function called yank to remove a recipient from being eligible for awards
  • Both the multisig and Governance will be able to yank a recipient’s award - i.e. remove a recipient from the award they are due in the event that they e.g. leave the team
  • The multisig will be capable of removing a recipient without the need for approval from governance
  • The multisig can only yank, it cannot create new recipients and/or awards. These must be approved solely by Governance

Recipient Awards:

  • Token reward before the cliff equals zero. Once the cliff is reached, the recipient will be entitled to claim the cliff amount
  • Following the cliff being reached, streaming rewards will be linearly accrued across the remaining vesting period. This will be calculated from block-to-block
  • As per the above point, it is up to the recipient when and at which interval they wish to claim their tokens
  • Awards are minted only at the point at which they are redeemed

Minting:

  • MKR will be minted at the time a user calls vest. This function calls the contract to redeem the MKR award available to them at that block. As stated above, this will be calculated from block-to-block
  • If a recipient wishes to change their address, they will be able to specify a new recipient address by calling the move function
  • Every recipient will have an on-chain ID from which DssVest will emit an Award ID so that users can scan events to see what is available to them for transparency
  • Once the vesting period ends and the streaming award is over, the Award ID will be removed from the DssVest module

Transparency:

  • Each award is represented with an ID and can be tracked as an ID to award mapping
  • The contract includes an unpaid function so anyone can take a look at it and see what the unpaid amount is on that contract
  • This is an arbitrary token vesting contract, not specific to MKR, and can easily be adapted for any token

Removing Awards:

  • In the instance an award is yanked before it has vested, it will not be possible to claim any reward
  • In the instance an award is yanked after an award has vested, and is now linearly accruring block-by-block, it will only vest up to the timestamp at which it was cancelled. The user will then be able to claim up to that timestamp

Resources:


Next Steps:

  • MIP Governance process
  • Contract audits
  • Expectation management: secondary importance relative to core protocol contracts/collateral onboarding
13 Likes

This is great, @Derek and PE team!

I’ll pretend that I don’t know how much feature requests at this stage annoy developers (hopefully @brianmcmichael won’t notice) and ask anyway…

How hard would it be to replace the continuous vesting for lump sums (in prefixed dates)?

Exampli Gratia: You vest the first lump sum after the cliff, then 6 later, then another 6 months later, etc.

2 Likes

Technically I believe you can simply split up the vesting schedules in many schedules for the same person and set duration=cliff to sidestep the continuous payout stream mechanism post cliff vest.

E.g. if Bob is supposed to get 100 MKR after 1 year, and then 50 MKR every 6 months you could simply create a number of vesting schedules that accommodate that:
Usr: Bob, cliff: 1 year, duration: 1 year, amount: 100 MKR
Usr: Bob, cliff: 1,5 year, duration: 1,5 year, amount: 50 MKR
Usr: Bob, cliff: 2 year, duration: 2 year, amount: 50 MKR

It might not be the most elegant or practical solution from a spell crafting or maintenance point of view, but I believe it would work (please correct me if I’m wrong).

3 Likes

Is there any reason why we use MKR.mint() Vs adding MKR inside the contract and distributing it.

Do we need to give full authorization from the MKR contract to this contract?

Also from your point of view it is less political to deauth this contract than burning MKR from governance action.

@juanjuan lollike’s comment is correct. You would need to create multiple cliffs. This would require a bit more overhead. Note, the user doesn’t have to claim their vested MKR until they want to. Are you asking from a tax concern perspective, or just the mechanism in general?

@alexis your approach is indeed an alternative solution, however we chose the above approach because the MKR is only minted once the user claims it. We’re not minting upfront and leaving it in a contract for a long period of time. I thought this approach was more elegant, arguments can be made for both methods though.

3 Likes

I did find @lollike’s solution quite elegant indeed.

I think it might help to convince people to stay for a little longer if you vest every 3 or 6 months, versus continuously.

Happy to know it can be done, though.

Streaming rewards even if accrued and not claimed/minted will still create a tax liability issue for anyone in the US. Making the tokens accessible on certain vesting dates as mentioned by others would be a great option for anyone residing in the US.

2 Likes

A way to circumvent continuously streaming rewards could also be to setup a single vesting schedule for the whole team, or one for each member (dependent on the maintenance work), controlled by a team multisig, and only payout to individual contributors from the multisig on specific vesting dates. Not sure if this fixes the tax issue though.

1 Like

It’s possible, but the DAO is moving to streaming payments generally by way of the Keg, so this seemed like a congruent solution enabled by the technology.

That’s an alternate solution, and one that requires that 1) the MKR exist, and 2) the MKR is managed. This was more of an issue before the Foundation transferred funds to the DAO, but it’s also somewhat messy, considering that not all MKR allocated will be paid out and that unpaid MKR would need to be recaptured (and probably burned) anyways. The ability to mint and burn MKR as needed is already a core component of the system that allows for clean accounting of the supply.

The tokens are minted at the time they are claimed, so they don’t exist until a user initiates the transaction. I’m not a lawyer and this is not financial advice, but I think there’s some room for a different interpretation here.

You can mint and put into it, that gives you a better security over the contract and over the found to be distributed. I just noticed it as yearn contract is doing it.
You can image a scenario where governance has to migrate the MKR contract. Also as I said it is more difficult to burn MKR from someone than deauth a contract for security reason as an example.
By doing that your contract is standalone vs depend of the MKR contract.

1 Like

Is it though? According the makers own website Maker only mints MKR when the Maker Protocol is running a deficit and the system debt exceeds a maximum threshold, MKR is created and auctioned for Dai in order to recapitalize the system

I understand it is more efficient from a programming stand point to mint/burn MKR on demand however I do have concerns that it goes against Makers original mission statement. I’m sure there are members in the community that would agree minting MKR should only be a last resort.

@alexis , we’ve chosen the above implementation because we believe it is the easiest and safest solution for MKR vesting. The alternative you suggest is possible, but minting the full amount upfront is not ideal because in many cases it may not be paid out in full. Likewise, in the current implementation, it is easier for either Governance or the Facilitator to remove the award if a person leaves. This eliminates any overhead for managing the burning of MKR, because it is only minted once it is claimed by the user.

@Zarevok , minting and burning MKR is a core component of the Maker protocol. When and how it is acceptable to mint MKR has indeed changed over time. We’ve recently seen Governance vote to mint MKR as an ongoing incentive for core units - if that is still up for debate, it’s probably worth a separate thread as this thread is specific to the mechanism for how to handle vesting.

2 Likes

FYI Submitting this MIP for Formal Submission into the June cycle.

4 Likes