Static analysis with PVS-Studio flags real bugs in Neo and NBitcoin—null dereferences, bad format strings, operator precedence traps, and even infinite recursionStatic analysis with PVS-Studio flags real bugs in Neo and NBitcoin—null dereferences, bad format strings, operator precedence traps, and even infinite recursion

Blockchain’s Bug Tax: The Neo and NBitcoin Mistakes a Linter Spotted

Blockchain development is a high-stakes game where code quality really matters. A single undetected bug can lead to major and sometimes irreversible financial losses. Should we really gamble on skipping a static analyzer check? Let's put it to the test by diving into the code of the Neo and NBitcoin projects.

Introduction

Since I brought up the unique nature of blockchain development, let's delve into what that specifically entails.

First, many blockchain projects handle digital assets with real-world value: tokens, cryptocurrencies, NFTs, access rights, and others. A code error might not just cause a program malfunction but lead directly to users' financial losses.

Second, fixing code in a blockchain project after release may be challenging. In decentralized networks, every node must agree to accept the changes. As for smart contracts, post-release fixes are often outright impossible. Often, it's also impossible to change data once it's recorded on the blockchain, including incorrect data resulting from a code error. These limitations are the price paid for near-perfect data integrity.

Technically, each node stores a full or partial copy of the blockchain to achieve this. The network uses specific algorithms to get all nodes to agree on a single, valid version of the blockchain. If a node blockchain version conflicts with the accepted one, it automatically synchronizes with the network version. So, any unauthorized changes to the blockchain state are rejected by the network.

It's not a full list, but it sufficiently illustrates a potentially immense cost of a code error in a blockchain project.

This article reviews examples of both evident and potential errors detected by PVS-Studio static analyzer in two open-source C# projects.

  • Neo is a full-featured, community-driven blockchain platform.
  • NBitcoin is a .NET library for Bitcoin-related operations.

About PVS-Studio

PVS-Studio is a static code analyzer that automatically detects potential errors and security vulnerabilities in the source code. As of this writing, PVS-Studio supports analyzing C#, C, C++, and Java code.

PVS-Studio integrates with various development tools, including IDEs, build systems, CI services, and other code quality tools like SonarQube.

To analyze Neo and NBitcoin, we used a basic approach—a check via an IDE plugin (in this case, Visual Studio). This plugin allows quick analysis of solutions, projects, or individual files directly from the IDE.

It also provides a simple and convenient interface for reviewing analysis results.

Now that we have a general understanding of the analyzer, let's review the detected issues.

Potential issues in the Neo code

We'll start with the Neo blockchain, version 3.8.2 (the latest at the time of writing).

Suspiciously redundant expression

internal static CommandStringToken Parse(...., ref int index, ....) { .... var ret = new CommandStringToken(....); index += end - index; return ret; }

Enter fullscreen mode Exit fullscreen mode

The analyzer warning: V3107 Identical expression 'index' to the left and to the right of compound assignment. CommandStringToken.cs 80

Note this strange expression: index += end – index. It's equivalent to index = index – index + end. The subtraction result is always 0. So, the entire expression evaluates to the value of the end variable. This makes the subtraction redundant. This could indicate a bug if, for example, a different value was intended to be subtracted instead of index.

Incorrect format

public override string ToString() { var sb = new StringBuilder(); sb.AppendFormat("{1:X04} {2,-10}{3}{4}", Position, OpCode, DecodeOperand()); return sb.ToString(); }

Enter fullscreen mode Exit fullscreen mode

The analyzer warning: V3025 [CWE-685] Incorrect format. A different number of format items is expected while calling 'AppendFormat' function. Format items not used: {3}, {4}. Arguments not used: 1st. VMInstruction.cs 105

Calling the overridden ToString method inevitably causes an exception. This is due to an incorrect sb.AppendFormat call containing two mistakes.

  • The number of arguments to insert is less than the number of placeholders in the format string, which causes an exception.
  • Even if we fix the first issue by matching the number of arguments and placeholders, the call still throws an exception. It's because the placeholder indexing starts at 0, not 1. This means a 5th argument is required for the placeholder with the index 4, which is absent.

Operator precedence confusion

public override int Size => base.Size + ChangeViewMessages?.Values.GetVarSize() ?? 0 + 1 + PrepareRequestMessage?.Size ?? 0 + PreparationHash?.Size ?? 0 + PreparationMessages?.Values.GetVarSize() ?? 0 + CommitMessages?.Values.GetVarSize() ?? 0;

