<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://jezer0x.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://jezer0x.com/" rel="alternate" type="text/html" /><updated>2023-06-26T10:23:01+00:00</updated><id>https://jezer0x.com/feed.xml</id><title type="html">Jezer0x</title><subtitle>A team of technology enthusiasts coming together to study, explore and build using cutting edge technology</subtitle><entry><title type="html">🦋 Does FlutterFlow save time with prototyping?</title><link href="https://jezer0x.com/using-flutterflow-to-prototype/" rel="alternate" type="text/html" title="🦋 Does FlutterFlow save time with prototyping?" /><published>2023-06-23T00:00:00+00:00</published><updated>2023-06-23T00:00:00+00:00</updated><id>https://jezer0x.com/using-flutterflow-to-prototype</id><content type="html" xml:base="https://jezer0x.com/using-flutterflow-to-prototype/">&lt;p&gt;To prototype our &lt;a href=&quot;www.sang.bio&quot;&gt;new app&lt;/a&gt;, we decided to use &lt;a href=&quot;www.flutterflow.io&quot;&gt;FlutterFlow&lt;/a&gt; (FF). Here I share my experience and some recommendations on how to use FF for rapid prototyping.&lt;/p&gt;

&lt;h2 id=&quot;my-background&quot;&gt;My background&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;I have extensive experience with React, front end development and the full web stack in general.&lt;/li&gt;
  &lt;li&gt;It’s been a few years since I did any mobile development, but I do have experience building moderately complex iOS and android apps.&lt;/li&gt;
  &lt;li&gt;I have used firebase for a small project before, but I am not an expert. I do have a lot of experience with both SQL and NoSQL DBs (CouchDB in specific).&lt;/li&gt;
  &lt;li&gt;I have tried using code generators before, usually with frameworks I understand and the code produced has been abysmal. Last time I had to rewrite all of it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;why-flutter-flow&quot;&gt;Why Flutter Flow?&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;I needed to get a mobile app up and running quickly, and I was told FF could do that.&lt;/li&gt;
  &lt;li&gt;I wanted to know what all the fuss around &lt;a href=&quot;https://dart.dev/&quot;&gt;Dart&lt;/a&gt; and &lt;a href=&quot;https://flutter.dev&quot;&gt;Flutter&lt;/a&gt; was.&lt;/li&gt;
  &lt;li&gt;It didn’t seem wise to start prototyping using a language and framework I didn’t understand, so I hedged my bets by prototyping using a language and framework I didnt understand, AND a tool that I hadn’t used before. (Hey, I think it turned out OK. Check out our &lt;a href=&quot;www.sang.bio&quot;&gt;app&lt;/a&gt;!)&lt;/li&gt;
  &lt;li&gt;Since CoPilot, I have become VERY LAZY about writing code. Especially UI code.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;⚠ &lt;strong&gt;Caveat&lt;/strong&gt;
Soon after we started, we realized that we could get away with a web app initially and speed up iteration. No problem, flutter has a browser target now. It works.. but I don’t think it is a good idea to use Flutter for webapps. That’s not what it was built for, and it manifests in subtle ways (For example, you cant create a simple hyperlink using Flutter).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;did-it-save-time&quot;&gt;Did it save time?&lt;/h2&gt;

&lt;p&gt;Yes! I am a happy paying customer for now.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I was able to get a mock UI with the core workflow (signup, import reports, manage profile, dashboard) in 2 days. A minimally working product plugged into Firebase was done in a week. It served as a great starting point for us to iterate on, and we had a working demo we could demo to people using the “Preview” feature on FF.&lt;/li&gt;
  &lt;li&gt;FF is particularly good at building mockups that “work”. You can use firebase collections, data types and app state to structure your data and maintain state offering higher fidelity than a Figma mockup. And it is fast enough that it was viable to skip the figma mockup process and ideate directly using FF.&lt;/li&gt;
  &lt;li&gt;1 month later, I still pay for, and use FF to build out draft UI components, copy them into my code base and then customize them. That said, I hope to ditch FF in another month, because merging code is becoming increasingly annoying.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-frustrated-me&quot;&gt;What frustrated me?&lt;/h2&gt;

&lt;h3 id=&quot;can-i-just-write-the-code-please&quot;&gt;Can I just write the code please?&lt;/h3&gt;

&lt;p&gt;Features that you know can be done quickly in code, but require you to fiddle around the UI for half an hour to find out if there is a way can get frustrating. And once you give up and fix that part in code, you cant import your code back so this component has to be written by hand henceforth &lt;sup id=&quot;fnref:gitdiff&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:gitdiff&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. After the first week I found it easier to setup a CI and starting using my own codebase as the source of truth. &lt;a href=&quot;https://docs.flutter.dev/get-started/install&quot;&gt;Flutter has great docs&lt;/a&gt; and it took &amp;lt; 1 day to setup my dev env + CI.&lt;/p&gt;

&lt;p&gt;FF does offer some ability to write &lt;em&gt;custom code&lt;/em&gt; as functions, but the editor is quite annoying. Copy pasting is janky, error checking is janky, you can’t import packages into the function &lt;sup id=&quot;fnref:noimports&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:noimports&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, plus no CoPilot (&lt;em&gt;Tab&lt;/em&gt; &lt;em&gt;tab&lt;/em&gt; why doesnt it read my mind?! ARGH).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/1-no-imports.png&quot; alt=&quot;No Imports&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Below are some examples of when you’d just want to switch to VS Code:&lt;/p&gt;

&lt;h4 id=&quot;complex-queries&quot;&gt;Complex Queries&lt;/h4&gt;

&lt;p&gt;The flutter flow list views are setup to query firebase using a &lt;strong&gt;single&lt;/strong&gt; query, doing a set of map or filter operations on that query and displaying it.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If you have group-by like queries, you need to write a custom function to serve as the data source.&lt;/li&gt;
  &lt;li&gt;If you want to merge multiple lists to display something, you need to create a container per query which results in a lot of boilerplate code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/2-only-one-query.png&quot; alt=&quot;Only one query allowed&quot; class=&quot;align-left&quot; width=&quot;320px&quot; /&gt;
&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/3-create-containers-for-query.png&quot; alt=&quot;Containers for more queries&quot; class=&quot;align-right&quot; width=&quot;320px&quot; /&gt;&lt;/p&gt;

&lt;h4 class=&quot;cf&quot; id=&quot;dynamic-component-paramenters&quot;&gt;Dynamic component paramenters&lt;/h4&gt;

&lt;p&gt;Some fields in the UI don’t take values from a variable. It was super easy to get the biomarkers graph up and running. But when I wanted to dynamically generate the number of lines on the graph, you can’t do this in FF. The number of lines has to be decided beforehand. You cant even use custom functions for this, you need to edit the component in code.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/4-hardcode-num-datasets.png&quot; alt=&quot;Hardcoded datasets&quot; class=&quot;align-left&quot; width=&quot;340px&quot; /&gt;
&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/5-hard-coded-graph-options.png&quot; alt=&quot;Hardcoded graph options&quot; class=&quot;align-right&quot; width=&quot;340px&quot; /&gt;&lt;/p&gt;

&lt;blockquote class=&quot;cf&quot;&gt;
  &lt;p&gt;I am not sure why the FF devs didn’t simply allow all fields where the datatype is known to be set by a variable. It means no preview sure, but that seems like a fair trade-off.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;ui-nitpicks-that-will-probably-get-fixed-soon&quot;&gt;UI Nitpicks (that will probably get fixed soon)&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Ordering widgets on the UI is quite annoying, especially if you try to move a widget to the end of a list, it has a tendency to go “inside” the last one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/6-cant-move-raw-details-after-card.png&quot; alt=&quot;I want to move the row out of the card!&quot; class=&quot;align-center&quot; width=&quot;400px&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;This one was probably a bug, but it was frustrating nevertheless. It was super easy to create a toggle-able star icon. But for some reason the toggle value box didn’t work. So I couldnt set any value to the toggle. Null values produce an error, and when there is an error anywhere you cant export code from FF. So I cant fix it myself either. So I had to redo the thing as a button and change it to a toggle after exporting. Not fun.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/7-cant-set-toggleicon-value.png&quot; alt=&quot;ToggleIcon is broken&quot; class=&quot;align-center&quot; width=&quot;400px&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;firestore-limitations&quot;&gt;Firestore Limitations&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;You will want to overwrite the Firestore deployed by FF, because the rules FF allows you to create are pretty basic (you can’t have a rule that matches based on logged in email for example). But after this, FF will forever try to delete your changes, so you cannot deploy rules from FF anymore. You can still copy paste from FF. Just make sure to use the “AFTER” tab. The diff tab oddly doesn’t allow you to copy text.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/8-dont-delete-my-rules.png&quot; alt=&quot;Dont delete my rules!&quot; class=&quot;align-center&quot; width=&quot;400px&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;miscellaneous&quot;&gt;Miscellaneous&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;This is a fun one. If you copy the code from the “Code” tab, all the numbers are integers. But if you download the code, they are doubles. I am guessing they run their linter before the download. So, if you generally export the entire code base, but sometimes want to do a quick copy paste of the updated Widget code, have fun merging!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/9-int-or-double.png&quot; alt=&quot;Int or double?&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;code-quality&quot;&gt;Code Quality&lt;/h3&gt;

&lt;p&gt;Generally speaking, I dont have the urge to rewrite all the code so that’s a good start. But hey, I am not a Dart expert, so maybe I will hate my past self for doing this 1 year from now.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The data models seem very tedious and repetitive. Isnt there a simpler ORM for this? The data types are more or less fixed. It’s really annoying to add a new variable to a model in code, I have to change at 5 different places for validation and serializing. Seems like there should be a better way. Maybe this is an ORM and I can use a code generator to generate the files? I dont know.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Code gets exports with lots of unused imports in the files. We also have instances of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import '/backend/schema/util/firestore_util.dart';&lt;/code&gt; where you don’t know which functions are being imported from that file. I prefer them being namespaced.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The styling however is a royal mess of repeated Padding wrappers that I need to clean up. I suspect I could have used Theme Widgets properly to avoid this. But once I setup a Design Libary, the entire UX around theming got too confusing that I gave up. Now I understand it better, but it’s a too late to do on FF. I cannot find a way to create a CustomTextInput and do a project-wide find and replace in FF. Maybe I will do it in code later, once I get a deeper understanding of how layout works in Flutter (it seems different from CSS).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/10-padding-and-padding.png&quot; alt=&quot;Padding, and more padding&quot; class=&quot;align-left&quot; width=&quot;320px&quot; /&gt;
&lt;img src=&quot;../assets/2023-06-23-using-flutter-flow-to-prototype/11-bracket-bracket.png&quot; alt=&quot;Wheeee&quot; class=&quot;align-right&quot; width=&quot;320px&quot; /&gt;&lt;/p&gt;

&lt;h2 class=&quot;cf&quot; id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Extracting out components is useful to maintain reusability in the app. I suggest you do it early and aggressively for every sub-component of a page, even if you don’t think it will get get reused. This helps later in merging manual code changes and FF changes.&lt;/li&gt;
  &lt;li&gt;Create a new Theme Widget whenever you create a widget with new styling.&lt;/li&gt;
  &lt;li&gt;It is fastest to use &lt;a href=&quot;https://www.youtube.com/watch?v=v_hR4K4auoQ&amp;amp;list=PLl-K7zZEsYLluG5MCVEzXAQ7ACZBCuZgZ&quot;&gt;Firestore&lt;/a&gt; to get started with the backend. Define the schema inside FF, sync the rules, and then import data into Firestore to create demo data. I would recommend this over using the App State for demo data. It is just as fast and gives your more flexibility down the line. You can plug &lt;a href=&quot;fowy.io&quot;&gt;Rowy.io&lt;/a&gt; into Firestore to create a quick admin panel.&lt;/li&gt;
  &lt;li&gt;Learn about streams in flutter and use them. It’s like swr in react, with built in changes feed. I was wondering if some redux type data store was needed, but realized I could just use streams everywhere.&lt;/li&gt;
  &lt;li&gt;Typechecking is great in Dart (love the ! and ? operators, it’s a step up from typescript). You can’t have ad-hoc union types though, so you need to be more deliberate with the typing.&lt;/li&gt;
  &lt;li&gt;Flutter has a large library of components, FF simply wraps (most of) them into a simplified interface. It might make sense to use the Flutter directly to speed up development time if you need finer control (I did that with an autocomplete input).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Flutter Flow has created a framework and scaffolding on top of Flutter components, and wrapped it in a decent UI with sensible defaults to quickly get a prototype working. I recommend using it for that, but be prepared to take over the codebase once you hit the limits of the UI which can happen pretty quickly.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:gitdiff&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;You can do some gymnastics using git diffs to an extent but soon it becomes too painful &lt;a href=&quot;#fnref:gitdiff&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:noimports&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;I just wanted to import collections package, but no imports allowed in the function editor &lt;a href=&quot;#fnref:noimports&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>MadNeutrino</name></author><category term="Development" /><summary type="html">To prototype our new app, we decided to use FlutterFlow (FF). Here I share my experience and some recommendations on how to use FF for rapid prototyping.</summary></entry><entry><title type="html">🧪 Optimize Fitness Plan Using Biomarkers</title><link href="https://jezer0x.com/biomarkers-for-fitness/" rel="alternate" type="text/html" title="🧪 Optimize Fitness Plan Using Biomarkers" /><published>2023-04-23T00:00:00+00:00</published><updated>2023-04-23T00:00:00+00:00</updated><id>https://jezer0x.com/biomarkers-for-fitness</id><content type="html" xml:base="https://jezer0x.com/biomarkers-for-fitness/">&lt;p&gt;Personalization plays a vital role in everyone’s fitness journey, as individuals have unique needs and goals that require tailored solutions. Baseline biomarker testing and regular monitoring offer a data-driven approach to personalization, allowing individuals to optimize their fitness routines based on their specific health status, nutritional needs, and genetic predispositions.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;⚠️ Please consult your doctor, trainer, and nutritionist before making any changes to your workout and diet. This article is meant for informational purposes only and is meant to be an exploration into how we can potentially use blood biomarkers to inform our training.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Incorporating baseline biomarker testing and regular monitoring into one’s fitness journey can lead to numerous benefits. These include improved health by addressing specific concerns, optimized progress through tailored workouts and nutrition plans, and increased motivation as individuals can track their progress and see tangible results - ultimately leading to greater efficiency and success.&lt;/p&gt;

&lt;p&gt;In this article, we’ll look at the major biomarkers and how they might help individuals optimize their fitness journey. We’ll divide the article into 3 categories:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;initially designing a unique workout plan&lt;/li&gt;
  &lt;li&gt;periodically adjusting the plan as we gather more data&lt;/li&gt;
  &lt;li&gt;optimizing nutrition as a multiplier,&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;This is a cross post from &lt;a href=&quot;https://sang.bio&quot;&gt;Sang.bio&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;designing-a-customized-exercise-plan&quot;&gt;Designing a Customized Exercise Plan&lt;/h2&gt;

&lt;h3 id=&quot;identifying-genetic-predispositions&quot;&gt;Identifying Genetic Predispositions&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://landen.imgix.net/blog_SxAPxBfkkiNeiPJg/assets/ayIZvFsuCusYBVWp.jpg&quot; alt=&quot;louis-reed-pwcKF7L4-no-unsplash.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Genetic markers can significantly impact your response to different types of exercise, influencing factors such as muscle fiber composition, endurance, strength, and even injury risk. By understanding your genetic predispositions, you can create personalized workout plans that focus on exercises best suited to your genetic makeup.&lt;/p&gt;

&lt;p&gt;Muscle fiber composition, determined by your genes, influences whether you’re more naturally inclined towards endurance or power-based activities. For example, the ACTN3 gene is associated with muscle power, while the ACE gene is linked to endurance. Individuals with specific variants of these genes may have an advantage in either power or endurance exercises. By analyzing your genetic markers, you can tailor your workout plan to focus on activities that align with your muscle fiber composition, maximizing your potential for progress.&lt;/p&gt;

&lt;p&gt;Another example is the PPARA gene, which plays a role in fat metabolism. Certain genetic variants of this gene can influence how effectively an individual burns fat during exercise. By understanding your genetic predisposition related to fat metabolism, you can optimize your workout program by incorporating training methods that are most effective for your specific needs, such as high-intensity interval training (HIIT) or steady-state cardio.&lt;/p&gt;

&lt;p&gt;Genetic predispositions can also influence your injury risk. Some individuals may have a higher genetic susceptibility to tendon or ligament injuries, while others might be more prone to muscle strains. By understanding these genetic factors, you can create a workout plan that prioritizes injury prevention strategies, such as targeted strengthening exercises and mobility work. &lt;a href=&quot;https://www.mensjournal.com/health-fitness/how-your-genes-could-impact-your-fitness-and-health-goals&quot;&gt;You can learn more about the various types of genes that we can look out for here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By using genetic information to create personalized workout plans, you can experience more effective progress and higher satisfaction with your workout program. Embracing your genetic strengths and addressing potential weaknesses allows you to optimize your fitness journey, ensuring that you make the most of your time and effort. The science is very new with this one, but some players in the market are already ahead of the curve trying to put the puzzle pieces together:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://vojo.health/genetics-and-muscle-growth/&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://vojo.health/genetics-and-muscle-growth/&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://vojo.health/genetics-and-muscle-growth/&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://www.fitnessgenes.com/&quot;&gt;Fitness Genes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://dynamicdnalabs.com/&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://vojo.health/genetics-and-muscle-growth/&quot;&gt;vojo.health&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://dynamicdnalabs.com/&quot;&gt;Dynamic DNA Laboratories&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;assessing-baseline-health&quot;&gt;Assessing Baseline Health&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://landen.imgix.net/blog_SxAPxBfkkiNeiPJg/assets/rcwMKunRloLsIBpb.jpg&quot; alt=&quot;kenny-eliason-5ddH9Y2accI-unsplash.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Blood markers play a crucial role in determining your current health status, providing valuable information that can inform the creation of a personalized exercise plan. Some key biomarkers for assessing baseline health include &lt;strong&gt;cholesterol levels (LDL, HDL, total cholesterol, apoB), blood glucose, and inflammation markers (C-reactive protein, CRP).&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Cholesterol levels are essential for understanding your cardiovascular health. High LDL (low-density lipoprotein) and low HDL (high-density lipoprotein) levels are associated with an increased risk of heart disease. &lt;strong&gt;If an individual their LDL, HDL (and apoB) are in non-optimal ranges, we can focus more on moderate-intensity aerobic exercise to decrease the overall risk of cardiovascular disease using multiple pathways.&lt;/strong&gt; &lt;a href=&quot;https://lipidworld.biomedcentral.com/articles/10.1186/s12944-017-0515-5&quot;&gt;&lt;strong&gt;[1]&lt;/strong&gt;&lt;/a&gt; &lt;a href=&quot;https://health.clevelandclinic.org/does-exercise-lower-cholesterol/&quot;&gt;&lt;strong&gt;[2]&lt;/strong&gt;&lt;/a&gt; &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/34792817/&quot;&gt;&lt;strong&gt;[3]&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Blood glucose levels can indicate your risk of developing type 2 diabetes. &lt;strong&gt;If your blood glucose levels are higher than normal, a personalized exercise plan can incorporate activities that help improve long-term insulin sensitivity, such as strength training to build moderate muscle mass.&lt;/strong&gt;&lt;a href=&quot;https://www.mayoclinicproceedings.org/article/S0025-6196(18)30789-4/fulltext&quot;&gt;&lt;strong&gt;[4]&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Inflammation markers, such as C-reactive protein (CRP), can provide insights into your body’s level of inflammation. Chronic inflammation has been linked to various health issues, including heart disease and certain cancers. &lt;strong&gt;If your CRP levels are elevated, a personalized exercise plan can include activities that help reduce inflammation, such as mind-body therapies (yoga, tai chi, etc.)&lt;/strong&gt;&lt;a href=&quot;https://labs.selfdecode.com/blog/how-to-lower-c-reactive-protein/&quot;&gt;&lt;strong&gt;[5]&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This targeted prioritisation of exercise can lead to reduced health risks, improved overall wellness, and more efficient progress toward fitness goals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It can also help towards specific goals.&lt;/strong&gt; Let’s take “muscle building” as a goal and see how this helps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Help build improved cardiovascular health: By incorporating exercises that promote better cardiovascular health, you enable your body to deliver more oxygen and nutrients to your muscles, which supports muscle growth.&lt;/li&gt;
  &lt;li&gt;Better insulin sensitivity: Improved blood glucose management helps your body effectively use the carbohydrates you consume to fuel your workouts and replenish glycogen stores in your muscles, promoting muscle recovery and growth.&lt;/li&gt;
  &lt;li&gt;Reduced inflammation: Lower levels of inflammation can contribute to better recovery, as chronic inflammation may impair the muscle repair process and negatively impact muscle growth.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a person is stalling in their muscle-building journey, these blood markers may be used to see what’s holding them back from reaching their full potential.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In this article we don’t talk about physiological biomarkers such as body mass composition (using a smart scale or a DEXA scan to see bone density, body fat and muscle mass), VO2max estimations, etc. These are useful to track and are already widely used, so we’ll focus on the more novel blood-based and “-omics” based approaches.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;adjusting-workout-based-on-biomarkers&quot;&gt;Adjusting Workout Based on Biomarkers&lt;/h2&gt;

