Test Solidity Smart Contracts Using Travis CI

What is Travis CI?

Our smart contract development team is using Travis CI to integrate automated testing into GitHub repositories. This guide for this great tool will not go into detail about Travis CI itself (you can refer to Travis Get Started Guide if you’re unfamiliar with it), but rather explain how to automate tests for Solidity smart contracts. We will be using Truffle for running and building tests and Ganache to set up the network since Travis has built-in support for JavaScript and Node.js.

Travis CI for smart contracts

  1. If you still haven’t given Travis CI access to your repo, follow this guide. Otherwise, just go to the next step.
  2. Create a file in your GitHub repo called .travis.yml. The purpose of this file is to detail which steps should be executed at each step of the build; if it’s not in your repo, Travis CI won’t trigger the build process. Your .travis.yml file should look like this:

    You may have noticed that many of the commands here are specifically for Debian-based distros. Don’t worry if you’re using another distro or a different OS altogether — all of these commands will run on a VM provided by Travis CI (more info here). ./bin/travis-install.sh and ./bin/test.sh are just the scripts you’ll use for installing any necessary modules or dependencies and testing your smart contracts, respectively. As we will see in the following steps, you can name them whatever you want as long as they execute some specific commands and they’re properly referenced in .travis.yml.
  3. Create a file called ./bin/travis-install.sh. In our example, we put shell scripts in ./bin/ to keep the repo organized, but it isn’t strictly necessary. This is what it should look like:

    This will install all the Node packages you need for setting up an Ethereum network and running your tests.
  4. Create another file called ./bin/test.sh. This is what will actually run the tests.
  5. Make sure to replace <yourLimit> with whatever you’d like to set as the gas limit for the network. If you only want to execute some specific test cases, you can just replace truffle test with truffle test the same way you would if you were executing them in the console.
  6. Now everything should be set for pushing your changes!
  7. Optionally, add a Travis status badge to your repo’s README.md.

You can now easily see if your smart contracts are working just by pushing changes to Git. No more manual testing before updating your remote repo — Travis CI will let you know if your project is working properly.

Cryptosolartech Security Audit

Introduction

Coinfabrik’s smart contract audit’s team was asked to audit the contracts for the Cryptosolartech sale. Firstly, we will provide a summary of our discoveries and secondly, we will show the details of our findings.

Summary

The contracts audited are from the Cryptosolartech repository. The audit is based on the commit 4a04863c1cf6ef55d89a3ed63c3e0de863efe4da and updated to reflect the changes made on commit bd4277db249d9550cea439f9044c54882c379d5d.

The audited contracts are:

  • contracts/Burnable.sol: Burnable token interface.
  • contracts/Crowdsale.sol: Deployable contract for the crowdsale.
  • contracts/CrowdsaleToken.sol: Deployable contract for the token.
  • contracts/DeploymentInfo.sol: View functions for additional information.
  • contracts/EIP20Token.sol: EIP20 Token interface.
  • contracts/GenericCrowdsale.sol: Abstract base contract for token sales.
  • contracts/Haltable.sol: Inheritable contract with modifiers for halting capabilities.
  • contracts/LostAndFoundToken.sol: Inheritable contract for securely retrieving mistakenly sent tokens.
  • contracts/Mintable.sol: Mintable token interface.
  • contracts/MintableToken.sol: Inheritable contract for minting capabilities.
  • contracts/Ownable.sol: Inheritable contract with modifiers for privilege calls.
  • contracts/ReleasableToken.sol: Inheritable contract
  • contracts/SafeMath.sol: Overflow checked arithmetic functions
  • contracts/StandardToken.sol: Standard ERC20 token implementation.
  • contracts/TokenTranchePricing.sol: Tranche pricing capabilities for the crowdsale.
  • contracts/UpgradeableToken.sol: Inheritable contract for upgrading capabilities.
  • contracts/UpgradeAgent.sol: Inheritable contract for the agent executing the upgrade.

The following analyses were performed:

  • Misuse of the different call methods: call.value(), send() and transfer().
  • Integer rounding errors, overflow, underflow and related usage of SafeMath functions.
  • Old compiler version pragmas.
  • Race conditions such as reentrancy attacks or front-running.
  • Misuse of block timestamps, assuming anything other than them being strictly increasing.
  • Contract softlocking attacks (DoS).
  • Potential gas cost of functions being over the gas limit.
  • Missing function qualifiers and their misuse.
  • Fallback functions with a higher gas cost than the one a transfer or send call allows.
  • Fraudulent or erroneous code.
  • Code and contract interaction complexity.
  • Wrong or missing error handling.
  • Overuse of transfers in a single transaction instead of using withdrawal patterns.
  • Insufficient analysis of function input requirements.

Detailed findings

Minor severity

Unintended multiplication by 0 in calculateTokenAmount()

It is possible for a user to buy tokens but receive nothing, as milieurs_per_eth isn’t updated in the constructor, which means that transfer will call calculateTokenAmount() and multiply it by 0 (being the value of tokensPerEth). The user will have sent money to the contract but received no tokens.

This could easily be fixed by adding the following to the function:

Fixed in the commit bd4277db249d9550cea439f9044c54882c379d5d.

Finalize does not call burn() function

At Crowdsale.sol, in the finalize function, unsold tokens aren’t burned:

This means that the CrowdsaleToken contract stores the address of the Crowdsale as if it had tokens. Since they are not going to be used, it is best to simply dispose of them.

This issue in the commit 4a04863c1cf6ef55d89a3ed63c3e0de863efe4da.

Enhancements

Use of updated pragmas

In later commits, the contracts use the following pragma:

pragma solidity ^0.4.19;

