MacroHard: a decentralized software corporation
By: Srisht, Panos, and Hossein
Open source devs don’t get the deserved monetary incentivization for their FOSS (free and open-source software) projects, and this is prevalent even for blockchain projects. Although some of them get donations on GitHub, charity is not the right way to reward them!
Take MITSUNARI Shigeo (herumi), the author of the mcl and bls pairing libraries. When we asked him why he was looking for sponsors, he replied that his libraries are used in many projects, that he often develops them outside of work, and that almost no one pays. The person who finds a bug in his library gets thousands of dollars in bounties, but fixing the bug doesn’t give him anything.
The problem goes beyond money. FOSS developers don’t even get ownership for their contributions (big or small) in the projects. Here ownership means decision-making power or intellectual property rights.
Software corporations, on the other hand, have incentivization and sometimes IP rights, but uncertain entry and a high barrier of entry. What is missing is freedom for everyone to showcase their talent.
MacroHard is our attempt to fill this gap. It is permissionless, so anyone can start contributing to a project at any point. It provides incentivization, as contributors receive native reward tokens based on their contributions. And it gives ownership, since project contributors can vote on technical and economic proposals in accordance with their token holdings.
The machinery behind all of this is a DAO, and we used OpenZeppelin Contracts for its implementation.
The voting token deserves a word. Why not just import an ERC20 smart contract? Because an OpenZeppelin extension of it called ERC20Votes provides us with functionalities that are pretty useful when it comes to dealing with DAOs and make it a much better voting tool. It keeps snapshots of the number of tokens contributors have, and we wanna avoid contributors just buying tokens right before a hot proposal and selling right after to get in on decision-making. It also gives useful vote-related info, such as how many votes one has and their past votes. Lastly, it supports delegation, so you can delegate your tokens to others and let them vote instead of you in case you weren’t able to do so.
On top of that sits a TimeLock. The TimeLock smart contract is the owner of the proposer contract, which means it’s up to this contract to call any function in the proposer contract or not. Whenever we make a proposal, we want to wait for a while to make sure after the new vote’s execution contributors have enough time to get out if they don’t like an update.
Not everything lives on the chain, though. All the votes are implemented in smart contracts (e.g. the vote on the confirmation of evaluation of contributors’ work), but the calculation of contributors’ work is implemented in the back-end, based on data fetched by GitHub APIs (yeah, it’s partially decentralized!). The front-end gets proposal information from the back-end and interacts directly with the blockchain for voting and balance retrieval.
That partial centralization is a deliberate trade-off. We evaluate each contributor’s work based on the number of their contributions to the project’s GitHub repository, which obviously is against our desire of having a fully decentralized system. Yet if we wanted to make it completely decentralized, we should have created an on-chain source-code management and version control service as well. Because of all the limitations, we decided to outsource this part and make use of a third party. The centralized parts are also covered. In case an adversary wants to make an attack on the back-end or on the third party’s services, the voters could easily reject the proposal (e.g. contribution evaluation) till everything goes back to normal.
Leaning on GitHub also means being careful with its servers. In order to get the contributions’ data, we need to send requests to GitHub through provided APIs. However, in case of making too many API calls, the API provider would not be able to respond to them or, depending on their policies, they could ban your IP. To avoid that, we should simply be “polite”, which means to keep the rate of API calls low. To do so, we needed to use an LRU cache to keep fetched data for repositories from the past hour and avoid sending requests for them.
Incentives need pacing too. In order to keep projects’ development going on in a consistent manner, we designed a feature that gives the voters the ability to define dynamic-sized time windows to evaluate contributors’ work within them. By normalizing the amount of work they did in each time window, we make sure to keep the work going on consistently. If nobody does any contribution within a time window, the tokens assigned to that time window would go back to the investors’ pockets. If only a few of them work in a time window, they’d gain a lot of money for less work. Hence, it’s not going to stay like that forever. Finally, the system would reach a state where there’s a balance between supply and demand of work.
The initial version already walks through the whole loop. A contributor registers, contributes, votes, and withdraws.
Next, we would like the amount to be split to be decided on-chain, to use a separate reward coin, and to design a decentralized repository. The original slide deck is available as a PDF.