The Sikoba Presale Smart Contract Security Audit

(Created Mar 08 2017. Updated with test results Mar 14 2017. Updated with multisig wallet contribution test results Mar 23 2017.)

I was asked to review the Sikoba presale smart contracts before the upcoming Sikoba presale crowdfunding event. This page documents Bok Consulting’s general and security audit of Sikoba’s presale smart contracts.

Summary

  • There was only one major recommendation to fix the original contract to remove the situation where the owner’s ethers can get locked up within the contract.
  • All other recommendations and changes have been to improve the readability of the source code. The third and final revision is listed below.
  • The contract has been tested with geth 1.5.9-stable and solc 0.4.9+commit.364da425.Darwin.appleclang and work as intended. The results are listed below.
  • The final tested version of the contract can be found at https://github.com/sikoba/token-presale/blob/f4cf1ab95e7b18cf0612076968342a4a4e1087f3/contracts/SikobaPresale.sol.
  • There may be deployment gas limit issues if there are too many preallocation entries to add to the contract constructor. The alternative fill(...) and seal() method can be used to work around this potential gas limit issue, but this procedure will require separate testing before deployment.
  • There is a small possibility that the deployed source cannot be verified on etherscan.io . The deployment of this contract can only be done once as the preallocation ethers will be sent along with the contract. It is advisable to first try deploying a test contract with a small preallocation amount and then verifying the source on etherscan.io.

References


Table of contents


1. The Original Contracts

The first version of the source code is located at https://github.com/sikoba/token-presale/commit/74a237d8da0d4c39e4bc90c3aa3b244910e4afd9.

Following are the original contracts with my additional comments marked as:

  • // CHECK: for the check done
  • // RECOMMENDATION: for any recommendations
  • // FORMAT: for recommended code reformatting for easier reading
  • // ACTION: for areas that require action

From the first round of reviews, there is only one important recommendation:

  • Fix the logic within withdraw(...) as the owner can accidentally end up with a situation where ethers can be trapped in this contract.

Lower priority, I would format the source code including the comments as a document for potential investors to read. There is some renaming that can be done to it easier for readers to understand, e.g., MINIMAL_BALANCE_OF_PRESALE -> PRESALE_MINIMUM_BALANCE and valueInWei -> value.

1.1 owned.sol

From https://github.com/sikoba/token-presale/blob/master/contracts/owned.sol:
owned.sol

1.2 SikobaPresale.sol

From https://github.com/sikoba/token-presale/blob/master/contracts/SikobaPresale.sol:
SikobaPresale.sol

1.3 Migrations.sol

From https://github.com/sikoba/token-presale/blob/master/contracts/Migrations.sol:
migrations.sol


2. The First Revision SikobaPresale.sol Contract

The latest version of SikobaPresale.sol was taken from https://github.com/sikoba/token-presale/commit/f58535440228e980ade19b0b44bfd4381b556cd1 that includes Roland’s addition of the totalFunding changes to correct for the only serious issue in the first round of reviews.

The formatting and recommendation from the first round of reviews was then applied to the code from github. Migrations.sol is not required for production deployment and has been omitted.

Following is the resulting code:
The First Revision SikobaPresale.sol


3. The Second Revision SikobaPresale.sol Contract

Roland has merged the results from the first revision of the reviews to the Github repository. This version is to be security reviewed in the second round.

The second revision of SikobaPresale.sol is based on the source code taken from https://github.com/sikoba/token-presale/blob/0d4f6f1b237853e1a6ff74de10e81f50eaf914a5/contracts/SikobaPresale.sol that includes the changes from the first revision.

The ad-hoc tests were conducted using Remix (Browser Solidity) using the JavaScript VM – remix-159aeff.zip.

3.1 SikobaPresale.sol

Following is the second revision of SikobaPresale.sol with my additional comments marked as:

  • // CHECK: for the check done
  • // RECOMMENDATION: for any recommendations
  • // ACTION: for areas that require action
SikobaPresale.sol

3.2 Confirming Events Are Not Logged In The Constructor

Deploying the following script in Remix (Browser Solidity) shows that event logs are NOT generated or persisted during the execution of the constructor. Once constructed, the event logs are generated and persisted.
Test Confirming Events Are Not Logged In The Constructor

The logging of the preallocation balances in the SikobaPresale constructor is redundant.


4. The Third And Final Revision SikobaPresale.sol Contract

Roland has merged the results from the second revision of the reviews to the Github repository. This version is to be security reviewed in the third round.

The third revision of SikobaPresale.sol is based on the source code taken from https://github.com/sikoba/token-presale/blob/f4cf1ab95e7b18cf0612076968342a4a4e1087f3/contracts/SikobaPresale.sol that includes the changes from the second revision and minor updates. Here are diff1, diff2 and diff3.

4.1 SikobaPresale.sol

Following is the third and final revision of SikobaPresale.sol.

4.2 Test Scenarios

