Discover more from Secureum
Making Alpha SAFU — Secureum #9
Security Audits For Users
Previous posts (#3, #4, #5, #6, #8) hypothesized that we can take a step towards making DeFi “SAFU” by breaking down Security Audits For Users (SAFU) and illustrated that with case studies of DeFi stablecoin, Zk-Rollup payment, risk coverage and options projects.
This post dives into another interesting DeFi project — Alpha Homora V2, a DeFi leveraged yield farming protocol from Alpha Finance.
To provide some context for new readers (others may skip this section), DeFi projects rely on external security audits as a stamp of security approval. Audit is not a security warranty of “bug-free” code by any stretch of imagination but a best-effort endeavour by trained security experts operating within reasonable constraints of time, understanding, expertise and of course, decidability.
Audit reports illustrate security issues with descriptions of underlying vulnerabilities, likelihood/impact, potential exploit scenarios and recommended/resolved fixes. They also provide subjective insights into code quality, documentation and testing. The scope/depth/format of audit reports varies across auditing teams but they generally cover similar aspects.
Security companies execute audits for clients who pay for their services. Engagements are therefore geared towards priorities of project owners and not project users. Audits are not intended to alert potential project users of any inherent risk. That is not their business/technical goal.
Nevertheless, the conjecture is that project users may be basing their risk without considering if the project had any security audits or incorrectly assuming no/minimal risk for audited projects without bothering to, or having the expertise (understandably so) to evaluate audit report contents.
Evaluating audit reports requires a reasonable level of expertise in smart contract security. Breaking down security audit reports for the benefit of less security-savvy users may make DeFi a bit safer by helping them DYOR.
Project Overview: Alpha Homora V2 is a leveraged yield farming and leveraged liquidity providing protocol.
Lenders can lend many assets, e.g. ETH, USDT, USDC, DAI, and more, to earn high lending interest rate. The lending interest rate comes from leveraged yield farmers/liquidity providers borrowing these assets to yield farm/provide liquidity.
Yield farmers can get even higher 1) farming APY and 2) trading fees APY from taking on leveraged yield farming positions. By taking on leverage, Alpha Homora would borrow the specified assets on behalf of the users to yield farm.
Liquidity providers can get even higher trading fees APY from taking on leveraged liquidity providing positions. By taking on leverage, Alpha Homora would borrow the specified assets on behalf of the users to provide liquidity.
Liquidators can earn 5% bounty by liquidating positions that are at 100% debt ratio.
Compared to V1, Alpha Homora V2 supports lending/borrowing of more assets (besides ETH) on Curve and Balancer protocols in addition to the earlier Uniswap and Sushiswap.
Exploit & Incident Response Overview: As explained in the well-detailed post-mortem report from Alpha Finance, on 13 February 2021, an attacker exploited Alpha Homora V2 for ~$38M using a series of more than 9 complex transactions involving flashloans. This was less than a month after completion of the two audits.
According to their internal analysis, the attacker had to know the following details for carrying out this complex exploit:
1. HomoraBankv2 has an sUSD pool on a contract level in preparation for the upcoming release, which is neither available on the UI nor publicly announced.
2. There was no liquidity in sUSD lending pool, so the attacker can fully manipulate and inflate the total debt amount and total debt share.
3. There is a rounding miscalculation in borrow function calculation, which only affects when the attacker is the sole borrower.
4. resolveReserve function can increase totalDebt without increasing totalDebtShare and the function, intended for collecting revenue to the reserve pool, can indeed be called by anyone.
5. HomoraBankv2 accepts any custom spell, as long as the invariant checks out that collateral > borrow (a spell is similar to a strategy in Yearn).
An independent analysis from Origin team further evaluated the context and complexity of the exploit. This level of complexity led to speculation that some insider information may have been involved and perhaps the reason why there was a “prime suspect.” Interestingly, the attacker’s first transaction ran out of gas and the suspicious transactions were alerted first on Twitter.
The affected funds were a debt between Alpha Finance V2 and Cream V2 via Iron Bank. The attacker took a loan from Iron Bank pretending to be Alpha thus leaving it in debt for the stolen funds. Alpha users were not directly affected.
In response, the project paused borrowing on V2, launched a joint investigation with Andre Cronje, Cream protocol team, Samczsun among others, closed the exploited loophole, whitelisted spells, blacklisted attacker’s accounts/ip’s and commissioned more internal/peer reviews plus another security audit, as described here.
They announced detailed plans for funds repayment (on 22 February) and made fixes (see commits on 24 February) to HomoraBank.sol, which included whitelisting tokens/spells/users, updating onlyEOA modifier usage, adding onlyGov modifier to resolveReserve() and fixing the rounding miscalculation in borrow().
Audits Overview: Quantstamp’s audit of Alpha Homora V2 reported on 14 January 2021 (3 auditors, 6 weeks) finding a total of 15 issues: 4 high (fixed), 2 medium (fixed), 4 low (fixed/acknowledged/mitigated), 4 informational (fixed/acknowledged) and 1 undetermined (fixed) severity issues, along with eleven best practice recommendations.
PeckShield’s audit of Alpha Homora V2 reported on 20 January 2021 (2 auditors; duration not mentioned) finding a total of 10 issues: 2 medium (resolved), 6 low (resolved), 2 informational (resolved) severity issues.
Quantstamp Report Breakdown
Quantstamp’s audit report (called “Security Assessment Certificate”) is well organized with an Executive Summary that provides a good snapshot of the audit followed by goals/methodology, tools used (Truffle, Solidity Coverage, Mythril and Slither), findings details, automated analyses, code documentation, best practices and test results.
Highlights: The audit summary (shown below) provides a great overview of the highlights.
The first highlight is that out of 15 issues found, 11 were fixed/mitigated and 4 low/informational ones were acknowledged, which is good.
The second highlight points to code comments being good but specifications/documentation being insufficient. Unit testing and code coverage reports were also lacking.
Finally, the audit called out the extensive logic/features/integrations resulting in significant edge cases and latent issues, therefore highly recommending additional reviews besides more specification/documentation/testing before project launch. It also pointed out addition of new files during their re-audit assessment which were out of scope for the audit.
Findings: QSP-1 (High) and QSP-2 (High) were about missing checks that turned out to be false positives. QSP-3 (High) was an incorrect math calculation where the variables totalShare and totalDebt were interchanged. QSP-4 (High) was about a potential exploit involving price oracles and flash loans, but the project clarified that the only collateral will be LP tokens which are not susceptible to this scenario.
Other findings were related to business logic, multiplication after division (potential loss of precision), lack of fallback oracles, flash crash insolvency, initialization front-running, privileged roles and missing checks/SafeMath.
The best practices called out potential issues related to missing unique token checks, price oracle manipulation of whitelisted tokens and infinite approvals. Functional tests were present but not unit tests.
PeckShield Report Breakdown
PeckShield’s audit report is very detailed with a project introduction, OWASP-based methodology details, check list of vulnerabilities and summary/details of all the findings.
Highlights: The highlight from the summary (shown below) is that the contracts could be further improved in security/performance, which is always the case. All 10 reported findings were resolved, which is good.
Findings: PVE-006 (Medium) was about better slippage control in repayment logic in the context of sandwich attacks on AMM-based DEXs. PVE-010 (Medium) was about missing updates in the borrow logic leading to incorrect contract state and potential DoS.
Other low and informational findings were related to incorrect function arguments, avoidable integer overflow, choice of public vs private function visibility, better validation, immutable state variables, refunding overpayments, unnecessary payable attribute and business logic.
This post gave a breakdown of audit reports on Alpha Homora V2 — a DeFi leveraged yield farming protocol from Alpha Finance — from Quantstamp and PeckShield, in the context of the recent exploit and incident response.
Overall, there were some red flags raised by the two audits, less than a month before the exploit, which were all fixed. But the exploited vulnerable scenario was present in the audited contract and remained undiscovered because of the complex constraints under which it could be triggered.
The exploited scenario was not a common Solidity coding pitfall that could have been detected by automated tools checking for security best practices. It was a complex set of constraints particular to the exploited contract’s logic and its interaction with other protocols. It is hard to say if more/better design/code/security reviews could have caught this earlier. Although Quantstamp’s audit did call out the need for better specification and more testing given the complexity of features and interactions, that’s often true for most projects.
The spells were meant to be user customizable by design which allowed the attacker to create an “evil” spell. The sUSD pool while unannounced and unavailable in the UI was nevertheless present in the contract which an attacker could figure out by looking at the deployed code.
The rounding miscalculation in the borrow() function and resolveReserve() visibility were coding errors that audits could perhaps have detected. Interestingly, Quantstamp audit had flagged a high-risk finding QSP-3 in that very same line of code: “L355 in contracts/HomoraBank.sol, should be amount.mul(totalShare).div(totalDebt) instead of amount.mul(totalDebt).div(totalShare)” but the rounding fix additionally required .add(1). Also, PeckShield audit had flagged a missing poke modifier on resolveReserve() but not onlyGov.
While these could be tricky for manual analysis to catch, it perhaps could have been caught by specifying/solving the right invariants/constraints using tools such as Echidna/Manticore or Certora Prover. Preventing these design/coding errors might have made it harder for the attacker to amplify the attack but it’s not clear if it would have averted the exploit altogether.
This project got two independent audits simultaneously from reputable firms in this space with 5 auditors spending more than 6-8 weeks effort. While both audits found/fixed different issues, the project still got exploited unfortunately. It’s not obvious that more/different audits would have necessarily helped. Auditing and auditors have limitations too. They provide a best-effort security snapshot over a brief (typically few weeks) period based on available information. Community-driven models such as ReviewsDAO and Code 423n4 are being tested as supplementary measures.
Furthermore, vulnerabilities may be reduced but cannot be ruled out. Guarded launches with built-in circuit breakers and better on-chain monitoring/response are therefore critical. One possibility here could have been an initial launch with whitelisted spells before allowing user-specified spells. Also, the fact that the exploit involved 9 transactions with suspicious activity first reported on Twitter indicates that on-chain monitoring/response can certainly improve.
Security hindsight, after an exploit/disclosure, is certainly 20/20 and regretful. Overall, better specification, more documentation, extensive testing of corner cases, use of security tools during development, internal code reviews, multiple independent audits covering the same/entire deployment scope for redundancy/completion and a public bug bounty program would help continually raise the bar.
Projects need 24/7 security expertise and should follow Secure Software Development Lifecycle (SSDLC) with “Continuous Auditing” and “Continuous Monitoring/Response” (similar to CI/CD process), which is both a hard market problem and a technical challenge.
Breaking down DeFi Security Audits For Users (SAFU) may be worthwhile as a public good but certainly should not be interpreted as an endorsement/indictment of projects/auditors or as financial/investment advice. DeFi SAFU should be a collective community responsibility.
I hope you found this somewhat useful. Thanks for reading and look forward to your comments and feedback.