This document is a security audit report performed by RideSolo, where AMO Project has been reviewed.
- AMOCoin.sol github commit hash 51b441202ba09186d2aec530a88f9e898205027c.
- AMOCoinSale.sol github commit hash 390f49f16827d272ce19ddd8a90757c45a974ff0.
5 issues were reported:
- 1 high severity issue.
- 1 medium severity issue.
- 3 low severity issue.
When allocateTokens
is called the tokenAmount
to be transfered to to
address is not substracted from allocationList[to].allowedAmount
, meaning that if the function is called again by the owner a higher amount than allocationList[to].allowedAmount
can be transfered to the to
.
https://github.com/RideSolo/AMO-Contracts/blob/master/contracts/AMOCoinSale.sol#L463#L476
https://github.com/RideSolo/AMO-Contracts/blob/master/contracts/AMOCoinSale.sol#L400#L407
If Multiple allocations are made to user
address using addToAllocationList
function member of AMOCoinSale
, the amount
allocated is not cumulated in allocationList[user].allowedAmount
.
Please note that addToAllocationList
is meant to be used when EarlyInvestment
is set, meaning that real payment are done offchain and this can lead to major errors from the team since this function is only used by the owner.
https://github.com/RideSolo/AMO-Contracts/blob/master/contracts/AMOCoinSale.sol#L400#L407
AMO token owner privileges:
- Enable/Disable transfers/burn/approval for all tokens holders (
onlyWhenTransferAllowed
,enableTransfer
,disableTransfer
) (check here). - Selectively freeze/unfreeze tokens by addresses (
onlyAllowedAmount
,lockAccount
,unlockAccount
) (check here).
AMO sale owner privileges:
- Token destinated to be sold through the crowdsale contract are approved and not transfered and locked in the sale contract, meaning that the owner will still be able to handle them without backing them up by ether (check here).
- Every round (EarlyInvestment, PreSale,CrowdSale) has three stages (SetUp,Started,Ended), the sale contract logic do not allow to go to a previous stage of a round but a round can be selected once the the previous round has ended using
setUpSale
, meaning that the owner can reset the round even to a previous one. owner should not be able to reselect round insetUpSale
butround
has to be incremented directly inside the function, (check here). - A sale round can be ended by the owner at any moment, (check here.
addToAllocationList
function member of AMOCoinSale
add tokens amount to mapping for a dedicated users since it is allowed only when EarlyInvestment
round then we can guess that the token sale was done offchain through fiat or any other way.
However removeFromAllocationList
can also cancel the allowed tokens before that allocateTokens
is called and the tokens are transfered to the user address. The main issue here is when is the fiat or crypto payment is done and why an address can be removed knowing that a user has maybe didn't get his payment back.
https://github.com/RideSolo/AMO-Contracts/blob/master/contracts/AMOCoinSale.sol#L400
https://github.com/RideSolo/AMO-Contracts/blob/master/contracts/AMOCoinSale.sol#L432
https://github.com/RideSolo/AMO-Contracts/blob/master/contracts/AMOCoinSale.sol#L463
- It is possible to double withdrawal attack. More details here
- Lack of transaction handling mechanism issue. WARNING! This is a very common issue and it already caused millions of dollars losses for lots of token users! More details here
The audited contracts issues should be fixed.