Bancor Unchained: All Your Token Are Belong To Us

Udi Wertheimer
Unchained Reports
Published in
11 min readJun 20, 2017

This post is the first in a series of Unchained Reports, covering the often overlooked details about projects in the current “ICO bubble”.

Last week, the Bancor project raised ~$150M. The team stood up an impressive campaign, ending with the largest amount raised in an ICO to date.

Bancor’s main product is said to be a way to provide liquidity to the “long tail” of tokens, and seems to be an interesting idea, that deserves exploration. It is lead by an accomplished team of entrepreneurs, and already produced some great-looking demos.

I took some time to read many of the materials published by Bancor, including its smart contract code. I was absolutely astonished by some of the things I found, including what I consider dangerous backdoors.

In this report, I will detail my findings, including the team’s ability to take anyone’s tokens arbitrarily. But first, a brief introduction on what smart contracts are, and why it’s so important to read and review them.

Did you read your smart contract?

“Smart contracts” are at the heart of the Ethereum blockchain. They are written by coders, so some people think of them as “apps”. But in reality, they aim to replace legal prose. Smart contracts can describe, for example, a set of conditions that will control who gets a pre-deposited amount of money. Or they can describe who will get to decide what happens with a pool of coins.

They are very much like regular legal contracts. But unlike regular contracts, there are no judges to make decisions at their discretion. Instead, blockchain participants will run the smart contract code to decide what’s the outcome of a transaction. There’s only one way to “interpret” a smart contract, and that’s the way a computer would. The intent of the contract writer does not matter, nor does the understanding of any counter party. The only thing that matters is what’s in the code.

Reading Bancor’s contracts

A lot of ICOs use smart contracts to raise money. Bancor is one of them.

This report is (at least) as much about the importance of reading contracts as it is about Bancor itself. I won’t be touching the actual details of Bancor’s protocol at all. I recommend reading Bancor’s whitepaper for that, which is very well written, and also Emin Gün Sirer and Phil Daian’s breakdown on its potential problems (Edit, 22/06/2017: and Bancor’s very detailed response, which was published after this report).

Instead, we will look at the contract of the actual crowdsale: did the contract code fit the sale terms that were published by the project?

Then, we’ll look at the contract governing the token created by that crowdsale, BNT, and the dangerous backdoors that contract contains.

Crowdsale Unlimited

Bancor’s crowdsale went live on June 12th. Prior to its start, in a blog post, the team pubished the sale terms, including the following:

  • The sale would run for no more than 14 days.
  • There would be a “hidden cap” for the amount of funds to be allowed in, which would be revealed when raising 80% of the cap.
  • During the first hour, called the “minimum time”, all funds would be allowed in, even if above the “hidden cap”. If the sale goes over the “hidden cap” during the first hour, it would stop immediately at the end of this first hour. Otherwise, it will continue until reaching the “hidden cap”.

However, the crowdsale contract, viewable here, told a slightly different story. I’ll explain what the contract says in words, and add code snippets so you can follow along if you can read contract code.

  • The sale will, indeed, run for a maximum of 14 days.
The corwdsale duration, in the actual contract code
  • There will be a “hidden cap”, and the team will cryptographically commit to it (meaning it’s hidden but can’t be changed after the sale starts). It will be revealed whenever the team decides to reveal it.
The “hidden cap” was to be revealed, and set, whenever the contract owner calls this enableRealCap function, which sets the totalEtherCap variable
  • The sale was to have no limits (other than a 1,000,000 ETH “safety limit” which equals roughly $400 million dollars, 4 times the “hidden cap” that was later revealed), until the team would reveal the “hidden cap”. Not until 1 hour passed, as the blog post detailing the sale terms promised. In fact, I can think of no reasonable way they could codify this promise into a contract, without revealing the “hidden cap” beforehand.
The safety cap is 1,000,000 ETH, until the enableRealCap function, from the previous snippet, is called by the contract owner to replace it with the “hidden cap”.
This etherCapNotReached modifier is called before every “contribution” to the sale, to assert that the total amount contributed isn’t higher than the current totalEtherCap, which is set to 1,000,000 ETH (above) until the contract owner decides to reveal the “hidden cap”.

As the sale started, people rushed to get their ethers in. The Ethereum network had a hard time processing all those transactions, as it frequently does during high-profile ICOs. As the first hour was approaching its end, about $70M worth of transactions were confirmed by the network, with tens of millions more sitting in the backlog, waiting to be confirmed.

