contract BoringBatchableWithDai is BaseBoringBatchable {
    IDaiPermit constant dai = IDaiPermit(0x6B175474E89094C44Da98b954EedeAC495271d0F); // DAI token contract
    
    /// @notice Call wrapper that performs `ERC20.permit` on `dai` using EIP 2612 primitive.
    /// Lookup `IDaiPermit.permit`.
    function permitDai(
        address holder,
        address spender,
        uint256 nonce,
        uint256 expiry,
        bool allowed,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public {
        dai.permit(holder, spender, nonce, expiry, allowed, v, r, s);
    }
    
    /// @notice Call wrapper that performs `ERC20.permit` on `token`.
    /// Lookup `IERC20.permit`.
    // F6: Parameters can be used front-run the permit and the user's permit will fail (due to nonce or other revert)
    //     if part of a batch this could be used to grief once as the second call would not need the permit
    function permitToken(
        IERC20 token,
        address from,
        address to,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public {
        token.permit(from, to, amount, deadline, v, r, s);
    }
}
/// @notice Extends `BoringBatchable` with DAI `permit()`.
function permitDai(
    address holder,
    address spender,
    uint256 nonce,
    uint256 expiry,
    bool allowed,
    uint8 v,
    bytes32 r,
    bytes32 s
) public {
    dai.permit(holder, spender, nonce, expiry, allowed, v, r, s);
}

/// @notice Call wrapper that performs `ERC20.permit` on `dai` using EIP 2612 primitive.
/// Lookup `IDaiPermit.permit`.