We recommend updating compiler directives so that newer compiler versions are used, as the current solidity version is 0.4.21. In the same vein, events are now emitted using the emit keyword, which results in more code legibility. This also helps to differentiate between function calls and event emission.

Conclusion

The contracts followed recommended practices and were acceptably documented. Common attacks like the EIP 20 approve/transferFrom attack were taken into account. Two errors were found for either undefined or unaccounted behavior. One was properly fixed, while the other wasn’t. We recommend considering if the changes suggested are beneficial for the users.

DreamTeam Smart Contract for Players’ Compensation

Security Audit Report


Introduction

Coinfabrik was asked to audit the contracts for the DreamTeam system. The DreamTeam contracts implement a system that teams can use to compensate their members with tokens. In the first part, we will give a summary of our discoveries and follow them with the details of our findings.

Summary

The contracts audited are from the DreamTeam source code repository at commit c1efcabf8a56a4d0a1fa5185a095052c110bdd87.

The audited contracts are:

  • SafeMath.sol: Safe integer calculations
  • BasicStorage.sol: Multiple ownership contract base
  • DreamTeamStorage.sol: Generic storage of primitive types, deployed separately uses BasicStorage for ownership.
  • StorageInterface.sol: Interface for DreamTeamStorage
  • TeamStorageController.sol: Functions to abstract high level types for storage in DreamTeamStorage
  • TeamContracts.sol: Inherits TeamStorageController. Implements token payments to team members and general management of teams.
  • ERC20TokenInterface.sol: ERC20 Token Interface
  • TDTT.sol: Simple ERC20 Token implementation

These checks are performed:

  • Misuse of the different call methods: call.value(), send() and transfer().
  • Integer rounding errors, overflow, underflow and related usage of SafeMath functions.
  • Old compiler version pragmas.
  • Race conditions such as reentrancy attacks or front running.
  • Misuse of block timestamps, assuming things other than them being strictly increasing.
  • Contract softlocking attacks (DoS).
  • Potential gas cost of functions being over the gas limit.
  • Missing function qualifiers or misuse of them.
  • Fallback functions with higher gas cost than a what a transfer or send call allows.
  • Underhanded or erroneous code.
  • Code and contract interaction complexity.
  • Wrong or missing error handling.
  • Overuse of transfers in a single transaction instead of using withdrawal patterns.
  • Insufficient coverage of function input requirements.

None of the issues found was of critical severity.

Detailed findings

Medium severity

Ambiguous return value

There is a function called storageGetTeamMemberIndexByAddress, it returns the member index given a member address:

The problem with this function is that it does not distinguish between returning 0 because nothing was found and returning the member with index 0. This means that removeMember will remove the member index 0 if an invalid address is given:

Consider returning a tuple with an index and a bool that is false for the case when nothing is found.

This was fixed by the DreamTeam developers in commit dbb8182f40eb15e2cd73b6f65014a280057fbaf4.

Minor severity

Vesting mechanism does not emit Transfer events

The TDTT contract does not emit Transfer events when balances are assigned to token holders as a consequence of its vesting mechanism. This could make it difficult for someone to examine the historical token movements in a block explorer. In particular, it poses an inconvenience to users of applications that depend on these events to interact with the token contract.

Due to the nature of the mechanism, we recommend emitting a Transfer event once the balance of an address is updated according to the current block in the subFromBalance function.

Enhancements

These are presented as mere suggestions to the smart contract development team. They may help with the smart contract system overall.

Addresses can be declared as contracts

Lines like these:

Can be simplified by making the variable erc20TokenAddress an ERC20TokenInterface instead of an untyped address:

Now the line above can be turned to:

The same can be done with contracts that are not interfaces.

Add token transfer failsafe mechanisms

We recommend adding failsafe mechanisms to ensure tokens don’t get stuck indefinitely in any of the contracts involved. While this makes for a nice feature in user-facing smart contracts, in this case it may be a good idea to have it considering the existence of an upgrade mechanism. The failsafe could even work for the DreamTeam token itself in the TeamContracts contract with adequate restrictions.

An easy way to implement such a failsafe is to write a function like this one:

This implementation could be used as is in DreamTeamStorage, but would require some tweaks if added in TeamContracts.

Conclusion

All the audited contracts are simple, straightforward and have an adequate amount of documentation to easily understand what they do. In particular, we haven’t found any important issues that we consider critical.

RCN Smart Contracts Audit v2

Summary

The smart contracts that have been audited were taken from the RCN repository at: https://github.com/ripio/rcn-network/tree/v2. The audit is based on the commit 3ded36151ad55543d16c354e70161852de4061d0, which was updated to reflect changes at: 052e5fd4d77301e854d0ecdaadbd785dd91950ce.

The audited files are:

  • NanoLoanEngine.sol: Lending engine
  • examples/BasicScoreProvider.sol: Example
  • examples/ReferenceCosigner.sol: Example of a cosigner
  • examples/ReferenceOracle.sol: Example of an oracle
  • interfaces/Cosigner.sol: Interface of cosigners
  • interfaces/Engine.sol: Interface of loan engine
  • interfaces/ERC721.sol: Interface ERC721 non-fungible token
  • interfaces/Oracle.sol: Interface of oracles
  • interfaces/Token.sol: Interface of ERC20 fungible token
  • utils/BytesUtils.sol: Utility to access bytes array
  • utils/Delegable.sol: Permission with valid date ranges for contract users
  • utils/Ownable.sol: Defines a contract’s owner
  • utils/RpSafeMath.sol: Math operations with overflow check
  • utils/SimpleDelegable.sol: Simple permission for contract users
  • utils/TokenLockable.sol: Withdrawal of arbitrary tokens, with lock/unlock operations

