Blockimmo Security Audit

Blockimmo AG engaged New Alchemy to perform a security focused audit reviewing a set of smart contracts for a decentralized online real-estate marketplace. blockimmo AG plans to utilize and deploy the same contracts for their own ICO fundraising round, selling tokens in the same proposed manner as shares in a real estate property.

The engagement was technical in nature and focused on identifying security flaws in the design and implementation of the smart contracts, finding differences between the contracts’ implementation and their behavior as described in public documentation, and finding any other issues with the contracts that may impact their trustworthiness. Blockimmo provided New Alchemy with access to the relevant source code, whitepapers, and a series of blog posts which describe the Swiss real estate market and how Blockimmo AG plans to integrate their smart contracts with the Swiss registry and the blockchain.

The audit was performed over 8 person days. This document describes the issues discovered during the audit.

Note: The initial version of this document was provided to Blockimmo who then made various changes to their code based upon New Alchemy’s findings. This document now consists of the original and unchanged audit report (v1.0) overlaid with re-test results (v2.0). Re-test results are reflected in each issue title as ‘Fixed’, ‘Partially Fixed’, ‘Not Fixed’ or ‘Informational’. Supporting re-test commentary is attached to a bolded ‘Re-test v2.0:’ prefix and placed at the end of the relevant section. The bulk of the re-test content relates to individual issues, along with brief comments in the executive summary and files audited sections. All figures are from the initial version of the document.


The Blockimmo AG series of Smart Contracts encompasses 6 highly custom contract source files, 8 open source files, one whitepaper, 3 blog posts, and a series of test cases.

The Blockimmo AG platform contracts exhibited many positive characteristics including extensive reuse of well known libraries, very modularized source code, and 5 well documented and thorough unit-level test cases. Blockimmo AG also took care to follow a number of best practice coding guidelines implementing features like extensive error logging using the emit keyword and explicitly marking visibility for all functions.

New Alchemy audits include deploying the contracts on a testnet and performing a thorough manual source code review, inspecting every line of the smart contract. New Alchemy also runs multiple static analysis tools and fuzzers including manticore^manticore, oyente^oyente, and mythril^mythril.

The audit identified one moderate and one minor issue within the smart contracts. No critical issues were found.

The test cases were not strictly in scope but were utilized to help understand and explore specific findings and trace workflows. A majority of the code was open source and derived from the widely-used, reviewed, and standard OpenZeppelin contract library and, as a result, many of the findings pertained to the custom portions of Blockimmo AG code. The official Blockimmo AG whitepaper was considered the primary source of documentation.

New Alchemy believes the way forward should include contract source corrections corresponding to the findings listed in this review and further test coverage development. From New Alchemy’s perspective, the Blockimmo AG code is very well written and follows many best practice guidelines. The absence of critical findings is a positive leading indicator.

Re-test v2.0: New Alchemy has discussed the prior re-test results with Blockimmo AG, advised on efficient and effective mitigation approaches, and inspected the resulting smart contract code and whitepaper provided for re-testing. New Alchemy has concluded:

  • All issues have been fixed and their risks mitigated.
  • The smart contract constants have been added to a link within the whitepaper.
  • All line by line comments have been addressed.

Files Audited

The code reviewed by New Alchemy was delivered in a .zip file by Blockimmo AG. Below are the names and respective hashes of each file:

DividendDistributingToken.sol                     ad1ffc0b711b09867c2be63453d113e3
LandRegistry.sol                                  55ad98843464966e08ca34fd88105607
LandRegistryProxy.sol                             b03e7fb591f3f807a485f4cfcd3dda08
ShareholderDAO.sol                                b7ec4f7a39dba2103435aa5ff67ca5e6
TokenizedProperty.sol                             0f65358cf2793371050b17c7437c1276
TokenSale.sol                                     6dec7a359b14f9333533954b21ab6d7d

In addition to the custom contracts Blockimmo AG made use of multiple open source OpenZeppelin smart contracts from https://github.com/OpenZeppelin/openzeppelin-solidity/tree/v1.11.0-rc.1/contracts listed with hashes below:

crowdsale/distribution/RefundableCrowdsale.sol     5134f2d7943beed6d83c9f01c460b6e3 

crowdsale/distribution/PostDeliveryCrowdsale.sol 2c5b66c5e0189791bda8b6998d5805d1
math/SafeMath.sol                                 74b680004a2b882e6fc95b0386355ad2 

ownership/Claimable.sol 67f128c2228e879c7d136a2a2a1b5d18

