rDAI V2: The Redirectening

Wherein our core devs analyze how to level up the permissionless programmable interest ecosystem

Victor Rortvedt
rToken-Project
11 min readMar 31, 2020

--

Where We Are

The history of rDAI is not especially long in non-crypto years, having been conceived by Francesco Renzi and Miao Zhicheng in August 2019. (Fun fact: the idea was formed while Fran read the Libra whitepaper!) But the rDAI team has made the most of these last seven months, having launched on mainnet with single collateral rDAI in November 2019 and launched multi-collateral rDAI on December 16, 2019. These milestones wouldn’t have been possible without all the awesome community support we’ve received, including through Gitcoin Grants and a grant from MetaCartel to fund a code audit.

Beyond the official rDAI dapp, a number of dapps have built on rDAI, including rTrees, GiveTogether and High Priests. Among other things, we’ve built a sizable Discord community, supported ETHGlobal hackathon buidlers, and created the coolest visual block explorer in all the land — BEHOLD:

Just a galactic programmable interest economy in motion — nbd.

But even all that wasn’t enough for the rDAI team. Prior to ETHDenver 2020, we held a summit to discuss issues with rDAI V1 and to design an improved framework for the protocol for eventual release as rDAI V2.

The rDAI core team post V2-summit

V2 Vision

The mission of the rToken project (because DAI is only the beginning) is to provide programmable interest payments to everyone. In V2, we want to expand upon the protocol’s current functionality to make it work as a generalized interest routing system. The future of DeFi will involve more interest-generating tokens, more lending pools, more derivatives and more automated yield-seeking strategies.

Instead of trying to choose which among these options to build on, we want to create an open rToken ecosystem with a narrow focus — to allow dapps and DeFi users to redirect programmable interest no matter its source. While we want to encourage interest generating projects to help create rToken allocation strategies, the focus for building out V2 isn’t integrating every DeFi project that launches but rather the creation of a robust, feature-rich programmable interest infrastructure that will be attractive and useful to as wide a swath of users and projects as possible.

QUICK PREEMPTIVE SHILL:

rDAI is a nonprofit, open source project run by volunteers. If you want to help us achieve the vision laid out below, please consider supporting us on Gitcoin Grants. During the current CLR Matching Round 5, your donation can be matched and magnified several times over!

To that end, here are four proposed V2 changes that we would love community feedback in our Discord #V2 channel.

PROPOSED V2 CHANGE #1: BUCKETS

First, a V1 problem. It involves the rDAI concept of a “hat,” which is an object that contains the programmable interest instructions that make the protocol work. A hat stores a set of addresses (up to 50) and their corresponding proportions. Users choose where to redirect their interest by setting the appropriate hat.

Hat yanking

The rDAI contract permits an address to have only one hat at a time, which leads to complications when using the same address to interact with multiple rDAI dapps. Opinionated dapps like rTrees made the UX choice to simplify the interface by pointing all users to the same hat. Yet if an rTrees user address also tried to send interest to Offsetra on the official rDAI app, their hat would be reset to the Offsetra hat, “yanking” the amount of rDAI directing interest to rTrees.

In our example, Apu is rTrees and Homer is the rDAI official app

Currently, hat yanking can be avoided in two ways, but neither is an especially attractive solution. First, a user could use different address for each rDAI dapp, but this is obviously annoying to manage. Second, a user could create a custom hat with the same address every time she wanted to do something new. In the example above, the user would need to create a new hat that proportionally allocated the amounts that should go to rTrees and to Offsetra. It’s possible that dapps could handle this with custom logic, but it would still be very inefficient because creating a new hat costs more gas than minting into an existing hat, and results in state bloat. Further, it’s unlikely that every dapp would implement the same logic, leading to more edge cases.

The V2 Solution: Buckets

Buckets. The solution is buckets.

Buckets.

Not detailed enough for you? Fine, we’ll ELI25.