In order to comply with the terms the project published before, they had to stop the “cap-less first hour” at that point, and reveal the “hidden cap” very soon after, once $80M was reached, which was ~80% of the hidden cap.

Instead, they released this critical update, saying:

We have decided to extend the minimum time to THREE HOURS in order to allow the Ethereum network to process all PENDING transactions and allow everyone who’s transactions have failed to RETRY. Our intention remains to include all early contributors.

Many were surprised by this. Some investors were grateful, as they weren’t able to get in during the first hour due to a high load on the network. Yet others were furious — probably the ones that already managed to get in — they were promised that the cap will be enforced after 1 hour, but now that the “minimum time” was expanded to 3 hours, they were effectively being diluted.

One group wasn’t surprised: those that took the time to read the contract before hand. They always knew this was an option.

It is hard to tell whether extending the “minimum time” was good or bad. The key takeaway from this ordeal though, is that when a contract gives its owner capabilities that aren’t listed in the official announcements and blog posts, some people who didn’t read the contract might end up being upset.

But for those who didn’t read the contract, a bigger surprise is in store…

A token full of back doors

When people think of “cryptocurrencies” or “digital assets”, or whatever the cool kids call them today, they think of decentralized, censorship resistant tokens, that no central party could control for any reason. And while some projects have various degrees of (de)centralization, I have never seen a token as centralized as BNT, that puts so much power in the hands of so few.

The BancorTokenContract controls the actual BNT token and its behavior. It is currently owned by the BancorCrowdsale contract, which is owned in turn by a closed-source contract which is most likely a “multisig” account held by the project and/or its partners.

These are the powers that the BancorCrowdsale contract allows its owners:

  • All transactions using the BNT token can be disabled by the team at any time for any reason. Presumably the capability is there to allow the tokens to be frozen immediately after the crowdsale for about a week, until Bancor’s main product is ready. However, for some reason, after they’ll unfreeze the tokens, the team will retain the option to freeze transactions again at any time.
In BancorTokenContract, contract owner (the contract below) is allowed to disable transactions
In BancorCrowdsale, contract owner (the Bancor team) is allowed to use BancorTokenContract (above) to disable transactions
  • The team can issue new tokens at any time. Bancor’s “changer” product requires the ability to create tokens programmatically based on a market-making formula distilled in another smart contract, so it must have the ability to create more tokens. However, for some reason, the team has the ability to create new tokens arbitrarily, for whatever reason they choose.
In BancorTokenContract, contract owner (the contract below) is allowed to issue new tokens arbitrarily
In BancorCrowdsale, contract owner (the Bancor team) is allowed to use BancorTokenContract (above) to issue new tokens arbitrarily
  • Shockingly, the team can DESTROY any tokens FROM ANY ACCOUNT, at any time. Once again, Bancor’s “changer” product requires the ability to programmatically destroy tokens sent to its contract, so there has to be a functionality to destroy tokens — but it could be easily limited to destroying only tokens sent to that contract. Instead, the team has the power to pick any account’s tokens and destroy any amount of them, at any time, for any reason.
In BancorTokenContract, contract owner (the contract below) is allowed to destroy anyone’s tokens arbitrarily
In BancorCrowdsale, contract owner (the Bancor team) is allowed to use BancorTokenContract (above) to destroy anyone’s tokens arbitrarily

This third point is unheard of. I’ve looked at other high-profile contracts managing other tokens, and couldn’t find anything similar. This puts unprecedented, and worse, unexpected power in the hands of the contract owners.

How did this go by unnoticed?

For anyone who’s been in crypto long enough, this is a big no-no. How come no one noticed this?

Well, people did notice.

As noted in this blog post, two security auditors were invited by Bancor to inspect the contracts. However, the blog post only refers to the positive points from the audits. The post didn’t list the concerns that both auditors raised, and instead linked to their full reports which are very lengthy and highly technical. I doubt many people took the time to deep dive into the full reports.

Martin Holst Swende, Security Lead at Ethereum, wrote in his report:

The Bancor protocol implementation has a security model based on centralized trust: the owner of the contracts have (sic), to a large degree, full control over assets traded over the platform… Since the bancor protocol is fairly a complex scheme … it makes sense to have a centralized model, at least initially.

