ERC20 metadata and ERC20Detailed

Greetings @abcoathup Andrew,

Thanks for your kind and prompt answers.

I reviewed ERC20, extensions, presets and security and I still have a few concerns that I would like to fully address before I decide importing OpenZeppelin Contracts instead of typing it myself; could you please help me understand the following topics:

  1. Since I need to deploy my contracts ASAP, I would most likely be using OpenZeppelin 3.x. Do I install it with
$ npm i @openzeppelin/contracts@3.0.1

or is there a later 3.x version?

  1. The reason I have a constructor with minting stages is because I need to ensure that certain supplies exists at different times. Can I replace my logic by simply calling the 3.x _mint function when I require it with the amount I require it?

  2. I need to set a maximun supply of tokens that will ever be minted. Would the ERC20Capped extension be used for this purpose and how? I would like to set up a 1.000.000 Tokens as Maximun Supply. Could you please review my New Contract Proposal below. :point_down:t2:

  3. I must ensure that the contract creator is the ONLY address able to mint, pause and possibly burn. I do not quite recall if I modified the Ownable function or created the PauseRole on my existing contact, but this security concern is the UPMOST CRITICAL for me. Could you please clarify if with 3.x my security concern is addressed; that is, the contract creator is the ONLY address with such priviledges. Is my concern addressed with ERC20PresetMinterPauser. Could you please review my New Contract Proposal below. :point_down:t2:

  4. Is the _burn function automatically available when deplying ERC20 or is it only available with ERC20Burnable? Are they different things? What is the difference?

  5. TokenTimeLock is not a required concern for me since we are not granting tokens to our core team (which is rather quite small and trustworthy) ahead of time. However, the ERCPausable is a requirement not for enforcing vesting periods but rather, for two main reasons: a) as a security measure in case there is a hack on a CEX or a DEX (as seen recently); and b) to pause all trading during voting periods. Could you please review my New Contract Proposal below. :point_down:t2:

  6. I would like to mint an initial supply during deployment. In this case, I would like to mint 9.000 tokens. Could you please review my New Contract Proposal below. :point_down:t2:

  7. Since ERC20Detailed has been integrated into 3.x, I would like to set up my name, symbol and decimals as follows: FilmVault, FilmVault, 9. Could you please review my New Contract Proposal below. :point_down:t2:

  8. The reason I typed my own contract instead of importing was due to a flattenning issue in order to verify the contract. I just reviewed Verifying a contract inheriting from OpenZeppelin Contracts and Deployed Preset ERC20 using Remix and can't verify - #2 by abcoathup Could you please confirm the latest and greatest the Flattening Process at the end. :point_down:t2:

New Contact Proposal

pragma solidity ^0.7.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract FilmVault_Token is ERC20, ERC20Capped, ERCPausable, ERC20PresetMinterPauser  {
    constructor (uint256 initialSupply, uint256 _cap) public ERC20 ("FilmVault", "FilmVault", 9) {
        _mint(msg.sender, 9000 * (10 ** uint256(decimals()))), cap (1000000 * (10 ** uint256(decimals()))) ;
    }
}

as supposed to

 **** ALL THE PREVIOUS TYPED CODE PLUS *****

contract FilmVault_Token is ERC20Pausable {

  using SafeERC20 for ERC20;
  address public creator;
  string public name;
  string public symbol;
  uint8 public decimals;
  uint256 public stage;
  uint256[13] private tokensToMint;

  constructor() public {

  creator = 0xbC57B9bb80DD02c882fcE8cf5700f8A2a003838E;
  name = "FilmVault";
  symbol = "FilmVault";
  decimals = 9;
  stage = 0;
  tokensToMint[0] = 9000000000000;
  tokensToMint[1] = 36000000000000;
  tokensToMint[2] = 100000000000000;
  tokensToMint[3] = 6000000000000;
  tokensToMint[4] = 49000000000000;
  tokensToMint[5] = 100000000000000;
  tokensToMint[6] = 100000000000000;
  tokensToMint[7] = 100000000000000;
  tokensToMint[8] = 100000000000000;
  tokensToMint[9] = 100000000000000;
  tokensToMint[10] = 100000000000000;
  tokensToMint[11] = 100000000000000;
  tokensToMint[12] = 100000000000000;
  }

  function mintFilmVault() public onlyOwner returns (bool) {
    require (stage <=12);
    _mint(creator, tokensToMint[stage]);
    stage = stage.add(1);
    return true;
  }
}

Flattening Process

$ npm init -y
$ npm i truffle
$ npx truffle init
$ npx truffle-flattener ./contracts/FilmVault_Token.sol > ./contracts/FlatFilmVault_Token.sol