HIGH severity: `ERPeriodTransferEnforcer` gas optimizations. **Description:**
1. The current implementation of `_validateAndConsumeTransfer` performs several validations on every function call, even though some of these validations are only need to be performed once during the first execution for a given delegation hash. Since the terms of a delegation are...

Vulnerable code:
function _validateAndConsumeTransfer(
        bytes calldata _terms,
        bytes calldata _executionCallData,
        bytes32 _delegationHash,
        address _redeemer
    )
        private
    {
        ...

        // Validate terms
--      require(startDate_ > 0, "ERC20PeriodTransferEnforcer:invalid-zero-start-date");
--      require(periodDuration_ > 0, "ERC20PeriodTransferEnforcer:invalid-zero-period-duration");
--      require(periodAmount_ > 0, "ERC20PeriodTransferEnforcer:invalid-zero-period-amount");

        require(token_ == target_, "ERC20PeriodTransferEnforcer:invalid-contract");
        require(bytes4(callData_[0:4]) == IERC20.transfer.selector, "ERC20PeriodTransferEnforcer:invalid-method");

        // Ensure the transfer period has started.
--      require(block.timestamp >= startDate_, "ERC20PeriodTransferEnforcer:transfer-not-started");

        PeriodicAllowance storage allowance_ = periodicAllowances[msg.sender][_delegationHash];

        // Initialize the allowance on first use.
        if (allowance_.startDate == 0) {
            allowance_.periodAmount = periodAmount_;
            allowance_.periodDuration = periodDuration_;
            allowance_.startDate = startDate_;
            allowance_.lastTransferPeriod = 0;
            allowance_.transferredInCurrentPeriod = 0;

++          require(startDate_ > 0, "ERC20PeriodTransferEnforcer:invalid-zero-start-date");
++          require(periodDuration_ > 0, "ERC20PeriodTransferEnforcer:invalid-zero-period-duration");
++          require(periodAmount_ > 0, "ERC20PeriodTransferEnforcer:invalid-zero-period-amount");
++          require(block.timestamp >= startDate_, "ERC20PeriodTransferEnforcer:transfer-not-started");
        }

        ...
    }

function _validateAndConsumeTransfer(
        bytes calldata _terms,
        bytes calldata _executionCallData,
        bytes32 _delegationHash,
        address _redeemer
    )
        private
    {
        ...
        PeriodicAllowance storage allowance_ = periodicAllowances[msg.sender][_delegationHash];
        // Initialize the allowance on first use.
        if (allowance_.startDate == 0) {
            allowance_.periodAmount = periodAmount_;
            allowance_.periodDuration = periodDuration_;
            allowance_.startDate = startDate_;
--          allowance_.lastTransferPeriod = 0;
--          allowance_.transferredInCurrentPeriod = 0;
        }
        ...
    }

function _validateAndConsumeTransfer(
        bytes calldata _terms,
        bytes calldata _executionCallData,
        bytes32 _delegationHash,
        address _redeemer
    )
        private
    {
        emit TransferredInPeriod(
            msg.sender,
            _redeemer,
            _delegationHash,
            token_,
            periodAmount_,
            periodDuration_,
--          allowance_.startDate,
++          startDate_,
            allowance_.transferredInCurrentPeriod,
            block.timestamp
        );
    }