I believe that this community, above all, appreciates the importance of rewarding creators, so I thought it would be fun to document my experience of making a (small) contribution to a Gitcoin Grant.
Gitcoin grants are, “a fast, easy and secure way to provide recurring token contributions to your favorite OSS maintainers.” Most of my work is on Ethereum 2.0 development, and one of the great services to the community is performed by @pggallagher who faithfully writes up the notes from the regular developers’ meetings. A little while ago, Peter suggested setting up a Gitcoin Grant to encourage this work.
Are you ready to DAI?
The first challenge: I had planned to make a donation in plain old Ether, but this didn’t seem to be an option. After some digging around, I eventually realised that grants can only be made in tokens. Wrapped Ether (WETH — an ERC20 token that is convertible 1:1 with Ether) would have been ideal, but that option didn’t appear on the drop-down list of 188 or so supported tokens. In the end I opted for the default option, DAI.
As an aside, the reason for this is that Gitcoin seeks to support the ERC-1337 standard for recurring subscriptions on the blockchain. This relies on ERC-20’s approve() method to pre-approve future payments. I suppose that it wouldn’t be difficult to set up an escrow contract to do this with Ether directly — but, yay for standards!
Anyway, DAI is a stable-coin aiming to track the US dollar, which is great, but I didn’t have any. After a quick Google, Bancor looked to be a convenient and cost-effective way to exchange Ether for DAI. Bancor is a “Decentralized Liquidity Network”, so you are not interacting with other people, or a company: your counterparties are smart contracts. The whole thing was straightforward, with no account required, no KYC or other hurdles to jump.
I settled on $10 per two-weekly meeting write-up, and planned for about six months. So I was after $120 worth in total. I typed “120” into the DAI box, and the Bancor dApp automatically populated the ETH box at what looked to be a reasonable rate (for New Year’s day 2019).
Clicking Convert led to some complexity, but nothing too scary:
Clicking through another couple of screens and signing the transaction with MetaMask was smooth, and the transaction went through pretty swiftly, launching a blizzard of internal activity that you can see on Etherscan. It looks like my initial Ether was converted to wrapped Ether that was passed between a couple of contracts. Then it was traded for some BNT which was again moved around, and finally into DAI that gets sent to my account after yet another hop. We truly have achieved “programmable money”.
Pretty soon, I had some DAI in my account:
Ooops — I wanted 120 of them! I assume the exchange rate moved fractionally against me while the transaction was pending. Oh well. (I have no idea why MetaMask shows the value of this as $135.31. It isn’t.)
Now I’ve got my DAI, I can get on with the Gitcoin Grant contribution.
Getting Going with Gitcoin Grants
Full disclosure, my first attempts to contribute failed due to a bug, but the Gitcoin people were super helpful and we found the problem. The below documents the eventual happy flow 😃.
Filling in the grants form was straightforward, except for having to divide my 119.997193078834529614 DAI by 12 to get the right regular payment (don’t use more than 4 decimal places for now, or you’ll run into the bug I found!). The default gas price was fine, and the transaction confirmation was near instantaneous.
As per the instructions, I had to sign twice in MetaMask: the first time for a transaction, the second just a signing operation (not a transaction) that Gitcoin will use to authorise future payments on my behalf.
The initial transaction went through after a few seconds, and a short time later I received an email confirming my support 🎉. Soon after that, 9.999 DAI was deducted from my account, and I received another email confirmation of the fact.
Modulo some small teething problems, everything works!
One day soon, we’ll be able to do all this and have no idea whatsoever that it is all taking place on a blockchain, trustlessly guaranteed by smart contracts.
Yes, from end to end there are extra steps due to having to use DAI or other tokens, but it already feels easier than setting up a recurring payment with my bank, and I feel more in control.
It’s all astonishing if you do happen to appreciate what’s happening under the hood. I’m simply blown away by Bancor. And the Gitcoin grants, while maybe technically less complex, have the potential to be an amazing service for the OSS community. Funding for valuable open source projects has long been an issue; wouldn’t it be wonderful if we all felt enabled to support the projects from which we benefit so much?
Disclaimer: I am not associated with Gitcoin, although I do work for the same overall organisation, ConsenSys.
Under the hood
This is totally optional and you don’t need to understand any of this in order to contribute to a grant, but it is interesting to take a little look at what’s going on behind the scenes.
The first transaction that you sign when making a grant is an approve() method call on your chosen ERC-20 token, in my case the DAI contract. The ERC-20 approve() functionality authorises a third party to transfer tokens out of your account, up to the limit you specify. In this case, the transaction authorised the Gitcoin Subscription contract for this grant to take up to 120 DAI (minus epsilon) from my account — the total amount for the whole 12 contributions.
The second operation is not a transaction, but signing some data. To understand why this is needed, we need to take a look at the Gitcoin Subscription contract source code.
The model is that, as users, we authorise payments to take place at certain times in the future. However, due to the way Ethereum works, smart contracts can’t be set to execute autonomously at specific times: they need to be prodded by an external actor when it’s time to do something. The Subscription contract has a method executeSubscription(). At the set intervals, Gitcoin will call this method in order to execute the next payment. The method checks that it is not being called too soon, before the payment is due.
As proof that I actually agreed to the parameters passed to the executeSubscription() — who is being paid, the token type, the amount, the payment interval — I need to sign a string containing these parameters when the grant is set up. Gitcoin stores this signature, and, every time the execute subscription method is called, passes it as proof that I agreed to the parameters. The contract checks the signature to ensure nothing untoward is going on. This should be happening every 14 days for the contribution I have set up.
It’s a belt-and-braces approach: my maximum contribution is already set by the amount I approved on the DAI contract, but it is reassuring to know that everything is double-protected. If I wanted to cancel outside the Gitcoin workflow, I could still do so simply by setting the approved amount to zero on the DAI contract, or just by moving my DAI elsewhere.
Finally, note that the total amount authorised to be taken from my account in the approve() transaction above (the “wad”) is my 9.999 DAI * 12 payments, plus another 14.4 nano DAI (plus 0.01 pico DAI that I can’t explain). The 14.4 nano DAI are intended to provide a 1.2 nano DAI fee to the relaying account that prods the Subscription contract every 14 days. It is to cover its gas fees for doing so and to provide some incentivisation. If this incentivisation were a more realistic amount, the whole process could be completely decentralised: any 3rd party other than the Gitcoin server could submit the executeSubscription() transaction in return for the reward. This is very cool.
To learn more about Gitcoin, click below. We welcome you on our journey to grow open source while changing the way we work.