- A flat pricing with ETH: USD - $0.02 per token (50 tokens to 1 USD)
- Coin rate should be $0.02 (can just use the live feed from www.oraclize.it or similar)
- Token supply: 1 billion, selling 150 million e.g. $3M cap.
- Token: 8 decimals
- Multisig wallet for the proceeds, as per gnosis (as that doesn't seem to have had any issues vs. parity)
- Ensure tokens are reserved and allocated by a certain date when they unlock to subscribers
- No ETH cap: Anyone can buy as many tokens as they like until all tokens are sold
- Sale ends when 150m tokens (out of 1bn) allocated to contract run out or a certain date is reached
- Ideally the smart contract should verify in etherscan and fit into the token tracker
- There will be no whitelisting of investors and no hard/soft cap.
- There will be no refund
Crowdsale code is audited against above specifications. AllocatedCrowdsale.sol is considered as a root for the crowdsale so audit covers only following files:
- AllocatedCrowdSale.sol
- Crowdsale.sol
- FinalizeAgent.sol
- Haltable.sol
- PricingStategy.sol
- FlatPricing.sol
Few contracts are imported from zeppline-solidity so commit8e01dd1
of zeppelin is used in audit.
No unit test are provided which is a big red flag. I will recommend to write unit test and use of truffle.
Some unnecessary code is found that is not required according the specs so I will recommend to remove this to minimizing the contract size.
- No Time Period for crowdsale
Crowdsale will be open until all the tokens are not sold and their is no ether cap so following line of codes are unnecessary.CrowdSale.sol:30
Crowdsale.sol:33
Crowdsale.sol:53
Crowdsale.sol:170
- No refund
There will be no refund in the crowdsale so following lines are unnecessary.Crowdsale.sol:74
Crowdsale.sol:77
Crowdsale.sol:125
- No whitelisting
Anonymous investments will be acceptable so following lines of code can be removed.CrowdSale.sol:83
Crowdsale.sol:89
Crowdsale.sol:92
Crowdsale.sol:101
Crowdsale.sol:104
Crowdsale.sol:128
Crowdsale.sol:131
Crowdsale.sol:281
toCrowdsale.sol:335
CrowdSale.sol:375
toCrowdSale.sol:415
CrowdSale.sol:476
toCrowdsale.sol:504
- Unused variables
- Remove unused variables from
FlatPricing:29
- Remove unused variables from
After removing redundant code following corrections are required:
- Remove
_minimumFundingGoal
,_baseEthCap
from constructor parameter list of Crowdsale.sol and AllocatedCrowdsale.sol. - Rename
investInternal(address receiver, uint128 customerId)
tobuy(address receiver)
and make it public - Modify
event Invested(address investor, uint weiAmount, uint tokenAmount, uint128 customerId)
toevent Invested(address investor, uint weiAmount, uint tokenAmount)
- Remove
PreFunding
State from the Crowdsale.sol - Modify check condition of
State.Success
in Crowdsale.sol:538 to depends upon amount of token sold instead of minimum funding.
Function calculatePrice()
in FlatPricing does not calculate right price because of invalid multiplier
value. Total decimal points in ether are 18 so we have to devide by 10 ** 10
instead of 10 ** 8
.
- At Crowdsale.sol constructor parameter
_token
- At AllocatedCrowdsale.sol constructor parameter
_beneficiary
- At
preallocate()
function parametersCrowdsale.sol:261
- At
setMultisig()
function parametersCrowdsale.sol:461
- At
setEthToUsd()
function parametersCrowdsale.sol:450
- At
setEthToUsd()
function parametersCrowdsale.sol:450
- At
setEthToUsd()
function parametersFlatPricing.sol:22
- At
calculatePrice()
function parametersFlatPricing.sol:29
- Restrict accessibility to external for the following functions
setPricingStrategy()
setEthToUsd()
setMultisig()
setEndsAt()
setFinalizeAgent()
finalize()
setMultisig()
- Use of wallet
Software wallets have pretty bad history so I would recommend hardware wallet. Multisig is secure until there is no bug in code but hardware wallet will always require physical interaction to initiate transaction.
One critical issue found regarding calculation mentioned in section 4. Crowdsale can go into invalid state or even unrecoverable state due to the absence of sanity checks at function arguments explained in section 5. Redundant code found that increases size of the contract so its a waste of gas(ethers). Right now contract is not complete according to the specs so after implementation of above changes please test it again.