The contracts are RCN lending protocol implementations. RCN is a protocol based on smart contracts which standardize credit lending through blockchain technology. Now, the NanoLoanEngine loans are treated as ERC721 non-fungible tokens.

We did not find any critical issues. However, there is one medium severity issue involving a function that does not validate the input data; a couple of functions can also cause problems if they are used in a contract.

Detailed findings

Medium severity

Read arbitrary data

The function readBytes32 in BytesUtil.sol reads data from memory, but it can return data past the valid length of the bytes array.

The assembly function mload reads 32 bytes from an arbitrary memory direction, it doesn’t check that the direction is valid.

We recommend that the calculated memory direction is inside the data.

For example, in the function requestCosign in ReferenceCosigner.sol it uses readBytes32 from a user-supplied bytes array. But it does not check that the data supplied is of the expected size.

This issue was fixed at commit 35b79591c13bf72fc6a0967901b241e21236927e.

Minor severity

Risk of running out of gas if large iterations take place

The functions tokenOfOwnerByIndex and tokensOfOwner can potentially iterate over all the loans in the contract.

These functions are not used by other contracts in the project, but if they are used by a third party contract there is the possibility of a lock caused by consuming more gas than the current block gas limit.

It was reported to us these functions are not designed to be used from other contracts and they will document the risk out of gas due to high gas consumption.

Observations

  • Use of the constant modifier is deprecated in favor of view or pure in recent versions of solidity.

This was fixed at commit 047605361e3f1f95db2984cdd15921d1684ac2cd

Conclusion

We did not find any serious issue in the analyzed contracts. However, we found one medium severity and one minor issue with a couple of functions.

The medium severity issue was caused by a function that did not validate input data and could be forced to return erroneous data. But it should be easy to fix to verify the length of the input. The minor issues can cause problems only if there are lots of loans and if they are called from within a badly programmed contract.

Overall: We found that the contracts are well written and extensively documented. Also, we noticed while we were performing the audit, that RCN was updating continuously to comply with new solidity compiler version once there was a new version released.

Security Audit – Send (SDT) Token Sale ICO Smart Contract

Introduction

Coinfabrik was asked to audit the contracts for the Send Token sale. In the first part, we will give a summary of our discoveries and follow them with the details of our findings.

Send (SDT) is making an ICO to create a 7-day price-stable crypto token that discovers a new market price once a week based on cross-border transaction volume and network liquidity.

Summary

The audited contracts are from the SendProtocol repository at https://github.com/SendProtocol/sdt-contracts.git. The audit is based on the commit 0e00bbab50d0ebe341b7d54475aceafb6303ff66, and updated to reflect changes at ba9d86e39d644ba3e63b2ed9f5b0417a5c381e20.

The audited contracts are:

  • Escrow.sol: Escrow contract for the token
  • Polls.sol: Basic polling contract, requires tokens before a certain block to vote.
  • SnapshotToken.sol:  Implements snapshot capabilities for the token, to allow the poll check balances before a determined block.
  • SendToken.sol: Token implementation, inherits both BurnableToken and  SnapshotToken.
  • SDT.sol: Final SendToken with ERC20 parameters set.
  • SaleProxy.sol: Acts as a proxy for the Token Sale.
  • TokenSale.sol: ICO implementation.
  • TokenVesting.sol: Allows the ICO to vest tokens.
  • IEscrow.sol: Escrow interface
  • ISendToken.sol: SendToken interface
  • ISnapshotToken.sol: SnapshotToken interface
  • ITokenSale.sol: TokenSale interface

These checks are performed:

  • Misuse of the different call methods: call.value(), send() and transfer().
  • Integer rounding errors, overflow, underflow and related usage of SafeMath functions.
  • Old compiler version pragmas.
  • Race conditions such as reentrancy attacks or front-running.
  • Misuse of block timestamps, assuming things other than them being strictly increasing.
  • Contract soft locking attacks (DoS).
  • Potential gas cost of functions being over the gas limit.
  • Missing function qualifiers or misuse of them.
  • Fallback functions with higher gas cost than a what a transfer or send call allows.
  • Underhanded or erroneous code.
  • Code and contract interaction complexity.
  • Wrong or missing error handling.
  • Overuse of transfers in a single transaction instead of using withdrawal patterns.
  • Insufficient coverage of function input requirements.
  • Standard non-compliance (EIP20, etc)

Detailed findings

Critical severity

Unverified BTC purchases allowed through SaleProxy

The TokenSale contract only allows contributions that go through a SaleProxy contract. However, the SaleProxy contract itself doesn’t provide any sort of check that a pertinent BTC transfer has been included in the bitcoin blockchain. We urge the developers to review the design of this feature if contributions through BTC are intended.

 

A simple example attack would be as follows:

  1. Address A gets whitelisted for contributions in the token sale contract.
  2. A signs a transaction with data corresponding to btcPurchase(address _beneficiary, uint256 _btcValue) ABI encoding found in the SaleProxy contract. _btcValue can be any amount. In particular, it needs to be bigger than $10 once converted so it doesn’t get rejected by the contract.
  3. The token sale contract assigns vested tokens to A depending on the vesting configuration of the SaleProxy contract used by A.

Fixed in commit 392d93c0a7109a86fba7de96d3137c787b70f842

Minor severity

Not extensive SafeMath usage

Some contracts like TokenSale.sol, are missing SafeMath functions for sensible calculations. Consider extending the usage of SafeMath to these contracts.

Fixed in commit aba8cf827774ce0b7abc8254271b8efe3c9761c4

Enhancements

Unnecessary and misleading interfaces