A bucket is a user-specific object that identifies a hat and an amount to mint into that hat. The user thereby gives each bucket of rDAI a distinct direction that is unaffected by prior and future rDAI directions. We could automatically create a userBucket 0 set to the user’s address (like self hat), which would only create a hat (and incur those gas costs) and direct the interest to the user under specific fallback conditions

As a user interacts with different rDAI dapps, she appends entries to her userBuckets array — in plain terms, bucket 1 sends interest on 15 DAI to the rTrees hat, bucket 2 sends interest on 10 DAI to the Offsetra hat, etc. User preferences are preserved and hat yanking is avoided — hooray!

But.

Now we have some new issues to wrangle with.

Bucket problems.

When a user wants to transfer or redeem some but not all of her rDAI, how do we decide which buckets to empty first?

Perhaps a last-in-first-out default strategy makes sense, given that the most recently assigned buckets will likely be freshest in the user’s mind. What are the pros and cons of a different default strategy?

It might also be useful to add a “sticky” flag to buckets, so that users and/or dapps can prioritize which buckets should be the last to be emptied.

We propose automatically creating a userBucket 0 set to the user’s address (like self hat), which would only create a hat (and incur those gas costs) and direct the interest to the user under specific fallback conditions.

To explore buckets further, here’s a proposed data structure example:

The array holds 4 objects, representing the self hat and three buckets totaling 330 rDAI. This user has interacted with two different dapps, represented by the hatIDs 11 and 2. She has one sticky bucket pointed at hatID 11 and two buckets (one sticky, one not) pointed at hatID 2, from two separate minting transactions. Should she want to redeem 150 DAI from her 330 total rDAI, the non-sticky bucket would be redeemed first (100 DAI) and then 50 rDAI from the last-in sticky hatID 2 bucket in the fourth array position.

Other hat musings:

  • Should userBucket slots be reusable, and if so, how should the data organization work? If user redeems all the rDAI in a bucket, should that bucket be deleted from the userBuckets array? How should that data reorg work? Deletion would help reduce state bloat, though it may also hinder attempts to pull data about past events, or at least remove a potential aid to doing so beyond blockchain transaction queries.
  • The gas costs involved in transferring multiple buckets worth of rDAI to another address could become gas prohibitive, so even though it would be possible to transfer using ERC20 methods, a better pattern would be to redeem each bucket to DAI through each dapp and then transfer the DAI. These gas calculations, and the utility of transferring rDAI vs. redeeming and then transferring DAI, deserve additional research.
  • Are there other bucket features, such as additional flags, variables or data structure improvements that are worth considering? Let us know on Discord V2 channel!

PROPOSED V2 CHANGE #2: HAT REFORM or THE DROP OF A HAT

One rhetorical crossroads is whether to keep the name “hat” to refer to our interest routing instructions. The core team is divided on this issue, with some loving the “hat” name and all its admittedly excellent puns (50 recipient limit = “the sombrero problem”; insured hats = “helmets”) while others think it needlessly remote from any helpful metaphor. So at this moment of transition to V2 — before rDAI is big enough to trigger the widespread groaning that followed Maker’s “CDPs are now Vaults” linguistic hard fork— we want to make a naming decision.

Here are a few alternate terms for consideration:

  • Route
  • Story
  • Program
  • Directive

And in the immortal tradition of divided teams everywhere, we want to punt this issue to the community — should we keep the term “hat” until eternity or should we change it now? If you favor a change, do you prefer “route,” “story” “program” or have another nomination? Let us know on the Discord #V2 channel!

PROPOSED V2 CHANGE #3: MANAGED AND CHANGEABLE HATS

We received community feedback asking to make a hat changeable by the entity that created it rather than have to always create a new hat. We agree that there is a use case for this feature.

Dapps wanna be like…

For instance, in the dapp High Priests, each flock leader selects three worthy Gitcoin Grants projects to support, and a hat is created to direct interest to them. Some of the High Priests have asked to change the set of projects they are evangelizing for, but under V1, the only solution is to create a new hat and direct new contributors to that hat. The prior contributors will continue to direct interest to the earlier set unless they manually switch. Certainly notifications could be used to get members to switch, but the better pattern would be for the High Priests to have the power to change the recipients for all their flock members.