&lt;h3 id=&quot;hormone-levels&quot;&gt;Hormone Levels&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://landen.imgix.net/blog_SxAPxBfkkiNeiPJg/assets/WjXbgFTjgwkeimjt.jpg&quot; alt=&quot;testalize-me-KWb_41kG0GE-unsplash.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Hormone balance plays a significant role in various aspects of fitness, including exercise performance, muscle growth, fat loss, and increased strength. Key hormones, such as cortisol, testosterone, and human growth hormone (HGH), influence these aspects of fitness, and maintaining an optimal balance is essential for progress and injury prevention.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Cortisol, known as the stress hormone, can have both positive and negative effects on fitness. While it helps mobilize energy stores during exercise, chronically elevated cortisol levels can hinder muscle growth, impair recovery, and contribute to fat storage. Cortisol is also used to detect overtraining. Since cortisol swings a lot depending on various factors, not having a fairly regularly measured cortisol level might make you draw the wrong conclusions.&lt;/li&gt;
  &lt;li&gt;Testosterone is crucial for muscle growth, strength development, and fat loss. By monitoring testosterone levels, you can ensure that your workout plan is tailored to support optimal hormonal balance. For example, if your testosterone levels are lower than desired, you might focus on resistance training exercises that are known to stimulate testosterone production, such as compound movements like squats, deadlifts, and bench presses. Ideally, you would use different training regimens to see which elicits&lt;strong&gt;.&lt;/strong&gt; &lt;a href=&quot;https://journals.lww.com/nsca-jscr/Fulltext/2008/03000/Significant_Strength_Gains_Observed_in_Rugby.14.aspx&quot;&gt;&lt;strong&gt;[6]&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Monitoring T:C ratio, along with DHEA and SHBG can help you identify when stress is impacting your fitness progress, allowing you to adjust your workout intensity or incorporate stress-reducing activities such as yoga or meditation.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Human growth hormone (GH) plays a vital role in muscle recovery, growth, and fat metabolism. Monitoring HGH levels can help you optimize your workout plan by identifying the best times for intense training sessions and rest periods. For instance, if your HGH levels are lower than ideal, you might schedule workouts during times when HGH production is typically higher, such as in the late afternoon or early evening, and prioritize adequate sleep for recovery. You can contextualize this data with IGF-1 and LH levels to get a better analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By regularly monitoring hormone levels and using this information to optimize your workout plans, you can experience improved progress across multiple aspects of fitness and reduce the risk of overtraining or injury. Understanding your hormonal balance allows you to make informed decisions about your training, ensuring that you’re working with your body’s natural rhythms for the best possible results.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;ℹ️ While there are research studies backing this article, significant work needs to be done to definitively make recommendations. A lot of these studies were done on elite athletes, though the accessibility of the technology means a lot more athletes are regularly using their blood data. Hopefully, the research will slowly trickle down to laypersons and we’ll have more concrete recommendations to give soon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;recovery-strategy&quot;&gt;Recovery Strategy&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://landen.imgix.net/blog_SxAPxBfkkiNeiPJg/assets/HRLZPxRbnjpQlznF.jpg&quot; alt=&quot;logan-weaver-lgnwvr-amgv9YUg-MA-unsplash.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Recovery is a crucial aspect of overall fitness, as it allows your body to repair and rebuild after exercise, promoting optimal performance and reducing the risk of injury. Biomarkers can provide valuable insights into your recovery needs and help you develop personalized recovery recommendations based on your unique physiological responses to exercise.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Muscle damage markers, such as &lt;strong&gt;myoglobin&lt;/strong&gt;, &lt;strong&gt;Creatine Kinase&lt;/strong&gt; &lt;strong&gt;(CK)&lt;/strong&gt;, and &lt;strong&gt;Urea Nitrogen&lt;/strong&gt;, can indicate the level of muscle stress experienced during your workouts. Elevated myoglobin levels may suggest that you’re experiencing significant muscle damage, which could require additional recovery strategies. By monitoring myoglobin levels, you can identify when you may need to prioritize rest or incorporate targeted recovery techniques, such as gentle stretching, deep tissue massage, or foam rolling to alleviate muscle tension and promote healing. &lt;a href=&quot;https://www.physio-pedia.com/Myoglobin&quot;&gt;[7]&lt;/a&gt; You need to use all these in conjunction, since CK can spike upto 24 hours later and remain elevated for 7 days, while the rest 2 are more immediate and shorter lived. Chronically elevated CK, however, is indicative of insufficient recovery.&lt;/li&gt;
  &lt;li&gt;Inflammation markers, like &lt;strong&gt;interleukin-6 (IL-6)&lt;/strong&gt;, can provide insights into your body’s inflammatory response to exercise. While some inflammation is a natural part of the recovery process, excessive inflammation can hinder your progress and increase the risk of injury. Monitoring IL-6 levels can help you identify when your inflammation levels are higher than desired, allowing you to adjust your training intensity, duration, or frequency, and implement anti-inflammatory strategies such as icing, compression, or the use of nonsteroidal anti-inflammatory drugs (NSAIDs) when appropriate. &lt;a href=&quot;https://faseb.onlinelibrary.wiley.com/doi/epdf/10.1096/fj.201700080R&quot;&gt;[8]&lt;/a&gt; Other biomarkers that can help contextualize actual inflammation are elevated levels of IL-1B, TNF-a, IL-10, IL-8 and IL-12p40.&lt;/li&gt;
  &lt;li&gt;Oxidative stress markers, such as &lt;strong&gt;malondialdehyde&lt;/strong&gt; &lt;strong&gt;(MDA)&lt;/strong&gt;, reflect the balance between free radical production and your body’s antioxidant defenses. Elevated MDA levels can indicate that your body is experiencing excessive oxidative stress, which can impair recovery and contribute to muscle fatigue. By monitoring MDA levels, you can make informed decisions about incorporating antioxidant-rich foods or supplements into your diet, as well as adjusting your training program to manage oxidative stress more effectively.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By using biomarkers to personalize your recovery strategies, you can experience reduced muscle soreness, minimized risk of injury, and improved overall fitness. Regularly monitoring these markers allows you to make data-driven decisions about your recovery needs, ensuring that your body gets the rest and support it requires to maximize the benefits of your workouts.&lt;/p&gt;

&lt;h2 id=&quot;nutrition-as-a-multiplier&quot;&gt;Nutrition as a Multiplier&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://landen.imgix.net/blog_SxAPxBfkkiNeiPJg/assets/ilXpLULpntZBVtwa.jpg&quot; alt=&quot;brooke-lark-jUPOXXRNdcA-unsplash.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Understanding your nutritional status is essential for optimizing your fitness journey, as nutrients play a critical role in exercise performance, recovery, and overall health. Blood markers can provide valuable insights into your nutritional status, helping you identify potential deficiencies, imbalances, or suboptimal macronutrient intake that may be impacting your fitness progress.&lt;/p&gt;

&lt;p&gt;Some key blood markers that can inform your nutritional status and macro/micro-nutrient utilization include:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Amino acid profile&lt;/strong&gt;: Monitoring the levels of essential amino acids, such as branched-chain amino acids (BCAAs) like leucine, isoleucine, and valine, can help you assess your protein intake and utilization. BCAAs play a crucial role in muscle protein synthesis and recovery. By tracking your amino acid profile, you can adjust your protein intake to ensure optimal muscle growth and repair.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Blood glucose and insulin levels&lt;/strong&gt;: These markers can provide insights into how your body is handling carbohydrate intake and metabolism. Monitoring blood glucose and insulin levels can help you optimize your carbohydrate intake to support energy levels, exercise performance, and recovery while minimizing the risk of blood sugar imbalances.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Vitamin D&lt;/strong&gt;: Adequate levels of vitamin D are essential for bone health, immune function, and even muscle function. Low levels of vitamin D can negatively impact your exercise performance and recovery. By monitoring your vitamin D levels, you can adjust your diet or supplementation to ensure optimal levels and support your fitness goals. (B-Complex vitamins and Vitamin A are also ideally monitored, but this is less commonly done.)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Iron&lt;/strong&gt;: Iron is crucial for oxygen transport and energy production, making it a vital nutrient for optimal exercise performance. Monitoring markers such as ferritin and transferrin saturation can help you identify iron deficiency or overload, allowing you to adjust your iron intake accordingly and prevent issues such as fatigue, decreased endurance, or impaired recovery.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Electrolytes&lt;/strong&gt;: Electrolytes, including sodium, potassium, magnesium, zinc, calcium, and chromium are essential for muscle function, hydration, and overall performance. Imbalances in electrolyte levels can lead to cramping, fatigue, or even more severe issues such as hyponatremia. Monitoring your electrolyte levels can help you fine-tune your intake through diet or supplementation to support optimal exercise performance and recovery.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Unique responses to certain foods:&lt;/strong&gt; IgE-based testing can help uncover mild food allergies that hinder progress by keeping different organs in a less-than-ideal state.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By using this information, you can create personalized nutrition plans that address any deficiencies or imbalances and support your fitness goals. This might involve adjusting your macronutrient ratios, incorporating specific nutrient-dense foods, or using supplements to target particular nutrient needs.&lt;/p&gt;

&lt;p&gt;The potential benefits of evaluating your nutritional status and optimizing your nutrition plans include enhanced exercise performance, improved recovery, and overall better health. By tailoring your diet to your unique needs, you can ensure that you’re fueling your body with the right nutrients, providing the foundation for success in your fitness journey.&lt;/p&gt;

&lt;h2 id=&quot;tracking-progress---what-when-and-how-should-we-test&quot;&gt;Tracking Progress - What, When, and How Should We Test?&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://landen.imgix.net/blog_SxAPxBfkkiNeiPJg/assets/DEthQpDvJRZiCRva.jpg&quot; alt=&quot;stephen-dawson-qwtCeJ5cLYs-unsplash.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The sampling above hopefully gives you a sense of the types of things to test.&lt;/p&gt;

&lt;p&gt;To start off, we want to get a &lt;strong&gt;one-time overview&lt;/strong&gt; of your health before you start training - this includes a comprehensive blood panel, genetic tests, and food allergy tests. This allows us to set better goals, set smarter workout plans, and fix nutritional deficiencies with diet and supplementation. All these combined will start us off in a good step.&lt;/p&gt;

&lt;p&gt;After this, we need to &lt;strong&gt;regularly monitor&lt;/strong&gt; 2 types of biomarkers.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Biomarkers we want to optimize for&lt;/strong&gt; (e.g. glucose level variability, ApoB, etc). We need to focus on these by measuring them more frequently. This helps us monitor progress toward our goals.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Biomarkers we want to keep an eye on&lt;/strong&gt; to make sure nothing is hindering progress in an obvious way. This includes markers of inflammation and muscle recovery.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are a few challenges when testing and analysing biomarkers. Remember that:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Single biomarkers are not definitive in diagnosing broad physiological functions&lt;/li&gt;
  &lt;li&gt;Reference ranges for specific subgroups of people are very different from the layperson&lt;/li&gt;
  &lt;li&gt;There’s a lot of interindividual variances when it comes to optimal/base biomarker levels&lt;/li&gt;
  &lt;li&gt;Biomarkers testing/analysis requires a lot of context to get right.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thankfully, with careful planning, these problems can be mitigated.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Take baseline of key markers during “rest week”, or before the training starts. This lets us see changes clearly, and account for individual differences in starting points and ranges.&lt;/li&gt;
  &lt;li&gt;Plan ahead and schedule various biomarker tests ahead of time on a calendar. Some biomarkers, such as glucose levels, can be continuously monitored for a couple weeks by using CGMs. Some finger prick tests can be done every week using at-home kits if we’re anticipating immediate results. Yet others can be done every 4-6 weeks to measure chronic changes over time. Some tests may be not as necessary, be too expensive, or require an IV draw at a clinic - we can monitor them every 3-6 months. All this depends on our focus markers, how quickly they can change given interventions, and how representative spot samples are.&lt;/li&gt;
  &lt;li&gt;Don’t rely on a single biomarker for explaining and prescribing any alterations to the regimen. We need to take multiple biomarker levels over time and compare it against the baseline readings we established earlier, and real-life context to make accurate guesses about what’s happening.&lt;/li&gt;
  &lt;li&gt;Know what biomarkers to test for before starting an intervention. For example, if zinc levels are low and you’re taking zinc supplements, scheduling regular tests for zinc over the next few weeks can tell you whether the particular brand is bioavailable for you.&lt;/li&gt;
  &lt;li&gt;Keep testing conditions static. For example, if we’re testing CK regularly to monitor recovery after an injury, we may decide to always to do it while fasted, in the morning, before training, the day after a rest day, or similar training day. This minimizes confounding effects of other variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are a few articles and a really good research paper that show you how athletes keep tabs on biomarkers to adjust their training:&lt;a href=&quot;https://journals.lww.com/nsca-jscr/Fulltext/2017/10000/Biomarkers_in_Sports_and_Exercise__Tracking.31.aspx&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://journals.lww.com/nsca-jscr/Fulltext/2017/10000/Biomarkers_in_Sports_and_Exercise__Tracking.31.aspx&quot;&gt;Biomarkers in Sports and Exercise, The Journal of Strength and Conditioning Research&lt;/a&gt;&lt;a href=&quot;https://blog.insidetracker.com/blood-testing-athletes-improving-performance-outsmarting-competition&quot;&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.insidetracker.com/blood-testing-athletes-improving-performance-outsmarting-competition&quot;&gt;https://blog.insidetracker.com/blood-testing-athletes-improving-performance-outsmarting-competition&lt;/a&gt;&lt;a href=&quot;https://blog.insidetracker.com/blood-testing-athletes-improving-performance-outsmarting-competition&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://trainright.com/using-blood-biomarkers-to-inform-training/&quot;&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://trainright.com/using-blood-biomarkers-to-inform-training/&quot;&gt;https://trainright.com/using-blood-biomarkers-to-inform-training/&lt;/a&gt;&lt;a href=&quot;https://www.rupahealth.com/post/blood-testing-for-athletes-improving-performance&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://www.rupahealth.com/post/blood-testing-for-athletes-improving-performance&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://www.rupahealth.com/post/blood-testing-for-athletes-improving-performance&quot;&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.rupahealth.com/post/blood-testing-for-athletes-improving-performance&quot;&gt;https://www.rupahealth.com/post/blood-testing-for-athletes-improving-performance&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>psyf</name></author><category term="Healthspan" /><summary type="html">Personalization plays a vital role in everyone’s fitness journey, as individuals have unique needs and goals that require tailored solutions. Baseline biomarker testing and regular monitoring offer a data-driven approach to personalization, allowing individuals to optimize their fitness routines based on their specific health status, nutritional needs, and genetic predispositions.</summary></entry><entry><title type="html">📜 Barren Wuffet - Technical Learnings</title><link href="https://jezer0x.com/bw-dev-learnings/" rel="alternate" type="text/html" title="📜 Barren Wuffet - Technical Learnings" /><published>2023-02-20T00:00:00+00:00</published><updated>2023-02-20T00:00:00+00:00</updated><id>https://jezer0x.com/bw-dev-learnings</id><content type="html" xml:base="https://jezer0x.com/bw-dev-learnings/">&lt;p&gt;It’s August of 2022. &lt;br /&gt;
I’ve understood as much of the tech stack powering blockchains that my brain can hold without exploding. I’ve learnt the basics of smart contracts and security from &lt;a href=&quot;https://cryptozombies.io/&quot;&gt;CryptoZombies&lt;/a&gt; and &lt;a href=&quot;https://ethernaut.openzeppelin.com/&quot;&gt;Ethernaut&lt;/a&gt;. I’ve dabbled in DeFi as a user and tried to understand how each of the protocols were designed. &lt;strong&gt;It’s time to build something of my own.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Luckily, my friends and I were playing around with the idea of a platform where traders could launch actively managed on-chain funds and people could put money in them. It sounded just the right amount of crazy to me that I could vaguely understand which direction to code in, without anticipating all the problems that would come up. This article will discuss the surprising, unanticipated technical learnings from building Barren Wuffet - with the lens of a fresh-faced web3 dev.&lt;/p&gt;

&lt;p class=&quot;notice--info&quot;&gt;The scope of this article is limited to the technical aspects only. If you want to learn more about the intended purpose of the project, or the nitty gritty details of the smart contract, please check out the docs at &lt;a href=&quot;https://barren-wuffet.gitbook.io/barren-wuffet/&quot;&gt;https://barren-wuffet.gitbook.io/barren-wuffet/&lt;/a&gt;. If you want to know why it ultimately failed, please read the &lt;a href=&quot;https://jezer0x.com/bw-post-mortem/&quot;&gt;business post-mortem&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;notice--warning&quot;&gt;Everything I write here is predicated on my own experience circa August 2022. If you have feedback regarding what I could have done better, or if things have changed, please reach out to me on &lt;a href=&quot;https://twitter.com/psyf01&quot;&gt;Twitter&lt;/a&gt; or comment below so I can update this article!&lt;/p&gt;

&lt;p&gt;I’ve split this article into 4 sections: Backend, Infra/Tooling, Frontend and Community. While Web3 systems don’t transfer directly to the Web2 model, it’s an okay way to think about the different aspects of the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let’s dive in!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/KmlTchPoFQT84/giphy.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;backend-peach&quot;&gt;Backend :peach:&lt;/h2&gt;