While Ethereum Foundation’s member Nick Johnson wrote in his own report:

Participants should note that the contracts as authored for the crowdsale are not trustless, and depend on the good behaviour of Bancor. Bancor have stated that this is intentional, intended to allow them to respond to and remedy any issues that come up during the crowdsale and in early operation, and that manual oversight will be exchanged for more automated operation once they are confident the system is working as intended.

So, both of these respectable auditors found that the contracts are fully centralized, in an unprecedented way. When they told the Bancor team, Bancor just said “we know, that’s the point”.

Now, the team’s reasoning seems to be that while their main smart contract is still being tested, they should retain full control in case anything goes wrong. They expand on this approach in a blog post about “learning from the DAO”. That blog post details the team’s control over their main “changer” product, control which they plan to diminish over time, but it doesn’t mention at all the backdoors listed above.

From Wikipedia’s article on backdoors:

Although normally surreptitiously installed, in some cases backdoors are deliberate and widely known. These kinds of backdoors might have “legitimate” uses such as providing the manufacturer with a way to restore user passwords.

I’m pretty sure that the Bancor team has no intention to misuse these backdoors, and that they believe they have “legitimate” uses. I’m not 100% sure of their legitimacy myself, but in any case I would argue that their existence should be clearly communicated to investors.

People in this space expect the control over tokens to be fully decentralized, and if for some reason they’re not, this should be made very clear.

Upgradeability

Bancor’s contracts are “upgradeable”, meaning they can replace them with new functionality, giving them more power, or removing power from themselves. They promise on some communications they will gradually remove their control over the system.

The currently deployed BancorCrowdsale contract is planned to be replaced by BancorChanger in the next few days, however this new contract still retains the 3 backdoors: freezing all transactions, issuing new tokens, and destroying any tokens.

The risks

As I mentioned before, I trust that Bancor’s team won’t try to misuse this backdoor. However, having so much power concentrated centrally, creates a potential single point of failure. The keys held by the team could be stolen for example. Or, law enforcement could force the project to freeze or destroy tokens if they realize this is possible (and if for some reason they would suspect any wrongdoing).

It could be argued that BNT investors would be at risk of the team being compromised anyway, so these backdoors don’t add any significant exposure. It could also be argued that if these backdoors are misused, Bancor could always use its reissuance capabilities to restore the state prior to any misuse.

However, because the existence of these backdoors isn’t properly communicated, this puts many users at risk, and especially exchanges.

Exchanges that list the BNT token, might not be aware that if the team’s keys are compromised, the exchanges could lose access to deposited tokens. This could raise regulatory concerns, but also technical risks: exchanges normally don’t “monitor” accounts to check that tokens are “still there”. They assume that once deposited the tokens stay in place, unless they’re moved. If an exchange’s tokens are destroyed (or frozen) while the market is active, this could bring a world of pain to the exchange operator, who might not be able to reverse executed orders.

Recommendations and Conclusion

  • For the Bancor project: I would recommend to immediately restructure the contracts to remove the team’s capability to freeze, issue, or destroy assets arbitrarily. Otherwise, a proper advisory should be given to investors and industry members about the existence of these backdoors, and how to mitigate their risks.
  • For exchanges: The safest route would be to delay listing BNT tokens until the team removes the backdoors. If this is not possible, at the very least inform users during the deposit process that their tokens may be frozen or destroyed by Bancor, and adapt the exchange’s system to monitor that tokens remain non-destroyed and liquid.
  • For future crowdsales: In order to be fully transparent with potential investors and users, it would be best if ICO projects share a clear “English translation” of their smart contracts, that explain step-by-step what the contract does. More than anything else, it should focus on the differences between the written terms and the contract itself, differences that sometimes have to exist.

And for users: always read the contract before you sign. The security of smart contracts depends on the users reading them. If you can’t read code yourself, find someone who can.

I’d like to thank Yair Weinberger and Oded Leiba for helping with the research on this report.

Disclosure: I am an employee at Colu, which develops the Colored Coins protocol and local currency solutions. My employer wasn’t involved in this report in any way, and any research leading up to it was done on my own time. Any and all opinions are my own, and I never owned any Bancor tokens.

Edit (22/06/2017): Bancor published their response to this article, which you may find here.

If you liked this post, tap the 👏 below so other people will see it on Medium!

--

--