There are four interface files: ISendToken, ISnapshotToken, ITokenSale, IEscrow. These are declared as contracts instead of being just interfaces. In addition, ISendToken inherits from two contracts. If the intention is to only use these interfaces inside the project, we recommend removing these contracts, and instead directly use the corresponding contract which the interface is derived from, as it is less error prone and much simpler. Consider using internal for those functions you don’t want to expose to other contracts. If not, we recommend using the interface directive to declare an interface, and moving the dependencies to the corresponding contract.

Fixed in commit d313e021aaaa0c9b9021207bd3e168a1545971b2

Conclusion

Overall the contracts were well documented and had extensive background documentation of their development. The main idea behind the contracts is simple and the deployment flow is expectable. It was also a good idea to reuse well tested OpenZeppelin contracts.

Rightmesh Token Sale Smart Contract Audit (Master)

Introduction

Coinfabrik was asked to audit the contracts for the RightMesh Token sale. In the first part, we will give a summary of our discoveries and follow them with the details of our findings.

The contracts audited are from the RightMesh repository at https://github.com/firstcoincom/solidity. The audit is based on the commit f24ea6c5787b2d40423f4dc312d832592b1cd335 at branch master.

Summary

The audited contracts are:

  • MeshToken.sol: Token implementation.
  • MeshCrowdsale.sol: Crowdsale implementation.
  • Migrations.sol: Truffle migration contract.

These checks are performed:

  • isuse of the several call methods: call.value(), send() and transfer().
  • Integer rounding errors, overflow, underflow and related usage of SafeMath functions.
  • Old compiler version pragmas.
  • Race conditions such as reentrancy attacks or front running.
  • Misuse of block timestamps, assuming things other than them being strictly increasing.
  • Contract softlocking attacks (DoS).
  • Potential gas cost of functions being over the gas limit.
  • Missing function qualifiers or misuse of them.
  • Fallback functions with higher gas cost than what a transfer or send call allows.
  • Underhanded or erroneous code.
  • Code and contract interaction complexity.
  • Wrong or missing error handling.
  • Overuse of transfers in a single transaction instead of using withdrawal patterns.
  • Insufficient coverage of function input requirements.

Detailed findings

Critical/Medium severity

None found

Minor severity

Owner cannot be allowed to transfer on pause

There is an override of the whenNotPaused modifier which is used for all the token transfer related functions in OpenZeppelin implementation:

 

And allowedTransfers mapping can be modified by the owner, but not for himself:

We recommend removing this require, as the owner cannot pause the token twice:

In order to stop depending on the behavior of allowedTransfers, you may also remove whenNotPause modifier from pause and move the requirement inside the function. Like this:

Update: The RightMesh team declared they do not want the Owner to make token transactions.

Function setLimit data race softlock

This function does not set the weiLimit for an address if said limit is bigger than its contributions. This can be exploited by buying tokens just before this function is called, to get over the limit which will cause the function to fail. Without even considering a hypothetical attack, this function may get softlocked indefinitely by multiple people contributing.

This can be fixed by directly setting the maximum value between the current weiContribution for the address and the new weiLimit. For example, assuming max is already implemented:

Update: The RightMesh team declared they will never use this function to reduce weiLimits, only to increase them which avoids the issue.

Outdated and differing solidity pragma versions

The three files are using different old Solidity versions. Migrations.sol and MeshToken.sol are using 0.4.17, while MeshCrowdsale.sol is using 0.4.15. Consider updating them all to the same latest version of Solidity.

Update: This was fixed in commit 59c1977301c071e3cd7fac670b00aa51d87bf1aa

Enhancements

Remove unnecessary pause and unpause functions from Crowdsale

The following functions in the crowdsale are not needed:

 

These functions are made redundant by transferTokenOwnership:

Which allows the owner to call the pause and unpause functions in the token directly.

Update: Fixed in commit c5454aa92583b21273764cc22ae595209b46c92e

Conclusion

The contracts were simple, they both relied on OpenZeppelin’s implementation of the token and sale. Using an already implemented, tested and audited token is always the best option if feasible. Neither contract added overcomplicated or large elements to the implementations which is also a desirable approach.

Beluga Pay (BBI) Security Audit

Introduction

Coinfabrik has been hired to audit the smart contracts which were included in the BBI Token sale. In the first part, we will detail a summary of our discoveries and follow them with the details of our findings.

Summary

The contracts audited are from the BBI repository at https://gitlab.com/cardedeveloper/contractBBIT/blob/master/bbi.sol.

The smart contract can be found at: https://etherscan.io/address/0x37d40510a2f5bc98aa7a0f7bf4b3453bcfb90ac1 

The audited contracts are:

  • bbi.sol: BBI Token Sale and Token, inherits StandardToken.

These checks were performed:

  • Misuse of the different call methods: call.value(), send() and transfer().
  • Integer rounding errors, overflow, underflow and related usage of SafeMath functions.
  • Old compiler version pragmas.
  • Race conditions such as reentrancy attacks or front-running.
  • Misuse of block timestamps, assuming things other than them being strictly increasing.
  • Contract soft locking attacks (DoS).
  • Potential gas cost of functions being over the gas limit.
  • Missing function qualifiers or misuse of them.
  • Fallback functions with higher gas cost than a what a transfer or send call allows.
  • Underhanded or erroneous code.
  • Code and contract interaction complexity.
  • Wrong or missing error handling.
  • Overuse of transfers in a single transaction instead of using withdrawal patterns.
  • Insufficient coverage of function input requirements.

Detailed findings

Critical severity

Function buyBBITokens can be used to get free tokens

When using this contract you are supposed to call the fallback function in order to buy tokens:

 

But you may bypass this function and directly call buyBBITokens:

This, this would allow you to assign both parameters, in particular, _value can be set just high enough to assign yourself all remaining tokens.