Under this proposed change, hats can be created with a “changeable” flag set to true or false. If “changeable” is set to true, the address that created the hat would be set as the “manager” with the power to change the hat’s recipients and/or proportional allocation. Dapps sharing their manager address (better yet, their ENS name) would allow their users to verify that they are interacting with the right hat. This would also allow wallets to verify which hats are managed by which dapps and potentially build custom products for their users.

Potential Pitfalls

Making hats changeable by their managers could result in malicious changes — for instance, by redirecting interest initially designated for charity to the manager’s own address. While this is not a trivial risk, we believe it is outweighed by the advantages of changeable hats and propose that the risk can be mitigated in the following ways:

  • Placing a time delay (say 24 hours) on any hat change taking effect, during which time the dapp community could verify that the change is legitimate and redeem their rDAI if they are not satisfied
  • Creating a (dapp-specific?) Twitter bot that reports hat change events such that a would-be malicious hat-changer could not feel confident that he or she could operate in stealth
  • Creating an rDAI dapp registry that tracks changeable hats and their histories
  • Providing a standard dapp disclosure notification and encouraging dapps to use it to let users know when they are interacting with a changeable hat, identifying which address has the power to change the hat

Further, it’s important to remember that the amount at stake from a malicious hat change is limited to the future redirected interest and not the underlying principal DAI. While of course the interest could grow to a substantial sum over time, this potential injury doesn’t present the same risk of sudden catastrophic loss as the loss of one’s private keys.

PROPOSED V2 CHANGE #4: HAT REGISTRY CONTRACT

The biggest proposed substantive change is to move hats outside of an rToken contract like rDAI.sol and into a new hat registry contract that all rToken contracts (such as hypothetical rUSDC.sol or rWETH.sol contracts) can utilize.

We’re thinking of calling this registry contract Switchboard.sol.

Inside the registry storage array, hats would look something like this:

There are several advantages to this proposed design, including:

  • Reduced friction for dapp developers — instead of having to create and deploy the same hat for every rToken used by the dapp, devs can create token-agnostic interest redirection instructions once
  • Reduced overhead — instead of having to query or watch multiple rToken contracts for the same redirection instructions, all interested parties can go to a single source. This reduces the incentive for a malicious hat change attack, as the chain monitoring deterrents described above have greater efficacy if they are all watching and reporting on the same contract as opposed to dozens of different contracts.
  • Trusty old hats — users may be more comfortable using newly deployed and innovative rTokens if they know they can trust the redirection instructions supplied by older vetted hats— this would be especially true for unmanaged/immutable hats
  • Users would be better able to take advantage of yield-maximizing rToken-switching strategies, as they would not have to wait for the hat to be created and deployed in whatever rToken they wished to switch to
  • Reduced storage costs and state bloat

As in V1, anyone could create a new hat inside the registry contract. We imagine that dapps seeking to utilize rTokens would likely create and manage their own changeable hats. This would give the dapp developers limited decentralized admin powers over the rTokens activated by their users. It would also allow them to build more flexible dapps that provide a smoother and feature-rich interface.

Wrapping Up

These four ideas form the core of our V2 vision, but we need your feedback to help determine whether these are the right decisions and to let us know how we can build the most useful rToken ecosystem for the future of DeFi.

To contribute ideas and feedback on this V2 vision, please visit our Discord #V2 channel, or you can also join us in the other channels for non-V2 discussions.

Twitter: @rDAI_DAO

Website: https://rdai.money

Support Us

Gitcoin Grants: https://gitcoin.co/grants/519/rdai-3

--

--

Victor Rortvedt
rToken-Project

Ethereum and web3 dapp developer interested in programmable interest — former lawyer — lover of lateral thinking puzzles. rDAI & Tribute & rTrees