ownership/Ownable.sol 0dcca46270f0dad0f7a753c8758bbe6a
token/ERC20/BasicToken.sol                        c88255702228b1f882fea4898ef45850 

token/ERC20/ERC20.sol 0cdf76866b6c90b8715242fb3372e586

token/ERC20/StandardToken.sol 1474ffcb71730bc98f2a60a247d81369

New Alchemy’s audit was additionally guided by the Blockimmo AG whitepaper and three blog posts which describe Blockimmo AG’s planned integration with the Swiss real estate market.

Blockimmo AG Whitepaper - Facilitating an Accessible & Streamlined Real-Estate
Market
Hash: 03e319cc699ad341a70f44c3e62dc47b

Re-test v2.0: New Alchemy performed the retest on the smart contracts located in https://github.com/blockimmo-ch/contracts/tree/36b2cb9bef58a9f7cd6f7968a205ff1332d56f23/. The updated whitepaper has the following hash: cff0fd1d2894fa130331740270e817c2


General Discussion

The Blockimmo AG smart contract platform implements a broad range of functionality through multiple interacting smart contracts. The smart contracts implement custom logic to support token creation, token sales, shareholder voting mechanisms, and a blockchain-to-real world linked property registry. The smart contract is based on nearly 700 lines of custom code including comments and incorporates code from the open-source OpenZeppelin project. This section discusses the general context around the specific findings elaborated in subsequent sections with an aim to better understand the current findings and prevent future instances.

New Alchemy identified one moderate and one minor vulnerability. The vulnerabilities could be classified as not following best practices and Blockimmo AG should implement fixes to strengthen the smart contract security posture.

The contracts have a fee feature which allows Blockimmo AG to collect a fee for running the token and real estate sale infrastructure. The fee mechanism utilizes integer division which always rounds down in the Solidity language. Due to the rounding down characteristic, Blockimmo AG will not be able to collect the full fee amount when calculating fee’s from token and property sales.

The minor security issue deals with missing clarity regarding specific contract constants.

The code implements and uses the OpenZeppelin SafeMath contract, which defines functions for safe math operations that will throw errors in the cases of integer overflow or underflows. While this functionality was used in multiple places, the auditors could not identify a valid attack and exploit scenario.

Additionally, the contracts make use of specialized functionality to open voting for specific real estate property decisions among the shareholders, which are defined as owners of the token associated with the property.

The current reuse of standard open-source components allows the platform to greatly reduce risk through leveraging well-reviewed, well-tested and usage-proven functionality.

New Alchemy strongly recommends staying current on compilers, (multiple) linters, formal methods and test coverage frameworks. The development team should integrate these procedures and tools into normal workflow. To maximize the leverage these tools provide, utilize their most conservative settings and aim to eliminate as many errors and warnings as possible early in the development process.

Contract / Whitepaper Token Coherence

This section examines and describes the number of issued tokens for each individual property sale. Due to Blockimmo AG planning to use the same token sale contracts for their own ICO these token amounts and distributions hold true for the Blockimmo AG ICO as well.

The whitepaper did not go into detail about the specific token amounts as such the values in this discussion were pulled directly from the smart contract source.

The TokenizedProperty.sol creates and sets the number of tokens. Line 55 and 56 set the decimal count and number of tokens:

uint8 public constant decimals = 18;
uint256 public constant NUM_TOKENS = 1000000;

The TokenizedProperty.sol constructor starting on line 76 sets the total supply and adds the balance to the contract creator. This amount will be distributed to the investors during the crowdsale period.

totalSupply_ = NUM_TOKENS * (uint256(10) ** decimals);
balances[msg.sender] = totalSupply_;

The DividendDistributingToken.sol smart contract is used to deposit and collect tokens. The code on line 26 sets the POINTS_PER_WEI. This variable is used to divide the tokens into smaller amounts.

uint256 public constant POINTS_PER_WEI = uint256(10) ** 32;

The POINTS_PER_WEI variable can be observed being used along with the totalSupplyvariable in the deposit()function on line 52.

function deposit(uint256 value) internal {
pointsPerToken = pointsPerToken.add(value.mul(POINTS_PER_WEI) / totalSupply_);
emit DividendsDeposited(msg.sender, value);
}

New Alchemy derived the amounts of the tokens directly from the smart contracts. We recommend amending the whitepaper to directly list the specific figures for clarity among investors. Parties interested in purchasing tokens should be able to clearly read the figures rather than having to locate them in the source code.


Critical Issues

No Critical Issues Found

Moderate Issues

1. Fixed: Improper Integer Division