Enter fullscreen mode Exit fullscreen mode

The analyzer warning: V3123 [CWE-783] Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. RecoveryMessage.cs 35

The analyzer issued several V3123 warnings for this code, but we'll break down only one for brevity. The ?? operator has lower precedence than the + operator. However, the formatting of this expression suggests the developer expected the opposite.

Does the order of operations matter here? To answer, let's look at the example of an addition sub-expression if ChangeViewMessages is null:

base.Size + ChangeViewMessages?.Values.GetVarSize() ?? 0

Enter fullscreen mode Exit fullscreen mode

Regardless of the base.Size value, the sub-expression result is always 0 because adding base.Size to null results in null.

If we place ChangeViewMessages?.Values.GetVarSize() ?? 0 in parentheses, changing the operation order, the result becomes base.Size.

Potential null dereference

Issue 1

public OracleNeoFSProtocol(Wallet wallet, ECPoint[] oracles) { byte[] key = oracles.Select(p => wallet.GetAccount(p)) .Where(p => p is not null && p.HasKey && !p.Lock) .FirstOrDefault() .GetKey() .PrivateKey; privateKey = key.LoadPrivateKey(); }

Enter fullscreen mode Exit fullscreen mode

The analyzer warning: V3146 [CWE-476] Possible null dereference. The 'FirstOrDefault' can return default null value. OracleNeoFSProtocol.cs 37

This code risks a typical null dereference by immediately using the value returned by FirstOfDefault on a reference-type collection. If the collection is empty, this method returns null, leading to an exception.

Issue 2

