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 ad1ffc0b711b09867c2be63453d113e3LandRegistry.sol 55ad98843464966e08ca34fd88105607LandRegistryProxy.sol b03e7fb591f3f807a485f4cfcd3dda08ShareholderDAO.sol b7ec4f7a39dba2103435aa5ff67ca5e6TokenizedProperty.sol 0f65358cf2793371050b17c7437c1276TokenSale.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 2c5b66c5e0189791bda8b6998d5805d1math/SafeMath.sol 74b680004a2b882e6fc95b0386355ad2
ownership/Claimable.sol 67f128c2228e879c7d136a2a2a1b5d18
ownership/Ownable.sol 0dcca46270f0dad0f7a753c8758bbe6atoken/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
- https://medium.com/blockimmo/the-smart-contracts-powering-blockimmo-fc16e1bbee09
- https://medium.com/blockimmo/a-simple-layer-enabling-a-smart-contract-based-web-app-691f0b64c475
- https://medium.com/blockimmo/enabling-on-chain-digital-assets-in-the-real-world-456d80aed0b0
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 totalSupply
variable 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