&lt;h3 id=&quot;evm-ヽ-メノ&quot;&gt;EVM ヽ(`⌒´ メ)ノ&lt;/h3&gt;

&lt;p&gt;By far my biggest frustration was &lt;a href=&quot;https://eips.ethereum.org/EIPS/eip-170&quot;&gt;EIP-170&lt;/a&gt; shipped with the &lt;a href=&quot;https://eips.ethereum.org/EIPS/eip-607&quot;&gt;Spurious Dragon Hard Fork&lt;/a&gt; to counteract DoS vulnerabilities found during the Shanghai Attacks.
I’ve hit this limit at least 3 times as my system evolved to be more complex. Everytime I dreaded the thought of having to refactor to fit within the 24KB limit. This article by &lt;a href=&quot;https://soliditydeveloper.com/max-contract-size&quot;&gt;soliditydeveloper&lt;/a&gt; outlines the different things you can do to be within the limit.&lt;/p&gt;

&lt;p&gt;TLDR:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;separate your contracts well (I was doing this),&lt;/li&gt;
  &lt;li&gt;use libraries (I wasn’t &lt;em&gt;really&lt;/em&gt; doing this, but this created a nice side effect of making the whole thing more readable),&lt;/li&gt;
  &lt;li&gt;use proxies if the contract is deploying child contracts (see below)&lt;/li&gt;
  &lt;li&gt;write only what you &lt;em&gt;must&lt;/em&gt; in contracts (see below)&lt;/li&gt;
  &lt;li&gt;shorten error messages (ended up marking reverts with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;OW1&quot;&lt;/code&gt; and having comments at the top of the file to explain what they mean)&lt;/li&gt;
  &lt;li&gt;change optimizer value to 1 (don’t have to think &lt;em&gt;too&lt;/em&gt; much about gas optimization if I’m on an L2, right?!)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;proxies-galore&quot;&gt;Proxies Galore&lt;/h3&gt;

&lt;p&gt;There are mainly 2 reasons I had to use proxies in the system:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The main contract was deploying child contracts, and I couldn’t pack the child contract’s bytecode into the main contract’s without hitting limits.&lt;sup id=&quot;fnref:children&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:children&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
  &lt;li&gt;We wanted to be able to upgrade contracts without having to redeploy the whole system. (at least until we were out of Beta)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Proxies are &lt;em&gt;confusing&lt;/em&gt; since there are different kinds that evolved over the years, with different use cases and tradeoffs and future consequences. OpenZeppelin has a &lt;a href=&quot;https://docs.openzeppelin.com/contracts/4.x/api/proxy&quot;&gt;well written guide&lt;/a&gt; but I’ll be lying if I say I remember much. The annoying thing is that you have to be aware of the proxy pattern you’re using, think through the workflows and then &lt;em&gt;change your contracts&lt;/em&gt; to fit the pattern. Proxies separate the contract logic and data store; And this can have serious security implications if not handled carefully. It takes you away from the business logic you’re trying to solve. It may be fun to learn, but definitely not fun to test.&lt;/p&gt;

&lt;p&gt;Take a look for yourself. We were using Upgradable Beacon Proxies&lt;sup id=&quot;fnref:diamond&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:diamond&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, if I remember correctly.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-02-21-bw-dev-learnings/arch.png&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;what-should-the-contract-do&quot;&gt;What Should The Contract Do?&lt;/h3&gt;

&lt;p&gt;If gas was free (i.e. the EVM was infinitely scalable), this wouldn’t be something to consider. Just throw in convenience functions, store everything, make the frontend dumb as hell. But gas isn’t free, so you have to think about exactly what smart contracts are for.
Smart Contracts are for replacing trusted third parties. They are not “just a database”. They are for enforcing rules in a system, for which they need to store a minimum set of data. This minimum set of data will &lt;em&gt;also&lt;/em&gt; be used by the frontend to display information to the user.
However, you also have to consider the problem of third party dependency here.&lt;/p&gt;

&lt;p&gt;Let’s take an example to illustrate the problem better. In Barren Wuffet, fund managers would be able to create IFTTT rules for the future, which would be automatically executed in the future. Now, EVM doesn’t have an automatic TX execution hook like that&lt;sup id=&quot;fnref:cosmos&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:cosmos&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;, so someone&lt;sup id=&quot;fnref:anyone&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:anyone&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; has to send a TX to trigger the execution. The smart contract has to make sure whatever is being triggered matches the IFTTT rule the fund manager specified (otherwise a whitelisted bot run by the fund manager will have to do it, which defeats the point of the setup &lt;sup id=&quot;fnref:permissioned-bot&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:permissioned-bot&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;). To do this, the smart contract has to store some info verify the rule that’s being executed. There are 2 ways of doing this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Smart Contract stores the entire IFTTT rule with all its triggers, actions and their parameters and gives back an identifier for this rule. Later, someone can send a TX saying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execute(id)&lt;/code&gt;. Smart Contract would lookup in a mapping &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id =&amp;gt; IFTTTRule&lt;/code&gt;, check that on-chain trigger conditions are met and execute the actions. Frontend would only have to be aware of the id. This incurs extra gas cost at rule creation time because we are storing the entire rule in the contract.&lt;/li&gt;
  &lt;li&gt;Smart Contract stores &lt;em&gt;a hash&lt;/em&gt; - a deterministic unique identifier - of the IFTTT rule. When some bot thinks it’s time to execute the rule, it sends a TX saying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execute(IFTTTRUle)&lt;/code&gt; and the smart contract just checks that the hash of the IFTTT rule matches the hash it has stored. Frontend would have to be aware of the entire IFTTT rule (it would read this from the events emitted by the contract). This incurs extra gas cost at execution time because we are sending the entire rule as calldata to the contract. This is more akin to the “UTXO model” of Bitcoin and Cardano.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In both these cases, you need to think about “data availability”. Do you expect frontends to keep track of the entire history of the contract and lookup/reconstruct the data? Do you use something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;The Graph&lt;/code&gt; that the frontend queries? What happens if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;The Graph&lt;/code&gt; goes down? (see more below). Does the gas cost economics make sense for the use case?&lt;/p&gt;

&lt;p&gt;No clear answers!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/3o6nV9XlrejzaBtKZq/giphy.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;admin-functions---wheres-the-balance&quot;&gt;“Admin” Functions - Where’s The Balance?&lt;/h3&gt;

&lt;p&gt;If you come from a web2 backend world, you’re used to being a “superuser” who can do anything - mostly for fixing bugs. This is not the case in Ethereum.&lt;/p&gt;

&lt;p&gt;You can get to an abusive level of power with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onlyOwner&lt;/code&gt; modifiers, but then would users use the product? &lt;br /&gt;
You could decentralize the onlyOwner &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;invocations&lt;/code&gt; with a DAO model, but would that have enough velocity to catch and fix bugs in the future?&lt;/p&gt;

&lt;p&gt;No easy answers here either. What we ended up doing is limiting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onlyOwner&lt;/code&gt; functions to the bare minimum - pausing during an attack, upgrading the contract logic, and then designing an emergency “escape hatch” for the community to use in case they feel this power is being abused. We wanted to retain the ability to move fast (i.e. have a small multisig of founding team), with plans to decentralize some things in the future (DAO), deprecate the upgrade-ability (why would you need this if it’s been stable for a while on mainnet?) and then finally remove the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onlyOwner&lt;/code&gt; functions altogether.&lt;/p&gt;

&lt;p&gt;Open a dialogue with your community and see what they are comfortable with.&lt;/p&gt;

&lt;h3 id=&quot;test-test-and-test-some-more-º--º-ll&quot;&gt;Test, Test and Test Some More ＼(º □ º l|l)/&lt;/h3&gt;

&lt;p&gt;I &lt;em&gt;hate&lt;/em&gt; writing tests.&lt;/p&gt;

&lt;p&gt;There was a running joke on the team - if you want Psyf to be productive, ask him to write tests and he’ll get everything else in the org done first just to avoid writing tests.&lt;/p&gt;

&lt;p&gt;Jokes aside, props to Madneutrino for setting up the first set of tests and getting me to write more (even though a redesign made us remove EVERY TEST I HAD PAINSTAKINGLY WRITTEN…UGHHHH). Tests meant I was able to refactor the codebase and make changes (add/remove) with confidence that I did not break something - especially when it came to large scale refactors involving proxies and contract size.&lt;/p&gt;

&lt;p&gt;Tests with very high coverage are particularly important with smart contracts because they are immutable (barring doors you create for yourself using proxies). Bugs can be expensive, and the entire contract is open for anyone to exploit.&lt;/p&gt;

&lt;p&gt;The setup / teardown tools provided by hardhat make it easy to instantiate and test the contracts easily. It even gives you information about where in the smart contract the errors happened. You will have to use (convenient af) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console.log()&lt;/code&gt; to troubleshoot, though.&lt;/p&gt;

&lt;h3 id=&quot;debuggability&quot;&gt;Debuggability&lt;/h3&gt;

&lt;p&gt;It’s useful to write good error messages and define every error scenario in a smart contract. Tests that verify the specific error messages in error scenarios are useful here. Once it goes to production, there is no stack trace, since you dont control the backend. You only get the text of the error message you throw.&lt;/p&gt;

&lt;p&gt;This can be quite important even if you are contract is functioning fine, you still need to figure out what’s going on when your front end inevitably sends some buggy data to the testnet, and you want to know why on earth the tx reverted!&lt;/p&gt;

&lt;p&gt;Another way is to use tools like &lt;a href=&quot;https://tenderly.co/&quot;&gt;Tenderly&lt;/a&gt; to simulate the reverted transaction step by step.&lt;/p&gt;

&lt;h3 id=&quot;decimalswhy&quot;&gt;Decimals…WHY?&lt;/h3&gt;

&lt;p&gt;The amount of time Madneutrino and I wasted on figuring out how to handle decimals makes me want to cry.&lt;/p&gt;

&lt;p&gt;Different popular ERC20s use different decimals. &lt;br /&gt;
Chainlink returns different decimals for each price feed. &lt;br /&gt;
You have to account for both decimals when doing math like combining ETH/USD and UNI/USD to ETH/UNI. &lt;br /&gt;
Different smart contracts expect different decimals when you send them limits for slippage. &lt;br /&gt;
Do you lose resolution if you go through this workflow? &lt;br /&gt;
Do your order of operations potentially make something go to zero in error? &lt;br /&gt;
Are there tokens you can’t handle? &lt;br /&gt;
Can you handle events like the UST crash?&lt;/p&gt;

&lt;p&gt;It’s a confusing mess. I wish we had just used 18 decimals everywhere.&lt;/p&gt;

&lt;p&gt;But then again, the front end user doesn’t want to see 18 decimals of everything. In fact, they mostly want to see values in USD (or maybe ETH).
So your significant figures translations have to be rock solid.&lt;/p&gt;

&lt;p&gt;We wrote a lot of utils to handle this (feel free to use them!). You can also find similar ones in other defi contracts that handle swaps.&lt;/p&gt;

&lt;p&gt;True story, this was the most used gif on our discord for a while.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/lQCV6K36nJfJYNxXbC/giphy.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;can-we-just-all-agree-to-use-weth-please&quot;&gt;Can we just all agree to use WETH, please?&lt;/h3&gt;

&lt;p&gt;The amount of code I had to write for different pathways of ERC20 and ETH for each integration (both input and output combinations) just makes me want to die.
I discovered Uniswap v3’s way of writing contracts for ERC20 and using WETH wrapper for ETH way too late :sad-face:&lt;/p&gt;

&lt;h2 id=&quot;infra-and-tooling-hammer_and_pick&quot;&gt;Infra and Tooling :hammer_and_pick:&lt;/h2&gt;

&lt;h3 id=&quot;chainlink-wheres-the-feed-registry-on-arbitrum-bro&quot;&gt;Chainlink, where’s the Feed Registry on Arbitrum Bro?&lt;/h3&gt;

&lt;p&gt;Don’t get me wrong - Chainlink is awesome and has powered a lot of the DeFi infrastructure. Their integration guides are nice and easy.&lt;/p&gt;

&lt;p&gt;BUT, the contract has to know which contract to call to get ETH/USD, and which to call to get UNI/USD and so on…So you have to spend all that gas saving this into your contracts. Then you have to have a workflow for updating these addresses when they change.
Chainlink has rolled out a &lt;a href=&quot;https://docs.chain.link/data-feeds/feed-registry&quot;&gt;Feed Registry&lt;/a&gt; so the contract can query at runtime, but I have zero idea why this is only available on Ethereum Mainnet. So now I have to write this extra contract to act as the chainlink registry when I deploy on other L2s (we were going to do this on Arbitrum, and then mainnet/Optimism/otherL2s later).&lt;/p&gt;

&lt;p&gt;We should focus a bit more on DevEx as a space.&lt;/p&gt;

&lt;h3 id=&quot;gelato-is-delicious&quot;&gt;Gelato Is Delicious&lt;/h3&gt;

&lt;p&gt;I initially nerd-sniped myself into the project by thinking about “good MEV” and how to align incentive mechanisms so that an IFTTT ecosystem could have strong guarantees. Ultimately, I caved in and just assumed we were going to use Gelato to start off.
Their docs were awesome and the devs in the discord were helpful. I was able to get a working prototype up and running in a few hours!&lt;/p&gt;

&lt;p&gt;There are 2 things to nitpick though:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;When I was integrating, they had rolled out some new upgrades to their contracts and the docs hadn’t been updated to reflect that. So I had to go and read the smart contracts and figure things out myself. They’ve now updated them, but I bring this up because I’ve seen this happen in multiple protocols.&lt;/li&gt;
  &lt;li&gt;Their bot is closed-source and the network hasn’t decentralized yet. So I had to write extra code to pretend to be the bot in my integration tests. So even though I did assume we’re going to use Gelato, I had to design the code such that it would be easy to swap out the Gelato integration for something else (e.g. a bot the DAO maintained, or anyone else could participate in for altruism/MEV).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;forking-is-awesome&quot;&gt;Forking Is Awesome&lt;/h3&gt;

&lt;p&gt;I was dreading setting up hardhat for forking Arbitrum Mainnet, but it was actually pretty easy&lt;sup id=&quot;fnref:notreally&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:notreally&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;. This is perhaps my favourite feature of developing smart contracts. You just grab an API key from Alchemy and then you can fork mainnet and test your code against it. You don’t have to write mocks for anything you’re integrating with - just use hardhat to send TX from a different address. This is a HUGE time saver - to the point where I almost never had an isolated local node running. Quite proud of how frictionless the test suite was to run, to be honest.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/ZB95y3XSFbljaNu7mT/giphy.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;testnets-are-not-as-clean-as-you-think&quot;&gt;Testnets are Not As Clean As You Think&lt;/h3&gt;

&lt;p&gt;Perhaps this problem was exacerbated by my timing, but deploying to testnet was a pain because:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Some platforms had different contracts on testnet than they did on mainnet. So documentation was behind, sometimes the changes were not backwards-compatible, and I had to code in-faith that they’d have deployed to mainnet by the time we were ready to launch.&lt;/li&gt;
  &lt;li&gt;The Ropsten, Rinkeby and Kovan nets were being deprecated, and everyone hadn’t moved over properly to Goerli yet.&lt;/li&gt;
  &lt;li&gt;Getting Goerli ETH was such a pain. Faucets were clogged or drained, and I had to waste multiple hours of my time and several days of CPU cycles to get enough testnet ETH. Not cool.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The decentralized community is incentivised to perform various actions on the mainnet (LP, nodes). Who has an incentive to run testnet nodes? It has to be the centralized players behind the smart contracts. No one cares enough to deploy contracts to arbitrum-goerli, so they test on eth-goerli. But USDT-ETH is empty, and 1 ETH is a million DAI. Also, there are subtle differences between arbitrum-goerli and eth-goerli; So when you are building a contract that interfaces with many other contracts, you are necessarily doing a bit of testing in production.&lt;/p&gt;

&lt;h3 id=&quot;decentralized-price-feeds-for-frontend&quot;&gt;Decentralized Price Feeds For Frontend&lt;/h3&gt;

&lt;p&gt;For all the hullaballoo about decentralizing frontends that I’ve been hearing forever, I was really surprised when I couldn’t find a decentralized price feed to show to the traders (think TradingView Charts on the frontend, marked by their positions and drawings).
ALL the options were centralized, and were too expensive for a beta launch, and had terrible granularity (once per 5 mins? really?). I’m talking spot prices, not even OHLC or something fancier. We have Chainlink prices every block, why can’t we just make a subgraph on the graph? We have DEXs with subgraphs, why can’t they have prices? (sometimes one of a few of these things did exist, but NOT FOR L2s. UGH!). Why can I not easily deploy the code of a subgraph to a different chain? Why can’t I build on top of a subgraph’s output without re-indexing the entire chain?&lt;/p&gt;

&lt;p&gt;Shout-out to my homies at Coingecko and DefiLlama for giving us free access to their APIs so we could at least keep building. I love animals! (NFA)&lt;/p&gt;

&lt;h3 id=&quot;why-are-audits-so-expensive&quot;&gt;Why Are Audits So Expensive?&lt;/h3&gt;

&lt;p&gt;Of course, being our first novel smart contract system, we wanted to make sure it was audited by someone more experienced. We used our experience, lessons learnt from Ethernaut, integrating knowledge of hacks we saw, and tools like Slyther and Mythril to get “audit ready”. Yet, audits costs would be so prohibitively expensive (6 figures!) that we’d definitely not be able to do that without VC money or launching a token (neither of which we wanted to do at this point in time).&lt;/p&gt;

&lt;p&gt;I’m not sure why 6 figure audits are a thing. Was that because of the bull market? It also looks like that auditor incentives are not aligned with the protocol’s - auditors don’t pay anything (except perhaps with reputation currency) in the case of a hack. Our strategy was to do a controlled launch (limited users, limited money that they could put in), until we had enough money to pay for an audit. We also planned on rolling out a small bug bounty right from the alpha release to incentivize people to find bugs.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/yIxNOXEMpqkqA/giphy.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If I was doing it now, I’d probably be using GPT3 a bit for security analysis. A team (&lt;a href=&quot;https://www.fortephy.com/&quot;&gt;Fortephy&lt;/a&gt;) has already done some work on using AI to do audits much cheaper. I’d probably talk to people from the Code4rena community to see if they could help us out as well.&lt;/p&gt;

&lt;h2 id=&quot;frontend-eyes&quot;&gt;Frontend :eyes:&lt;/h2&gt;

&lt;h3 id=&quot;typing-coding-once-is-for-n00bs-you-got-to-do-it-twice-to-really-learn&quot;&gt;Typing: Coding once is for n00bs, you got to do it twice to really learn&lt;/h3&gt;

&lt;p&gt;You have written your contracts, and you have the abi. How do you use them in your frontend?
Oh but first, we have to write those tests in typescript right? How do we handle calls to the contract, without going back and forth to figure out the exact functions and calldata? &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hardhat-ethers&lt;/code&gt; makes this as easy as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;contract&amp;gt;.connect(&amp;lt;wallet&amp;gt;).&amp;lt;fnname&amp;gt;(&amp;lt;data&amp;gt;)&lt;/code&gt; and you have nice autocomplete available if you type the contract properly thanks to typechain.&lt;/p&gt;

&lt;p&gt;But when you come to the front end, you cant simply copy paste this code you so painstakingly wrote, because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hardhart-ethers&lt;/code&gt; is not a front end thing, because…well, you aren’t using hardhat.&lt;/p&gt;

&lt;p&gt;This is where it gets a bit painful on 2 counts:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;If you are writing truly reactive code, using say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;react-query&lt;/code&gt; to read from an RPC, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wagmi&lt;/code&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;usePrepareContractWrite&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;useContractWrite&lt;/code&gt; flows, you need to ditch all the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;awaits&lt;/code&gt; from the tests. I think this is excellent practice, as it forces you to limit your async code and extract out the non-async code as functional components. We didn’t quite do that in our tests so some refactoring was in order.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The bigger problem though was the typing. We couldn’t get the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typechain&lt;/code&gt; interfaces to play well with wagmi, which only accepts ABIs. The best way to do this is to convert your json abi files (from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;artifacts&lt;/code&gt; folder) into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ts&lt;/code&gt; files and then load the abi into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;usePrepareContractWrite&lt;/code&gt;. You then get static type-checking, but it is subtly different from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typechain&lt;/code&gt; interface (which has a lot of utility functions especially when it comes to things like enums). And so you resign to your fate of re-organizing the tests you already wrote to fit into the front end.
But hey you learn to write disciplined functional code in the process. Win some, lose some, right? &lt;sup id=&quot;fnref:copilot&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:copilot&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;writing-txs--post&quot;&gt;Writing TXs != POST&lt;/h3&gt;

&lt;p&gt;Writing TX to a blockchain is all async, so it’s not like your usual HTTP POST call. When you send a tx, you have to wait for it to be mined, and then you want to wait for the block to be confirmed. This process could take a while and the UI needs to reflect that.&lt;/p&gt;

&lt;p&gt;This gets particularly complicated when the first tx needs to be followed up with a second tx (create a fund, set rules for the fund after you create it). You need to make sure that the second tx is sent only after the first tx is confirmed. You could let the user operate on an expected state meanwhile, but you might end up having to revert the state if the first tx fails.&lt;/p&gt;

&lt;p&gt;The graph also only returns data from confirmed txes, you would need to store these pending state in local storage, and merge them with the graph data if the page gets refreshed.
If the user opens the app in a different browser, they wont see this unconfirmed data. The UI needs to make sure that the user is aware of this.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://wagmi.sh/&quot;&gt;WAGMI&lt;/a&gt; helps you handle some of these state changes using React Hooks, but the UX around this takes some thought.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/4FT4I2eg2zVkUHe7wz/giphy.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;take-the-time-to-search-for-nice-libraries&quot;&gt;Take The Time To Search For Nice Libraries&lt;/h3&gt;

&lt;p&gt;We’ve already mentioned WAGMI above. This + &lt;a href=&quot;https://www.rainbowkit.com/docs/installation&quot;&gt;RainbowKit&lt;/a&gt; encapsulate a lot of the complexity of interacting with the blockchain - chain selection, transaction broadcasting, reading from the chain - in a nice way.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.tradingview.com/HTML5-stock-forex-bitcoin-charting-library/&quot;&gt;TradingView&lt;/a&gt; was also super useful for everything we wanted to do out of the box.&lt;/p&gt;

&lt;p&gt;If we hadn’t used these, we would have had to write a lot more code to handle all the edge cases.&lt;/p&gt;

&lt;h3 id=&quot;where-does-frontend-get-info&quot;&gt;Where Does Frontend Get Info?&lt;/h3&gt;

&lt;p&gt;Firstly, it’s important to use a decentralized service, but The Graph hadn’t decentralized yet (not on L2s at least). Infura hasn’t decentralized yet. Both have plans of doing so.&lt;/p&gt;

&lt;p&gt;Secondly, you also have to decide what to use The Graph for, what to use the wallet’s provider for, and what to use Alchemy for when the dapp is not connected to the wallet. \&lt;/p&gt;

&lt;p&gt;Also worth mentioning: Every time I mentioned The Graph some dev that we were using The Graph, they sounded concerned and asked us about the backup plans.&lt;/p&gt;

&lt;p&gt;It’s also interesting that token lists are maintained as JSON files in frontend repos. Then you have to maintain one for each testnet. Some don’t have the tokens you want.
Similarly, you have to curate a list of addresses that are related to your protocol, times each chain you’re deploying on.&lt;/p&gt;

&lt;h2 id=&quot;community-heart&quot;&gt;Community :heart:&lt;/h2&gt;

&lt;h3 id=&quot;community-makes-or-breaks-this-space-of-builders&quot;&gt;Community Makes or Breaks This Space of Builders&lt;/h3&gt;

&lt;p&gt;One of the biggest surprises in my short dev career is how helpful devs can be.
Uniswap was one of my first protocol integrations and I was having quite some trouble different aspects (especially with LP-ing). I was able to get help from CryptoRachel on their discord.
I was similarly having trouble with the GMX integration, and Itburnz was able to help me out. Itburnz has since become a friend of the project and joined our discord. I’ve mentioned Gelato, DefiLlama and coingecko before.
I’ve also had the pleasure of taking help from various individuals who joined our twitter and startups that agreed to let us test their product for free. (Already mentioned Fortephy before, and there was also &lt;a href=&quot;https://www.guardrail.ai/&quot;&gt;Guardrail&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;On the flip side, I’ve stopped working on some integrations and products because nobody answered my questions.&lt;/p&gt;

&lt;p&gt;What I’ve found is as long as you are nice and respectful, describe the problem in the right level of detail and tell them what you’ve tried, people are generally willing to help you with pointers and advice. &lt;br /&gt;
Mandatory reading that teaches you this: &lt;a href=&quot;https://stackoverflow.com/help/how-to-ask&quot;&gt;https://stackoverflow.com/help/how-to-ask&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;having-usable-latest-documentation-is-important&quot;&gt;Having Usable, Latest Documentation is Important&lt;/h3&gt;

&lt;p&gt;This should be really self-explanatory for any open-source project, especially things people build on top of.&lt;/p&gt;

&lt;p&gt;I won’t belabour this point, other than the fact that it inspired me to create &lt;a href=&quot;https://barren-wuffet.gitbook.io/barren-wuffet/&quot;&gt;https://barren-wuffet.gitbook.io/barren-wuffet/&lt;/a&gt; and think about how to structure it for various audiences.&lt;/p&gt;

&lt;h2 id=&quot;keep-buidling-degens&quot;&gt;Keep Buidling, Degens!&lt;/h2&gt;

&lt;p&gt;Thanks for reading all the way down this laundry list of learnings, and for tolerating the occasional whiny vents .-.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/CuuSHzuc0O166MRfjt/giphy.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:children&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;If you’re curious why: a lot of smart contracts do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.sender&lt;/code&gt; based accounting instead of position based ones. This means we need to deploy new child contracts to keep the positions of funds separate (for security reasons mostly). &lt;a href=&quot;#fnref:children&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:diamond&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;I believe the “Diamond Pattern” is in vogue now, but I didn’t get the chance to use that (would be overkill). &lt;a href=&quot;#fnref:diamond&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:cosmos&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Cosmos SDK does &lt;a href=&quot;#fnref:cosmos&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:anyone&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;In fact, anyone, if you want the contract to be decentralized &lt;a href=&quot;#fnref:anyone&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:permissioned-bot&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;If the fund manager is whitelisted to run a bot to execute the trigger, that means they have to run special infrastructure to use the system which makes their lives harder. It also means, we can trust whatever the whitelisted bot does, so the bot can handle the IFTTT triggers and we don’t have to do this in-contract so the entire architecture will be different. &lt;a href=&quot;#fnref:permissioned-bot&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:notreally&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Well… is anything really &lt;em&gt;that&lt;/em&gt; easy in this space? Arbitrum had just done the Nitro upgrade, and hardhat’s forking broke. I hope they’ve patched it by now. &lt;a href=&quot;#fnref:notreally&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:copilot&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Here I must thank CoPilot for easing my burden somewhat, this is exactly the kind of thing humans shouldn’t be doing. &lt;a href=&quot;#fnref:copilot&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>psyf</name></author><category term="Development" /><summary type="html">It’s August of 2022. I’ve understood as much of the tech stack powering blockchains that my brain can hold without exploding. I’ve learnt the basics of smart contracts and security from CryptoZombies and Ethernaut. I’ve dabbled in DeFi as a user and tried to understand how each of the protocols were designed. It’s time to build something of my own.</summary></entry><entry><title type="html">🪦 Barren Wuffet Post Mortem</title><link href="https://jezer0x.com/bw-post-mortem/" rel="alternate" type="text/html" title="🪦 Barren Wuffet Post Mortem" /><published>2023-02-17T00:00:00+00:00</published><updated>2023-02-17T00:00:00+00:00</updated><id>https://jezer0x.com/bw-post-mortem</id><content type="html" xml:base="https://jezer0x.com/bw-post-mortem/">&lt;p&gt;Barren Wuffet was created with the aim of assisting individuals to navigate the DeFi ecosystem and crypto trading while adhering to the web3 philosophy and building with the help of the community. The collapse of 3AC, Voyager, and Celsius led us to develop an on-chain, self-custodial fund management platform, allowing traders to manage funds without having direct access to them. By logging traders’ actions on-chain, their historical performance and trading strategies could be verified by anyone at any time.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-02-17-bw-post-mortem/wb_logo.png&quot; alt=&quot;WB logo.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;However, the venture came to an early end due to flawed assumptions regarding the business concept, divergent objectives, and a lack of understanding regarding stakeholder needs. Despite our experience in lean customer development as seasoned entrepreneurs, it is still possible to fall victim to suboptimal business-building practices. In this article, we will examine our errors and the reasons behind them.&lt;/p&gt;

&lt;p class=&quot;notice--info&quot;&gt;If you want to see where we got to technically, you can check out the docs at &lt;a href=&quot;https://barren-wuffet.gitbook.io/barren-wuffet/&quot;&gt;https://barren-wuffet.gitbook.io/barren-wuffet/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;fails&quot;&gt;Fails&lt;/h2&gt;

&lt;h3 id=&quot;understand-your-customers&quot;&gt;Understand your customers&lt;/h3&gt;

&lt;p&gt;The most critical aspect of product development is securing early customers who are willing to pay for the product before it is built, either through advance payments or by providing feedback during the development process. Unfortunately, we failed to attract a sufficient number of customers who were genuinely interested in our product. Rather than seeking out potential customers, we relied on reverse reasoning to validate the existence of a market for our product. This approach hindered our ability to create demand for the product. As a domain expert, I provided justifications that customers couldn’t envision the product because it was a novel concept. I also convinced my team that I could represent the customer and knew precisely what was necessary to build. Looking back, these were merely standard excuses to avoid rejection associated with customer development.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.tenor.com/M6KYKYfHGQcAAAAC/aakash-mehta-customer-is-king.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;sloppy-landscape-analysis&quot;&gt;Sloppy landscape analysis&lt;/h3&gt;

&lt;p&gt;My team members were also seeking validation in their own ways. The brain has a way of alleviating fears of being wrong. We took comfort in the fact that there were similar solutions like &lt;a href=&quot;http://stfx.io/&quot;&gt;STFX.io&lt;/a&gt;, a developer working on a copy trade platform for GMX, traders who ran paid signal groups, and trading bot marketplaces. We believed this confirmed the existence of a market. However, many traders we reached out to were not interested, and while we did not receive a clear reason, analyzing how our competition structured their product led us to believe that tax and regulatory implications in their respective markets may have played a role. We justified the existence of Warrent Buffet by pointing out flaws in our competitors’ models, but we did not stop to ask ourselves why they avoided the obvious route of allowing a trader to manage a self-custodial portfolio through copy trading.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.tenor.com/Rc3ei0zZ-1gAAAAd/im-trying-to-convince-myself-that-im-doing-the-right-thing.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;regulation&quot;&gt;Regulation&lt;/h3&gt;

&lt;p&gt;From the outset, our goal was to create a community-led product that would come into being once it attained a certain level of maturity and acceptance. As developers, we believed that we were not subject to any regulations since we were not offering financial advice or managing funds, and since our platform was self-custodial, even traders didn’t have access to the funds. However, this belief was misguided and resulted in significant delays and complications.&lt;/p&gt;

&lt;p&gt;Although cryptocurrency regulations were not present in the past, governments and regulatory bodies worldwide have recently published draft financial regulations that could have far-reaching consequences for new entrants in the industry. We wanted to ensure that we were in compliance with the laws and that our platform users were not in breach of them either. While these laws are not currently in effect, the prospect of having to navigate bureaucratic obstacles in the future was unappealing to us.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.tenor.com/I_wa224mwNYAAAAS/you-know-my-values-steve-horn.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;conflicting-interests&quot;&gt;Conflicting interests&lt;/h3&gt;

&lt;p&gt;We spent the first six months of 2022 familiarizing ourselves with the technical aspects of the web3 ecosystem. We wanted to work on a meaningful project that wasn’t too complex for our current technical capabilities, and that we could scale to a reasonable size without external funding. Our idea was that if we built something that solved a problem, we would have a product that could act as a cash cow to fund our future experiments. We didn’t want to launch a token, as we felt this went against our ethos. Instead, we wanted to build a product that could potentially share revenue with the community in the future via contributions based on NFTs. However, we soon realized that the community needed an incentive to contribute, and tokens had become the preferred currency to seed initial interest and onboard influencers. We also realized that navigating the regulatory challenges would require us to have the assistance of people who have experience with this and funds, which meant potentially raising money and launching a token in the future. This went against our ethos of putting the community first and having a project that was a cash cow.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.tenor.com/DXrCfM5OHg8AAAAC/hamilton-alexander-hamilton.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;wins&quot;&gt;Wins&lt;/h2&gt;

&lt;h3 id=&quot;lean-development&quot;&gt;Lean Development&lt;/h3&gt;

&lt;p&gt;Despite the challenges, we were able to maintain a lean approach and keep our burn rate low while staying accountable. We focused on defining the minimum viable product, honing in on the core function that would demonstrate its value. To keep costs down, we outsourced non-essential components such as front-end and design to freelancers we found through networking and Upwork. We used DALL-E to generate our logo and memes, and gave advisory equity to friends in the legal industry to help us navigate the legal challenges we faced.&lt;/p&gt;

&lt;h3 id=&quot;tripwires&quot;&gt;Tripwires&lt;/h3&gt;

&lt;p&gt;One of the most critical tools we used to stay on track were tripwires, a combination of deadlines and key success metrics. If we didn’t meet a metric by the deadline, we would review the entire plan, including whether we were fooling ourselves with any of our hypotheses. We had monthly tripwires, and when we repeatedly fell short on revenue and assets deposited, we faced the reality that it was time to shut down the project in December.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.tenor.com/Gbo-UG4grlgAAAAC/soldier-boy-oh-fuck.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Our experience with Barren Wuffet reinforced the importance of customer development, and we’re now refocusing on this crucial step. We’ve learned that the cost of wasting time acquiring customers through subsidizing their adoption cost with VC money is much higher than the time spent validating a pain point by speaking with potential customers. Most of our problems above would have been addressed if we had started with interviewing potential traders.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.tenor.com/iDZGIqYsEEEAAAAS/fake-call-dialing.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;</content><author><name>krenzx</name></author><category term="Business" /><summary type="html">Barren Wuffet was created with the aim of assisting individuals to navigate the DeFi ecosystem and crypto trading while adhering to the web3 philosophy and building with the help of the community. The collapse of 3AC, Voyager, and Celsius led us to develop an on-chain, self-custodial fund management platform, allowing traders to manage funds without having direct access to them. By logging traders’ actions on-chain, their historical performance and trading strategies could be verified by anyone at any time.</summary></entry><entry><title type="html">🦾 Using External APIs to Augment LLMs</title><link href="https://jezer0x.com/using-external-apis-to-augment-llms/" rel="alternate" type="text/html" title="🦾 Using External APIs to Augment LLMs" /><published>2023-02-17T00:00:00+00:00</published><updated>2023-02-17T00:00:00+00:00</updated><id>https://jezer0x.com/using-external-apis-to-augment-llms</id><content type="html" xml:base="https://jezer0x.com/using-external-apis-to-augment-llms/">&lt;h2 id=&quot;why-do-we-need-to-augment-llms&quot;&gt;Why do we need to augment LLMs?&lt;/h2&gt;

&lt;p&gt;We know that LLMs aren’t always accurate. They do some kind of broad pattern matching, and get the general context good enough to be convincing. But, they bad at math or computational responses.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/n8IDk4HoJJu18IqQIX/giphy.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Could we make the LLMs work with external data sources or APIs that are good at math, computation, fact checking such that they provide more accurate responses?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I want to explore ToolFormer and reAct, 2 ways augmenting LLMs to work with external APIs to improve their accuracy.&lt;/p&gt;

&lt;h2 id=&quot;toolformer&quot;&gt;Toolformer&lt;/h2&gt;

&lt;h3 id=&quot;how-does-it-work&quot;&gt;How does it work?&lt;/h3&gt;

&lt;p&gt;Meta research recently shared ToolFormer, a tool to teach LLMs to call external APIs to augment its response. Here is a &lt;a href=&quot;https://twitter.com/mathemagic1an/status/1624870248221663232&quot;&gt;nice summary&lt;/a&gt; of what it does.&lt;/p&gt;

&lt;p&gt;In ToolFormer, you pre-train the LLM with examples, so it can, by itself, &lt;strong&gt;figure out what APIs are useful for what data&lt;/strong&gt;. In other words, by teaching it to convert a statement like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Two + Three = Five&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Two + Three = Calculator(2+3)&lt;/code&gt;, you teach it to respond to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Two + Three = &lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator(2+3)&lt;/code&gt;. And then we code up the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator&lt;/code&gt; API to get the answer, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Five&lt;/code&gt; and the LLM continues from there.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgflip.com/1p4trj.jpg&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;How does it know that the right thing to call here is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator(2+3)&lt;/code&gt; and not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculater(2-3)&lt;/code&gt;? You rely on the LLM’s existing ability to make decent guesses and fine tune it.&lt;/p&gt;

&lt;p&gt;This is done per-API. In the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator&lt;/code&gt;, the LLM makes repeated guesses on WHEN and WHAT to call the API with and checks if it gave the correct result. In this case, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculater(2-3)&lt;/code&gt; results in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Minus One&lt;/code&gt;, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculater(2+3)&lt;/code&gt; results in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Five&lt;/code&gt;, so the latter is the correct guess. It might similarly try to use Calculator on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Three&lt;/code&gt; by guessing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator(2)&lt;/code&gt; (and a bunch of other guess) but none of them will give the correct answer so it will discard that guess. The paper says the calculator was trained with a million documents, but it found only a few thousand documents where it was actually useful to call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;why-is-this-interesting&quot;&gt;Why is this interesting?&lt;/h3&gt;

&lt;p&gt;Typically when you train LLMs, you teach it to guess the next word / token in a sequence. That means we would teach the LLM to say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Five&lt;/code&gt; when prompted with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Two + Three = &lt;/code&gt;. In ToolFormer, we teach the LLM to say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator(2+3)&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Five&lt;/code&gt;. Note that, this doesnt mean the LLM knows to say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator(Number(Two) + Number(Three))&lt;/code&gt;. Each pass is done with 1 specific tool (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator&lt;/code&gt; in this case), and it learns where that specific tool can give the correct answer by trying to call the tool with various inputs.&lt;/p&gt;

&lt;p&gt;One of the main advances here seems to be that you can use a much smaller LLM like GPT2 or GPTJ outperform plain GPT3 when they are able to call external APis to augment the LLM predictions. Which makes sense: As long as the base LLM is smart enough to use the tools provided to it, it will be better than a larger model which is limited by what it knows and its ability to predict the answer by itself.&lt;/p&gt;

&lt;h2 id=&quot;react&quot;&gt;reAct&lt;/h2&gt;

&lt;h3 id=&quot;how-does-it-work-1&quot;&gt;How does it work?&lt;/h3&gt;

&lt;p&gt;There is also some overlap with the reAct framework, we are still trying to get the LLM to answer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Two + Three = &lt;/code&gt; as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator(2+3)&lt;/code&gt; but the approach is a bit different.&lt;/p&gt;

&lt;p&gt;You can see how it breaks down the problem in this more fleshed out example provided in the langchain implementation of reAct:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://langchain.readthedocs.io/en/latest/modules/agents/implementations/react.html&quot;&gt;ReAct — 🦜🔗 LangChain 0.0.84&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The difference in approach here is that, with each Tool (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Calculator&lt;/code&gt; is a Tool in this setup), you need to provide a text description. The LLM uses this text description to figure out if it’s the right tool for the job, and it also guesses what to call it with. The example above shows the default Search Tool, but you can create custom Tools. All you need to do a provide a description and specify the “type” of the tool.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://langchain.readthedocs.io/en/latest/modules/agents/examples/custom_tools.html&quot;&gt;Defining Custom Tools — 🦜🔗 LangChain 0.0.84&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/doYuyYIEkAYPJYrwvM/giphy.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;why-is-this-interesting-1&quot;&gt;Why is this interesting?&lt;/h3&gt;

&lt;p&gt;The nice thing to notice from the complex examples above (“Author David Chanoff has collaborated with a U.S. Navy admiral who served as the ambassador to the United Kingdom under which President?”) is that reAct is doing nested queries because it is considering the prompt as a whole. It breaks down the prompt, finds the the answer to the first query, using that response to do the next query till it finds the answer.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/xTeWOVI8shjIDTq9Yk/giphy.gif&quot; alt=&quot;&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;ToolFormer isn’t designed to do that, it’s explicitly trained to specific words / tokens with API calls - but the point of ToolFormer is that it expects much less of the LLM it’s working with. reAct will give you garbage unless the base LLM is very good.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I dont know of research comparing applying reAct vs toolformer to a sophisticated LLM like GPT3 using the ToolFormer dataset (we dont want to test ToolFormer on nested queries, it’s not designed for it). I suspect that toolformer will do a better job, because you would need a much smarter model to figure out what API to call with what inputs based on the description alone.&lt;/p&gt;</content><author><name>MadNeutrino</name></author><category term="AI" /><summary type="html">Why do we need to augment LLMs?</summary></entry><entry><title type="html">🪄 Prompting GPT to Write Code</title><link href="https://jezer0x.com/prompting-gpt-to-code/" rel="alternate" type="text/html" title="🪄 Prompting GPT to Write Code" /><published>2023-02-02T00:00:00+00:00</published><updated>2023-02-06T00:00:00+00:00</updated><id>https://jezer0x.com/prompting-gpt-to-code</id><content type="html" xml:base="https://jezer0x.com/prompting-gpt-to-code/">&lt;p&gt;ChatGPT’s ability to write code (in addition to an uncanny ability to “understand” what we are saying) has fascinated all of us the last couple months.&lt;/p&gt;

&lt;p&gt;In this post, I want to compile some attempts to nudge GPT to write runnable code [as opposed to just guiding us with principles and snippets as we outlined &lt;a href=&quot;https://www.jezer0x.com/trading-bot/&quot;&gt;in our earlier post&lt;/a&gt;]. Can we prime GPT in a such a way as to remove the developer from the loop?&lt;/p&gt;

&lt;h2 id=&quot;copilot&quot;&gt;CoPilot&lt;/h2&gt;

&lt;p&gt;Before we get into directly working with GPT, we must talk about CoPilot. It has been around for a while and saved many hours of developer time. I have been very impressed by its abilities to generate boilerplate / repetitive code based on what I have already written. It is also good at writing out functions based on comments that document the function.&lt;/p&gt;

&lt;p&gt;CoPilot is based on Codex, which is currently based on GPT3. ChatGPT is based on a newer 3.5 version (which I think is currently cut ahead of copilot). CoPilot is specifically structured to complete code that you start writing.&lt;/p&gt;

&lt;p&gt;Here is a good analysis of what CoPilot is actually doing under the hood: &lt;a href=&quot;https://thakkarparth007.github.io/copilot-explorer/posts/copilot-internals&quot;&gt;https://thakkarparth007.github.io/copilot-explorer/posts/copilot-internals&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It sends the code from the file you are currently in + other files in your project using the same programming language and asks GPT to generate a completion for the code you are currently writing. Then it does a bunch of cleanup and presents you the autocompletion.&lt;/p&gt;

&lt;p&gt;This interface is restrictive when you want to write code from scratch.&lt;/p&gt;

&lt;p&gt;In this article, we will explore some attempts&lt;sup id=&quot;fnref:upg&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:upg&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; to directly interface with GPT to generate code and the prompts being used to do the same.&lt;/p&gt;

&lt;h2 id=&quot;simple-website&quot;&gt;Simple Website&lt;/h2&gt;

&lt;p&gt;Let’s start with an example of someone using ChatGPT to create the html, js and css files of a website.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;//www.youtube.com/watch?v=ng438SIXyW4?width=100&amp;amp;height=50&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Compared to CoPilot, this is better interface for writing code from scratch. You dont have to write any code to prime the model. The prompts are quite straightforward and specify what is needed in English. The dev mentions specific technologies to use, asks for specific code snippets and ChatGPT gets it in the right ballpark. Most of the code is used as-is, but the dev does end up making some minor changes by hand.&lt;/p&gt;

&lt;p&gt;A job board is a common website pattern and ChatGPT ought to have a lot of examples to generate from. One might have to offer more detailed guidance if you are building something new.&lt;/p&gt;

&lt;h2 id=&quot;custom-json&quot;&gt;Custom &lt;strong&gt;JSON&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Can we ask GPT to generate JSON based on templates or examples?&lt;/p&gt;

&lt;h3 id=&quot;basic&quot;&gt;Basic&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/yoheinakajima/status/1617954171780747265&quot;&gt;This example&lt;/a&gt; uses a very simple prompt and a couple of example JSON to generate Zapier tasks (the examples arent shown but the prompt is). The generated JSON seems to have been imported fine into Zapier.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-02-02-prompting-gpt-to-code/zapier-zap.png&quot; alt=&quot;zapier-zap&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;intermediate&quot;&gt;Intermediate&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/colinfortuner/status/1619558128772874245?s=46&amp;amp;t=SGTwwmdLIR_cbQuYZSSsrg&quot;&gt;Here is a slightly more advanced approach&lt;/a&gt;. GPT is given a json &lt;strong&gt;type&lt;/strong&gt;, and asked to generate Fake JSON for testing. You can see the instructions show examples only of the &lt;em&gt;format&lt;/em&gt; of correct and wrong answers with some guidance on JSON structure expected. I expect these fine tunings were in response to issues found while testing. Examples generally seem to help a lot! This is called few-shot learning.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2023-02-02-prompting-gpt-to-code/typed-testing.png&quot; alt=&quot;typed-testing&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;eyes&quot;&gt;:eyes:&lt;/h3&gt;

&lt;p&gt;We can go one step further, and &lt;a href=&quot;https://github.com/TheAppleTucker/backend-GPT/blob/main/backend/server.py&quot;&gt;ask it to BE the entire API&lt;/a&gt;. The dev has simply described Database State in JSON, specified the api call to respond to&lt;sup id=&quot;fnref:api-call-format&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:api-call-format&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, an app description. He then gives general instructions to GPT to respond with JSON, and show the new state. The starting Database State seeds GPT with example data. Even though this isn’t specifically labeled as an example, GPT seems to know enough to return the right JSON when you query something. If you look at the code, even the parsing is done using GPT by replaying its own response and asking to return either the state or the response.
This works surprisingly well! It even filters correctly if you do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET /todolist/?completed=false&lt;/code&gt;. And there is an example for an entire chess engine built this way!&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;This&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;todo&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;API&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Call&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;indexes&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;are&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;indexed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;todolist&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Database&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;todos&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Learn react&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;completed&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Buy Milk&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;completed&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Do laundry&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;completed&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Clean room&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;completed&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;API&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prefixed&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;API response:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Then&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;database&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prefixed&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;New Database State:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;API&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;only&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;requesting&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;don&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;t change the database state, but base your &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;API&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; off what&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A TodoList is very common application, but it is still amazing how much implicit knowledge GPT knew without us being explicit about it.&lt;/p&gt;

&lt;h2 id=&quot;browser-manipulation&quot;&gt;&lt;strong&gt;Browser manipulation&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Here are 2 examples which define a subset of commands, a detailed description and prime GPT to convert english text into set of browser actions.&lt;/p&gt;

&lt;h3 id=&quot;actgpt&quot;&gt;&lt;a href=&quot;https://yihui.dev/actgpt&quot;&gt;ActGPT&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;This uses selenium and here you give very specific instructions to GPT (go to wikipedia, find a text box that is visible, enter gpt into the textbox etc.)&lt;/p&gt;

&lt;p&gt;Here is the preparatory prompt&lt;/p&gt;

&lt;div class=&quot;language-jsx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;You&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;an&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`env`&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;following&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`env.driver.find_elements(by='id', value=None)`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;which&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;finds&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;WebElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arguement&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`by`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;that&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;specifies&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;locator&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;strategy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arguement&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`value`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;that&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;specifies&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;locator&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`by`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;usually&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`xpath`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`value`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;xpath&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`env.find_nearest(e, xpath)`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;can&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;only&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;used&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;locate&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;an&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;that&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;matches&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;xpath&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;near&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`env.send_keys(text)`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;only&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;used&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`text`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ENTER&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ENTER&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`env.get(url)`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;goes&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`env.get_openai_response(text)`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;that&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ask&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AI&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;about&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`text`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`env.click(element)`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;clicks&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;WebElement&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;functions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`element.text`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`element.get_attribute(attr)`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;attribute&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;attribute&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;does&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;exist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`element.find_elements(by='id', value=None)`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;s the same as `env.driver.find_elements()` except that it only searches the children of the element.
4.  `element.is_displayed()` returns if the element is visible

The xpath of a textbox is usually &quot;//div[@role = &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textarea&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;]|//div[@role = &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textbox&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;]|//input&quot;.
The xpath of text is usually &quot;//*[string-length(text()) &amp;gt; 0]&quot;.
The xpath for a button is usually &quot;//div[@role = &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;]|//button&quot;.
The xpath for an element whose text is &quot;text&quot; is &quot;//*[text() = &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;]&quot;.
The xpath for the tweet is &quot;//span[contains(text(), &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;)]&quot;.
The xpath for the like button is &quot;//div[@role != &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; and @data-testid=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;like&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;]|//button&quot;.
The xpath for the unlike button is &quot;//div[@role != &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; and @data-testid=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unlike&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;]|//button&quot;.

Your code must obey the following constraints:
1. respect the lowercase and uppercase letters in the instruction.
2. Does not call any functions besides those given above and those defined by the base language spec.
3. has correct indentation.
4. only write code
5. only do what I instructed you to do.

write code:
1. go to www.wikipedia.org
2. find all textboxes. find one from them that is visible
... and you can give it more instructions ...
20. click on the nearest like button

```python
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A thin wrapper around selenium API is explained to GPT and it writes code to perform the actions specified using the selenium api. It is then directly passed into exec.&lt;/p&gt;

&lt;p&gt;Some useful pointers that were mentioned and used in the above project.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;End the prompt with backquote ```python, so GPT understands it’s writing code.&lt;/li&gt;
  &lt;li&gt;When the prompt becomes longer and longer, sometimes GPT gets confused. It’s better to dynamically load relevant rules or use chain of thoughts - &lt;strong&gt;the prompt provides the api to be used instead of the full selenium api.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Set constraints helps reducing hallucinations such as “Does not call any functions besides those given above and those defined by the base language spec.” - &lt;strong&gt;this also stops it from writing random python code with imaginary apis.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;natbot&quot;&gt;&lt;a href=&quot;https://github.com/nat/natbot/blob/main/natbot.py&quot;&gt;Natbot&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;The natbot is more useful IMO than ActGPT as it lets you specify broad objectives and let GPT figure out what to do. It’s simpler version of adept.ai.&lt;/p&gt;

&lt;p&gt;This defines a set of instructions (SCROLL UP, SCROLL DOWN, CLICK X, TYPE X “TEXT” etc.) that represent the next action to be performed on the browser at each step. This is then parsed using custom code and sent to Playwright (a headless browser tool like selenium).&lt;/p&gt;

&lt;p&gt;The prompt explains the DSL, gives a few examples and sends the following with an generic objective (eg. “Find a 2 bedroom house for sale in Anchorage AK for under $750k”)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CURRENT BROWSER CONTENT:
------------------
$browser_content
------------------

OBJECTIVE: $objective
CURRENT URL: $url
PREVIOUS COMMAND: $previous_command
YOUR COMMAND:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The browser generates the instruction (eg. TYPESUBMIT X “anchorage redfin”) to perform the next action at each step.&lt;/p&gt;

&lt;p&gt;The prompt is similar to ActGPT, but asks GPT to take the decision on what action to perform based on the HTML and an objective. It would be interesting to see if we can remove the custom instructions and ask GPT to generate the playwright code directly.&lt;/p&gt;

&lt;h2 id=&quot;what-did-we-learn&quot;&gt;What did we learn?&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Give 2-3 examples (referred to as few-shot-learning in many LLM (GPT is an LLM, a Large Language Model) libraries) after your description on the type of answer you need.&lt;/li&gt;
  &lt;li&gt;Limit the scope of what the LLM operates on so it doesnt hallucinate too much.&lt;/li&gt;
  &lt;li&gt;It also helps to specify what you dont want, along with what you want.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my next post, I will try using some of these learnings to actually get GPT to write an end-to-end program.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:upg&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;To get a sense of what could ultimately be possible with GPT, look at &lt;a href=&quot;https://github.com/gptlabs/tools/tree/canary/packages&quot;&gt;UPG&lt;/a&gt;. They have an interface where GPT codes entire programs with you, works with you to make changes, writes it to a file and then executes it for you. However the prompt is hidden behind an API so we dont know what prompt they use. &lt;a href=&quot;#fnref:upg&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:api-call-format&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;This can be in any format. A REST API call, a graphql query, a python function. There is no predefined format specified for the API, so GPT will adapt its response to each request. You do need to setup you server to receive the requests, and encoded it as text though. &lt;a href=&quot;#fnref:api-call-format&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>MadNeutrino</name></author><category term="AI" /><summary type="html">ChatGPT’s ability to write code (in addition to an uncanny ability to “understand” what we are saying) has fascinated all of us the last couple months.</summary></entry><entry><title type="html">💸 Lessons From A 23YO First Cycler</title><link href="https://jezer0x.com/crypto-investing-as-a-23-year-old/" rel="alternate" type="text/html" title="💸 Lessons From A 23YO First Cycler" /><published>2023-02-01T00:00:00+00:00</published><updated>2023-02-04T00:00:00+00:00</updated><id>https://jezer0x.com/crypto-investing-as-a-23-year-old</id><content type="html" xml:base="https://jezer0x.com/crypto-investing-as-a-23-year-old/">&lt;p&gt;It’s been about 18 months since I started investing in crypto. Yep, I’m a “top-signal baby” 👶&lt;/p&gt;

&lt;p&gt;At the peaks and troughs of the market, the market stops thinking rationally and you get drunk on groupthink. I’ve made my fair share of mistakes. I’ve also stopped myself from making some big ones thanks to a few principles I follow. This is the story of a first cycler. Hopefully, it will act as guardrails for myself (and others!) for the upcoming market cycle(s).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/BIN5glg3g2cJLXet7q/giphy.gif&quot; alt=&quot;NFA&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;notice--info&quot;&gt;It’s important to judge the thought process instead of the results, since the result could have been a fluke. I will still be illustrating my bad results sometimes to hit the point home.&lt;/p&gt;

&lt;h2 id=&quot;may-2021&quot;&gt;May, 2021&lt;/h2&gt;

&lt;p&gt;I’m freshly minted out of a CS degree from a reputable university, and I’ve been learning the ropes at a Web2 startup as fast as I could.
For the first time in life I can afford Startbucks without feeling &lt;em&gt;too&lt;/em&gt; guilty about it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/sKma6XaxyeNUs/giphy.gif&quot; alt=&quot;Starbucks&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;“Hmmm…”, I thought, “If I have money to burn on mediocre-at-best drinks, maybe it’s time for me to learn about investing”.
I read up on the usual suspects - Rich Dad Poor Dad, The Psychology of Money, Die with Zero, etc. These forced me to think clearly about my relationship with money and how I want to change it moving forward. Part of the money puzzle was investments - and it was obvious to me that I wanted to be a long-term investor, instead of putting it in a “savings account” or becoming a daytrader&lt;sup id=&quot;fnref:daytrading&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:daytrading&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Buuuuut I wasn’t not sure what to invest in.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Financial Advisors seemed to have misaligned incentives.&lt;/li&gt;
  &lt;li&gt;Opening a robo-advisor was easy, and I regularly put some money in. Too boring.&lt;/li&gt;
  &lt;li&gt;Trying to open a SAXO account for investing in ETFs and stockpicking had such a bad UX that I kinda gave up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During this time, I was introduced to Bitcoin and Ethereum by krenzx. This was around DeFi Summer, and I was fascinated by the idea of a decentralized (censorship-resistant, permissionless, trustless, and immutable) alternate financial system. I joined crypto twitter and discord servers - people seemed to have a grand time getting rich supporting a good cause and being at the cutting edge of tech! I was sold.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/l0IykOsxLECVejOzm/giphy.gif&quot; alt=&quot;conspiracy&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Buying the first bit of ETH took some time. &lt;br /&gt;
SO. MANY. QUESTIONS! &lt;br /&gt;
Isn’t KYC against the ethos? &lt;br /&gt;
Isn’t stablecoin making us dependent on the centralized financial system? &lt;br /&gt;
What’s an exchange? What wallet should I use? &lt;br /&gt;
What’s a private key and how should I secure it? &lt;br /&gt;
What’s all these squiggly lines people draw on charts and predict so confidently?&lt;/p&gt;

&lt;p&gt;Once I found good-enough answers, I decided to put some skin in the game by buying a few hundred dollars of ETH.
Soon I figured that I did not want to learn more about “Technical Analysis” and instead wanted to learn about the underlying tech that powers blockchains.&lt;/p&gt;

&lt;p class=&quot;notice--success&quot;&gt;✅ I didn’t go all in because I was still learning. But putting some money in would motivate me to learn more.&lt;/p&gt;

&lt;p class=&quot;notice--success&quot;&gt;✅ Learning about the underlying tech is more akin to “Fundamental Analysis” and is better suited to my longer time horizon. Worst case scenario, I pick up new software skills.&lt;/p&gt;

&lt;p&gt;Krenzx was a huge fan of Thorchain’s RUNE around this time, and predicting how it’d 10x soon. I intuited the necessity of a cross-chain DEX after my horrible CEX experience with Binance and Crypto.com (spoiler alert: I did not know what any of these meant). So I started allocating my monthly investment to RUNE instead of ETH and BTC. My average RUNE price was around $4. I was convinced that I was going to have 6 figures wired to my bank account in a few months :D&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/tGlVbAFCJqXzSGvnS1/giphy.gif&quot; alt=&quot;6 figures&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ I deviated from my plan of “only invest in blue chips” without a good reason. Greed.&lt;/p&gt;

&lt;h2 id=&quot;november-2021&quot;&gt;November, 2021&lt;/h2&gt;

&lt;p&gt;I negotiated a nice little bonus and invested most of it in 1 shot.&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ I wasn’t trying to time the market, but turned out I invested very close to the top. Always DCA&lt;sup id=&quot;fnref:dca&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:dca&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/jTrMNc8FPZntcZmSS7/giphy.gif&quot; alt=&quot;allin&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Somewhere around this time, the $THOR IDO happened and I was lucky enough to get in - promptly getting dumped on and losing the small amount I put in plus the fees in the eye-watering gas wars. “No worries, good experience to feel what ICO mania felt like”, I thought.&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ Retroactively rationalizing stupidity. The main intention wasn’t to know what ICO mania felt like.&lt;/p&gt;

&lt;p&gt;Most of my bags are still ETH, BTC and RUNE. I can branch out a bit and put some money into other projects, right? Call it an exploratory budget.
Let me install the FTX app and log my trades there so I can see how I’m faring in the market.&lt;/p&gt;

&lt;p class=&quot;notice--success&quot;&gt;✅ Exploring is fun and I learn through the process. Good decision to set bounds around this, within which I can be guilt free.&lt;/p&gt;

&lt;p class=&quot;notice--success&quot;&gt;✅ Tracking my trades is a good way to keep myself accountable. I can see how I’m doing and make adjustments if needed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/URW2lPzihY5fq/giphy-downsized-large.gif&quot; alt=&quot;calculate&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I started learning about Finance, how DeFi protocols worked, how to write smart contracts, etc. That’s all I consumed when I was not sleeping/working/spending time with someone else. Crypto Youtube, Crypto Twitter. Checking prices obsessively every few minutes - even though I only bought once a month.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/FuSJ5C7SSHlZCxjC6q/giphy-downsized-large.gif&quot; alt=&quot;obsessed&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ Putting all your attention into one thing is similar to putting all your eggs in one basket. Good way to get burnt out, lose focus, or fuck up mental health.&lt;/p&gt;

&lt;p&gt;I started seeing “Ponzinomics” and (3,3) everywhere. Guess I’m stupid to question whether “Ponzi” is a good thing or not, since all these smart sounding people seem to be right and getting rich off of it. Algorithmic stablecoins sound like a terrific idea! Buy a bit of $LUNA even though Do Kwon seems like a dick. He’s just trolling, right? All the posts against $LUNA is probably just FUD by jealous people who missed the train.&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ I didn’t do my own research and just followed the crowd. During a bull market, everyone seems like a genius. If you’re invested in a project, you should pay special attention to the negative news and try to bucket them into FUD vs valid argument.&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ Do Kwon being a dick and &lt;em&gt;the persona&lt;/em&gt; for Terra was a clear red flag that I ignored.&lt;/p&gt;

&lt;p&gt;While we’re at it, why not invest in this upcoming project? $VADER sounds like they’re gonna improve $LUNA with more ponzinomics. I don’t know how it works but everyone is saying it’ll go up. Just put some money in. What are all these new coins in the Cosmos ecosystem? I’ll just buy a bit of each even though I have no idea. No ETH killers though, I’m not stupid. SO I won’t even take the time to study them properly because all the previous ETH-killers were dud. Boo SOLANA and AVALANCHE!&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ Classic FOMO with $VADER and Cosmos coins. DYOR always. If you don’t understand it, don’t invest. There will be LOTS of trains to catch and you only have to catch 1 to get rich. No need to try and catch all.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/e0ixZgambeBsvdIGAE/giphy.gif&quot; alt=&quot;fomo&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ Just because I was so heavily invested into ETH, I had allergic reactions against “ETH Killers” and didn’t even bother to study them properly. Had I done so, at least I’d learn more about consensus mechanisms, why the merge was taking so long, and how the EVM was a bottleneck from some perspectives.&lt;/p&gt;

&lt;p&gt;OOOOH Chainlink and The Graph seem to be crucial to the smart contract system, better buy some LINK and GRT. Didn’t even know what tokenomics meant.&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ Just because X protocol has usage by devs doesn’t mean $X has value. Taking a second to think about Econ 101 supply-demand dynamics would have been a good idea.&lt;/p&gt;

&lt;h2 id=&quot;may-2022&quot;&gt;May, 2022&lt;/h2&gt;

&lt;p&gt;Terra death spiral happened in astonishing speed, and the contagion felt terrible. What a crash! I was already numb to the pain by June of 2022 (or so I thought, lol). Of course, all of this was the fault of centralized bad actors, how would I have known? It was buidl market! I’d left my job earlier and was full time into crypto, trying to build something novel in Web 3.0! Always buy the dip! So even though my net worth was down bad, I had other things to think about. Prices would take care of themselves since I had conviction on any asset that wasn’t close to 0 by now (read: ETH, BTC, RUNE). I’ll just keep hodling and wait for the next bull run. I’ll probably hodl forever!&lt;/p&gt;

&lt;p class=&quot;notice--success&quot;&gt;✅ What’s happened has happened. No point overthinking the could haves.&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ It might be someone else’s fault, but I suffer the consequences.&lt;/p&gt;

&lt;p class=&quot;notice--danger&quot;&gt;❌ I rode coins to 0 because I had no exit plan - neither stop-loss, nor take-profit. A podcast episode from Tascha Labs convinced me this was a bad idea. I had to internalize that investor psyf (the one that was motivated by money), and buidler psyf (the one that was motivated by the potential and the ethos) had to sometimes work at odds and that’s okay.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/NTur7XlVDUdqM/giphy.gif&quot; alt=&quot;thisisfine&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Lesson learnt: decide on a stop-loss and take-profit when you’re entering a position. Since DeFi tools to do that don’t exist yet, I would have to manually execute them. Never touching a CEX again!&lt;/p&gt;

&lt;p class=&quot;notice--success&quot;&gt;✅ Adjusting strategy based on new information is a good thing. I’m glad I learned this lesson.&lt;/p&gt;

&lt;p class=&quot;notice--success&quot;&gt;✅ Sticking to DEX-es was ultimately a decision based on the desire to fit in with the ethos of the space. It ultimately helped me avoid having funds stolen in the FTX collapse. Use CEX to onramp, and then move to self-custody. Trust me, the gas prices are worth it.&lt;/p&gt;

&lt;p&gt;Maybe it’s time I remove the single points of failure. Buy a ledger, distribute horcruxes to friends and family and make a secure backup plan. Do the same for multiple wallets.&lt;/p&gt;

&lt;p class=&quot;notice--success&quot;&gt;✅ Backup plans + multiple wallets = no fear of completely fucking up. Sleep better at night.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/IWfm4Mcfjw4Yo/giphy.gif&quot; alt=&quot;ready&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;november-2022&quot;&gt;November, 2022&lt;/h2&gt;

&lt;p&gt;FTX unravelling happened at a crazy pace. Thank God I took self custody seriously. Heart goes out to everyone affected in this and the following contagion.
Not making a lot of mistakes these days, but that might just be a side effect of pausing my DCA to keep investments to build up a personal runway. Invest some money on what makes you happier long term - travel, mental health, physical health, gifts for friends.&lt;/p&gt;

&lt;p class=&quot;notice--success&quot;&gt;✅ If you have a runway, you’ll be less emotional with decisions. It also enforces “don’t invest more than you can afford to lose” to a certain extent.&lt;/p&gt;

&lt;p class=&quot;notice--success&quot;&gt;✅ Your mind, body and relationships are your biggest asset. The ROI of figuring things out and putting in good systems early in your 20s is way higher than DCA-ing another 1k into crypto.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/j0eRJzyW7XjMpu1Pqd/giphy.gif&quot; alt=&quot;curious&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;february-2023&quot;&gt;February, 2023&lt;/h2&gt;

&lt;p&gt;Wrote a post about my journey so far&lt;sup id=&quot;fnref:recursion&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:recursion&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.
Started DCA-ing back in because I think we’re close to the bottom.&lt;/p&gt;

&lt;p&gt;Now that I’ve experienced first-hand the result of not following (or following) popular and “boring” investment advice, I’m more confident about what I want and what works.
Here’s my plan for the next 2 years:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;80% of the upcoming investments will be DCA into assets I believe in, rest of the 20% is exploration budget for more exciting bets.&lt;sup id=&quot;fnref:bags&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:bags&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
  &lt;li&gt;I have stop-losses and take-profits in my head. I know what I’ll ride down to 0.&lt;/li&gt;
  &lt;li&gt;I have bounds on how much I’ll invest.&lt;/li&gt;
  &lt;li&gt;I will not buy or sell without due dilligence, but I won’t have analysis paralysis either.&lt;sup id=&quot;fnref:analysis&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:analysis&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
  &lt;li&gt;I will remove single points of failure everywhere, but not spread myself too thin either.&lt;/li&gt;
  &lt;li&gt;I will stick to self-custody.&lt;/li&gt;
  &lt;li&gt;I will not lose sight of why I’m doing this in the first place.&lt;/li&gt;
  &lt;li&gt;I will be accountable for my mistakes, which means I will take an honest assessment and improve anything within my control.&lt;/li&gt;
  &lt;li&gt;I will keep learning technical skills so I can contribute to building a decentralized web.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the end of 2030, I might be a millionaire, or I might be broke, or I might still sit on what I have now. Either way, I’ll be happy because I’m playing the game I want to play the way I want to play it.&lt;/p&gt;

&lt;p&gt;Trust the process.&lt;/p&gt;

&lt;p&gt;Enjoy the journey.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/hqoInD6ATfvW0/giphy.gif&quot; alt=&quot;dancing&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:daytrading&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Day Trading feels like monkeys pulling levers randomly, but using random ass lines drawn on a chart to justify to themselves that it’s not random. &lt;a href=&quot;#fnref:daytrading&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:dca&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;dollar cost averaging &lt;a href=&quot;#fnref:dca&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:recursion&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;That’s called recursion ;) &lt;a href=&quot;#fnref:recursion&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:bags&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;If you’re still curious about my bag: I’ve divested out of BTC because I don’t have confidence in the community being able to evolve. ETH I still DCA into because Lindy, and the core community still has the ethos and drive to keep improving (see the Merge, EIP4844, etc.). All the other “dust” bags are not worth selling off, let ‘em ride (none were shitcoins anyways, so there’s some probability few will survive till the next bull). RUNE I hold - still feels important to a multichain world and is slowly gaining adoption, though I think the community needs to grow up and be more effective at execution. &lt;a href=&quot;#fnref:bags&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:analysis&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;This means looking at the community dialogue, tokenomics and actual utility of the token, understand well the whitepaper and the unique tech fueling the protocol, look at counterarguments and then augment my git feeling to make a call on whether I want to invest or not. &lt;a href=&quot;#fnref:analysis&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>psyf</name></author><category term="Crypto" /><category term="Investment" /><summary type="html">It’s been about 18 months since I started investing in crypto. Yep, I’m a “top-signal baby” 👶</summary></entry><entry><title type="html">🤖 ChatGPT As An Assistant Developer</title><link href="https://jezer0x.com/trading-bot/" rel="alternate" type="text/html" title="🤖 ChatGPT As An Assistant Developer" /><published>2022-12-30T00:00:00+00:00</published><updated>2023-01-03T00:00:00+00:00</updated><id>https://jezer0x.com/trading-bot</id><content type="html" xml:base="https://jezer0x.com/trading-bot/">&lt;h2 id=&quot;the-task&quot;&gt;The Task&lt;/h2&gt;

&lt;p&gt;I was feeling pretty down after we had to close down a project we had been working on for months and wanted to take a small break from smart contracts to collect my thoughts about what we did wrong. Around the same time, I was digging around Github Copilot and OpenAI’s GPT3. They released ChatGPT right around then, and - like most people - I was blown away by its abilities. The new Large Language Model was inpiring me to build something fun and useful to test its limits. But what?&lt;/p&gt;

&lt;p&gt;Krenzx was following some Telegram groups that made trading calls in crypto markets and boasted about their success. Maybe we could make a bot that would execute those calls automatically and make some money?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2022-12-30-trading-bot/call_example.png&quot; alt=&quot;Trading Calls&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As someone who had never traded before&lt;sup id=&quot;fnref:seriously&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:seriously&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, I saw this as the perfect opportunity.&lt;/p&gt;

&lt;h2 id=&quot;the-test&quot;&gt;The Test&lt;/h2&gt;

&lt;p&gt;There were 2 metrics to test the LLMs against:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;How much Google/StackOverflow do I need?&lt;/li&gt;
  &lt;li&gt;How fast can I iterate on the product?&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Hey, could you write me a &lt;strong&gt;Python&lt;/strong&gt; script that takes in &lt;strong&gt;trading calls&lt;/strong&gt; from a &lt;strong&gt;Telegram group&lt;/strong&gt; and executes them on &lt;strong&gt;Binance&lt;/strong&gt;?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;the-good&quot;&gt;The Good&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Assumptions:&lt;/strong&gt; It made a few reasonable assumptions about (1) the contents of the trading call, (2) using a Telegram Bot and (3) using Spot on Binance.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Fast Iteration:&lt;/strong&gt; It churned out some mostly-usable lines of code that encompassed the entire workflow.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Learning:&lt;/strong&gt; It would also explain what it was doing. So even though I didn’t know anything about the Telegram or Binance APIs, I picked it up faster than I would otherwise&lt;sup id=&quot;fnref:otherwise&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:otherwise&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-bad&quot;&gt;The Bad&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Bugs:&lt;/strong&gt; The draft code had some bugs and I couldn’t run it directly. I had to ask ChatGPT to tweak some lines and tell it what errors the repl was throwing in order to fix them.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Tweaking:&lt;/strong&gt; I also gave it examples of chat messages the group sent and had it tweak the parser. The regex it wrote wasn’t perfect, but perhaps giving it more examples would have helped it write more generalizable code instead of overfitting to an example.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Domain Knowledge:&lt;/strong&gt; While ChatGPT greatly reduced my workload, I still had to be careful to ensure the code was bug-free and actually understand what I was doing. As a result, I ended up asking Krenzx and Madneutrino a lot about the futures concepts in order to understand the API, as I couldn’t fully trust the language model.&lt;sup id=&quot;fnref:itried&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:itried&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Infinite Loop:&lt;/strong&gt; There were also times when ChatGPT got caught up in loops or made incorrect assumptions about the APIs, requiring me to read the documentation and understand the nuances myself. For example, the Telegram API had multiple ways of doing things and the Binance API was total crap&lt;sup id=&quot;fnref:tbf&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:tbf&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. It also could not deal with multiple versions of SqlAlchemy, and could not code to SQLite spec.
&lt;img src=&quot;../assets/2022-12-30-trading-bot/openai-meme.png&quot; alt=&quot;meme&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;development-and-deployment&quot;&gt;Development and Deployment&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Coded and ran on ReplIt&lt;sup id=&quot;fnref:whynot&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:whynot&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;. It was awesome and has come a &lt;em&gt;long&lt;/em&gt; way since I last used it in 2018.&lt;/li&gt;
  &lt;li&gt;But soon moved it to a DigitalOcean Droplet&lt;sup id=&quot;fnref:config&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:config&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; because I’d have to learn and make some ReplIt specific changes that I did not want to. Plus if I was ever moving this intro production, pretty sure I’d self host.&lt;/li&gt;
  &lt;li&gt;Synced the calls from the Telegram channel to a local SQLite DB and stored logs for what the bot was doing on flat files (to debug - and there was a lot of debugging).&lt;/li&gt;
  &lt;li&gt;Started off on the spot testnet but hit annoying limits. So we just YOLO-ed 1K of ACTUAL USDT. To our surprise, we did not lose money. Time spent so far was about a couple days of work, and I think we went at least 2x fast. &lt;strong&gt;As the code gets more complex returns you get from using LLM drops off.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;ape-in&quot;&gt;Ape In&lt;/h2&gt;

&lt;p&gt;Encouraged by this initial success, we decided to try futures. This is when it all went downhill&lt;sup id=&quot;fnref:sweet&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:sweet&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;. Both Copilot and ChatGPT were kind of useless and I ended up throwing away a lot of the Spot code, rewriting for the futures API and refactoring for maintainability&lt;sup id=&quot;fnref:maintain&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:maintain&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;. To be fair, Copilot did act sometimes as a delightful auto-complete. This part of the project took 4-5 days of work, and mostly unaided by LLMs. Here’s a prime example of what the current version of ChatGPT/Codex would never be able to figure out: https://dev.binance.vision/t/how-to-implement-otoco-tp-sl-orders-using-api/1622/18&lt;/p&gt;

&lt;h2 id=&quot;future-of-the-project&quot;&gt;Future of the Project&lt;/h2&gt;

&lt;p&gt;Looking to the future, there were 2 potential directions for this side project:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Build a BotAsAService. Anyone who wanted to copy trade a telegram channel could give it to us and we’d run it for them for a flat daily fee. One interesting twist on this would be to integrate the LLM into the onboarding flow so it could talk to the user, write a parser, do some testing and deploy it to production all by itself (think @levelsIO style business for software consultancy, but where the typical onboarding personnel/tier3Dev would be replaced by an AI).&lt;/li&gt;
  &lt;li&gt;Ramp up the risk and leverage by sending in a larger amount of money (say 10k USDT), and see where it takes us with a 10x leverage, take profits and stoplosses. While I was tempted, we ultimately didn’t have the motivation to risk such a large amount of money without proper backtesting (and I was too lazy to backtest properly). Similarly, we didn’t have the motivation to develop our own trading algorithm, as it felt like a PvP game that wasn’t adding much value to the world &lt;em&gt;(spoiler alert: that’s the followup post!)&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The money in either the directions did not motivate us, and we found alternative BotsAsAService solutions that seemed to have a reasonable UX. Just make sure you’re not using 3commas :clown_face:&lt;/p&gt;

&lt;p&gt;But if you’re interested in tinkering with the bot yourself, or going ape shit with leverage, you can find the source code &lt;a href=&quot;https://github.com/madneutrino/trading-bot/tree/main&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just be careful and don’t use more money than you’re willing to lose! :monkey:&lt;/p&gt;

&lt;h2 id=&quot;future-of-development&quot;&gt;Future of Development&lt;/h2&gt;

&lt;p&gt;Looking back at the metrics we set earlier, we can safely say that LLMs reduced the amount of Googling/StackOverflow I needed by a dramatic amount at the start of the project. It also got me up and running fast with v1, but further iterations were much slower owing to (1) bugs and (2) its inability to access to internet.&lt;/p&gt;

&lt;p&gt;Here’s someone on twitter saying the same thing, but on a thread:&lt;/p&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I spent Christmas programming with ChatGPT. &lt;br /&gt;&lt;br /&gt;Some observations:&lt;/p&gt;&amp;mdash; Dan Shipper 📧 (@danshipper) &lt;a href=&quot;https://twitter.com/danshipper/status/1609931358213935105?ref_src=twsrc%5Etfw&quot;&gt;January 2, 2023&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;Both of those problems should be solvable by:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Scaling up the AI so it can store more context about the entire codebase and relevant libraries. Copilot’s underlying model is small in comparison to chatGPT’s, but it’s difficult to send the entire codebase to chatGPT to get better results.&lt;/li&gt;
  &lt;li&gt;Hooking the AI up to pieces of infra it can use to simulate its own answer, test it, and fix bugs. This is what’s known as an “Agentic AI” and is a very active area of research. You can see a mind-blowing demo here: https://youtu.be/_3MBQm7GFIM?t=265&lt;/li&gt;
  &lt;li&gt;Allowing the AI to search on the internet. This would have solved the versioning problems we saw with Binance, Telegram and SQLAlchemy. Lots of companies are trying to “take on Google” like this. You can check some of them out at You.com, PerplexityAI, Metaphor Systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s pretty clear it’s going to change the nature of the job of a software engineer &lt;strong&gt;in a good way&lt;/strong&gt;. Gone are the days of “googling stuff is 90%” of my day, and “I will grind Leetcode until I pass interviews”. Everyone’s productivity will 10x, when going from idea to execution. So what will matter is coming up with ideas, directing the AI superpower properly (almost like a smart, super-fast intern who doesn’t know what to do), and iterating on the end result till you are satisfied with your creation.&lt;/p&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;11 ways ChatGPT saves me hours of work every day, and why you&amp;#39;ll never outcompete those who use AI effectively.&lt;br /&gt;&lt;br /&gt;A list for those who write code:&lt;br /&gt;&lt;br /&gt;1 of 16&lt;/p&gt;&amp;mdash; Santiago (@svpino) &lt;a href=&quot;https://twitter.com/svpino/status/1611357154514186241?ref_src=twsrc%5Etfw&quot;&gt;January 6, 2023&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;I’m SO excited to see how this plays out.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:seriously&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;seriously, I’ll struggle to explain the difference between margin and futures &lt;a href=&quot;#fnref:seriously&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:otherwise&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;i.e. by reading docs, seeing and trying to replicate easy examples &lt;a href=&quot;#fnref:otherwise&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:itried&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Yes, I tried asking chatGPT about the finance concepts but it wouldn’t go back and forth with examples, analogies, and step through specific scenarios like my friends would. &lt;a href=&quot;#fnref:itried&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:tbf&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;To be fair, even though ChatGPT made incorrect assumptions about the parameters and responses, I’d made the same assumptions before reading the docs. Or maybe it was a versioning problem yet again? &lt;a href=&quot;#fnref:tbf&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:whynot&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Because why not explore a shit tonne of things at the same time and whine when it doesn’t all work butter smooth - it’s 2022 people! I’m an entitled af Dev &lt;a href=&quot;#fnref:whynot&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:config&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Where I had to configure a minimal Ubuntu droplet with poetry+pyenv - BY HAND &lt;a href=&quot;#fnref:config&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:sweet&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;apart from the fact that the futures testnet is SWEET in comparison to the rest of the clusterfuck Binance has &lt;a href=&quot;#fnref:sweet&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:maintain&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;e.g. onitoring, debugging, making future changes, db schema etc. ChatGPT also structures python projects in a very throwaway-script manner which is no bueno for production &lt;a href=&quot;#fnref:maintain&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>psyf</name></author><category term="AI" /><summary type="html">The Task</summary></entry><entry><title type="html">🐂 The Next Crypto Bull Run Picks</title><link href="https://jezer0x.com/the-next-crypto-bull-run-picks/" rel="alternate" type="text/html" title="🐂 The Next Crypto Bull Run Picks" /><published>2022-11-30T00:00:00+00:00</published><updated>2022-11-30T00:00:00+00:00</updated><id>https://jezer0x.com/the-next-crypto-bull-run-picks</id><content type="html" xml:base="https://jezer0x.com/the-next-crypto-bull-run-picks/">&lt;p class=&quot;notice--warning&quot;&gt;⛔ Any views expressed in the below are the personal views of the author and should not form the basis for making investment decisions, nor be construed as a recommendation or advice to engage in investment transactions.&lt;/p&gt;

&lt;p&gt;It’s that time of the Bitcoin cycle when bottom snipers assemble to load up on the end-year fire sale. Bitcoin typically forms a price bottom 10 quarters after a halving event and the last halving was in Q2 2020.&lt;/p&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;This is historically the optimal time to allocate to Bitcoin. All prior Bitcoin cycles had bottomed by this point in the halving cycle. We have less than 100 days until all the other cycles went vertical. I am getting very excited. Not investment advice. &lt;a href=&quot;https://t.co/O7BJr5qomz&quot;&gt;pic.twitter.com/O7BJr5qomz&lt;/a&gt;&lt;/p&gt;&amp;mdash; Charles Edwards (@caprioleio) &lt;a href=&quot;https://twitter.com/caprioleio/status/1594961520307441666?ref_src=twsrc%5Etfw&quot;&gt;November 22, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;Typically it is marked by miners turning off their machines and dumping their reserves to survive the “winter”. This would result in the hash rate dropping and marking the end of the final leg down to form the new price floor that would be the springboard for the next run.&lt;/p&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&lt;a href=&quot;https://twitter.com/hashtag/Bitcoin?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#Bitcoin&lt;/a&gt; hash rate is starting to turn over here. Hash rate 7d moving average is now 13.7% off all time highs; mining difficulty is projected to adjust -9% a week from now. &lt;br /&gt;&lt;br /&gt;Early stages of another miner capitulation by the looks of it. &lt;a href=&quot;https://t.co/79aw6OF7uo&quot;&gt;pic.twitter.com/79aw6OF7uo&lt;/a&gt;&lt;/p&gt;&amp;mdash; Dylan LeClair 🟠 (@DylanLeClair_) &lt;a href=&quot;https://twitter.com/DylanLeClair_/status/1597326928914296832?ref_src=twsrc%5Etfw&quot;&gt;November 28, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Hashrate dipping &lt;a href=&quot;https://t.co/PZ6amsNLvF&quot;&gt;pic.twitter.com/PZ6amsNLvF&lt;/a&gt;&lt;/p&gt;&amp;mdash; //Bitcoin 𝕵ack 🐐 (@BTC_JackSparrow) &lt;a href=&quot;https://twitter.com/BTC_JackSparrow/status/1597242727426850817?ref_src=twsrc%5Etfw&quot;&gt;November 28, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Hash Rate:&lt;br /&gt;&lt;br /&gt;👀🧐🤔 &lt;a href=&quot;https://t.co/rf2Zyh5goz&quot;&gt;pic.twitter.com/rf2Zyh5goz&lt;/a&gt;&lt;/p&gt;&amp;mdash; Nunya Bizniz (@Pladizow) &lt;a href=&quot;https://twitter.com/Pladizow/status/1597384834510647296?ref_src=twsrc%5Etfw&quot;&gt;November 29, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;The implosion of Terra/Luna, 3AC and FTX trio caused the major sell-offs in the last 12 months. But the contagion is not over. We still have residual contagion left in the system. Once there is clarity on the DCG/ Grayscale/Genesis situation and the miners stop selling, we &lt;em&gt;may&lt;/em&gt; have confirmation of the bottom.&lt;/p&gt;

&lt;p&gt;Other anticipated downward price shocks are the Mt Gox coin distribution, Silvergate Bank insolvency rumours, macroeconomic downturn and finally the potential liquidation of the MicroStrategy/ Michael Saylor. My read is we will have clarity on all of them by Q1 2023 and if not it would not have a significant impact on price after.&lt;/p&gt;

&lt;p&gt;These events have certainly left many questioning the legitimacy of the industry. Is crypto a solution seeking a problem if it suffers the same pitfalls of traditional finance?&lt;/p&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;At the end of every cycle, an industry either dies, or there’s a cleanse of it. Mistaking a cleanse for being its death strips you of major future profits. &lt;br /&gt;&lt;br /&gt;2022 is clearly crypto’s 2001 + 2008.&lt;br /&gt;&lt;br /&gt;2001 = hyped up worthless businesses.&lt;br /&gt;&lt;br /&gt;2008 = financial fraud + over-leverage.&lt;/p&gt;&amp;mdash; him.eth (@himgajria) &lt;a href=&quot;https://twitter.com/himgajria/status/1591728255115341825?ref_src=twsrc%5Etfw&quot;&gt;November 13, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;The Terra Luna Trio are the epitome of traditional banking. Opaque, flamboyant and centralised. The same traits that caused the global financial crisis that gave birth to Bitcoin.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“The Times 03/Jan/2009 Chancellor on brink of second bailout for banks.” - Satoshi Nakamoto&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This was the first message stored in the genesis block mined. But one must not miss the silver lining of this aftermath. There are no bail-outs for any projects and decentralised protocols performed as designed. All 3 firms had to pay down their leverage positions on decentralised protocols first before declaring insolvency, to unlock the collateral which was at least twice in value of the loans taken out.&lt;/p&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;From our newsletter: &lt;br /&gt;&lt;br /&gt;Data from &lt;a href=&quot;https://twitter.com/DuneAnalytics?ref_src=twsrc%5Etfw&quot;&gt;@duneanalytics&lt;/a&gt; shows how tokens leaving FTX seem to have chosen &lt;a href=&quot;https://twitter.com/hashtag/DeFi?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#DeFi&lt;/a&gt; as a destination over centralized exchanges. &lt;br /&gt;&lt;br /&gt;The volume share of decentralized exchanges grew by 5% vs centralized exchanges, with &lt;a href=&quot;https://twitter.com/hashtag/Uniswap?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#Uniswap&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/hashtag/Curve?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#Curve&lt;/a&gt; capturing the majority. &lt;a href=&quot;https://t.co/vkg57oyliZ&quot;&gt;pic.twitter.com/vkg57oyliZ&lt;/a&gt;&lt;/p&gt;&amp;mdash; Grayscale (@Grayscale) &lt;a href=&quot;https://twitter.com/Grayscale/status/1595576115581448193?ref_src=twsrc%5Etfw&quot;&gt;November 24, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;Alas, our regulatory friends and traditional financiers have the perfect excuse to flex their raison d’être. They will use this series of events to advance their agendas. The governments want to launch their centralised digital currencies (CBDCs) and the big banks want to have a piece of the trading volume of centralised &lt;a href=&quot;http://exchanges.my/&quot;&gt;exchanges.&lt;/a&gt; But I believe well-engineered DeFi protocols will weather this storm and live up to the mission of levelling the playing field for the disenfranchised and unbanked.&lt;/p&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Major changes coming to the crypto industry in 2023 &lt;a href=&quot;https://t.co/qW6cHLyc6N&quot;&gt;pic.twitter.com/qW6cHLyc6N&lt;/a&gt;&lt;/p&gt;&amp;mdash; Alex Krüger (@krugermacro) &lt;a href=&quot;https://twitter.com/krugermacro/status/1597149734518820866?ref_src=twsrc%5Etfw&quot;&gt;November 28, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;On to the question I get asked every day, do I buy now? It’s hard to time the bottom, but many on-chain indicators are flashing the buy signal. The MVRV ratio (it tracks the ratio between Bitcoin’s market cap vs the capital invested into the network) and CVDD (uses the age &amp;amp; value of BTC moving to new investors to create a floor) are testing the floor which signals extreme value.&lt;/p&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;gm&lt;br /&gt;&lt;br /&gt;4 charts of hopium &lt;a href=&quot;https://t.co/GteyzSGXCt&quot;&gt;https://t.co/GteyzSGXCt&lt;/a&gt; &lt;a href=&quot;https://t.co/HvOf3JpK5Y&quot;&gt;pic.twitter.com/HvOf3JpK5Y&lt;/a&gt;&lt;/p&gt;&amp;mdash; 찌 G 跻 じ 𝙎𝙚𝙣𝙥𝙖𝙞 of the 𝙃𝙚𝙣𝙩𝙖𝙞 (@DegenSpartan) &lt;a href=&quot;https://twitter.com/DegenSpartan/status/1597382901477552129?ref_src=twsrc%5Etfw&quot;&gt;November 29, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Here&amp;#39;s the 3rd in my series of macro bottom charts...&lt;br /&gt;&lt;br /&gt;MVRV ratio is deep inside the value zone.&lt;br /&gt;&lt;br /&gt;Under this signal we were in already bottoming (1) until the latest FTX white swan debacle brought us back into a buy zone (2). &lt;a href=&quot;https://t.co/WjmOM6EJMK&quot;&gt;pic.twitter.com/WjmOM6EJMK&lt;/a&gt;&lt;/p&gt;&amp;mdash; Willy Woo (@woonomic) &lt;a href=&quot;https://twitter.com/woonomic/status/1597034435157057536?ref_src=twsrc%5Etfw&quot;&gt;November 28, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;On the other hand, one must not forget that there are a lot more systemic risks as mentioned above. We saw the greatest injection of liquidity into the economy in the last 2 years. It takes time for all the dominoes to fall. Theoretically, bitcoin could reach a low of $3,500. But I think anything below $10,000 is a generational buy opportunity.&lt;/p&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;$3,500 per &lt;a href=&quot;https://twitter.com/search?q=%24BTC&amp;amp;src=ctag&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;$BTC&lt;/a&gt; is the worst case scenario for 2023. &lt;br /&gt;&lt;br /&gt;(Chart illustration) ✍️ &lt;a href=&quot;https://t.co/hVD9wX6YiZ&quot;&gt;https://t.co/hVD9wX6YiZ&lt;/a&gt; &lt;a href=&quot;https://t.co/e7TGt8GHmY&quot;&gt;pic.twitter.com/e7TGt8GHmY&lt;/a&gt;&lt;/p&gt;&amp;mdash; Harry (@illiquidmrkts) &lt;a href=&quot;https://twitter.com/illiquidmrkts/status/1574502368376369152?ref_src=twsrc%5Etfw&quot;&gt;September 26, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&lt;a href=&quot;https://twitter.com/hashtag/Bitcoin?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#Bitcoin&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Following projection like clockwork. The sub $17,5k fakeout scenario is active. ✔️&lt;br /&gt;&lt;br /&gt;Reclaim $17580 and we are going to see another retest of descending trendline resistance first (projection). &lt;br /&gt;&lt;br /&gt;The macro-uptrend bottom is at $12k (candle close, wick probably lower). &lt;a href=&quot;https://t.co/FZ5opvLz0T&quot;&gt;pic.twitter.com/FZ5opvLz0T&lt;/a&gt;&lt;/p&gt;&amp;mdash; AN₿ESSA (@Anbessa100) &lt;a href=&quot;https://twitter.com/Anbessa100/status/1592103850202529793?ref_src=twsrc%5Etfw&quot;&gt;November 14, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;Additionally, one must not forget about the potential time capitulation that will ensue. While price capitulation may be almost over (between Q4 22 and Q1 23), there is a high chance that we range for the next year (unless general liquidity in the economy improves). This would mean that any investment strategy should incorporate a yield component.&lt;/p&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;While I still believe price axis wise we are in the process of bottoming (between here and Q1) &lt;br /&gt;&lt;br /&gt;Most underestimate the time axis. &lt;br /&gt;&lt;br /&gt;I too believe in echo bubbles like we had in 2019, but this one w/ diminishing returns as is standard &lt;a href=&quot;https://t.co/HwZXOdIAPZ&quot;&gt;pic.twitter.com/HwZXOdIAPZ&lt;/a&gt;&lt;/p&gt;&amp;mdash; Pentoshi 🐧 (@Pentosh1) &lt;a href=&quot;https://twitter.com/Pentosh1/status/1597243496716697600?ref_src=twsrc%5Etfw&quot;&gt;November 28, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;Thankfully, many protocols that demonstrated their ability to deliver during the market crash are generating sustainable revenue and redistributing it to token holders in the form of yield.&lt;/p&gt;

&lt;p&gt;My strategy would be to hold a mix of tokens that can generate revenue (yield) and at the same time play to two types of strong narratives. The first being the privacy narrative and the other being the DeFi infrastructure. Both of these narratives will have their limelight when regulations kick into high gear next year.&lt;/p&gt;

&lt;p&gt;Here is a list of my top picks and why I think they are a great investment. Be mindful of the above context and plan your entries accordingly.&lt;/p&gt;

&lt;h2 id=&quot;large-caps&quot;&gt;&lt;strong&gt;Large caps&lt;/strong&gt;&lt;/h2&gt;

&lt;h3 id=&quot;btc&quot;&gt;&lt;strong&gt;BTC&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The granddaddy of them all. The heavyweight champion. The one that is sometimes used interchangeably to refer to the entire industry. It has weathered 12 years of fear, uncertainty and doubt (FUD). Yet it has only grown in adoption and value globally. It is un-censorable as most governments are coming to realise, transparent and neutral.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Risks:&lt;/strong&gt; The rising electricity cost and increasing hash rates mean that miners with better economies of scale would start to wield more control over the security of the chain. Governments with deep pockets and the ability to ramp up mining capabilities (China) could pose a systemic risk in the future.&lt;/p&gt;

&lt;p&gt;Deposit it on Thorchain savers to earn ~4% APY.&lt;/p&gt;

&lt;p&gt;(&lt;a href=&quot;https://app.thoryield.com/savers&quot;&gt;https://app.thoryield.com/savers&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Marketcap: $315,487,903,247&lt;/p&gt;

&lt;h3 id=&quot;eth&quot;&gt;&lt;strong&gt;ETH&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;If Bitcoin is the muscle, Ethereum is the brain. It brings the required infrastructure to allow trust-less automation and verification of value movement. It has won the application layer 1 war along with the ecosystem of roll-ups/side chains (Arbitrum/optimism/Polygon)&lt;/p&gt;

&lt;p&gt;Risks: There is potential for OFAC regulation to affect the new staking model. Solidity is a pain in the arse to work with. There is still room for a protocol to come in and address these 2 shortcomings, but that window of opportunity is very small and decreasing.&lt;/p&gt;

&lt;p&gt;Deposit it on Thorchain savers to earn ~6% vAPR / Instadapp for 9%&lt;/p&gt;

&lt;p&gt;(&lt;a href=&quot;https://app.thoryield.com/savers&quot;&gt;https://app.thoryield.com/savers&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Marketcap: $145,831,629,377&lt;/p&gt;

&lt;h3 id=&quot;ltc&quot;&gt;&lt;strong&gt;LTC&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Litecoin is seen as the silver of crypto if Bitcoin is the gold. However, the core dev team has been more active in improving the technology. LTC has adopted a privacy feature called MWEB. It recently introduced merge mining which allows miners to mine DOGE and LTC simultaneously. The team has also been focused on pushing the adoption of the LTC network in Africa. LTC’s next halving event is set to take place in July 2023. Typically it sees an aggressive rally up before that.&lt;/p&gt;

&lt;p&gt;Risks: Litecoin’s adoption on the lightning network would require large adoption numbers to support the current valuation. Further, exchanges may be forced by regulation to censor LTC given it is a privacy-enabled coin.&lt;/p&gt;

&lt;p&gt;Deposit it on Thorchain savers to earn ~16% vAPR&lt;/p&gt;

&lt;p&gt;(&lt;a href=&quot;https://app.thoryield.com/savers&quot;&gt;https://app.thoryield.com/savers&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Marketcap: ****$5,448,665,865&lt;/p&gt;

&lt;h3 id=&quot;atom&quot;&gt;&lt;strong&gt;ATOM&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Cosmos is the leading layer 1 chain for infrastructure protocols. Infrastructure applications like Thorchain and Akaash use components of the cosmos protocol. It aspires to be the go-to protocol for interchain infrastructure support.&lt;/p&gt;

&lt;p&gt;Risks: currently the tokenomics are poorly designed. It’s infinitely inflationary and the protocol does not have a sustainable revenue generation mechanism. However, a revamped tokenomics model is being discussed in the DAO and we should expect a revamp in 2023.&lt;/p&gt;

&lt;p&gt;Deposit it on Thorchain savers to earn ~7% vAPR&lt;/p&gt;

&lt;p&gt;(&lt;a href=&quot;https://app.thoryield.com/savers&quot;&gt;https://app.thoryield.com/savers&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Marketcap: $2,933,310,567&lt;/p&gt;

&lt;h2 id=&quot;mid-caps&quot;&gt;&lt;strong&gt;Mid caps&lt;/strong&gt;&lt;/h2&gt;

&lt;h3 id=&quot;zec&quot;&gt;&lt;strong&gt;ZEC&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The only privacy-focused chain that has been pushing the boundaries of decentralised privacy. There are talks of becoming a deflationary PoS smart chain by 2025. This would change the tokenomics and value proposition significantly. Combined with the 7-year accumulation pattern on the charts, this is like a rocket waiting to take off&lt;/p&gt;

&lt;p&gt;Risks: Censorship by centralised exchanges because of new regulations&lt;/p&gt;

&lt;p&gt;Marketcap: $517,368,969&lt;/p&gt;

&lt;h3 id=&quot;crvcvx&quot;&gt;&lt;strong&gt;CRV/CVX&lt;/strong&gt;&lt;/h3&gt;

&lt;div class=&quot;jekyll-twitter-plugin&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; align=&quot;center&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Introduction to &lt;a href=&quot;https://twitter.com/search?q=%24crvUSD&amp;amp;src=ctag&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;$crvUSD&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Part 2&lt;br /&gt;&lt;br /&gt;Three birds with one stone.&lt;br /&gt;&lt;br /&gt;Thread 🧵 &lt;a href=&quot;https://t.co/eNqEy72Zqb&quot;&gt;pic.twitter.com/eNqEy72Zqb&lt;/a&gt;&lt;/p&gt;&amp;mdash; DeFi Made Here (@DeFi_Made_Here) &lt;a href=&quot;https://twitter.com/DeFi_Made_Here/status/1597234924003672064?ref_src=twsrc%5Etfw&quot;&gt;November 28, 2022&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;CRV is the household name for deep stable coin liquidity. The low slippage AMM model combined with the 3crv and crv incentivisation model has cemented its position as the exchange where any currencies would go to maintain the peg. Any stable currency launching in DeFi ecosystem or CBDCs would/should list on Curve to gain deep liquidity and widespread adoption. To mitigate the potential downside of upcoming DeFi regulations, Curve is launching a new algorithmic stable coin called CRVUSD.&lt;/p&gt;

&lt;p&gt;Risks: DeFi regulation on stablecoins can censor platforms they interact with as seen with the Tornado case. There is a risk that any stable coin that passes through Curve could face something similar if the governments take a heavy-handed approach on stablecoins.&lt;/p&gt;

&lt;p&gt;Deposit CRV on Convex finance to earn ~21% vAPR&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.convexfinance.com/stake&quot;&gt;https://www.convexfinance.com/stake&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tip: use &lt;a href=&quot;https://curve.fi/#/ethereum/pools/factory-v2-22/deposit&quot;&gt;https://curve.fi/#/ethereum/pools/factory-v2-22/deposit&lt;/a&gt; to profit from the CVXCRV/ CRV arbitration.&lt;/p&gt;

&lt;p&gt;Deposit CVX on convex finance to earn ~3.7% vAPR and votium bribes of ~27%vAPR. Total of ~30% vAPR. But take note of the 3 month lock in period.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.convexfinance.com/lock-cvx&quot;&gt;https://www.convexfinance.com/lock-cvx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CRV Marketcap: $429,541,879
CVX Marketcap: $282,194,622&lt;/p&gt;

&lt;h3 id=&quot;aave&quot;&gt;&lt;strong&gt;AAVE&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;AAVE is the first and biggest decentralised multi-chain lending platform. It has survived 1 full crypto cycle. The team is now creating LensProtocol and GHO stable coins which will work in close tandem with AAVE to reduce the collateral requirement and eventually compete with traditional banks for credit.&lt;/p&gt;

&lt;p&gt;Risks: Long tail assets posed a threat to the collateral based model given the ability for actors with large liquidity to manipulate price and trade against the collateral positions. AAVE suffered a small attack recently and since has taken measures to halt long tail assets.&lt;/p&gt;

&lt;p&gt;Stake on AAVE on to receive ~8% vAPR. Note: up to 30% of your funds could be used as liquidity insurance in the event of large price swings.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://app.aave.com/staking/&quot;&gt;https://app.aave.com/staking/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://governance.aave.com/t/introducing-gho/8730&quot;&gt;Introducing: GHO&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Marketcap:$859,264,553&lt;/p&gt;

&lt;h3 id=&quot;thorchain-rune&quot;&gt;&lt;strong&gt;Thorchain (Rune)&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;only decentralised native cross-chain swap&lt;/strong&gt; that aims to become a vertically integrated decentralised platform. Thorchain is the only protocol capable of bringing DeFi to non-smart contract chains like Bitcoin and Litecoin. Currently, the platform generates yield through swaps and distributes that to users of the Savers and Liquidity provision features. Soon Thorchain would have a lending model similar to AAVE but for Bitcoin, ThorUSD and derivatives. All of which would drive yield to savers or liquidity providers.&lt;/p&gt;

&lt;p&gt;Risks: Thorchain is prone to be hacked like any of the other DeFi protocol. It has suffered 2 hacks so far. However, the team has improved security significantly since then.&lt;/p&gt;

&lt;p&gt;Rune tokens need to pair with other coins like BTC/ETH for liquidity provision that would earn varying rates of yield. Take note, this is a liquidity provision (LP) mechanism which is subject to impermanent loss. However, Thorchain provides impermanent loss protection of 1% for every day of LP. Refer to this dashboard for the yield rates: &lt;a href=&quot;https://app.thoryield.com/dashboard&quot;&gt;https://app.thoryield.com/dashboard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Marketcap: $367,174,358&lt;/p&gt;

&lt;h3 id=&quot;gmx&quot;&gt;&lt;strong&gt;GMX&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Futures are the most profitable and used function of a centralised exchange. GMX is the largest decentralised futures protocol. Regardless of how the market performs, the house always wins! Revenue generated from exchange fees is distributed to liquidity providers and the token holders. As a result, GMX is one of the rare few tokens that appreciated significantly in value during the bear market.&lt;/p&gt;

&lt;p&gt;Risk: The GLP liquidity provision mechanism limits the depth of position one can take given the decentralised nature of the design. This is to ensure protection against liquidation of the entire pool during extremely volatile periods.&lt;/p&gt;

&lt;p&gt;Stake GMX token to earn ~16% vAPR&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://app.gmx.io/#/earn&quot;&gt;https://app.gmx.io/#/earn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Marketcap: $338,543,297&lt;/p&gt;

&lt;h2 id=&quot;security-tips&quot;&gt;Security tips&lt;/h2&gt;

&lt;p&gt;1.Always store your tokens on a hardware wallet (Trezor/ ledger are great options)&lt;/p&gt;

&lt;p&gt;2.If you are buying any of the tokens above, use coingecko to find out the exchanges that offer it and click on those trading pairs to avoid falling prey to phishing scams&lt;/p&gt;

&lt;p&gt;If you liked this article and want to see more in the future, like, retweet and follow me on twitter! &lt;a href=&quot;https://twitter.com/krenzx&quot;&gt;@krenzx&lt;/a&gt;&lt;/p&gt;</content><author><name>Krenzx</name></author><category term="Investment" /><summary type="html">⛔ Any views expressed in the below are the personal views of the author and should not form the basis for making investment decisions, nor be construed as a recommendation or advice to engage in investment transactions.</summary></entry><entry><title type="html">⛓️ Blockchain Consensus</title><link href="https://jezer0x.com/blockchain-consensus/" rel="alternate" type="text/html" title="⛓️ Blockchain Consensus" /><published>2022-09-03T00:00:00+00:00</published><updated>2022-09-05T00:00:00+00:00</updated><id>https://jezer0x.com/blockchain-consensus</id><content type="html" xml:base="https://jezer0x.com/blockchain-consensus/">&lt;h2 id=&quot;what-is-consensus&quot;&gt;What is Consensus?&lt;/h2&gt;

&lt;p&gt;Consensus means a general agreement has been reached between multiple parties. When you and your friends go out for dinner and (finally!) agree on a restaurant to go to, you’ve reached a consensus. The process you used to reach this consensus is called a consensus mechanism (or consensus protocol). For example, for most votes in the group chat, the youngest gets to decide, or use youngest if there is a tie.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;../assets/2022-09-03-blockchain-consensus/5963fd39d9fccdb1278b5384.webp&quot; alt=&quot;Me and the boys deciding who to mess with next.&quot; class=&quot;align-center&quot; /&gt;
Me and the boys reaching a consensus on who to mess with next.&lt;/p&gt;

&lt;p&gt;Systems made of multiple nodes (aka distributed systems)&lt;sup id=&quot;fnref:distributedsystemexample&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:distributedsystemexample&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; also need to use consensus mechanisms to maintain a “shared state” (a singular view of the system). In the blockchain context (which can be thought of as a distributed database context), reaching consensus means the network participants have come to a general agreement on the global state of the blockchain at a given moment.&lt;/p&gt;

&lt;h2 id=&quot;consensus-in-traditional-distributed-systems&quot;&gt;Consensus in Traditional Distributed Systems&lt;/h2&gt;

&lt;p&gt;Traditional Web2 giants have had to deal with consensus complexities for a while now.&lt;/p&gt;

&lt;p&gt;Traditional Web2 giants have had to deal with consensus complexities for a while now.
To understand why this is such a difficult problem, let’s look at a hypothetical system. Suppose Company A has 10 servers located globally with users worldwide able to interact with each other. Users’ computers interact with the server nearest to them to minimize latency. Assuming the 10 servers have to agree on a shared truth, we immediately run into problems. If many people are commenting on a viral post via Server 1 and others are commenting on the post via Server 2 at the same time &lt;strong&gt;(concurrency),&lt;/strong&gt; the servers need to exchange messages &lt;strong&gt;(asynchronous process)&lt;/strong&gt; to figure out the ordering of the interactions (&lt;strong&gt;clock-drift&lt;/strong&gt; makes getting a global clock complicated). This coordination also has to happen between all 10 servers in parallel. The process is complicated further because any of the nodes may crash at any time (&lt;strong&gt;fault tolerance&lt;/strong&gt;) or the network may drop/delay packets (&lt;strong&gt;unbounded latency&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;To tackle all these problems, the servers have to run an identical consensus protocol such that the ordering of events and resolution of conflicts can be done, usually by relaxing some of the constraints mentioned above.&lt;sup id=&quot;fnref:traditionalconsensus&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:traditionalconsensus&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&quot;fnref:relax&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:relax&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/EhQc4kXe2y2CX08z7E/giphy.gif&quot; alt=&quot;https://media.giphy.com/media/EhQc4kXe2y2CX08z7E/giphy.gif&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Decades of distributed systems research have produced breakthroughs and successful implementations (e.g. Paxos and Raft), enabling huge-scale companies like Facebook and Google.&lt;/p&gt;

&lt;h2 id=&quot;what-do-blockchain-validators-need-to-agree-on&quot;&gt;What do Blockchain Validators Need to Agree on?&lt;/h2&gt;

&lt;p&gt;Since consensus mechanisms are complicated processes, you want to minimize the amount of data you need to reach a consensus on to provide useful service. All the other states in the system can either be derived from this set or, should not need consensus for proper functioning.&lt;/p&gt;

&lt;p&gt;For example: if users are “reacting” to a post, the servers don’t have to maintain a strict ordering of reaction timestamps, so they can simplify the consensus mechanism there to building a complete set of (reactions, reactor) or (#reactions).&lt;/p&gt;

&lt;p&gt;Similarly different blockchains (and their layers) define what consensus means in different ways.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Most blockchains today reach a consensus on the strict ordering and validity of transactions&lt;sup id=&quot;fnref:validity&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:validity&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; (e.g. Ethereum and Bitcoin).&lt;/li&gt;
  &lt;li&gt;Some blockchains relax the constraints by only requiring that validators converge on a partial ordering in the form of a Directed Acyclic Graph (e.g. Avalanche).&lt;/li&gt;
  &lt;li&gt;Some blockchains leave the validity and interpretation of transactions up to the layers built on top (i.e. rollups) and provide consensus on the integrity &lt;sup id=&quot;fnref:integrity&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:integrity&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; and availability &lt;sup id=&quot;fnref:da&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:da&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; of data in the system (e.g. Celestia, post-Dank-Sharding Ethereum).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;so-whats-different-in-blockchains-consensus&quot;&gt;So What’s Different in Blockchains’ Consensus?&lt;/h2&gt;

&lt;p&gt;The one saving grace is that Company A owns and controls all the servers, so the consensus protocol running on one server can assume that all the other servers are playing by the rules (i.e. are good actors). Here, Company A is the ultimate authority as they can change the protocol and underlying data however and whenever they want.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This ultimate authority is what we’re trying to get rid of in public blockchains.&lt;/strong&gt; Since there is no ultimate authority that owns all the nodes, we cannot assume all the nodes in the network (often run by anonymous actors) are honest. We have to deal with this additional failure mode - where malicious nodes may withhold information, lie and even coordinate for their own benefit. This is a “Byzantine” environment, and the name originates from a paper called &lt;a href=&quot;https://en.wikipedia.org/wiki/Byzantine_fault&quot;&gt;“The Byzantine General’s Problem”&lt;/a&gt;.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;../assets/2022-09-03-blockchain-consensus/combine_images.jpg&quot; alt=&quot;combine_images.jpg&quot; class=&quot;align-center&quot; /&gt;
More complicated models divide the actors into 3 buckets - “always malicious”, “always honest” and “rational”. The rational node may be malicious or honest depending on the self-benefit analysis.&lt;/p&gt;

&lt;p&gt;To ensure coordination in such a hostile environment, blockchains use rewards to incentivize proper behavior and punishments to discourage malice. They also have to fine-tune the incentive and reward mechanisms such that honest mistakes are not harshly punished and incentives don’t tend towards centralization &lt;sup id=&quot;fnref:centralization&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:centralization&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;. &lt;strong&gt;Economic incentives are a form of social consensus mechanism.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;byzantine-consensus-trade-offs&quot;&gt;Byzantine Consensus Trade-Offs&lt;/h2&gt;

&lt;p&gt;Over time, researchers have separated the concerns in a Byzantine environment into 2 categories.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Safety (aka Agreement):&lt;/strong&gt; All non-faulty nodes will decide on the same state. This guarantees that the system (given enough “honest” nodes) can stay in sync at time t+1 since they agree on a single valid global state at time t. For blockchains, safety violations will occur if there are 2 different valid chains.&lt;/p&gt;

    &lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;https://media.giphy.com/media/HIxtxVhs1LRm0/giphy.gif&quot; alt=&quot;https://media.giphy.com/media/HIxtxVhs1LRm0/giphy.gif&quot; class=&quot;align-center&quot; /&gt;
Safety getting violated&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Liveness (aka Termination):&lt;/strong&gt; All non-faulty nodes will &lt;em&gt;eventually decide&lt;/em&gt; on the same output. For blockchain, liveness violation means the system has come to a halt and no more blocks are being produced.&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://i.imgflip.com/6q2i1c.jpg&quot; alt=&quot;https://i.imgflip.com/6q2i1c.jpg&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;In the case of blockchains, having a live service that can’t agree on what the “truth” is as good as having no service at all. But having a system that is taken down by malicious actors is not useful either.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;According to &lt;a href=&quot;https://en.wikipedia.org/wiki/Consensus_%28computer_science%29#Solvability_results_for_some_agreement_problems&quot;&gt;FLP&lt;/a&gt;, both safety and liveness cannot be achieved in the case of &lt;strong&gt;&lt;em&gt;asynchronous&lt;/em&gt;, &lt;em&gt;deterministic&lt;/em&gt;&lt;/strong&gt; processes. There are 2 ways forward - relax one of the 2 assumptions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Introduce non-determinism.&lt;/strong&gt; For example, we can use random factors in the consensus mechanism.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Assume network communication is synchronous.&lt;/strong&gt; For example, we could put an upper bound to latency by using a timeout mechanism.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The war of blockchain consensus mechanisms is taking variations on these paths to ensure Byzantine-Fault Tolerance (i.e. system is both live and safe). Some systems also make &lt;em&gt;temporary&lt;/em&gt; compromises on liveness and safety.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;questions-to-ask-when-analyzing-blockchain-consensus-mechanisms&quot;&gt;Questions to Ask When Analyzing Blockchain Consensus Mechanisms&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Who can join the network to become a validator?
    &lt;ol&gt;
      &lt;li&gt;What resources do they need to join the network and maintain its share of power over the network?&lt;/li&gt;
      &lt;li&gt;What are the incentives against misuse of this responsibility and power?&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;What are the steps to go from a user signing a transaction to the transaction being included in the blockchain with high probability that it will not be rolled back?
    &lt;ol&gt;
      &lt;li&gt;How can a malicious actor (or set of malicious actors coordinating against honest actors) disrupt each step of the protocol?
        &lt;ol&gt;
          &lt;li&gt;Can the protocol detect and punish malicious actors at each step?&lt;/li&gt;
          &lt;li&gt;Can the users detect and punish malicious actors using the “social consensus layer”?&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;What assumptions are being made at each step of the protocol?
        &lt;ol&gt;
          &lt;li&gt;How can this assumption be broken?&lt;/li&gt;
          &lt;li&gt;What happens if the assumption is broken&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;introduce-non-determinism&quot;&gt;Introduce Non-Determinism&lt;/h2&gt;

&lt;p&gt;Consensus mechanisms that rely on random factors are simple to design and understand because they sidestep all the complicated problems that come with the different forms of synchrony assumptions.&lt;/p&gt;

&lt;p class=&quot;notice--info&quot;&gt;💡 We won’t be discussing the application-specific optimizations made in the implementations of these algorithms. While clever, they might distract from the main principles.&lt;/p&gt;

&lt;h3 id=&quot;nakamoto-consensus-bitcoin&quot;&gt;Nakamoto Consensus (Bitcoin)&lt;/h3&gt;

&lt;p&gt;Here’s how this Proof-of-Work mechanism works &lt;sup id=&quot;fnref:3b1b&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3b1b&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:whitepaper&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:whitepaper&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Gather and propagate (using a peer-to-peer “gossip protocol”) valid, pending transactions.&lt;/li&gt;
  &lt;li&gt;Bundle a subset of transactions into a block.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;Try random numbers&lt;/em&gt;&lt;/strong&gt; (aka mining) that make the hash of the block match certain pre-defined properties. &lt;sup id=&quot;fnref:zeros&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:zeros&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
  &lt;li&gt;If you find a valid nonce first, broadcast it to the network and collect your &lt;strong&gt;reward (economic incentive)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;If someone else finds a valid nonce first (you must verify this), abandon the block you were trying and repeat from step 1.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that there may be a &lt;strong&gt;temporary lapse in safety&lt;/strong&gt; if 2 nodes find differing valid blocks at the same time. The network splits (fork) and everyone chooses which one they want to support and tries to build on top of it. Since it is a random process, eventually one branch gets ahead and the network abandons the other. Supporters of the abandoned branch wasted energy &lt;strong&gt;(economic punishment).&lt;/strong&gt; This is &lt;strong&gt;probabilistic safety.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Anyone can join (or leave) the network at will with minimal overhead to the network as a whole &lt;sup id=&quot;fnref:antisybil&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:antisybil&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;11&lt;/a&gt;&lt;/sup&gt;. Whoever joins the network can validate every block since genesis &lt;strong&gt;(objectivity).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This mechanism &lt;strong&gt;optimizes for liveness&lt;/strong&gt; since “halting” is not an option unless every node shuts down (i.e. as long as one miner is online, the network can keep making blocks). The algorithm adjusts the difficulty of finding a valid hash such that the frequency of blocks can remain roughly constant regardless of total hash-power.&lt;/p&gt;

&lt;p&gt;The way to attack the safety of this network is by doing a “51% attack”, where a malicious actor has a majority of the hash-power in the network:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;can dictate which transactions censor/prioritize because their chain will be the longest.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;cannot change history that’s too far back, because finding a valid block is energy and resource intensive (random process) &lt;sup id=&quot;fnref:pos&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:pos&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

    &lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;https://media.giphy.com/media/DB2oahQFa0qeQ/giphy.gif&quot; alt=&quot;https://media.giphy.com/media/DB2oahQFa0qeQ/giphy.gif&quot; class=&quot;align-center&quot; /&gt;
Real-life footage of mining&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;assume-synchrony-in-various-forms&quot;&gt;Assume Synchrony in Various Forms&lt;/h2&gt;

&lt;h3 id=&quot;tendermint-consensus---splitting-the-synchrony-assumption-cosmos&quot;&gt;Tendermint Consensus - Splitting the Synchrony Assumption (Cosmos)&lt;/h3&gt;

&lt;p&gt;If we make a synchrony assumption to ensure liveness, and the assumption fails, the blockchain stops producing blocks. If we make a synchrony assumption to ensure safety, and the assumption fails, the blockchain will have 2 valid states and split into 2. &lt;strong&gt;One could argue that even though we need both safety and liveness, safety is more important. In other words, we can make some assumptions to ensure liveness but we must use weaker/fewer assumptions to ensure safety.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where &lt;a href=&quot;https://groups.csail.mit.edu/tds/papers/Lynch/jacm88.pdf&quot;&gt;DLS&lt;/a&gt; comes into play. It showed that we can solve the FLP impossibility by assuming &lt;strong&gt;partial synchrony.&lt;/strong&gt;&lt;sup id=&quot;fnref:flp&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:flp&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;13&lt;/a&gt;&lt;/sup&gt; DLS argues that &lt;strong&gt;a partial synchrony assumption can be made to achieve liveness&lt;/strong&gt;, and &lt;strong&gt;no synchrony assumption is needed to ensure safety.&lt;/strong&gt; The next iteration of the DLS idea was the &lt;a href=&quot;http://pmg.csail.mit.edu/papers/osdi99.pdf&quot;&gt;“Practical Byzantine Fault Tolerant”&lt;/a&gt; (PBFT) algorithm.&lt;sup id=&quot;fnref:dls&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:dls&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;14&lt;/a&gt;&lt;/sup&gt; Cosmos’ Tendermint builds on top of these.&lt;sup id=&quot;fnref:pbft&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:pbft&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;15&lt;/a&gt;&lt;/sup&gt; &lt;a href=&quot;https://docs.tendermint.com/v0.34/introduction/what-is-tendermint.html#consensus-overview&quot;&gt;Here’s how it works&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/2022-09-03-blockchain-consensus/Untitled.png&quot; alt=&quot;Untitled&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Every round, there’s a new “proposer” in the network. The other nodes are considered “validators”. The probability of being chosen proposer is proportional to the amount staked relative to the other validators. &lt;sup id=&quot;fnref:sybil&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:sybil&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;16&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
  &lt;li&gt;New transactions are broadcast to the proposer.&lt;/li&gt;
  &lt;li&gt;The proposer packages the transactions into a block and broadcasts it to all the validators.&lt;/li&gt;
  &lt;li&gt;The validators vote for the block (given it is valid) in 2 steps - a pre-vote and a pre-commit.
    &lt;ol&gt;
      &lt;li&gt;Each node pre-votes for a block (where pre-vote means “I’ve received a block”) and listens on the network for others’ votes. Once 2/3rd is reached we move on to the pre-commit step.&lt;/li&gt;
      &lt;li&gt;Each node pre-commits to the block (where pre-commit means “I agree with this block”) and listens on the network for others’ votes. Once more than 2/3rd of the network pre-commits, the block is committed (i.e. confirmed). The proposer gets a reward for a successful block.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Repeat.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For step 3, if the proposer fails to create a block (may be offline, or unreachable due to network conditions) within a specific timeout &lt;strong&gt;(synchrony assumption)&lt;/strong&gt;, this round will have an empty block &lt;strong&gt;(liveness sacrificed).&lt;/strong&gt; There are no forks &lt;strong&gt;(safety is not compromised since it does not make synchrony assumptions).&lt;/strong&gt; A similar synchrony assumption is put in for the voting steps as well.&lt;sup id=&quot;fnref:votes&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:votes&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;17&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;This means that the network can be kept &lt;strong&gt;“halted” in perpetuity if 1/3rd of the nodes are malicious&lt;/strong&gt; and silent. To make the network &lt;strong&gt;“unsafe”, malicious actors need more than 2/3rd of the validators.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To encourage on-time behaviour, cosmos chains usually punish nodes for being offline (by slashing their stake). Every node that votes for an invalid block gets slashed. Double voting gets slashed as well, as does proposing 2 different blocks (aka equivocation).&lt;sup id=&quot;fnref:dpos&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:dpos&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;18&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:minority&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:minority&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;19&lt;/a&gt;&lt;/sup&gt; Failure mode for Tendermint is discussed in-depth &lt;a href=&quot;https://docs.tendermint.com/master/spec/light-client/accountability/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;https://media.giphy.com/media/fBEMsUeGHdpsClFsxM/giphy.gif&quot; alt=&quot;Tendermint Validator trying not to get slashed for being slow&quot; class=&quot;align-center&quot; /&gt;
Tendermint Validator trying not to get slashed for being slow&lt;/p&gt;

&lt;p&gt;To join the network you need to put in a security deposit (i.e. stake) and become one of the top ~100 stakers and then wait for the next “churn” (when nodes are kicked and others added). To leave the network you have to wait for a churn as well (else, you get slashed for every round you remain offline). If Tendermint wants to have higher number of validators, they will have to give up on the tight timeouts and make the network slower - the communication overhead increases rapidly. To get around the problem, Tendermint-based networks rely on social consensus and economic incentive mechanisms of staking delegation.&lt;/p&gt;

&lt;p&gt;The Nodes that join the network rely on the other nodes in the network to get the ground truth &lt;strong&gt;(aka subjectivity, which is inherent to PoS)&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;gasper---finding-a-compromise-pos-ethereum&quot;&gt;Gasper - Finding a Compromise (PoS Ethereum)&lt;/h3&gt;

&lt;p&gt;There were a few problems that made the Ethereum Research community improve on Tendermint’s design. Key among those is “&lt;a href=&quot;https://medium.com/@Vlad_Zamfir/the-history-of-casper-chapter-4-3855638b5f0e&quot;&gt;Cartel Analysis&lt;/a&gt;”: it’s economically beneficial for 67% of validators in Tendermint to form a cartel (concentration of power) and to shun the 33% non-cartel nodes to increase their own revenue &lt;sup id=&quot;fnref:cartel&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:cartel&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;20&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:rebuttal&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:rebuttal&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;21&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:posdebate&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:posdebate&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;22&lt;/a&gt;&lt;/sup&gt;. This complicated the security model further from the bribing-adversary model (single actor game theory) to oligopolistic analysis (social/cooperative game theory). This led to the realization that detecting censorship by the cartel (and punishing such censorship) would be key. This led to the realization that detecting censorship by the cartel (and punishing such censorship) would be key.&lt;/p&gt;

&lt;p&gt;After years of research, Proof-of-Stake Ethereum came up with “Gasper”, a combination of 2 different mechanisms. Here’s how the entire system works: &lt;sup id=&quot;fnref:ethdevresources&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:ethdevresources&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;23&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;There is &lt;strong&gt;1 slot every 12 seconds&lt;/strong&gt;, where a slot can have 1 block. &lt;strong&gt;32 slots make up an epoch&lt;/strong&gt;.&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;../assets/2022-09-03-blockchain-consensus/Untitled%201.png&quot; alt=&quot;Untitled&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In every slot, a validator is randomly selected to become the &lt;strong&gt;block proposer&lt;/strong&gt;. A separate subset of validators is randomly selected to vote on the proposal &lt;strong&gt;(committee)&lt;/strong&gt;.&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;../assets/2022-09-03-blockchain-consensus/Untitled%202.png&quot; alt=&quot;Untitled&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;&lt;strong&gt;Within an epoch runs LMD-GHOST. “&lt;/strong&gt;It stands for “latest message-driven greedy heaviest observed sub-tree”. Translating it to English, it means:
        &lt;ol&gt;
          &lt;li&gt;Regardless of how many messages someone sends, take only the latest one.&lt;/li&gt;
          &lt;li&gt;Follow the fork with the most attestations (note that there’s no 2/3rds rule as in Tendermint).&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;Under normal network conditions, the proposer proposes a valid block, and the committee of validators properly attests to it.&lt;/li&gt;
      &lt;li&gt;If the block proposer is offline (crashed / network fault), they do not get slashed. Their “punishment” is losing out on the potential rewards. This is also the case for the attestors. &lt;sup id=&quot;fnref:nottender&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:nottender&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;24&lt;/a&gt;&lt;/sup&gt; Slashing should only happen for dishonesty/malice, as far as possible, and there are some kinds of actions that are near impossible to take unless you’re malicious (e,g, double proposing, double voting), in which case you’re progressively slashed until your entire stake is gone and you’re booted from participation in Gasper.&lt;/li&gt;
      &lt;li&gt;If there’s large network asynchronicity or when a dishonest block proposer has equivocated (i.e. proposed 2 different blocks to different parts of the validator committee) that a fork choice algorithm is required. LMD-GHOST is used to secure the correct chain in these cases.
        &lt;ol&gt;
          &lt;li&gt;Note that this fork choice rule means &lt;em&gt;if&lt;/em&gt; the network forks under adversarial conditions &lt;strong&gt;(safety not guaranteed)&lt;/strong&gt;, the validators have a way to keep making blocks and eventually come to the proper conclusion &lt;strong&gt;(liveness is prioritized).&lt;/strong&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Between epochs runs Casper Friendly Finality Gadget.&lt;/strong&gt; Within the next epoch boundary (i.e. slot 1 of the epoch E+1), every validator in the network should vote on the validity of the block at slot 1 of the current epoch (i.e. slot 1 of epoch E). This means every node in the network gets 384 seconds to vote. If this slot gets more than 2/3rd of votes, it is considered a “justified” checkpoint, and slot 1 of epoch E-1 is considered a “finalized” checkpoint.&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;&lt;strong&gt;This ensures “Accountable Safety”&lt;/strong&gt;. To create an alternate finalized chain, an attacker would need to either:
        &lt;ol&gt;
          &lt;li&gt;own 2/3rd of the total stake, or&lt;/li&gt;
          &lt;li&gt;destroy 1/3rd of the total staked ether. If 2/3rd of the network voted for 2 forks, it means 1/3rd voted for both (which is a slashable offense), and thus 1/3rd of the ETH will get slashed (a very expensive attack). &lt;sup id=&quot;fnref:correlation&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:correlation&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;25&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;strong&gt;Casper also ensures “Plausible Liveness”&lt;/strong&gt;, which says that as long as 2/3rd of the staked ether is honest the network can keep finalizing. However, if 1/3rd of the ether is compromised, the network may fail to finalize. To protect against this, if there have been no finalized checkpoints for 4 epochs, Casper will start slashing validators that have not voted with the majority. This “inactivity leak” will bleed this minority’s stake until the network reaches finality again &lt;strong&gt;(liveness fault is temporary).&lt;/strong&gt;&lt;/p&gt;

        &lt;p&gt;&lt;img src=&quot;../assets/2022-09-03-blockchain-consensus/Untitled%203.png&quot; alt=&quot;Untitled&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The coordination between nodes is done by the Beacon Chain - joining, staking, withdrawing stakes, and attestation are all happening on the Beacon Chain &lt;sup id=&quot;fnref:aggregation&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:aggregation&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;26&lt;/a&gt;&lt;/sup&gt;. When a new node joins the network, they need to rely on the rest of the network to get the “truth” of the chain (hello again, &lt;strong&gt;subjectivity).&lt;/strong&gt; There are 2 other attack vectors that this opens up, and are solved by “Weak Subjectivity”: &lt;sup id=&quot;fnref:weaksub&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:weaksub&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;27&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;There may be a “long-range attack”, where nodes that were very early in the network release a conflicting fork after a long time. New nodes may use this as the universal truth. To solve this, Ethereum uses the finalized checkpoint as the “universal truth”. New validators will need to independently validate from this point onwards. This limits the range of the attacks by restricting how long forks can be.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If 33% of the validators withdraw their stake and still attest and produce blocks, new nodes might be misled to follow the wrong fork for a few slots. To solve this, the withdrawal period for staked ETH is longer than the time between weak subjectivity checkpoints. If malicious validators try to trick new entrants during this time, their stake will be slashed before a withdrawal is completed.&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/ethereum-hackmd/upload_f76a1c2499efcaabcf2aa167986a06d3.png&quot; alt=&quot;https://storage.googleapis.com/ethereum-hackmd/upload_f76a1c2499efcaabcf2aa167986a06d3.png&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We haven’t done (or found) a proper “Cartel Analysis” for Ethereum’s Gasper as suggested by Vlad Zamfir, but a few answers from the PoS FAQ at Vitalik’s blog give you the intuitive understanding - see them &lt;a href=&quot;https://vitalik.ca/general/2017/12/31/pos_faq.html#can-one-economically-penalize-censorship-in-proof-of-stake&quot;&gt;here&lt;/a&gt;, &lt;a href=&quot;https://vitalik.ca/general/2017/12/31/pos_faq.html#will-exchanges-in-proof-of-stake-pose-a-similar-centralization-risk-to-pools-in-proof-of-work&quot;&gt;here&lt;/a&gt;, and &lt;a href=&quot;https://vitalik.ca/general/2017/12/31/pos_faq.html#are-there-economic-ways-to-discourage-centralization&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/3o6Mb5AxV7ZLhRnhRK/giphy.gif&quot; alt=&quot;https://media.giphy.com/media/3o6Mb5AxV7ZLhRnhRK/giphy.gif&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;miscellaneous&quot;&gt;Miscellaneous&lt;/h2&gt;

&lt;p&gt;Let’s take a quick look at other consensus mechanisms that don’t fall into the buckets above, but may warrant an honorable mention.&lt;/p&gt;

&lt;p class=&quot;notice--warning&quot;&gt;We haven’t dug into these mechanisms, so please take our word with a grain of salt.&lt;/p&gt;

&lt;h3 id=&quot;snow---leaderless-pos-avalanche&quot;&gt;&lt;a href=&quot;https://docs.avax.network/overview/getting-started/avalanche-consensus&quot;&gt;Snow&lt;/a&gt; - Leaderless PoS (Avalanche)&lt;/h3&gt;

&lt;p&gt;The team behind Snow contends that the removal of the quadratic network overhead and the need for a leader in consensus are properties we can do away with and still have a safe and live network. Here’s how it works in Avalanche, where each node follows the same process:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Randomly samples &lt;em&gt;k&lt;/em&gt; peers&lt;/strong&gt; (sample size) and asks them &lt;strong&gt;“Given this is the latest block I have, give me the next block.”&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;If more than &lt;strong&gt;&lt;em&gt;a&lt;/em&gt;&lt;/strong&gt; (quorum size) **has given the same response, count it as 1 success for the block.&lt;/li&gt;
  &lt;li&gt;Repeat until some block has &lt;strong&gt;&lt;em&gt;b&lt;/em&gt;&lt;/strong&gt; (decision threshold) votes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;there’s no proposer. Everyone “proposes” blocks in step 1’s response, given they have staked in the network.&lt;/li&gt;
  &lt;li&gt;the communication overhead does not increase with the number of nodes in the network, since &lt;strong&gt;&lt;em&gt;k&lt;/em&gt;&lt;/strong&gt; is fixed.&lt;/li&gt;
  &lt;li&gt;The liveness and safety of this algorithm are configurable. For example, if a network wants more safety, they have to increase the quorum size - but liveness will be decreased.&lt;sup id=&quot;fnref:avax&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:avax&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;28&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p class=&quot;notice--info&quot;&gt;💡 Avalanche also uses a DAG instead of a linear chain (this is not a property of the Snow Algorithm). This means each slot can have multiple blocks given they don’t contain conflicting transactions, increasing throughput! &lt;sup id=&quot;fnref:conflux&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:conflux&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;29&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h3 id=&quot;algorand&quot;&gt;&lt;a href=&quot;https://developer.algorand.org/docs/get-details/algorand_consensus/&quot;&gt;Algorand&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;A Byzantine Agreement Proof-of-Stake protocol that optimizes for speed. For the random selections, &lt;strong&gt;Verifiable Random Functions are used and the selection is secret&lt;/strong&gt; (happens without user communication, and only the selected knows they were selected until they send messages). &lt;strong&gt;The VRF and votes are weighted according to the stakes&lt;/strong&gt; the account has. Here’s how it works:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Block Proposal:&lt;/strong&gt; Randomly selected Accounts propose new blocks to the network. They propagate the block they built, along with proof that they were indeed selected in the secret VRF round.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Soft Vote:&lt;/strong&gt; Randomly selected Committee votes on proposals and filters down to one. Committee accounts vote for the block with the lowest VRF hash (which is random too) at timeout. The probability of a fork is extremely low since the probability that 2 valid proposed blocks will have the same VRF hash is negligible.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Certify Vote:&lt;/strong&gt; Separate randomly selected committee votes to certify the block after checking for problems such as conflicting transactions.&lt;/li&gt;
  &lt;li&gt;Each node receives a certificate for the block and writes it to the ledger&lt;/li&gt;
  &lt;li&gt;Repeat.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;hotstuff&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1803.05069&quot;&gt;HotStuff&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;A Leader-Based BFT protocol makes partial synchrony assumption. It simplifies the mechanism by using a linear communication footprint in each round. This allows it to be more “responsive” than Tendermint and Casper.&lt;/p&gt;

&lt;h3 id=&quot;honeybadger&quot;&gt;&lt;a href=&quot;https://eprint.iacr.org/2016/199&quot;&gt;HoneyBadger&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Argues that partial synchrony assumptions are not suitable for critical applications like blockchains, since the parameters are tough to tune and transient network conditions may break the assumptions or cripple throughput.&lt;/p&gt;

&lt;h3 id=&quot;using-proof-of-history-to-simplify-pos-solana&quot;&gt;Using &lt;a href=&quot;https://docs.solana.com/cluster/synchronization&quot;&gt;Proof of History&lt;/a&gt; to simplify PoS (Solana)&lt;/h3&gt;

&lt;p&gt;Argues that most consensus mechanisms are slow because of synchronization issues. So they try and tackle that head-on - which also allows them to confirm individual transactions instead of waiting to create a block. Here’s how it works:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Selection&lt;/strong&gt;: A &lt;em&gt;single&lt;/em&gt; Leader is selected in a &lt;strong&gt;&lt;em&gt;deterministic&lt;/em&gt;&lt;/strong&gt; way beforehand (i.e. is not random)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Proposal with Proof of History for Synchronization (to agree on the ordering of TXes)&lt;/strong&gt; - “Leader nodes ‘timestamp’ blocks with cryptographic proofs that some duration of time has passed since the last proof. All data hashed into the proof must have occurred before the proof generation. The node then shares the new block with validator nodes, which are able to verify those proofs. The blocks can arrive at validators in any order.” &lt;sup id=&quot;fnref:mev&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:mev&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;30&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Vote:&lt;/strong&gt; Every 800ms, validators vote on the set of transactions to achieve consensus - “What’s happening under the hood is that entries are streamed to validators as quickly as a leader node can batch a set of valid transactions into an entry. Validators process those entries long before it is time to vote on their validity. By processing the transactions optimistically, there is effectively no delay between the time the last entry is received and the time when the node can vote. In the event consensus is not achieved, a node simply rolls back its state.”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Repeat.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;narwhal-and-tusk-sui&quot;&gt;&lt;a href=&quot;https://docs.sui.io/learn/architecture/consensus&quot;&gt;Narwhal and Tusk&lt;/a&gt; (Sui)&lt;/h3&gt;

&lt;p&gt;A new approach where 2 separate protocols run in the same network for different tasks.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Narwhal ensures “the availability of data submitted to consensus”. This is a fancy way to say the mempools of the stakers reliably get the data necessary to run the consensus stage, even under adverse network conditions.&lt;/li&gt;
  &lt;li&gt;Tusk’s simplified job (not replaced by Bullshark) is to agree on a specific ordering of this data made available.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;https://media.giphy.com/media/3NtY188QaxDdC/giphy.gif&quot; alt=&quot;https://media.giphy.com/media/3NtY188QaxDdC/giphy.gif&quot; class=&quot;align-center&quot; /&gt;
When you &lt;em&gt;think&lt;/em&gt; you finally get it&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:distributedsystemexample&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;for example, big databases, application servers, and computer infrastructure running on dozens to thousands of computers &lt;a href=&quot;#fnref:distributedsystemexample&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:traditionalconsensus&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;We will not go in depth about consensus mechanisms in traditional crash-tolerant only systems. This is a wonderful article that expands on these: https://www.preethikasireddy.com/post/lets-take-a-crack-at-understanding-distributed-consensus &lt;a href=&quot;#fnref:traditionalconsensus&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:relax&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;For example, the unbounded latency problem can be relaxed by using timeouts. The coordination problem can be simplified by partitioning the nodes into different roles (a leader who arbiters, proposers that submit data and passive acceptors). The fault tolerance (mainly crash-faults) are tackled by rotating leaders when the current one fails. &lt;a href=&quot;#fnref:relax&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:validity&quot; role=&quot;doc-endnote&quot;&gt;

      &lt;p&gt;Validity is easily established using some basic rules of the blockchain. For eg.&lt;/p&gt;

      &lt;ol&gt;
        &lt;li&gt;No-one can spend more than they have.&lt;/li&gt;
        &lt;li&gt;The person who spends their coin, needs to sign it.&lt;/li&gt;
        &lt;li&gt;If there are smart contracts, Input + Prev. State = New state as per the rules of the VM.
These can be validated as long as the rules of the blockchain are clearly specified and are made public.&lt;/li&gt;
      &lt;/ol&gt;
      &lt;p&gt;&lt;a href=&quot;#fnref:validity&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:integrity&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;there is a single agreed ordering of transactions, and they have valid signatures. &lt;a href=&quot;#fnref:integrity&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:da&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;at some point in time, the data was made widely available &lt;a href=&quot;#fnref:da&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:centralization&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;ie. that only well funded validators can meet the requirements of the system &lt;a href=&quot;#fnref:centralization&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3b1b&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Awesome animated video that takes you through nakamoto consensus in an ELI5 way: https://www.youtube.com/watch?v=bBC-nXj3Ng4 &lt;a href=&quot;#fnref:3b1b&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:whitepaper&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;The original whitepaper that started all this is also quite readable and short. Find it here: https://bitcoinwhitepaper.co/ &lt;a href=&quot;#fnref:whitepaper&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:zeros&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;For example, in Bitcoin it’s the number of 0s at the start of the hash &lt;a href=&quot;#fnref:zeros&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:antisybil&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;This is Sybil resistance without PKI, where the anti-sybil asset is the mining rig. &lt;a href=&quot;#fnref:antisybil&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:pos&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Note that this is not the case in Proof of Stake. Creating a block takes way less energy. This and other subtle byzantine failure modes, is why PoS is usually much more complicated than PoW. &lt;a href=&quot;#fnref:pos&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:flp&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Which can mean either of the following 2 scenarios:&lt;/p&gt;

      &lt;ol&gt;
        &lt;li&gt;Fixed bounds exist, but they are not known upfront.&lt;/li&gt;
        &lt;li&gt;Fixed bounds exist and are known, but the guarantee starts at some unknown time in the future.&lt;/li&gt;
      &lt;/ol&gt;
      &lt;p&gt;&lt;a href=&quot;#fnref:flp&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:dls&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Sadly, DLS was not widely adopted in the real world because it relied on a synchronous processor clock which does not fare well in a Byzantine environment. &lt;a href=&quot;#fnref:dls&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:pbft&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Even PBFT wasn’t practical, simple and scalable enough for blockchain systems. Here’s an article comparing the 2: https://jimyang.medium.com/tendermint-vs-pbft-159b467a9e84 &lt;a href=&quot;#fnref:pbft&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:sybil&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;the anti-sybil mechanism &lt;a href=&quot;#fnref:sybil&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:votes&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;The fact that every node has to know every other nodes’ 2 step votes (or lack thereof) every round is why Tendermint chains have a small number of nodes. If the number of nodes is increased, each round will take more time and we’ll get slower blocks. &lt;a href=&quot;#fnref:votes&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:dpos&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;This is why you see the proliferation of Delegated PoS in Cosmos - users delegate their coins to parties that compete on running the best operations so they gain credibility and are able to stay in the top ~100 nodes with maximum staked. &lt;a href=&quot;#fnref:dpos&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:minority&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;where invalid here is defined as “not the same as the majority vote” &lt;a href=&quot;#fnref:minority&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:cartel&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;““Tendermint is two dudes!” Matthew Wampler-Doty excitedly told me, one evening. He explained that a cartel of Tendermint validators with more than 2/3 of the security deposits would form, because it does not require participation from the remaining validators to create finalized blocks (these “non-cartel validators” have less than 1/3 of security deposits). These less than 1/3 of nodes would be censored and eventually removed from the validator set. A new cartel with more than 2/3 of the (now smaller) set of security deposits would then form, and this process would continue until only [at most] 2 validators remain.” &lt;a href=&quot;#fnref:cartel&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:rebuttal&quot; role=&quot;doc-endnote&quot;&gt;

      &lt;p&gt;The Tendermint team disagrees with this viewpoint by invoking the Social Layer as a defense:
”Jae also argued that censorship would not be a problem because it would be noticed by the community, who would promptly rebel against the cartel and stop using the blockchain.” &lt;a href=&quot;#fnref:rebuttal&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:posdebate&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Bitcoin is also vulnerable to this, with a lower threshold of 51%. On that note, we didn’t focus on PoS vs PoW in this article because that is well discussed. You can find a good debate &lt;a href=&quot;https://shows.banklesshq.com/p/the-pow-vs-pos-debate-lyn-alden-and?triedSigningIn=true&quot;&gt;here&lt;/a&gt; with good writeups &lt;a href=&quot;https://www.lynalden.com/proof-of-stake/&quot;&gt;here&lt;/a&gt;, &lt;a href=&quot;https://medium.com/@VitalikButerin/a-proof-of-stake-design-philosophy-506585978d51&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;https://vitalik.ca/general/2017/12/31/pos_faq.html&quot;&gt;here&lt;/a&gt;. &lt;a href=&quot;#fnref:posdebate&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:ethdevresources&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;more resources about the merge found at https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/ and https://ethos.dev/beacon-chain/ &lt;a href=&quot;#fnref:ethdevresources&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:nottender&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;This is different from Tendermint, so you don’t need a team of specialists to keep the node healthy with 100% uptime. This is much more “normie-friendly”, increasing the decentralization of the network since everyone is incentivized to run a validator node. &lt;a href=&quot;#fnref:nottender&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:correlation&quot; role=&quot;doc-endnote&quot;&gt;

      &lt;p&gt;It’s worth noting that the amount slashed is variable on both time and correlation.
”… it can be minor (~1% stake for a single validator slashed on their own) or can result in 100% of the validator’s stake getting destroyed (mass slashing event). It is imposed halfway through a forced exit
period that begins with an immediate penalty (up to 0.5 ETH) on Day 1, the correlation penalty on Day 18, and finally, ejection from the network on Day 36.” &lt;a href=&quot;#fnref:correlation&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:aggregation&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;To remove the quadratic overhead of sending everyone’s attestations to everyone else, ethereum uses &lt;a href=&quot;https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/attestations#aggregated-attestation&quot;&gt;Aggregated Attestations on the Beacon Chain&lt;/a&gt;. &lt;a href=&quot;#fnref:aggregation&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:weaksub&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Some arguments about why weak subjectivity is fine: https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/weak-subjectivity/#how-weak-is-weak &lt;a href=&quot;#fnref:weaksub&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:avax&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;k = 20, a = 14 and b = 20 in Avalanche. &lt;a href=&quot;#fnref:avax&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:conflux&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;DAGs are not limited to Proof of Stake. A project called “Conflux” tried to put DAG on top of Nakamoto consensus. &lt;a href=&quot;#fnref:conflux&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:mev&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Note that this can be gamed. “That data is a double-edged sword. On one side, the data “proves history” - that the data most certainly existed before hashes after it. On the other side, it means the application can manipulate the hash chain by changing when the data is hashed.” &lt;a href=&quot;#fnref:mev&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>MadNeutrino</name></author><category term="Consensus" /><summary type="html">A quick dive into consensus mechanisms used in blockchains today.</summary></entry></feed>