Into the FLOW: Under the Hood of a Code Audit

The Focus Group
8 min readOct 20, 2020

--

Well well well what do we have here? No really, please tell us. We can’t read it.

DeFi is a dangerous place. There are scams and scammers everywhere you look. That’s why it was so important to us at The Focus Group to put FLOW Protocol through a code security audit. Besides, many top exchanges and platforms require one to be considered for integrations or partnerships so it was going to be necessary eventually.

As you may know, thanks to donors from the community, and top audit firm, Red4Sec, the FLOW Protocol smart contract recently passed an audit with flying colors (link to the full report here).

This was a critical step in FLOW’s journey towards trust, credibility, and ultimately, adoption.

While there were zero vulnerabilities found in the contract that would put user funds at risk, there were a handful of secondary recommendations made in the audit.

As non-technical community members, some of these points sounded to us as either ominous, or like opportunities to update and relaunch the smart contract. We talked to Morpheus about them and it turns out they’re all either moot (because they have to do with gas efficiency for executing the contract, which has already happened) or they represent intentional design choices.

We found it educational to compare why Red4Sec highlighted them for recommended updates with Morpheus’ logic behind implementing the FLOW Protocol smart contract the way he did. This seems like an opportunity to share a little blockchain education, provide deeper transparency for the FLOW community and the blockchain space as a whole, and offer a rare non-tech-friendly dive into a cryptocurrency design.

So, for anyone who wants a peak under the hood (all 3 of you lol), we want to take a moment here to go through some of the details from Red4Sec’s report.

Missing Notification: Yikes? Nah, We’re Good.

There’s been a lot of news lately about scams called “rug pulls”, where hidden functions in smart contracts are used to mint a bunch of tokens for the creator(s) which they then dump on the market, leaving supporters holding a hyperinflated token that has lost almost all of its value. People have lost millions of dollars from these projects, being taken in by the hype, and the allure of fast, easy profit.

So you can imagine how a non-technical DeFi aficionado might feel reading this ominous-sounding piece about a “missing initial mint notification”:

“During the FLOW deployment the constructor of the CappedToken is invoked, in which an initial balance with total supply is established for the owner. This initial mining process does not issue the Transfer notification recommended in the ERC20. “A token contract which creates new tokens SHOULD trigger a Transfer event with the _from address set to 0x0 when tokens are created.” 1 Bypassing notifications can incur in mismatches in the balances shown by light wallets and explorers which based on the events issued by the smart contract, calculate the balance of each account.”

This turns out to be quite innocent (which we already knew because it wasn’t considered a vulnerability to user funds by Red4Sec).

Here’s Morpheus putting non-technical supporters at ease:

“In some cases, certain wallets may only look at transfer events to determine balances of accounts. If you don’t create a transfer event initially when the supply is created, it could confuse those wallets. However, because Flow Protocol uses transactionless inflation you cannot rely on transfer events to determine account balances. In this case an initial transfer event doesn’t matter at all. When FLOW is actually transferred between parties a transfer event IS emitted. This has some utility as a website might update your balance on the screen when FLOW is transferred to or from your account.”

We’ve noticed the transactionless inflation mechanism causing some minor hiccups like the rich list not updating properly on sites like Blockpour because they pull their data from etherscan, and etherscan only updates balances when a transaction takes place. This is what Morpheus means by not being able to rely on transfer events to determine account balances.

It’ll be interesting to see if blockchain infrastructure is updated over time to account for this if/when transactionless inflation models become more popular.

Gas Savings: No One Rides for Free

There’s a number of recommendations in Red4Sec’s audit report that are listed as providing “gas” savings.

Most Ethereum users have some sense of how gas works. For those who don’t know, Red4Sec gives the simplest description like this:

“On Ethereum blockchain, GAS is an execution fee which is used to compensate miners for the computational resources required to power smart contracts.”

Clear enough, right? Gas is used for sending tokens between wallets, staking tokens to smart contracts, and more.

Tl;dr: It’s a transaction fee.

There’s a whole section in the audit report about optimizing the smart contract to save gas costs, titled “GAS optimization”.

Here’s their high level description of the section:

“Software optimization is the process of modifying a software system to make an aspect of it work more efficiently or use less resources. This premise must be applied to smart contracts as well, so that they execute faster or in order to save GAS… If the network usage is increasing, so will the value of GAS optimization.”

There’s a handful of recommendations they offer in this section to save gas in the FLOW Protocol smart contract, with headers like “Fixed Arguments” and “Wrong Type”.

At first, we thought this meant there were revisions to the smart contract that would provide significant savings for FLOW transactions. But, in fact, these recommendations mostly relate to launching (aka “executing”) the FLOW Protocol smart contract. Since the contract is only launched once, these recommendations are irrelevant for us.