Consider qualifying the function visibility as internal instead, in case you wanted to use only the fallback function.

Medium/Minor severity

None found.

Enhancements

Use solidity time literals instead of declared constants

This definition is redundant due to the supported time literals in solidity like 1 years:

Use SafeMath functions like methods for unsigned integers

And instead of writing this:

You can write this:

These calls can also be chained, improving overall clarity.

Conclusion

The contract was simple, consistent and straightforward, which is what we always recommend. It is always good to see code reuse. In particular, it is good to reuse already tested token implementations, like in this case.

Survey of Blockchain Storage and Computing Services

Introduction

Public blockchains are not suited to function as a data storage provider. Since they are append-only ledgers, storing many large files would result in a dramatic increase of the whole distributed ledger. That would force the network nodes to store huge databases leaving it in the hands of just a few providers. Likewise, the use of a public blockchain as a computing engine has its limitations. Smart contracts on a blockchain are decentralized, i.e., every miner verifies the correct execution of the contract. Hence it is very expensive to run, for example on the Ethereum blockchain, computationally intensive programs, to prevent the network of becoming paralysed.

Public blockchains can be used for a decentralized open market platform where users can trade cloud infrastructure resources. This way, a distributed storage system could be connected directly to the client without relying on a third party, providing features like commitment policies, access to data policies, or micropayment systems. Similarly, off-chain distributed computation services could run computationally intensive programs which might even take care of privacy issues.  

Storj, one of the projects in this field, describes the use of blockchain technology for distributed storage as a possible way to move away from the traditional large storage provider monoliths. They also point to the problem that client-side encryption is usually not standard which incurs risk of exposure of private consumer and corporate data. Client-side encryption can easily be integrated in decentralized market platforms. In general, distributed storage can guarantee data availability since there is no single point of failure, allow redundancy storage, and can, usually, offer lower service fees than existing service providers.

General Picture

The key role of a blockchain in distributed storing or distributed computing lies in its capability of securely taking record of all services performed in the cloud, and to automate (micro-) payments accordingly. The challenge we are faced to is to find a secure way to connect the off-chain services with the blockchain, i.e., that all records have a publicly verifiable proof which guarantees the correctness of the off-chain service.

Cloud

The cloud service could either be provision of storage, computation resources, or an application service. Many of the existing proposals for distributed storage systems make use of distributed hash tables (DHT). We recall the very basics of DHTs quickly in the next section. Kademlia is a well-known protocol built on DHT which some of the proposals extend in order to connect the distributed storage network with the blockchain. Redundancy schemes may be employed to ensure availability and the capability to restore data in case some hosts go offline.

Those platforms which offer distributed computation services either rely on some kind of  multi-party computation (MPC) protocols or employ distributed grid computing. We recap both approaches in the next section and give references to survey articles. In both cases, a proof of correct execution or proof of contribution is needed.

Blockchain

The blockchain may be used to store data or intermediate in the following steps:

  • Audits and Proofs: Clients may ask for a proof of retrievability, a proof of data integrity, or a proof of correct execution which are then recorded on the blockchain.
  • Security deposits: Coins can be used to lock collaterals as a guarantee for correct service execution. Time locked coins can serve the host as payment guarantee.  
  • Payment service: Smart contracts enable automatically enforced payment executions relying on the verification of proofs recorded on-chain. Off-chain payment channels can be used for exact billing (like Lightning or Raiden network).
  • Orderbook: An on-chain orderbook might be used to intermediate the “trade” between client and host.
  • Access control: Cryptography can be used to control the access to the cloud or to perform computations on stored data.

Blockchain Consensus

Many proposed off-chain networks can be connected to a (existing suitable) blockchain. Nodes participating in the consensus protocol (“miners”) check (beyond the usual transactions of the blockchain) the proofs that some off-chain service was (correctly) completed. The reward for their work depends on the blockchain used.

In some proposals miners are directly involved in providing storage, offering computing service, or provide proofs related to the former to services. These systems have their proper blockchain and reward the miners in their native coins which can be used to pay services or can be exchanged on some exchange platform to other currencies.

Technical Tools

Building blocks and methods which are often used in distributed cloud services:

Distributed Hash Tables for Storage

One way to store data between peers in a network is through distributed hash tables. The hash table consists of pairs (key, value), where keyis the hash of the data value.  All nodes of the network receive an ID which are of the same format as key. In the Kademlia protocol, a metric based on XOR introduces a topology on the network, and a pair (key, value) is assigned to nodes which are the “nearest” to key with respect to this metric. This can be used to distribute data in the network and lookup the data in logarithmic time. The protocol has four remote procedure calls (RPCs): Ping, Store, Find_Node, and Find_Data. For further details see Kademlia.

Proof of Retrievability / Proof of SpaceTime

A standard method to guarantee the integrity and existence of a certain piece of data on a
remote host uses Merkle trees and Merkle proofs. These are hash trees built in a similar way as the blockchains of Bitcoin or Ethereum. The client sends a challenge and the host has to respond with a correct hash calculation to prove existence of data. There are ways to improve on message size in the challenge-response interaction (see e.g. in Storj whitepaper, section 2.3). Filecoin uses the advanced cryptographic tool zk-SNARK (see for a short intro our blog post) which produces succinct proofs of knowledge of the response. They propose a Proof of SpaceTime that can even provide evidence that some data was being stored throughout a period of time. This might be achieved by using iterated challenge-response interactions.

Multi-party Computation and Proof of Correctness

