contract PolyTradeToken is ERC20Permit {

    address public governance;

    // The timestamp after which minting may occur
    uint256 public mintAllowedAfter;

    // The timestamp after which burning may occur
    uint256 public burnAllowedAfter;

    // Minimum time between mints/burns
    uint32 public constant minimumTime = 1 days * 365;

    // Cap on the percentage of totalSupply that can be minted/burned at each mint/burn
    uint8 public constant cap = 2;

    event GovernanceChanged(address indexed oldGovernance, address indexed newGovernance);

    constructor(
        string memory name,
        string memory symbol,
        uint256 initialSupply,
        uint256 allowedAfter,
        address _governance,
        address account
    )
        ERC20(name, symbol)
        ERC20Permit(name)
    {   
        require(allowedAfter >= 0, "Minting/Burning can only begin after deployment");
        mintAllowedAfter = block.timestamp + allowedAfter;
        burnAllowedAfter = block.timestamp + allowedAfter;
        governance = _governance;
        _mint(account, initialSupply);
    }

    /**
     * @notice Change the governance address
     * @param _governance The address of the new governance
     */
    function setGovernance(address _governance) external {
        require(msg.sender == governance, "Unauthorised access");
        emit GovernanceChanged(governance, _governance);
        governance = _governance;
    }

    /**
     * @notice Mint new tokens
     * @param receiver The address of the destination account
     * @param amount The number of tokens to be minted
     */
    function mint(address receiver, uint amount) external {
        require(msg.sender == governance, "Unauthorized access");
        require(block.timestamp >= mintAllowedAfter, "minting not allowed yet");
        require(receiver != address(0), "cannot transfer to the zero address");

        // record the mint
        mintAllowedAfter = block.timestamp + minimumTime;

        // mint the amount
        require(amount <= ((totalSupply() * cap)/100), "exceeded mint cap");
        _mint(receiver, amount);
    }

    /**
     * @notice Burn tokens
     * @param amount The number of tokens to be burned
     * Tokens will be burned from governance account
     */
    function burn(uint amount) external {
        require(msg.sender == governance, "Unauthorized access");
        require(block.timestamp >= burnAllowedAfter, "burning not allowed yet");

        // record the mint
        burnAllowedAfter = block.timestamp + minimumTime;

        // mint the amount
        require(amount <= ((totalSupply() * cap)/100), "exceeded burn cap");
        _burn(governance, amount);
    }

}
function mint(address receiver, uint amount) external {
    require(msg.sender == governance, "Unauthorized access");
    require(block.timestamp >= mintAllowedAfter, "minting not allowed yet");
    require(receiver != address(0), "cannot transfer to the zero address");

    // record the mint
    mintAllowedAfter = block.timestamp + minimumTime;

    // mint the amount
    require(amount <= ((totalSupply() * cap)/100), "exceeded mint cap");
    _mint(receiver, amount);
}

/**
 * @notice Mint new tokens
 * @param receiver The address of the destination account
 * @param amount The number of tokens to be minted
 */