One exception was a section entitled “Logic Optimization”.

Red4Sec notes:

“All the inputs of the _eras array are sequentially reviewed in the _getSupply function, this with the intention of finding which is the correct era according to the current date. This logic is correct but not very efficient in time, if we assume that the contract will have great longevity, because when the maximum era is reached, it will always have to perform the same sequence, checking that the initial eras will not be valid ever again.

If we revert the loop, so that instead it goes back to front, overtime you will obtain a significant save in gas. This is because it will always take the last input as valid instead of checking each and every one of the existing inputs. Another possibility to improve said function is by checking if currentCycle is equal to FINAL_CYCLE, so that it automatically returns the value corresponding to the last era.”

Once you cut through all the technical language you can see this is reasonable advice, but it turns out the trade off was chosen intentionally.

According to Morpheus: “If we switched to their recommendation, gas would be higher now and lower over time. I chose to go the other way as gas fees are expected to drop with Ethereum over time.”

Eras in FLOW last a year each, and there are ten of them. So, the way Morpheus designed the protocol, gas fees are lower now (nominally and in real cost), and though they’ll rise nominally over time, this design choice should result in low fees in the future as well — saving money for FLOW holders on both ends of the time spectrum.

I mean, if gas fees don’t drop over time we’ll have bigger things to worry about, right?

Another standout in the Gas Optimization section has to do with airdrops.

Entitled “Possible Wrong Types”, this section talks about design choices for airdrops of equal amounts to groups of wallets (say, 10 FLOW to 100 different wallets) vs airdrops based on size of holdings (ex. FLOW going to 100 different wallets based on the amount of x token each holds).

“Airdrops are usually made based on the balance of the receptor’s accounts, consequently it would be convenient to review if such variables should be modified to turn airdropAmt into an array or to change recipients to stop being one. Setting the correct type of inputs is a necessary practice for an optimized execution.”

Since the airdrop function in FLOW Protocol was included specifically to send equal amounts of tokens rather than based on size of holdings, this review is not necessary.

Third Party Library: ABDKMath

There were a few notes related to a third party library called “ABDKMath”.

This is what Morpheus has to say about why ABDKMath is included in the FLOW Protocol smart contract:

“Solidity doesn’t let you use decimal numbers so you need complex code to perform some operations that would normally be easy. ABDKMath handles this. In the case of Flow Protocol, ABDKMath is used for compounding.”

One of the notes provided by Red4Sec about ABKDMath is entitled “Unsecure Underflow”.

The comments read as follows:

“During the review of ABDKMath contract, it has been observed that the underflows and the overflows produced by the mathematical operations made within the powu function, are not equally treated. Therefore, in order to avoid triggering unexpected issues in the contract’s logic, every time an overflow is carried out during a mathematical operation a revert must be executed.”

Underflow.. Isn’t that a Tool album?

This sounds scary! So naturally we asked Morpheus to put us at ease. His reply for us lay folk:

“This is rather difficult to explain to someone that is not a dev. It isn’t critical because Flow Protocol code doesn’t use this function in a way that would be affected by what they are describing.”

Since this didn’t come up as a critical vulnerability (because there were none!), this is a perfectly acceptable explanation for us.

Another comment relates to “improvable unit testing”.

Regarding unit testing, Red4Sec notes:

“[T]he ABDKMath library lacks unitary tests. It is recommended to add unitary tests to the ABDKMath mathematical library since it lacks these in its official repository and within the Smart Contract there are critical operations that rely on it.”

Morph comments: “There may be a little confusion here. Flow Protocol code relies on ABDKMath, so by thoroughly testing Flow Protocol code, ABDKMath code is being tested within that context.”

So even though it’s technically true that there aren’t unit tests directly targeting ABDKMath code, this code is in fact tested.

The other note about ABDKMath was the aforementioned “Wrong Type”, which only relates to initial execution of the FLOW Protocol smart contract. Since FLOW has already launched and functions as intended, that one is clearly moot.

Conclusion

If you’re still reading we’re super impressed. We in the Focus Group found it fascinating to go through this report piece by piece and learn more about how Morpheus designed the FLOW Protocol, and how intimidating technical-ese can be totally innocuous and/or represent well thought-out design considerations.

We hope you’ve learned a little something, too, and gained a deeper appreciation for the depth of knowledge it takes to design a cryptocurrency or smart contract.

Thanks again to all the community members who donated to make the security audit happen, and thanks to Morpheus for his time educating us about the protocol.

Keep It Flowin’,

The Focus Group

--

--

The Focus Group

A self-organized group of FLOW Protocol tokenholders pulling together to support the project and community