In multi-party computation (MPC) protocols, each party has a secret value, and the task is to compute a common function over all of their inputs, without revealing any information about their inputs. In A.C. Jao´s work in the 80’s, garbled circuits are proposed to solve this problem. In Engima, the entire encrypted data is split in n shards and is distributed between n peers. A kind of homomorphic encryption allows peers to do basic arithmetic operation on their shards allowing to construct a circuit for any arithmetic function. To obtain turing-completeness, the protocol has to provide control flow to the system as well. The ultimate goal is to achieve privacy, liveness, and correctness of the distributed computation. Please read here for more information about MPC in general.

Distributed grid computing and Proof of Contribution

Grid computing coordinates resource sharing by offering an infrastructure that couples computers, often constructed across LAN or Internet backbone networks, or with IPFS. The Gridcoin project employs a desktop grid computing platform BOINC in combination with a proof of contribution which they call Proof of Research. The iEX.ec project follows the same lines adding a reputation mechanism to the protocol which runs on a Proof of Stake blockchain. Please read here for more information about grid computing.

Projects


Binex (No documentation available)

Binex is a storage and computing marketplace in beta version (not public). The Binex platform connects to all data, computation, and application services. Binex token can be used for payments.

Design overview:

Cloud  

  • Storage: Any providing service
  • Computation: Distributed computing, grid computing, …

Blockchain

  • Audit/Proofs: No information available.
  • Security deposits in native coins: No information available.
  • Payment service: No information available.
  • Orderbook: No information available.
  • Access control: No information available.

Blockchain consensus 

No information available.


Enigma

The Enigma project started from a research group at MIT aiming at a private and scalable smart contract platform. Enigma network can be connected to any smart contract blockchain and provides off-chain distributed data storage and private off-chain computation (private contracts). Distributed computing accelerates code execution and comes with a Proof of Correct Execution.

Enigma’s network protocol is based on the Kademlia DHT protocol for storage extended by private communication channels. The encrypted data stored in the DHT are referenced and can be used for privacy-preserving multi-party computation (MPC).

The network is connected to the blockchain via shared identities and predicates which are stored on the blockchain and govern access-control. This way, access to any off-chain resources is moderated in a decentralized manner, and without verifying ownership, data (which are encrypted) can not be found.  

Design overview:

Cloud

  • Storage: modified Kademlia DHT protocol with secure communication channel.
  • Computation: Scripting language with state-of-the-art MPC. Interpreter breaks down the execution and distributes code resulting in improved run-time.

Blockchain

  • Audit/Proofs: Proof of Correctness uses SPDZ (kind of “homomorphic encryption”). They are made “publicly verifiable” through commitment schemes.
  • Security deposits (in native coins): Nodes of the Enigma network have to deposit a collateral on the blockchain. In case of misbehaviour (not completing execution) deposit gets split between honest nodes.
  • Payment service: Storage contract is automatically renewed using the owner’s account balance. If the balance is too low, access to the data will be restricted, unless additional funds are deposited, and will be deleted after some time. Computation fees get split automatically between participating nodes of Enigma network.
  • Orderbook: Not explicitly mentioned.
  • Access control: Shared identity addresses are stored on the blockchain regulating: Store & Load. Storing party provides a custom predicate for verifying who can read the data and outputs a pointer to the data. Share & Compute. Stored data in DHT with permissions to work on it internally in network.

Blockchain consensus 

Enigma connects to any smart contract blockchain, hence consensus depends on host blockchain. 


Golem

Golem is building a decentralized marketplace of computing power on top of the Ethereum blockchain. There are three groups of participants in the Golem network: clients, providers of CPU, and software developers. Clients can ask for computation resources or software services. The network makes matches between clients and providers.

There will be an Application Registry where software developers can offer their software programs. Computation audits will be available in form of challenge-response protocols in the style of TrueBit. Services are paid in Golem tokens (GNT), and there will be many options for secure payments including deposits and reputation systems.

Design overview:

Cloud

  • Computation: Volunteer grid computing and application services.

Blockchain

  • Audit/Proofs: TrueBit-style proofs in the future .
  • Security deposits: Client may require and providers may accept only time locked GNT payments.
  • Payment service: Golem tokens; planned off-chain payment channels (Raiden), escrows, and more.
  • Orderbook: Golem network, in the future Application Registry provides list of software services
  • Access control: Golem token.

Blockchain consensus

Built on top of Ethereum blockchain.


Gridcoin

Gridcoin is a decentralized cryptocurrency in which volunteers are rewarded for their contribution in the BOINC distributed grid computing project. The project is based at Berkeley university and enables to share computing resources for scientific research purposes. Researchers who contribute with computational power towards BOINC research are compensated in Gridcoin.

The blockchain is based on an energy-efficient Proof-of-Stake process and a Proof of BOINC (Work), called Proof of Research. This consensus protocol allows to use the computing power to maintain the blockchain almost exclusively for scientific research replacing the cryptographic puzzle of “classical” PoW by useful work. The mining reward is calculated using the research age of the miner.

Design overview:

Cloud

  • Computation: Volunteer grid computing

Blockchain

  • Audit/Proofs: part of CPID hashing algorithm.
  • Security deposits in native coins: Not needed.
  • Payment service: Block reward for Proof of Research.
  • Orderbook: Not on chain. There is a whitelist of BOINC projects.

Blockchain consensus

Proof of Stake and Proof of BOINC (WORK)  hybrid (“Proof of Research”). Reward in Gridcoins.


iExec

iExec is a project (in Proof of Concept version) lead by researchers from the CNRS in France. Their project shares similarities with the Gridcoin project and uses desktop grid computing. Unlike Enigma, but similar to Golem, they plan to integrate any legacy applications or libraries through a Proof of Contribution, instead of specializing in off-chain computation. The protocol Proof-of-Contribution should allow to build consensus between the blockchain and off-chain resources (no details available yet).

