
{"id":170138,"date":"2026-05-25T09:23:33","date_gmt":"2026-05-25T09:23:33","guid":{"rendered":"https:\/\/mycryptomania.com\/?p=170138"},"modified":"2026-05-25T09:23:33","modified_gmt":"2026-05-25T09:23:33","slug":"five-things-we-fix-before-the-audit-firm-sees-the-code","status":"publish","type":"post","link":"https:\/\/mycryptomania.com\/?p=170138","title":{"rendered":"Five things we fix before the audit firm sees the code"},"content":{"rendered":"<h4>When we ship a smart contract system, the third-party audit isn\u2019t the finish line. It\u2019s a stress test of how well the development phase was\u00a0run.<\/h4>\n<p>We work with auditors like <strong>Hacken<\/strong> and <strong>CertiK<\/strong> on most production deployments. Over time, you start to notice a pattern: the projects that come back with short reports and quick remediation cycles look completely different <strong><em>at the code level<\/em><\/strong> from the ones that come back with 40 page reports and three weeks of\u00a0rework.<\/p>\n<p>The difference isn\u2019t talent. It\u2019s discipline during development. Here are five things we deliberately get right before we hand a codebase over, because we\u2019ve watched what happens when teams skip\u00a0them.<\/p>\n<p><strong>1. The ownership graph is on paper before any contract is\u00a0deployed<\/strong><\/p>\n<p>Every contract has owners. Multisigs, proxies, role admins, pausers, upgraders. By the time a system has more than three contracts, the ownership relationships start to look like family tree diagrams.<\/p>\n<p>We\u2019ve seen audit reports where the first finding is essentially: <em>\u201cIt is unclear who controls the upgrade path.\u201d<\/em> That\u2019s a finding the dev team should never have allowed to reach the auditor because they didn\u2019t know\u00a0either.<\/p>\n<p>Before we write deployment scripts, we draw the ownership graph. Every contract, every role, every multisig threshold. One diagram, version controlled, reviewed by whoever holds the\u00a0keys.<\/p>\n<p>When the auditor opens the repo, that diagram is the first thing in the README. Half their access control questions answer themselves.<\/p>\n<p><strong>2. Oracle reads are wrapped, never\u00a0raw<\/strong><\/p>\n<p>If a contract pulls a price from anywhere\u200a\u2014\u200aChainlink, Pyth, a custom feed, a <strong>TWAP<\/strong> (Time-Weighted Average Price) that read goes through a wrapper. Not the raw oracle call\u00a0inline.<\/p>\n<p>Why: the wrapper is where you put the staleness check, the deviation check, the fallback logic. It\u2019s the chokepoint where you can say <em>\u201cthis is what we do if the price is stale, wrong, or zero.\u201d<\/em> Without it, those checks get scattered across the codebase or, more commonly, forgotten entirely.<\/p>\n<p>Auditors love wrappers because they collapse the audit surface for oracle-dependent logic. One function to verify instead of forty inline\u00a0reads.<\/p>\n<p>We\u2019ve had reports where the entire oracle-handling section was two paragraphs because there was nothing else to\u00a0say.<\/p>\n<p><strong>3. State changes happen before external calls.\u00a0Always.<\/strong><\/p>\n<p>Checks-Effects-Interactions is a pattern from 2016. It still catches bugs in\u00a02026.<\/p>\n<p>Reentrancy hasn\u2019t disappeared\u200a\u2014\u200ait\u2019s gotten subtler. ERC-777 callbacks, ERC-721 receivers, custom hooks in token routers\u200a\u2014\u200aall of them give external code a chance to re-enter your contract mid-execution. The defense isn\u2019t really nonReentrant modifiers. Those help, but they&#8217;re a backstop.<\/p>\n<p>The real defense is that any state variable controlling a balance or an authorization gets written <strong>before<\/strong> any external call. Period. We grep for this pattern in code\u00a0review.<\/p>\n<p>If a function calls out before it finishes updating state, that function gets rewritten. It\u2019s not a stylistic preference it\u2019s the difference between a clean audit and a critical\u00a0finding.<\/p>\n<p><strong>4. Every event tells the\u00a0truth<\/strong><\/p>\n<p>Events look like a logging concern. They aren\u2019t. They\u2019re the contract\u2019s API surface for every off-chain system that reads it\u200a\u2014\u200aindexers, subgraphs, monitoring dashboards, compliance tools.<\/p>\n<p>We\u2019ve seen contracts that emit Transfer(from, to, amount) from functions that don&#8217;t always actually transfer. Or events fired before revertable external calls, so the event lies when the state change rolls\u00a0back.<\/p>\n<p>By the time the subgraph diverges from on-chain reality, you have a very expensive reconciliation problem.<\/p>\n<p>Before we hand a codebase to an auditor, we do an events pass: every emit must be <strong>after<\/strong> the state change it describes, and the parameters must reflect what actually happened, not what the function was supposed to\u00a0do.<\/p>\n<p><strong>5. The upgrade has been rehearsed against forked\u00a0mainnet<\/strong><\/p>\n<p>This is the one we get asked about least and matters\u00a0most.<\/p>\n<p>If your contracts are upgradeable, the upgrade is part of the system. It needs to be tested with the same rigor as the contracts themselves.<\/p>\n<p>Storage layout collisions, initializer reentrancy, proxy selector clashes\u200a\u2014\u200anone of these appear in unit tests. They appear the first time you push a real upgrade against real\u00a0state.<\/p>\n<p>So before the auditor gets the code, we\u2019ve already done at least one full upgrade dry run on a mainnet fork. The forked-state test, the upgrade transaction, the post-upgrade invariant checks.<\/p>\n<p>If it works there, it\u2019ll work on mainnet. If it doesn\u2019t, we\u2019d rather find out before the audit clock starts\u00a0ticking.<\/p>\n<p><strong>Why this matters for the audit\u00a0phase<\/strong><\/p>\n<p>Third-party audits aren\u2019t expensive because the auditors are expensive. They\u2019re expensive because the second round is. The first review finds issues; you fix them; they re-review. That cycle is where budgets blow up and launch dates\u00a0slip.<\/p>\n<p>Everything above is designed to make round one\u00a0short.<\/p>\n<p>When the ownership graph is clear, the oracles are wrapped, the state changes are ordered correctly, the events are honest, and the upgrade has been rehearsed\u200a\u2014\u200athe auditor\u2019s job gets a lot\u00a0smaller.<\/p>\n<p>The report comes back faster. Remediation is two days, not two weeks. The launch\u00a0holds.<\/p>\n<p>We don\u2019t replace the audit. Hacken and CertiK do work we can\u2019t do independent verification, formal methods, adversarial testing at a level that only a dedicated audit firm can\u00a0offer.<\/p>\n<p>Our job is to hand them code that\u2019s already been built to survive their\u00a0review.<\/p>\n<p>That\u2019s the dev team\u2019s contribution to a clean launch. The audit is downstream of\u00a0it.<\/p>\n<p><em>Bitronix Technologies builds enterprise <\/em><a href=\"https:\/\/bitronix.ai\/services\/smart-contract-development\"><em>smart contract systems<\/em><\/a><em> for regulated industries engineered to ship through audit and into production. If you\u2019re scoping a contract system that has to hold up under third-party review, <\/em><a href=\"https:\/\/bitronix.ai\/booking\"><em>book a 30-minute call.<\/em><\/a><\/p>\n<p><a href=\"https:\/\/medium.com\/coinmonks\/five-things-we-fix-before-the-audit-firm-sees-the-code-fc9258843241\">Five things we fix before the audit firm sees the code<\/a> was originally published in <a href=\"https:\/\/medium.com\/coinmonks\">Coinmonks<\/a> on Medium, where people are continuing the conversation by highlighting and responding to this story.<\/p>","protected":false},"excerpt":{"rendered":"<p>When we ship a smart contract system, the third-party audit isn\u2019t the finish line. It\u2019s a stress test of how well the development phase was\u00a0run. We work with auditors like Hacken and CertiK on most production deployments. Over time, you start to notice a pattern: the projects that come back with short reports and quick [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":170139,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-170138","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-interesting"],"_links":{"self":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts\/170138"}],"collection":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=170138"}],"version-history":[{"count":0,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/posts\/170138\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=\/wp\/v2\/media\/170139"}],"wp:attachment":[{"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=170138"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=170138"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mycryptomania.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=170138"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}