100 Days of Web3 (Days 31-40)

Days 31-40 marked a transition for me as I moved on from instructor-led courses to learning more independently. It was challenging at first to decide what to learn and how to do it, but doing so increased my confidence and encouraged me to explore Web3 more.

Day 31

Having completed the DeFi Development Mastery course, taking the Flashloans course from EatTheBlocks, seemed like a natural choice. The objective of the course was to build a script which monitors price differences of the ETH-DAI pair on Uniswap and Kyberswap and to create an arbitrage smart contract which would buy from one of the exchanges and sell on the other.

The first part of the course focused on the monitoring portion of the project. We wrote a Node.js script which would poll the prices of the ETH-DAI pair on different exchanges using a WebSocket connection to Infura nodes. Using the Uniswap SDK made it a little easier to retrieve the prices.

Day 32

The next part of the Flashloans course was writing the smart contract which executes the arbitrage transaction. We made heavy use of the famous money-legos library to do a lot of the heavy lifting, especially when taking the flashloan from dYdX. One part of the arbitrage contract that was interesting was interacting with the Uniswap router contract. In order to trade ETH for DAI, I had to specify to the Uniswap router to first change the ETH to WETH (wrapped ether), and then swap the WETH for DAI. This is because most DeFi protocols don’t deal with ETH directly, and instead use it’s tokenized form (WETH).

Day 33

Having spent a decent amount of time learning more about DeFi, it was time to visit an important subject I had neglected thus far: decentralized autonomous organizations (DAOs). I had already heard about OpenZeppelin’s governor templates which were based on the industry standard: Compound’s Governor Bravo DAO contract. I came across a great video on YouTube which goes through an example involving OpenZeppelin’s Governor contracts. Following along with this video also gave me my first exposure to the the Brownie development tool which is similar to Hardhat and Truffle but uses Python instead of JavaScript.

Day 34

Although watching that YouTube video gave me a good overview of how to use the OpenZeppelin Governor contracts, I still didn’t have a good understanding of how they work. I decided to inspect all contracts involved in the example individually to get a better understanding of how the Governor contracts worked. I found the code for the contracts on OpenZeppelin’s GitHub repo. Basically the Governor contracts consists of three pieces:

  1. An extended ERC20 token contract which keeps track of the history of token balances in addition to current token balances
  2. A governor contract which stores details of the proposals, and the logic for voting and determining the success of the proposals
  3. A timelock controller contract which delays the execution of a successful proposal by a certain amount of time

Day 35

After getting a better understanding of how the OpenZeppelin Governor contracts worked, I deployed a simple implementation of the contracts to a local blockchain using Hardhat. I then wrote a script to go through the full lifecycle of a proposal including:

  • Granting the governor contract an executor role for the timelock controller contract
  • Revoking the deployer account’s admin role on the timelock controller contract
  • Giving the proposer the minimum number of tokens to create a proposal
  • Making the proposer self-delegate the tokens for voting
  • Creating a proposal
  • Casting enough votes using the tokens for the proposal to be successful
  • Queuing the proposal for execution
  • Executing the proposal after the required delay period had elapsed

Day 36

I took a short break from DAOs and learned a bit more about writing Solidity assembly. I had encountered some assembly before in code related to upgradeable contracts, but I didn’t really understand how to write it. I learnt more about the syntax for assembly and how it differs from normal Solidity. Perhaps the trickiest part with writing assembly is dealing with memory addresses directly. I also found it really cool how it is possible to use opcodes directly when writing assembly. Opcodes are what Solidity gets compiled into and what the Ethereum Virtual Machine runs. You can check out a few basic examples of assembly I added here.

Day 37

The next day, I learned about Web3Storage, which is a simple way of getting data to persist on IPFS (InterPlanetary File System) and is backed by Filecoin. IPFS is a censorship-resistant and decentralized way of storing files and data. However data can be garbage-collected on IPFS so there is no guarantee of data persistence. In order for data to be persisted on IPFS, the data has to be pinned to an IPFS node. This is a problem which Filecoin tries to solve. However since it is complicated to integrate with Filecoin, Web3Storage gives us a way to persist files in IPFS without dealing with Filecoin directly.

Day 38

I thought it would be interesting to create a variation of the OpenZeppelin Governor contracts to handle voting with ERC-1155 tokens instead of ERC-20 tokens. I envisioned a game where there are multiple factions, for example CryptoPunks, Bored Apes and Doodles. I would want each faction to have one vote and if two of the factions voted in favor of a proposal, then it should pass. An individual faction’s vote should be determined by how members of that faction would vote. An ERC-1155 contract seemed ideal for this scenario since each token id within the contract can represent a different faction.

I started by writing the ERC-1155 contract. I made it inherit from the basic OpenZeppelin ERC-1155 template so I didn’t have to rewrite the basic token functions. I then completed the contracts by adding the code to keep track of the historical account balances of the tokens and the historical total supply of the tokens. It was similar to the OpenZeppelin implementation for the ERC-20 contract for voting, but required some adjustments since ERC-1155 can have multiple token types.

Day 39

Having finished with the token contract, the next step was to was to write the governor contract. I started with the basic OpenZeppelin Governor contract and interface. I had to make some changes such as returning arrays from functions instead of individual integers to account for the fact that the ERC-1155 contract would have multiple token ids to represent each faction. I implemented the counting module which was analogous to the ERC-20 version from OpenZeppelin. However, I wasn’t adding all the votes together, but computing the votes for each faction separately, deciding what the vote for that faction would be and accordingly determining whether a quorum had been reached and whether the proposal would be considered successful.

There was no need to create a timelock controller contract from scratch as the existing one from OpenZeppelin would suffice. I also created the contract to be governed which represented a game and had a function to set the difficulty of the game. The end goal would be to create proposals through the governor contract in order to change the game difficulty.

Day 40

After writing the initial drafts of the contracts, I wrote a basic sanity test with a Hardhat script. In this test, I deployed all the contracts to a local blockchain, minted some tokens, created a proposal, voted on it, executed the proposal and verified that the game difficulty had changed accordingly.

After writing the sanity test, I wrote a set of tests for each of the three contracts I created. I made sure to test every externally accessible function I had written with at least one successful and one failing test case. It wouldn’t be nearly enough for a production contract, but since I’m only deploying to the testnet, this seemed sufficient for the moment.

Summary

Days 30-40 have been challenging in a different way. Part of the challenge has been to decide what to learn and figure out the steps and sources myself. Its a lot easier to take a course, where everything is laid out for me. However, most of the Web3 development courses out there are mainly focused on beginners, and so it’s time for me to be more self-reliant in my learning. I’ve spent a lot of time on DAOs and will probably still spend a few more days since I’m not done with the multi-faction DAO project. After that, I think I’ll revisit DeFi to find the inspiration for another project.