public bool ValidatorsChanged { get { .... TrimmedBlock currentBlock = NativeContract.Ledger.GetTrimmedBlock(....); TrimmedBlock previousBlock = NativeContract.Ledger.GetTrimmedBlock(...., currentBlock.Header // <= .PrevHash); return currentBlock.Header.NextConsensus != previousBlock.Header.NextConsensus; // <= } }

Enter fullscreen mode Exit fullscreen mode

The analyzer warnings:

V3080 [CWE-476] Possible null dereference. Consider inspecting 'currentBlock'. ConsensusContext.cs 89

V3080 [CWE-476] Possible null dereference. Consider inspecting 'previousBlock'. ConsensusContext.cs 90

The analyzer warns twice about potential null dereferences, pointing to the currentBlock and previousBlock variables. Why is dereferencing these variables dangerous? Let's look at their source—the GetTrimmedBlock method:

public TrimmedBlock GetTrimmedBlock(IReadOnlyStore snapshot, UInt256 hash) { if (snapshot is null) throw new ArgumentNullException(nameof(snapshot)); var key = CreateStorageKey(Prefix_Block, hash); if (snapshot.TryGet(key, out var item)) return item.Value.AsSerializable<TrimmedBlock>(); return null; }

Enter fullscreen mode Exit fullscreen mode

This method can indeed return null. It's possible that this might only occur under specific circumstances. Only the code author can confirm this for sure. We can estimate the probability by checking how often the GetTrimmedBlock return value is checked for null elsewhere. I found that the return value is checked in 70% of calls, indicating a significant risk of an exception.

Issue 3

private void OnTimer(Timer timer) { .... if ( timer.Height != context.Block.Index // <= || timer.ViewNumber != context.ViewNumber) { return; } if ( context.Block != null // <= && context.TransactionHashes?.Length > context.Transactions? .Count) { .... } }

\ The analyzer warning: V3095 [CWE-476] The 'context.Block' object was used before it was verified against null. Check lines: 173, 191. ConsensusService.cs 173

Another warning about a potential null dereference. The context.Block property is used without the check first, but is checked for null later. At best, this is a redundant check. However, it's possible that the code containing the dereference was added later than the base logic with the check. In this case, the developer might not have noticed that context.Block could be null.

Incorrect loop

[RpcMethodWithParams] protected internal virtual JToken GetCandidates() { .... foreach (var item in resultstack) { var value = (Array)item; foreach (Struct ele in value) { var publickey = ele[0].GetSpan().ToHexString(); json["publickey"] = publickey; json["votes"] = ele[1].GetInteger().ToString(); json["active"] = validators.ToByteArray() .ToHexString() .Contains(publickey); jArray.Add(json); json = new(); } return jArray; // <= } .... }

\ The analyzer warning: V3020 [CWE-670] An unconditional 'return' within a loop. RpcServer.Blockchain.cs 380

Note the method return statement inside the loop body. This loop lacks any conditions or continue statements to alter its flow. As a result, it always exits after the first iteration, which almost certainly is a critical error. The developer probably made a typo—the intention was likely to return the value after the loop.

Typo in the Equals method implementation

public bool Equals(Nep11BalanceKey other) { if (other is null) return false; if (ReferenceEquals(this, other)) return true; return UserScriptHash.Equals(other.UserScriptHash) && AssetScriptHash.Equals(AssetScriptHash) // <= && Token.Equals(other.Token); }

\ The analyzer warning: V3062 An object 'AssetScriptHash' is used as an argument to its own method. Consider checking the first actual argument of the 'Equals' method. Nep11BalanceKey.cs 57

A simple but very subtle error. In this Equals implementation, theAssetScriptHash field of the parent object is compared to itself. Clearly, the intention was to compare it with the value of the same field of the other object.

Interestingly enough, the analyzer found the exact same error in the equivalent code of another class:

public bool Equals(Nep17BalanceKey other) { if (other is null) return false; if (ReferenceEquals(this, other)) return true; return UserScriptHash.Equals(other.UserScriptHash) && AssetScriptHash.Equals(AssetScriptHash); }

Enter fullscreen mode Exit fullscreen mode

The analyzer warning: V3062 An object 'AssetScriptHash' is used as an argument to its own method. Consider checking the first actual argument of the 'Equals' method. Nep17BalanceKey.cs 50

Potential issues in NBitcoin

Now let's move on to potential issues in NBitcoin version 9.0.1.

Error due to careless copy paste

bool SameSigHash(uint a, uint b) { if (a == b) return true; if (GetTransaction() is not IHasForkId) return false; a = ((uint)a & ~(0x40u)); b = ((uint)a & ~(0x40u)); // <= return a == b; }

Enter fullscreen mode Exit fullscreen mode

The analyzer warning: V3127 [CWE-682] Two similar code fragments were found. Perhaps, this is a typo and 'b' variable should be used instead of 'a' PSBTInput.cs 948

At the end of the method, a and b variables are assigned the result of the same expression. While this could theoretically be intentional, the following comparison makes that unlikely. It looks like the line for 'b' was copied from 'a' but the author forgot to edit it.

Infinite recursion

public static Message ReadNext(Socket socket, Network network, uint version, CancellationToken cancellationToken, out PerformanceCounter counter) { return ReadNext(socket, network, version, cancellationToken, out counter); }

Enter fullscreen mode Exit fullscreen mode

Here is the analyzer warning:

V3110 [CWE-674] Possible infinite recursion inside 'ReadNext' method. Message.cs 167

Calling this method overload causes StackOverflowException, as the only expression in its body is a recursive call to itself.

Identical switch blocks

public override string ToString() { switch (this.Tag) { case Tags.BoolAnd: return "BoolAnd"; case Tags.BoolOr: return "BoolAnd"; // <= case Tags.Add: return "Add"; case Tags.Equal: return "Equal"; case Tags.EqualVerify: return "EqualVerify"; .... } throw new Exception("Unreachable"); }

Enter fullscreen mode Exit fullscreen mode

The analyzer warning: V3139 Two or more case-branches perform the same actions. ScriptToken.cs 169

The ToString method implementation contains a switch statement where one case block duplicates another. Given the explicit pattern implying each case block should be unique, we can confidently say this is a typo.

Overloading Equals method without overloading GetHashCode

public class MoneyBag : IMoney, IEnumerable<IMoney>, IEquatable<MoneyBag> { .... public bool Equals(MoneyBag other) { return Equals(other as IMoney); } public bool Equals(IMoney other) { if (other is null) return false; var m = new MoneyBag(other); return m._bag.SequenceEqual(_bag); } .... }

Enter fullscreen mode Exit fullscreen mode

The analyzer warning: V3126 Type 'MoneyBag' implementing IEquatable interface does not override 'GetHashCode' method. Money.cs 78

The analyzer detected a class implementing the IEquatable<T> interface but not overriding the GetHashCode method. This can lead to issues, as some methods, like those in the Linq library, start by checking hash codes. They only use the Equals method if the hash codes match. If the hash codes differ, the objects are considered unequal.

Conclusion

Our check with PVS-Studio static analyzer uncovered several issues, even in the high-stakes code of blockchain projects. Some of these could be quite serious, leading to unexpected exceptions, incorrect equality checks, and infinite recursion.

This article covered most obvious problems, while many warnings requiring deeper code understanding remained behind the scenes.

If you want to try PVS-Studio on your project, you're welcome to get a trial license on the official website. This documentation section provides activation instructions and links to other sections to help you get started with the analyzer.

Thanks for your attention and see you in future articles!

Market Opportunity
NEO Logo
NEO Price(NEO)
$3.543
$3.543$3.543
+0.42%
USD
NEO (NEO) Live Price Chart
Disclaimer: The articles reposted on this site are sourced from public platforms and are provided for informational purposes only. They do not necessarily reflect the views of MEXC. All rights remain with the original authors. If you believe any content infringes on third-party rights, please contact service@support.mexc.com for removal. MEXC makes no guarantees regarding the accuracy, completeness, or timeliness of the content and is not responsible for any actions taken based on the information provided. The content does not constitute financial, legal, or other professional advice, nor should it be considered a recommendation or endorsement by MEXC.

You May Also Like

Will XRP Price Increase In September 2025?

Will XRP Price Increase In September 2025?

Ripple XRP is a cryptocurrency that primarily focuses on building a decentralised payments network to facilitate low-cost and cross-border transactions. It’s a native digital currency of the Ripple network, which works as a blockchain called the XRP Ledger (XRPL). It utilised a shared, distributed ledger to track account balances and transactions. What Do XRP Charts Reveal? […]
Share
Tronweekly2025/09/18 00:00
Ripple IPO Back in Spotlight as Valuation Hits $50B

Ripple IPO Back in Spotlight as Valuation Hits $50B

The post Ripple IPO Back in Spotlight as Valuation Hits $50B appeared first on Coinpedia Fintech News Ripple, the blockchain payments company behind XRP, is once
Share
CoinPedia2025/12/27 14:24
Lovable AI’s Astonishing Rise: Anton Osika Reveals Startup Secrets at Bitcoin World Disrupt 2025

Lovable AI’s Astonishing Rise: Anton Osika Reveals Startup Secrets at Bitcoin World Disrupt 2025

BitcoinWorld Lovable AI’s Astonishing Rise: Anton Osika Reveals Startup Secrets at Bitcoin World Disrupt 2025 Are you ready to witness a phenomenon? The world of technology is abuzz with the incredible rise of Lovable AI, a startup that’s not just breaking records but rewriting the rulebook for rapid growth. Imagine creating powerful apps and websites just by speaking to an AI – that’s the magic Lovable brings to the masses. This groundbreaking approach has propelled the company into the spotlight, making it one of the fastest-growing software firms in history. And now, the visionary behind this sensation, co-founder and CEO Anton Osika, is set to share his invaluable insights on the Disrupt Stage at the highly anticipated Bitcoin World Disrupt 2025. If you’re a founder, investor, or tech enthusiast eager to understand the future of innovation, this is an event you cannot afford to miss. Lovable AI’s Meteoric Ascent: Redefining Software Creation In an era where digital transformation is paramount, Lovable AI has emerged as a true game-changer. Its core premise is deceptively simple yet profoundly impactful: democratize software creation. By enabling anyone to build applications and websites through intuitive AI conversations, Lovable is empowering the vast majority of individuals who lack coding skills to transform their ideas into tangible digital products. This mission has resonated globally, leading to unprecedented momentum. The numbers speak for themselves: Achieved an astonishing $100 million Annual Recurring Revenue (ARR) in less than a year. Successfully raised a $200 million Series A funding round, valuing the company at $1.8 billion, led by industry giant Accel. Is currently fielding unsolicited investor offers, pushing its valuation towards an incredible $4 billion. As industry reports suggest, investors are unequivocally “loving Lovable,” and it’s clear why. This isn’t just about impressive financial metrics; it’s about a company that has tapped into a fundamental need, offering a solution that is both innovative and accessible. The rapid scaling of Lovable AI provides a compelling case study for any entrepreneur aiming for similar exponential growth. The Visionary Behind the Hype: Anton Osika’s Journey to Innovation Every groundbreaking company has a driving force, and for Lovable, that force is co-founder and CEO Anton Osika. His journey is as fascinating as his company’s success. A physicist by training, Osika previously contributed to the cutting-edge research at CERN, the European Organization for Nuclear Research. This deep technical background, combined with his entrepreneurial spirit, has been instrumental in Lovable’s rapid ascent. Before Lovable, he honed his skills as a co-founder of Depict.ai and a Founding Engineer at Sana. Based in Stockholm, Osika has masterfully steered Lovable from a nascent idea to a global phenomenon in record time. His leadership embodies a unique blend of profound technical understanding and a keen, consumer-first vision. At Bitcoin World Disrupt 2025, attendees will have the rare opportunity to hear directly from Osika about what it truly takes to build a brand that not only scales at an incredible pace in a fiercely competitive market but also adeptly manages the intense cultural conversations that inevitably accompany such swift and significant success. His insights will be crucial for anyone looking to understand the dynamics of high-growth tech leadership. Unpacking Consumer Tech Innovation at Bitcoin World Disrupt 2025 The 20th anniversary of Bitcoin World is set to be marked by a truly special event: Bitcoin World Disrupt 2025. From October 27–29, Moscone West in San Francisco will transform into the epicenter of innovation, gathering over 10,000 founders, investors, and tech leaders. It’s the ideal platform to explore the future of consumer tech innovation, and Anton Osika’s presence on the Disrupt Stage is a highlight. His session will delve into how Lovable is not just participating in but actively shaping the next wave of consumer-facing technologies. Why is this session particularly relevant for those interested in the future of consumer experiences? Osika’s discussion will go beyond the superficial, offering a deep dive into the strategies that have allowed Lovable to carve out a unique category in a market long thought to be saturated. Attendees will gain a front-row seat to understanding how to identify unmet consumer needs, leverage advanced AI to meet those needs, and build a product that captivates users globally. The event itself promises a rich tapestry of ideas and networking opportunities: For Founders: Sharpen your pitch and connect with potential investors. For Investors: Discover the next breakout startup poised for massive growth. For Innovators: Claim your spot at the forefront of technological advancements. The insights shared regarding consumer tech innovation at this event will be invaluable for anyone looking to navigate the complexities and capitalize on the opportunities within this dynamic sector. Mastering Startup Growth Strategies: A Blueprint for the Future Lovable’s journey isn’t just another startup success story; it’s a meticulously crafted blueprint for effective startup growth strategies in the modern era. Anton Osika’s experience offers a rare glimpse into the practicalities of scaling a business at breakneck speed while maintaining product integrity and managing external pressures. For entrepreneurs and aspiring tech leaders, his talk will serve as a masterclass in several critical areas: Strategy Focus Key Takeaways from Lovable’s Journey Rapid Scaling How to build infrastructure and teams that support exponential user and revenue growth without compromising quality. Product-Market Fit Identifying a significant, underserved market (the 99% who can’t code) and developing a truly innovative solution (AI-powered app creation). Investor Relations Balancing intense investor interest and pressure with a steadfast focus on product development and long-term vision. Category Creation Carving out an entirely new niche by democratizing complex technologies, rather than competing in existing crowded markets. Understanding these startup growth strategies is essential for anyone aiming to build a resilient and impactful consumer experience. Osika’s session will provide actionable insights into how to replicate elements of Lovable’s success, offering guidance on navigating challenges from product development to market penetration and investor management. Conclusion: Seize the Future of Tech The story of Lovable, under the astute leadership of Anton Osika, is a testament to the power of innovative ideas meeting flawless execution. Their remarkable journey from concept to a multi-billion-dollar valuation in record time is a compelling narrative for anyone interested in the future of technology. By democratizing software creation through Lovable AI, they are not just building a company; they are fostering a new generation of creators. His appearance at Bitcoin World Disrupt 2025 is an unmissable opportunity to gain direct insights from a leader who is truly shaping the landscape of consumer tech innovation. Don’t miss this chance to learn about cutting-edge startup growth strategies and secure your front-row seat to the future. Register now and save up to $668 before Regular Bird rates end on September 26. To learn more about the latest AI market trends, explore our article on key developments shaping AI features. This post Lovable AI’s Astonishing Rise: Anton Osika Reveals Startup Secrets at Bitcoin World Disrupt 2025 first appeared on BitcoinWorld.
Share
Coinstats2025/09/17 23:40