Moviecoin - Smart Contract Audit Report
Moviecoin is building a new community-driven ERC20 token with vesting capabilities.
For this audit, we reviewed the project team's Moviecoin contract at commit 7dd97e0f503dea51a51deecec47527c73cbe9d71 on the team's private Gitlab repository.
Notes on the Contracts:
Audit Findings Summary:
- Initially, 100% of the total supply will be held by the owner.
- There was no token allocation for our team to analyze as the contract has yet to be deployed.
- There is no mint function so there is no way for the team to increase the total supply after the initial amount.
- There is no burn function, but the tokens can be sent to the 0x..dead address to reduce the circulating supply at any time.
- There is a fee on all transfers when neither the sender or receiver are whitelisted.
- The owner address, fee addresses, and specified whitelisted addresses set by the owner are exempt from fees.
- The four types of fee categories are new movies, profit, development, and user credit.
- The percentages of how the total fee amount is divided among the different fee catagories can change.
- Users can choose to lock their tokens using the vesting process; in which they specify how many tokens they are locking, when the release time will be, and beneficiary who will receive the tokens. Once the release time has elapsed, their tokens can be claimed.
- Users can create multiple vesting instances at once with different amounts and release times.
- A for loop is used to create multiple vesting instances; The team must ensure the maximum number of addresses that can be involved in a single group of vesting instances is not too large to prevent this loop from hitting the block gas limit.
- While the anti-whale protocol is active, users that are whitelisted are unable to send or receive more tokens than the anti-whale amount.
- Users are unable to receive tokens that push their total balance over the set whale amount. The whale amount effectively acts as a max wallet amount as well.
- Any liquidity pool added must be whitelisted from the anti whale amount in order to ensure users can sell the token effectively.
- Anyone can use the multisend function to airdrop any amount of tokens to any address at any time.
- A for loop is used to transfer funds for the airdrop; The user must ensure the maximum number of addresses that can be involved in a single airdrop is no more than 350 to prevent this loop from hitting the block gas limit.
- The contract is implemented with Solidity v0.8.9 so its protected from any underflow/overflow attacks along with following the ERC20 standard.
- The owner can renounce and transfer ownership.
- The owner can change any of the four fee addresses at any time.
- The owner can change how the fee is divided between the different fee categories.
- The owner can change the tax percentage with a maximum of 6% at any time.
- The owner can include or exclude any address from fees at any time.
- The owner can include or exclude any address from the whale amount at any time.
- The owner can set the whale amount to any value lower than the total supply at any time.
- The owner can disable the anti whale limit at any time.
- No security issues from outside attackers were identified.
- Ensure trust in the team as they have some control in the ecosystem.
- Date: December 23rd, 2021.
External Threat Results
|Arbitrary Storage Write||N/A||PASS|
|Centralization of Control||The owner is able to set a limit on how many tokens can be in a user's wallet at any time.||WARNING|
|Delegate Call to Untrusted Contract||N/A||PASS|
|Dependence on Predictable Variables||N/A||PASS|
|State Change External Calls||N/A||PASS|
|User Supplied Assertion||N/A||PASS|
|Critical Solidity Compiler||N/A||PASS|
|Overall Contract Safety||PASS|
($) = payable function # = non-constant function Int = Internal Ext = External Pub = Public + [Int] IERC20 - [Ext] totalSupply - [Ext] balanceOf - [Ext] transfer # - [Ext] allowance - [Ext] approve # - [Ext] transferFrom # + Context - [Int] _msgSender + Ownable (Context) - [Pub]
# - [Pub] owner - [Pub] renounceOwnership # - modifiers: onlyOwner - [Pub] transferOwnership # - modifiers: onlyOwner - [Int] _transferOwnership # + Token (IERC20, Ownable) - [Pub] # - modifiers: Ownable - [Pub] name - [Pub] symbol - [Pub] decimals - [Pub] totalSupply - [Ext] updateWhaleAmount # - modifiers: onlyOwner - [Ext] updateAntiWhale # - modifiers: onlyOwner - [Pub] approve # - [Int] _approve # - [Pub] allowance - [Pub] increaseAllowance # - [Ext] decreaseAllowance # - [Pub] updateWhitelistedAddressFromWhale # - modifiers: onlyOwner - [Ext] transferFrom # - [Ext] transfer # - [Ext] multiSend # - [Int] _transfer # - [Prv] _transferFee # - [Pub] isExcludedFromFee - [Ext] isTaxApplicable # - modifiers: onlyOwner - [Ext] changeTaxAddress # - modifiers: onlyOwner - [Ext] changeTaxPercentages # - modifiers: onlyOwner - [Ext] changeTaxFeePercent # - modifiers: onlyOwner - [Pub] excludeFromFee # - modifiers: onlyOwner - [Pub] includeInFee # - modifiers: onlyOwner - [Pub] balanceOf - [Pub] createVesting # - [Ext] createMultipleVesting # - [Pub] getReleaseTime - [Ext] claim # - [Ext] getReceiverIDs