contract Chromia is ERC20, ERC20Detailed {
    uint8 public constant DECIMALS = 6;
    address private _minter;
    // one billion tokens with 6 decimals
    uint256 private _cap = 1000000000 * 1000000;

    event MinterSet(address indexed account);
    event TransferToChromia(address indexed from, bytes32 indexed to, uint256 value);
    event TransferFromChromia(address indexed to, bytes32 indexed refID, uint256 value);

    /**
     * @dev Constructor that gives msg.sender all of existing tokens.
     * @param minter the multi-sig contract address
     */
    constructor(address minter, uint256 initialBalance) public ERC20Detailed("Chroma", "CHR", DECIMALS) {
        _mint(msg.sender, initialBalance);
        _setMinter(minter);
    }

    modifier onlyMinter() {
        require(isMinter(msg.sender), "caller is not a minter");
        _;
    }
    
    function cap() public view returns (uint256) {
        return _cap;
    }

    /**
     * @dev Burns a specific amount of tokens and emit transfer event for Chromia
     * @param to The address to transfer to in Chromia.
     * @param value The amount of token to be burned.
     */
    function transferToChromia(bytes32 to, uint256 value) public {
        _burn(msg.sender, value);
        emit TransferToChromia(msg.sender, to, value);
    }

    /**
     * @dev Function to mint tokens
     * @param to The address that will receive the minted tokens.
     * @param value The amount of tokens to mint.
     * @return A boolean that indicates if the operation was successful.
     */
    function transferFromChromia(address to, uint256 value, bytes32 refID) public onlyMinter returns (bool) {
        _mint(to, value);
        emit TransferFromChromia(to, refID, value);
        return true;
    }
    
    function _mint(address account, uint256 value) internal {
        require(totalSupply().add(value) <= cap(), "ERC20Capped: cap exceeded");
        super._mint(account, value);
    }

    function isMinter(address account) public view returns (bool) {
        return _minter == account;
    }

    function _setMinter(address account) internal {
        _minter = account;
        emit MinterSet(account);
    }
    
    function changeMinter(address newMinter) public onlyMinter {
        _setMinter(newMinter);
    }
}
function transferToChromia(bytes32 to, uint256 value) public {
    _burn(msg.sender, value);
    emit TransferToChromia(msg.sender, to, value);
}

/**
 * @dev Burns a specific amount of tokens and emit transfer event for Chromia
 * @param to The address to transfer to in Chromia.
 * @param value The amount of token to be burned.
 */