23 Mar
Technology , Opinion

Lunyr ICO smart contract audit


This is a technical audit for Lunyr crowdsale and token smart contracts. Lunyr is a Wikipedia like decentralized world knowledge base that uses Ethereum tokens to pay for contributions and sell advertisements.

No issues were founded during the audit.


This audit scope includes

  • Crowdsale and token contract contract (ERC-20)

I was one of two parties that independently audited Lunyr. This audit is purely technical and is not an investment advise.

About Lunyr

Lunyr implements crowdsale and token in a single contract. Please see the link for the reviewed source code revision.

The contract seems to be heavily inspired by Golem crowdsale that did a successful crowdsale of USD 10M by the time. It is always a good idea to build on the top of tested solution.

The team uses a multisig wallet created by Stefan George (Consensys).

Investor protection

Refund mechanism

In the case the ICO does not reach the minimum funding goal, the crowdsale smart contract can automatically issue a refund for all the participants. The crowdsale participants can request a refund through refund() function.

Opt-in for new token contract

The Lunyr token issued in the crowdsale might not be the final version of the token contract. Lunyr system will grow in scope and complexity when decentralized content production and advertising are added in. These features are not yet available during the crowdsale, but will happen later in the product development.

The Lunyr team can centrally only give an upgrade path. The users are not forced to follow.

All token holders need to opt in to new token contract versions. This happens through upgrade function.

The similar mechanism is employed by Golem token smart contract.

Founder vesting

The founders receive 15% of issued tokens. The founders have their tokens locked in a time vault contract for 180 days.

Furthermore 7% of tokens are reserved for bug bounties and crowdsourced marketing.


The token price is fixed 44 Lunyrs tokens for 1 ETH. The price is flat during the duration of ICO.

Code practices

Lunyr uses Truffle development framework. Smart contracts are based on OpenZepplin foundational contracts. These are the state-of-art Solidity development tools used by multiple other projects.

The source code is one of the most carefully commented smart contract I have seen.

Test coverage

Lunyr has one of the most extensive crowdsale test suite I have seen.

Lunyr comes with a Truffle based test suite. It contains 50 different tests for the crowdsale and token contract.

Below is the list of the run tests.

  • Before Crowdsale -- getState returns PreFunding
  • Before Crowdsale -- disallows transfer
  • Before Crowdsale -- disallows transferFrom
  • Before Crowdsale -- disallows upgrade
  • Before Crowdsale -- disallows approve
  • Before Crowdsale -- disallows setUpgradeAgent
  • Before Crowdsale -- disallows setUpgradeMaster
  • Before Crowdsale -- disallows create
  • Before Crowdsale -- disallows refund
  • Before Crowdsale -- disallows finalizeCrowdfunding
  • Before Crowdsale -- allows totalSupply, which is 0
  • Before Crowdsale -- allows balanceOf, which is 0
  • Before Crowdsale -- disallows approve
  • Before Crowdsale -- allows allowance, which is 0
  • During Crowdsale -- getState returns Funding
  • During Crowdsale -- disallows transfer
  • During Crowdsale -- disallows transferFrom
  • During Crowdsale -- disallows upgrade
  • During Crowdsale -- disallows approve
  • During Crowdsale -- disallows setUpgradeAgent
  • During Crowdsale -- disallows setUpgradeMaster
  • During Crowdsale -- allows create
  • During Crowdsale -- disallows creation of too many tokens
  • During Crowdsale -- disallows refund
  • During Crowdsale -- disallows finalizeCrowdfunding
  • During Crowdsale -- allows totalSupply
  • During Crowdsale -- allows balanceOf
  • During Crowdsale -- disallows approve
  • During Crowdsale -- allows allowance, which is 0
  • Successful Crowdsale -- getState returns Success after tokenCreationMax
  • Successful Crowdsale -- getState returns Success after fundingEndBlock
  • Successful Crowdsale -- allows transfer and balanceOf
  • Successful Crowdsale -- allows upgrade
  • Successful Crowdsale -- allows setUpgradeAgent
  • Successful Crowdsale -- allows setUpgradeMaster
  • Successful Crowdsale -- disallows create
  • Successful Crowdsale -- disallows refund
  • Successful Crowdsale -- allows finalizeCrowdfunding
  • Successful Crowdsale -- vault works correctly
  • Successful Crowdsale -- allows totalSupply
  • Successful Crowdsale -- approve, allowance and transferFrom enabled
  • Failed Crowdsale -- getState returns Failed after fundingEndBlock
  • Failed Crowdsale -- allows refund
  • Failed Crowdsale -- disallows transfer
  • Failed Crowdsale -- disallows upgrade
  • Failed Crowdsale -- disallows setUpgradeAgent
  • Failed Crowdsale -- disallows setUpgradeMaster
  • Failed Crowdsale -- disallows create
  • Failed Crowdsale -- disallows finalizeCrowdfunding
  • Failed Crowdsale -- disallows approve
  • Failed Crowdsale -- allows totalSupply