The TokenSale.sol and TokenizedProperty.sol contracts utilize integer divsion math which, in Solidity, always rounds down[^intdiv]. In these particular functions the side effect would be Blockimmo AG not collecting a full fee percentage. This is raised as a moderate issue due to fee collection being a central use case.

For example a value of 190 divided by 100 will award a fee of 1 rather than 1.9, losing nearly 50% of value.

The finalization() function in TokenSale.sol.

uint256 fee = address(this).balance / 100;
blockimmo.transfer(fee);

Fallback function in TokenizedProperty.sol

uint256 fee = value / 100;
blockimmo.transfer(fee);

Fixed-point types are on the Solidity development roadmap but until they are officially part of the language it is recommended to use smaller units, such as Wei, or to implement a calculation which uses basis points to award and collect fee amounts.

[^intdiv]: Official Ethereum Wiki entry regarding integer division. https://github.com/ethereum/wiki/wiki/Safety#beware-rounding-with-integer-division

Re-test v2.0: New Alchemy discussed the issue with Blockimmo AG and has determined that the clean, simple code in the current state is preferred. The possible lost amounts are minuscule and cannot negatively affect the token purchasers in anyway. This is considered a non-issue.

Minor Issues

2. Fixed: Token Constants Are Not Well Documented

The Blockimmo AG whitepaper does specify smart contract constants such as token amounts, prices in USD or Ether, percentages of shares for sale, or ICO dates. Well documented projects should include such figures in the whitepaper to allow non-technical readers to review the data. For example it is unclear what percentage of tokens will be sold during the Blockimmo AG ICO. While not strictly a security finding, it is important to the overall posture of the contract as it adds clarity and a definitive source for evaluating smart contracts.

This issue is also discussed in the Contract / Whitepaper Token Coherence section of the report.

Re-test v2.0: New Alchemy has read the updated whitepaper and confirms that the constants are now documented in the Section 6 Token Generation Event portion.


Smart Contract ABI Reference

This section provides the fully-elaborated application binary interface (ABI) for the 6 primary contracts as seen at runtime. The ABI defines how the contracts may be interacted with while running inside the EVM. The tables make for very easy inspection of top-level specifics including:

  • The definitive reference of all exposed functions
  • Correct input and output function signatures
  • Presence of constructors and fallbacks as expected
  • Correct state mutability (pure, view, nonpayable, payable)
  • Extraneous functions which should be private

From inspecting the tables below it becomes clear that many return values have no name. New Alchemy recommends naming all return values wherever possible to maximize clarity and minimize cognitive loading. Further, the absence of some function return (output) values may also represent missed opportunities to report then check/handle status above and beyond simple transaction failures.

DividendDistributingToken.sol ABI Reference

LandRegistry.sol ABI Reference

LandRegistryProxy.sol ABI Reference

ShareholderDAO.sol ABI Reference

TokenizedProperty.sol ABI Reference

TokenSale.sol ABI Reference


Line by line comments

This section lists comments on design decisions and code quality made by New Alchemy during the review. These warnings were discovered during manual source code inspection but can also be generated during compilation and while running various language linters. They are not known to represent security flaws.

The Blockimmo AG code was well written and the analysis only reported two non-security issues.

Pervasive across the code base

It is recommended to lock pragma to a specific compiler version, it is seen as best practice to enable that feature on every smart contract. To remediate this issue modify the code to remove the caret symbol ^ as such:

pragma solidity 0.4.24;

Re-test v2.0: New Alchemy has confirmed that the contracts now lock to the newest compiler version. Completely remediating the issue.

ShareholderDAO.sol

The compiler threw a warning on ShareholderDAO.sol line 170. The contract contains an unused function parameter. Remove or comment out the variable name to silence this warning.

function tallyVotes(uint256 tallyFor, uint256 tallyAgainst) {
if (tallyFor > property.totalSupply() / 2) {
outcome = Outcomes.Accept;
} else {
outcome = Outcomes.Reject;
}
}

Re-test v2.0: New Alchemy has inspected the source code and confirmed that the unused tallyAgainst function argument has been removed.


Disclaimer

The audit makes no statements or warranties about utility of the code, safety of the code, suitability of the business model, regulatory regime for the business model, or any other statements about fitness of the contracts to purpose, or their bug free status. The audit documentation is for discussion purposes only.


New Alchemy is a leading blockchain strategy and technology group specializing in tokenized capital solutions for the most innovative companies worldwide. New Alchemy’s Blockchain Security division is a highly trusted name that has assisted clients in securely raising over $500m through custom-tailored solutions, smart contract audits and comprehensive security strategy. Get in touch with us at Hello@NewAlchemy.io