Switch branches/tags
Nothing to show
Find file History
Pull request Compare This branch is 20 commits ahead, 39 commits behind GizerInc:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
..
Failed to load latest commit information.
code-review
deployed-contracts
presaleTest
test
README.md

README.md

Gizer Crowdsale And Token Contract Audit

Summary

Gizer intends to run a crowdsale commencing in Nov 2017.

Bok Consulting Pty Ltd was commissioned to perform an audit on Gizer's crowdsale and token Ethereum smart contract.

This audit was originally conducted on Gizer's Presale + Crowdsale source code in commits 3198d0e, c1e4255, 43b4d51, 9ed59cc and 50cfcec.

No potential vulnerabilities have been identified in the original crowdsale and token contract.


Nov 28 2017 - The presale and token contract was later separated out in commits 1bff114 and 0808abc.

No potential vulnerabilities have been identified in the new presale and token contract.


Presale Contract Mainnet Address

The presale contract has been deployed to 0x92683b8A2dbbC02d1C6303d5b4362a06E46f5616.

The source code from the deployed contract has been saved to deployed-contracts/GizerTokenPresale_deployed_at_0x92683b8A2dbbC02d1C6303d5b4362a06E46f5616.sol and has the following difference to the audited contract:

$ diff -w ../../contracts/GizerTokenPresale.sol GizerTokenPresale_deployed_at_0x92683b8A2dbbC02d1C6303d5b4362a06E46f5616.sol 
14c14
< // SafeMath (div not needed but kept for completeness' sake)
---
> // SafeM (div not needed but kept for completeness' sake)
18c18
< library SafeMath {
---
> library SafeM {
121c121
<   using SafeMath for uint;
---
>   using SafeM for uint;
224c224
<   uint public constant MAX_CONTRIBUTION = 100 ether;
---
>   uint public constant MAX_CONTRIBUTION = 2300 ether;
228c228
<   uint public constant PRIVATE_SALE_MAX_ETHER = 2300 ether;
---
>   uint public constant PRIVATE_SALE_MAX_ETHER = 1000 ether;
233c233
<   uint public constant DATE_PRESALE_END   = 1513260000; // 14-Dec-2017 14:00 UTC
---
>   uint public constant DATE_PRESALE_END   = 1512914400; // 10-Dec-2017 14:00 UTC

The SafeM library has been deployed to 0xC7dc19502DB685fBFe3399042d443feF240D513b and has the following source:

library SafeM {

  function add(uint a, uint b) public pure returns (uint c) {
    c = a + b;
    require( c >= a );
  }

  function sub(uint a, uint b) public pure returns (uint c) {
    require( b <= a );
    c = a - b;
  }

  function mul(uint a, uint b) public pure returns (uint c) {
    c = a * b;
    require( a == 0 || c / a == b );
  }

  function div(uint a, uint b) public pure returns (uint c) {
    c = a / b;
  }  

}

Presale Contract

  • Ethers (ETH) contributed to the presale contract are immediately moved to the crowdsale wallet

Presale Token Contract

  • The tokens will only be transferable into the redemptionWallet, before the tokens are frozen
  • The tokens can be frozen by the contract owner. The intention here is for the presale token balances to be frozen, and the presale token balance will then be used to generate the crowdsale token contract balances


Table Of Contents



Recommendations

First Review

  • LOW IMPORTANCE Please reformat the code and comments to make it easier to read the code. Some inconsistencies:
    • Variable comment styles makes it hard to pick out the different sections, functions, variables, events:

      // events -------------------------
      // VARIABLES ================================
      // utility variable
      // Allow _spender to withdraw from your account up to_amount.
      //
      // --------------------------------
      // implement totalSupply() ERC20 function
      // --------------------------------
      

      It is easier to read "Events" than "events" or "VARIABLES"

    • Brackets and spacings:

      require( _amount > 0 );
      require( _amount == 0 || allowed[msg.sender][_spender] == 0 );
      require (balances[msg.sender] >= _amount);
      require( balances[_participant] == 0 || locked[_participant] != true);
      
    • Don't need LogXxx for events as the standard convention is just to use Xxx

    • Sometimes there is one blank line before function declarations, sometimes none

    • Updated in 9ed59cc

  • LOW IMPORTANCE GizerToken.GizerToken() does not need the statement owner = msg.sender; as this assignment is already made in Owned.Owned()
  • MEDIUM IMPORTANCE Token balances for all the accounts should add up to the totalSupply. Currently the different token allocations do not add up to TOTAL_TOKEN_SUPPLY. At least the known allocations should be represented in this token contract
  • MEDIUM IMPORTANCE Any changes to the balances[...] mapping should have a related Transfer(...) event. When these transfers are displayed in EtherScan.io or Ethplorer.io, the accounting should balance. Minted tokens should have a Transfer(0x0, ...) event
  • LOW IMPORTANCE The comment https://github.com/ethereum/EIPs/issues/20 should be updated to the final standard at https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
  • MEDIUM IMPORTANCE In setRedemptionWallet(...), RedemptionWalletUpdated(wallet); should be RedemptionWalletUpdated(redemptionWallet);
  • MEDIUM IMPORTANCE In setWhitelistWallet(...), WhitelistWalletChanged(wallet); should be WhitelistWalletChanged(whitelistWallet);
  • LOW IMPORTANCE The logic in isWhitelisted(...) can be simplified, and this function can be removed and replaced by setting whitelist to public visibility. See the NOTEs in the code review
  • LOW IMPORTANCE DATE_ICO_START and DATE_ICO_END are not constants and should be camelCased
  • LOW IMPORTANCE In approve(...), consider removing require( _amount == 0 || allowed[msg.sender][_spender] == 0 ); as this is no longer recommended in https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md:

    THOUGH The contract itself shouldn't enforce it, ...


New Presale Contract Review

Added in commit 1bff114.

  • LOW IMPORTANCE Owned.acceptOwnership() will log the event when owner has already been assigned to newOwner
  • LOW IMPORTANCE The require(...) statements in transfer(...) and transferFrom(...) are redundant as the SafeMath library function will REVERT if the numbers cause a problem. It is your preference whether the require(...) statements are used or not
    • Developer decided to leave the require(...) statements in place for clarity
  • LOW IMPORTANCE privateSaleContribution(...) will be called by the owner to add contribution entries without any ethers being sent. This function calls issueTokens(...) which executes wallet.transfer(this.balance); at the end. Place a check if (this.balance > 0) { ... } around the wallet.transfer(this.balance); statement


Potential Vulnerabilities

No potential vulnerabilities have been identified in the crowdsale and token contract.

No potential vulnerabilities have been identified in the new presale and token contract.



Scope

This audit is into the technical aspects of the crowdsale contracts. The primary aim of this audit is to ensure that funds contributed to these contracts are not easily attacked or stolen by third parties. The secondary aim of this audit is that ensure the coded algorithms work as expected. This audit does not guarantee that that the code is bugfree, but intends to highlight any areas of weaknesses.



Limitations

This audit makes no statements or warranties about the viability of the Gizer's business proposition, the individuals involved in this business or the regulatory regime for the business model.



Due Diligence

As always, potential participants in any crowdsale are encouraged to perform their due diligence on the business proposition before funding any crowdsales.

Potential participants are also encouraged to only send their funds to the official crowdsale Ethereum address, published on the crowdsale beneficiary's official communication channel.

Scammers have been publishing phishing address in the forums, twitter and other communication channels, and some go as far as duplicating crowdsale websites. Potential participants should NOT just click on any links received through these messages. Scammers have also hacked the crowdsale website to replace the crowdsale contract address with their scam address.

Potential participants should also confirm that the verified source code on EtherScan.io for the published crowdsale address matches the audited source code, and that the deployment parameters are correctly set, including the constant parameters.



Risks

Old Crowdsale Contract

  • Contributed ethers will accummulate in this crowdsale contract until the minimum funding level is reached. In the case where the minimum funding level is not reached, refunds are provided to participants. Once this minimum funding level is reached, all contributed ether is be immediately transferred to an external wallet

New Presale Contract

  • All ethers contributed to the presale contract are immediately transferred to an external wallet, reducing the risk of funds being hacked or stolen from the presale contract


Testing

Crowdsale Contract Testing

Test 1 Success

The following functions were tested using the script test/01_test1.sh with the summary results saved in test/test1results.txt and the detailed output saved in test/test1output.txt:

  • Deploy the crowdsale/token contract
  • Change wallets
  • Whitelist participant accounts
  • Contribute in the presale stage
  • Contribute in the crowdsale stage
  • Finalise the crowdsale
  • Transfer tokens

Test 2 Refunds

The following functions were tested using the script test/02_test2.sh with the summary results saved in test/test2results.txt and the detailed output saved in test/test2output.txt:

  • Deploy the crowdsale/token contract
  • Change wallets
  • Whitelist participant accounts
  • Contribute in the presale stage
  • Contribute in the crowdsale stage
  • Claim refunds

Details of the testing environment can be found in test.

Presale Contract Testing

Test 1 Presale

The following functions were tested using the script presaleTest/01_test1.sh with the summary results saved in presaleTest/test1results.txt and the detailed output saved in presaleTest/test1output.txt:

  • Deploy the crowdsale/token contract
  • Change wallets
  • Send private sale contribution
  • Contribute in the presale period
  • Contribute after the presale period (expecting failure)
  • Transfer tokens to the redemption wallet
  • Transfer tokens to the other wallets (expecting failure)
  • Freeze tokens
  • Transfer tokens to the redemption wallet (expecting failure)

Details of the testing environment can be found in presaleTest.



Code Review

First Review

  • code-review/GizerToken.md
    • library SafeMath
    • contract Owned
    • contract ERC20Interface
    • contract ERC20Token is ERC20Interface, Owned
    • contract GizerToken is ERC20Token

Second Review Of The Presale Only Contract

  • code-review/GizerTokenPresale.md
    • library SafeMath
    • contract Owned
    • contract ERC20Interface
    • contract ERC20Token is ERC20Interface, Owned
    • contract GizerTokenPresale is ERC20Token


(c) BokkyPooBah / Bok Consulting Pty Ltd for Gizer - Nov 29 2017. The MIT Licence.