The most exciting aspects of Ethereum is its composability. For example, locks can use stable coins such as DAI or USDc for their pricing. These coins are both using the ERC20 token standard. Today we're showing how we leverage another characteristic of the ERC20 specification to make recurring memberships.
Introducing the Key Purchaser contract
Locks have a pretty simple mechanism to "purchase" memberships, which has one handy characteristic: the sender of the transaction can specify the recipient of the membership. It means that someone can buy a key (membership) for themselves or, for someone else. We already use this mechanism for our credit card support, for example.
We created a new contract, called the Key Purchaser, whose sole purpose is to purchase keys to a specific lock. This contract enables recurring memberships!
How does it work?
The lock owner deploys a Key Purchaser contract dedicated to their lock. When they do so, they define some characteristics for the recurring memberships:
- the frequency at which keys can be renewed,
- the earliest an existing key can be renewed (before it expires),
- the maximum price to pay per key (in case the lock's key price was increased)
- a reward for the transaction sender (see below!)
Rather than buying keys immediately, prospective members use the ERC20 allowance mechanism to allow the Key Purchaser contract to spend some of their ERC20 tokens. The amount that they approve should cover multiple renewals, based on the use case.
A third party application should monitor these approvals, and, for each of them, if the approver does not have a valid key to the lock, it should call the Key Purchaser contract to perform a purchase. That transaction will only succeed if all of the following pre-requisites are met:
- The approver has approved an amount that is large enough
- The approver has enough ERC20 to perform the purchase
- The key price has changed significantly
- The approver does not have a key or has a key which is soon to be expired
If the transaction succeeds, the member will see their ERC20 being spent. Some of the tokens are used to purchase the key and the balancer to provide a reward to the 3rd party application, which sends the transaction. The reward's goal is to cover for the gas spent to perform the transaction.
A full example
A lock priced in DAI was deployed at this address:
0x72ef8d4a4.... The lock's name is v7 DAI Lock. The key price is 1 DAI, and the duration is 1 day.
A Key Purchaser was deployed at this address:
0xa1c718312fd0.... This Key Purchaser allows for a maximum price of 1 DAI (in other words, all renewals would fail if the price was increased). The Key Purchaser enables for renewals every 20 hours (72000 seconds) and would only succeed if it was mined at most 1 hour (3600 seconds) before the expiration of a previous key. Finally, there is a reward of 0.1 DAI for the address which sent the transaction.
A user approved the key purchaser to spend up to 10 DAI to cover multiple renewals.
Another user then sent a transaction to the key purchaser to perform the actual purchase. The Etherscan UI provides a good understanding of what happened.
We can see 1.1 DAI transferred from the member's address, 1 DAI sent to the lock, 0.1 DAI sent to the sender. Additionally, a new NFT for the lock was minted and granted to the members!
Easter egg: The membership has now expired, which means it can be renewed... and there is a 0.1 DAI reward to whoever sends it!
We are working on running a 3rd party service that would issue transactions to execute key purchases. This service will monitor deployments of new key purchasers and the corresponding ERC20 approvals. For each of these, it will check whether the user should get a new key and issue a transaction on that case. This service will only execute transactions where the reward covers the gas we would spend.
Another next step is to update our paywall application to support recurring memberships.