in

CryptoCurrency : FunFair has a vulnerability which is even worse than Oyster!

CryptoCurrency : FunFair has a vulnerability which is even worse than Oyster!


EDIT: Apparently there is an [audit report](https://funfair.io/wp-content/uploads/FunFair-Token-Contract-Audit.pdf) which raises this issue. I don’t know how to find this via the site, only found it via Google – I advice the team to make this report more visible. Also the team claiming this is “not a vulnerability” – if a single wallet has entire control over all funds this falls within my definition of a vulnerability. Please see the [response](https://www.reddit.com/r/CryptoCurrency/comments/9vgesp/funfair_has_a_vulnerability_which_is_even_worse/e9cjm11/) from the actual team.

Few days back the Oyster exit scam happened because the developers had failed to close the possibility to re-open minting of Oyster tokens for a certain price. An anonymous developer took advantage of this and re-opened the Oyster ICO, bought a lot of Oyster for the ICO price and then dumped them all via a market sell on Kucoin.

FunFair is susceptible to the same level – but this is even WORSE!

* FunFair can currently STEAL your tokens from your wallet
* FunFair can MINT infinitely many tokens!

Let’s take a look why this is possible. Let me stress that this is all fixable, but right now FunFair is *NOT* trustless. You need to trust that a single wallet – we don’t know who has this private key (does one person have it, or do multiple people of the company have access to it who can pull of this attack?) – does not do something funny and dump YOUR coins on Binance!

[This is the FunFair contract](https://etherscan.io/address/0x419d0d8bdd9af5e606ae2232ed285aff190e711b). The contract is called “Token” so in the etherscan source code we find the contract “Token” and take a look what’s in there.

function transfer(address _to, uint _value)
onlyPayloadSize(2)
returns (bool success) {
success = controller.transfer(msg.sender, _to, _value);
if (success) {
Transfer(msg.sender, _to, _value);
}
}

This is the transfer function which you use to transfer tokens to anyone (like Binance, or Binance transfers to you). What is funny is that this actually calls into `controller` which is ANOTHER contract! This means that the actual transfers are done via another contract! The “owner” can set the controller address:

function setController(address _c) onlyOwner notFinalized {
controller = Controller(_c);
}

But only when the `finalized` property is set to false. When it is finalized this property cannot be set to true. What is the setting of this now? Well, if we `Read Contract` on etherscan we see that `finalized` is false which means that the owner ([0xb2e4f9c3ca031894a96197de724f05786a00dbf1](https://etherscan.io/address/0xb2e4f9c3ca031894a96197de724f05786a00dbf1)) can set the controller to anything! Note that this is a normal address, not a multisignature address which would need multiple owners to sign off a transaction. Everyone with this private key can reset the controller! And what can they do? Well, we already know they can transfer tokens with NO arbitrary check. Even the `balanceOf`, the ERC20 function to check the balance of an address, calls into `controller`:

function balanceOf(address a) constant returns (uint) {
return controller.balanceOf(a);
}

This basically means that you can create a controller which can return any amount of tokens for a certain address! In fact, if you reset the controller you can create an account with an arbitrary amount of tokens, **even more than the circulating supply!**

Let’s take a look at the [controller](https://etherscan.io/address/0x8f19f89675422fa420a56a3e20b2e8c8cb295c71) which calls into this [Ledger](https://etherscan.io/address/0xe6a51bd48f93abcd6c1d532112094044971d8d4e) contract. This Ledger contract is the core of FunFair currently and this contract actually holds your balance!

Now what is funny is this function:

function transfer(address _from, address _to, uint _value)
onlyController
returns (bool success) {
if (balanceOf[_from] < _value) return false;

balanceOf[_from] = safeSub(balanceOf[_from], _value);
balanceOf[_to] = safeAdd(balanceOf[_to], _value);
return true;
}

As you can see, the `controller` here can just supply a `from` address and a `to` address. If the `from` address has enough tokens they can just transfer these tokens! This means that if the `Controller` contract wants to take all tokens from Binance, they can just do so (probably by resetting the controller contract to a malicious one). Or, what they can also do is just erase all connections to this `Ledger` contract and create a new one where one address (the attacking address) has one trillion Fun tokens!

This can all be prevented by:

* Finalizing the FunFair contract
* Verifying the Controller code which the FunFair contract is tied to

But, right now, your Fun funds are not safe! It only takes one person who has access to the `owner` account to pull an Oyster and steal all your FUN. Also realize that if you are playing in one of their casino’s the funds you get from them are NOT final at this moment!




View the link

Cryptocurrency



The official source for CryptoCurrency News, Discussion & Analysis.
Author: SketchingStories

Score: 751

Don’t forget to share the post if you love it !

Ethereum : Blockchain Crash Course: Protocols, dApps, APIs and DEXs

Bitcoin : Who said crypto was stressful?