iEx.ec will rely on a blockchain to coordinate the access of computing resources to distributed applications. Multicriteria scheduling smart contract is among their innovations encompassing different needs of the customers: fast execution or low costs. iEx.ec will be based on a decentralized network with Proof of Stake consensus and trusted nodes. Trust is built on reputation which gets built with backward mutability (Gridcoin) and certifications (Sarmenta) at early days of blockchain inauguration.

Design overview:

Cloud

  • Computation: Volunteer grid computing

Blockchain

  • Audit/Proofs: Proof of Contribution.
  • Security deposits in native coins: No.

  • Payment service: Automated post-execution payments using smart contracts.

  • Orderbook: Yes. Matchmaking smart contracts. Multicriteria scheduling smart contract.

  • Access control: Yes. Blockchain to coordinate access to application resources.

Blockchain consensus

Proof of Stake protocol with trusted nodes. Trust is built on reputation which gets built with backward mutability (Gridcoin) and certifications (Sarmenta).


SIA

SIA is a peer-to-peer decentralized network for cloud storage created by the Nebulous Lab. This marketplace of storage is built on top of the Sia blockchain, and permits providers to rent their unused storage space.  

Storage contracts provide the option to fix an allowance of the client, a prepaid amount of Siacoins to pay storage and bandwidth (uploads, downloads) for a certain period of time, and allows to lock a collateral of the host. Clients can ask for a Proof of Retrievability based on Merkle proofs. Off-chain payment channels, similar to payment channels in Bitcoin, provide a secure way to make transactions per bandwidth within the timeframe written in the storage contract.  

The blockchain enforces automatically the final payments associated to the storage contracts. Host are compensated with fees, or client/host is punished with a percentage of their allowance or collateral, in case of non-compliance. There is a file repair mechanism: if host goes offline, a redundancy protocol takes care that data are uploaded to a new host.

Design overview:

Cloud

  • Storage: Host address database on blockchain. Reed-Solomon redundancy algorithm.  

Blockchain

  • Audit/Proofs: Proof of Retrievability using file size and Merkle Proofs.
  • Security deposits in native coins: Allowance of client and collateral of host in Siacoins.
  • Payment service: Storage contract and off-chain payment channels between renter and host. Revisions (money movement in contract — not on blockchain) allow updating the actual bandwidth consumption.
  • Orderbook: Best 50 hosts of ranking system.
  • Access control: Private key for decryption.

Blockchain consensus

PoW Blake2b algorithm. Mining rewarded in Siacoins.


Storj

Storj is a P2P cloud storage network built on top of any blockchain (Storjcoin X token on Bitcoin blockchain or Storj on Ethereum blockchain). Access to and communication in the network is regulated by master nodes functioning as bridges.

If a client wants to upload a file, it is split in pieces and these pieces are sent to different nodes transferred via HTTP. Storj network is based on Kademlia DHT extended by new message types: Offer, Consign, Mirror, and Retrieve for contracting. Clients can ask for Proof of Retrievability via Audit which employs Merkle trees and Merkel proofs. Partial audits are available to lower computational overhead. There is a redundancy scheme (erasure coding: k out of m shards necessary to restore data) to secure availability of the data, KFS local file store to scale, and NAT traversal and Tunneling to protect participation of adversary peers not belonging to the network.

Client and host can negotiate via secure messaging a contract including payments. There are standard contracts provided. Upon receipt and validation of an audit, the data owner must issue payment to the farmer according to agreed-upon terms in the contract through payment channels.

Design overview:

Cloud

  • Storage: Sharding and modified DHT Kademlia protocol extended by efficient messaging. Redundancy scheme (t out of n shards), network access authentication via Bridge (master node) organizing network transfer and mirror creation.

Blockchain

  • Audit/Proofs: Proof of Retrievability. Client can ask for partial audits. The host must respond with a Merkle proof. Partial audits to lower computational overhead.
  • Security deposits: none.
  • Payment service: Payments with Storjcoin X or Storj tokens (so far) via channels (opening channel transaction and then updating) or any other currency per bandwidth usage.
  • Orderbook:

    Directly between peers. (Reputation not yet implemented).

  • Access control: Not through blockchain, but via master node of Storj network.

Blockchain consensus

Storj connects to any smart contract blockchain, hence consensus depends on host blockchain. At the moment (via Counterparty) to Bitcoin and to Ethereum blockchain.


SWARM

SWARM is a distributed storage platform (Proof of Concept version). Swarm primarily aims at a decentralized and redundant storage of Ethereum’s blockchain to off-load dapp code. SWARM is a network whose nodes are connected to the Ethereum blockchain.

The storage network is organized by a modification of the Kademlia DHT system. Data get split in pieces and assembled at an interface called “Chunker”. Manifest is a data structure describing collections which allows URL based access to content.

The Ethereum name service (ENS) enables content retrieval based on mnemonic names. Swarm will have an accounting protocol and secure automated ways to pay storage services.

Design overview:

Cloud

  • Storage: Sharding (Chunker) and modified DHT Kademlia protocol.

Blockchain

  • Audit/Proofs: Challenge-response audit proofs using Merkle Proofs.
  • Security deposits in native coins: SWINDLE – Secured With INsurance Deposit Litigation and Escrow. SWEAR – Storage With Enforced Archiving Rules or Swarm Enforcement And Registration
  • Payment service: Swarm Accounting Protocol, Secured With Automated Payment
  • Orderbook: Not needed. Upload to Swarm.
  • Access control: Manifest – data structure for data access.

Blockchain consensus

Built on top of Ethereum blockchain.


Some links to other projects:

Academic (Scalability, Proof of Space, useful PoW):

Dynamic Distributed Storage for Scaling Bitcoin (Scalability)

