contract ERC20Migrator is Pausable, Ownable {
  BARTToken private _legacyToken;

  BARTToken private _newToken;

  /**
   * @param legacyToken address of the old token contract
   */
  constructor (address legacyToken) public {
    require(legacyToken != address(0), "legacyToken address is required");
    _legacyToken = BARTToken(legacyToken);
  }

  /**
   * @dev Returns the legacy token that is being migrated.
   */
  function legacyToken() public view returns (address) {
    return address(_legacyToken);
  }

  /**
   * @dev Returns the new token to which we are migrating.
   */
  function newToken() public view returns (address) {
    return address(_newToken);
  }

  /**
   * @dev Begins the migration by setting which is the new token that will be
   * minted. This contract must be a minter for the new token.
   * @param newTokenAddress the token that will be minted
   */
  function beginMigration(address newTokenAddress) public onlyOwner {
    require(address(_newToken) == address(0), "_newToken must be 0");
    require(newTokenAddress != address(0), "newTokenAddress cannot be 0");

    _newToken = BARTToken(newTokenAddress);

    bytes32 MINTER_ROLE = _newToken.MINTER_ROLE();
    require(_newToken.hasRole(MINTER_ROLE, address(this)), "ERC20Migrator must be a minter");
  }

  /**
   * @dev Burn part of an account's balance in the old token
   * and mints the same amount of new tokens for that account.
   * @param account whose tokens will be migrated
   * @param amount amount of tokens to be migrated
   */
  function migrate(address account, uint256 amount) public whenNotPaused {
    _legacyToken.burnFrom(account, amount);
    _newToken.mint(account, amount);
  }

  /**
   * @dev Burns all of an account's allowed balance in the old token
   * and mints the same amount of new tokens for that account.
   * @param account whose tokens will be migrated
   */
  function migrateAll(address account) public {
    uint256 balance = _legacyToken.balanceOf(account);
    uint256 allowance = _legacyToken.allowance(account, address(this));
    uint256 amount = Math.min(balance, allowance);
    migrate(account, amount);
  }

  function pause() external onlyOwner {
      _pause();
  }

  function unpause() external onlyOwner {
      _unpause();
  }
}
/**
 * @title ERC20Migrator
 * @dev This contract can be used to migrate an ERC20 token from one
 * contract to another, where each token holder has to opt-in to the migration.
 * To opt-in, users must approve for this contract the number of tokens they
 * want to migrate. Once the allowance is set up, anyone can trigger the
 * migration to the new token contract. In this way, token holders "turn in"
 * their old balance and will be minted an equal amount in the new token.
 * The new token contract must be mintable. For the precise interface refer to
 * OpenZeppelin's BARTToken, but the only functions that are needed are
 * `isMinter(address)` and `mint(address, amount)`. The migrator will check
 * that it is a minter for the token.
 * The balance from the legacy token will be burned by the migrator, as it
 * is migrated.
 */
function legacyToken() public view returns (address) {
  return address(_legacyToken);
}

/**
 * @dev Returns the legacy token that is being migrated.
 */