Test & Expected Results Passed?
1. At deployment of contract, before presale period PASS
1.1 Preallocation balances incorrect – fail deployment PASS
1.2 Preallocation balances correct – deploy PASS
1.3 No one can contribute to the contract PASS
2. During the presale period PASS
2.1 Participant cannot contribute below minimum amount PASS
2.2 Participant cannot contribute above maximum amount PASS
2.3 Participant can contribute in correct range PASS
2.4 Participant cannot contribute once funding max reached PASS
2.5 Owner cannot withdraw PASS
2.6 Owner cannot clawback PASS
2.7 Participant cannot withdraw PASS
3. After presale period when funding goal not reached PASS
3.1 Owner cannot withdraw PASS
3.2 Owner cannot clawback PASS
3.3 Participants cannot contribute PASS
3.4 Participants can withdraw partial amounts PASS
3.5 Participants can withdraw full amount PASS
4. After presale period when funding goal reached PASS
4.1 Participant cannot contribute PASS
4.2 Participant cannot withdraw PASS
4.3 Owner cannot clawback PASS
4.4 Owner can withdraw partial amounts PASS
4.5 Owner can withdraw full amount PASS
5. After clawback period when funding goal not reached PASS
5.1 Owner cannot withdraw PASS
5.2 Participants cannot contribute PASS
5.3 Participants can withdraw partial amounts PASS
5.4 Participants can withdraw full amount PASS
5.5 Owner can clawback PASS

4.3 Test Results

The test inputs, outputs and results were run at 02:16 Mar 14 2017 AEST and are available at https://github.com/sikoba/token-presale/tree/bc5bf008dd2ea0507b9c33514b2e0215d6643c9c/test (but does not include Roland’s preallocations.txt and sikobapresale.js). The tests were run using geth 1.5.9-stable and solc 0.4.9+commit.364da425.Darwin.appleclang on an OS/X notebook.

To view in a wider window, click on the <-> icon on the top right of the window.

4.3.1 Test 1. At deployment of contract, before presale period

4.3.2 Test 2. During the presale period

4.3.3 Test 3. After presale period when funding goal not reached

4.3.4 Test 4. After presale period when funding goal reached

4.3.5 Test 5. After clawback period when funding goal not reached


5. Testing Multisig Wallet Contributions To The SikobaPresale Contract

5.1 Deploying SikobaPresale.sol

The SikobaPresale.sol from section 4. above was deployed to Mainnet with the following parameters:

  • MINIMUM_PARTICIPATION_AMOUNT = 0 ether
  • MAXIMUM_PARTICIPATION_AMOUNT = 250 ether
  • PRESALE_MINIMUM_FUNDING = 1 ether
  • PRESALE_MAXIMUM_FUNDING = 2 ether
  • TOTAL_PREALLOCATION = 0 ether
  • PRESALE_START_DATE = now (1490191425 = 2017-03-22T14:03:45+00:00)
  • PRESALE_END_DATE = PRESALE_START_DATE + 15 minutes (1490192325 = 2017-03-22T14:18:45+00:00)
  • OWNER_CLAWBACK_DATE = PRESALE_START_DATE + 20 minutes (1490192625 = 2017-03-22T14:23:45+00:00)
  • No preallocations in the constructor

Reference: How Does The Ethereum Multisig Contract Wallet Execute Contract Functions?

5.2 Test Scenarios

  • Deploy the contract. Presale ends in 15 minutes. Clawback active in 20 minutes
  • Contribute 0.01 ETH from a multisig wallet before presale ends
  • Withdraw the contributions of 0.01 ETH using a multisig wallet after the presale ends

5.3 Test Results

  • PASS Deployed the contract to 0xe67907329dafd1ff826523e3f491bec8733f7376. Presale ends in 15 minutes. Clawback active in 20 minutes.
  • PASS Contributed 0.01 ETH from a multisig wallet before presale ends. Tx 0xded8a025… with 99,252 gas used:

     
    PASS Balance of 0.01 ETH in the SikobaPresale contract:
  • UNABLE TO EXECUTE – see below. Withdraw the contributions of 0.01 ETH using a multisig wallet after the presale ends

Conclusion: The multisig wallet created by Ethereum Wallet 0.8.9 at , originally deployed Aug-31-2016 07:12:59 PM +UTC interacts with the SikobaPresale contract without any issues in this test.

5.4 DEPLOYMENT WARNING

I deployed the SikobaPresale contract to 0xe67907329dafd1ff826523e3f491bec8733f7376 with the following datetime parameters:

I was expecting PRESALE_START_DATE = now to be evaluated to a constant (the deployment time), PRESALE_END_DATE and OWNER_CLAWBACK_DATE to both be constants of 15 minutes and 20 minutes relative to the deployment time. But NO. These variables are NOT evaluated to constants. You can verify for yourself by viewing the contract’s READ CONTRACT page and refreshing the page periodically. These values for these three variables will change with the page refresh.

Here’s the page at 1490193613 = 2017-03-22T14:40:13+00:00:

And here’s the page again at 1490193727 = 2017-03-22T14:42:07+00:00. Note that the highlighted variables have changed:

WARNING. Do not use now in the uint256 public constant variables!

Further information:

This entry was posted in Blog and tagged , , , . Bookmark the permalink.