Rollerchain (Proof of Retrievability, useful PoW)

Permacoin (Proof of Retrievability, useful PoW)

SpaceMint (Proof of Space, useful PoW)

Related projects

Sigwo technologies (Blockchain to store small data)

Decent (Decentralized content providers – not for storage)

RCN BasicCosigner Smart Contract Security Audit

Introduction

Coinfabrik security audit’s team was asked to audit the BasicCosigner contract. This contract is part of a Loan system where multiple contracts interact, where the main contract is NanoLoanEngine. Particularly, this is an example implementation of a loan cosigner, which serves as a guarantee for the lender. In the first part, we will give a summary of our discoveries and then, the details of our findings.

The contract is at https://github.com/ripio/rcn-network/blob/master/contracts/examples/BasicCosigner.sol. The audit is based on the commit d206c4f1e95ac5c9a06defcbdc899b7fedb18f7c, and updated to reflect changes at fc63852b012fcad68dd174418d48d4d6740e15cc.

Detailed findings

Critical severity

NanoLoanEngine transfer doesn’t allow the lender to call the claim function safely

There is a transfer call to the engine in the claim function:

This function is used to transfer ownership of the loan. It only allows the lender or someone approved by the lender to do so:

In the case the sender is neither the lender nor someone approved, this function will always fail.

The alternative usage of the function is that the lender has to call approveTransfer before calling claim. RCN team confirmed that this is the expected workflow of the function. There is a possible attack using in this way.

The cosigner owner tries to put a transferLoan call to himself between approveTransfer and claim calls. Although these functions are called consecutively, the attacker can spam the transaction. This spam mechanism is a bit expensive, but it may result in a very good return for the cosigner owner as he saves the compensations. Note that the original lender cannot call claim after this, as he is not the lender of the loan anymore.

Update: This was fixed by the RCN team by locking the transfer of the loan until the lender calls claim at commit 70955c54e42fbecbb23783f7e8375c028ba1ad5f.

Minor severity

Solidity warnings

Multiple function qualifier warnings are emitted by the solidity compiler at compile time. Consider fixing these as they may occlude other more important warnings. Also, consider bumping up the required compiler version as more specific function mutability qualifiers have been added recently.

The Token Interface isn’t ERC20 standard.

Token Interface:

Consider using something like this:

The Token interface seems to be used in place of a standard token interface. This isn’t a good idea in code that is meant to be an implementation example unless there’s a good reason for it. In which case, it should be properly documented in the example.

This was fixed in commit fc63852b012fcad68dd174418d48d4d6740e15cc.

Enhancements

Documentation

Documentation in the form of comments and/or a separate specification would greatly increase the auditability of the contract.

Testing

There are a few functions in this contract that may require higher than average amounts of gas. Crafting test cases not only improves the quality of the code, but it can even help to save gas.

Conclusion

The code quality is good but requires more documentation since it is was hard to infer the intention behind some functions, it would prevent misunderstandings and greatly improve auditability. 

Sever issues pointed were fixed by RCN team.

Theta Token Sale Security Audit

Introduction

Coinfabrik was asked to audit the contracts for the Theta Token sale. In the first part, we will give a summary of our discoveries and follow them with the details of our findings.

The contracts audited are from the Theta repository at https://github.com/thetatoken/theta-erc20-token-sale. The audit is based on the commit 46592ac461949fa793b9d0dc1f59df9bf7ea07f3 and updated to reflect changes up until commit 3158c10d1a0b6347b9490aad68caab7e5f17d753.

Summary

The audited contracts are:

  • SafeMath.sol: Safe math operations library
  • StandardToken.sol: Inheritable class for ERC20 token implementation.
  • ThetaToken.sol: The token contract itself, inherits StandardToken.
  • ThetaTokenSale.sol: The token sale contract

Detailed findings

Medium severity

Bad handling of whitelist array

There is a whitelist array for addresses that is used to keep track of accounts that are able to buy tokens. This array is modified by a function to add accounts and another one to remove them:

There are two potential problems here, the first one is the gas costs, since the function deleteAccountsFromWhitelist may fail if the array grows too much, which may be the case given that whitelisting is required for buying tokens. The second, which complements the first, is the delete in said function. This delete will zero the entry which means removing addresses will not reduce the size of the array, and since addresses are just pushed back when adding them depending on how these functions are used externally it may grow unexpectedly large, in the worst case softlocking the second function because of gas costs.

We recommend removing the array, leaving only the mapping, and keeping track of the account list externally instead. In the end, all whitelisting transactions will be saved in the blockchain so everyone can reconstruct the array if needed. You may also add an event to facilitate this.

This was fixed in commit 64b3d75b6431d75ebeb426ce935009d2187830c1, including the addition of the Whitelist event.

Minor severity

Missing minting call according to comments in finalizeSale

According to the comments in function finalizeSale, there should be a minting call here:

If this is not the case, we recommend removing the comments as they are misleading.

This was acknowledged by the development team and the comments were removed at commit 64b3d75b6431d75ebeb426ce935009d2187830c1.

Enhancements

Unnecessary requirements in mint function at token

The first three statements in the mint function are unnecessary as both requires are already checked by using SafeMath functions:

Consider removing these lines to simplify the contract.

This was enhanced in commit 64b3d75b6431d75ebeb426ce935009d2187830c1.

Commented code in doPayment function

Remove commented code if it’s not going to be present in the final contract:

This was enhanced in commit 64b3d75b6431d75ebeb426ce935009d2187830c1.

Conclusion

We found the contracts to be straightforward and simple, which is always the best thing to see in audits. We were pleasantly impressed by the contracts Code quality. Most functions have a few lines, which is another plus.

References