Permit Vulnerabilities
Detects ERC-2612 permit implementation issues including front-running, nonce manipulation, and deadline bypass.
Permit Vulnerabilities
Overview
The permit vulnerability detector identifies issues in ERC-2612 permit() implementations and their usage. The permit function allows gasless approvals via off-chain signatures, but introduces vulnerabilities including front-running of permit transactions, nonce desynchronization, and missing deadline enforcement.
Why This Is an Issue
Permit signatures can be:
- Front-run: An attacker observes a pending
permittransaction and submits it first, potentially in a context that benefits them (e.g., before atransferFrom). - Replayed: If nonce handling is incorrect, the same permit signature can be used multiple times.
- Stolen: Permit signatures are valid until the deadline; if leaked, they can be used by anyone before expiry.
Protocols that combine permit + transferFrom in separate transactions are particularly vulnerable, as the permit can be front-run and the approval redirected.
How to Resolve
// Before: Separate permit and transfer -- front-runnable
function depositWithPermit(uint256 amount, uint8 v, bytes32 r, bytes32 s) external {
token.permit(msg.sender, address(this), amount, deadline, v, r, s);
token.transferFrom(msg.sender, address(this), amount);
}
// After: Atomic permit+transfer with try/catch for already-permitted
function depositWithPermit(uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external {
try token.permit(msg.sender, address(this), amount, deadline, v, r, s) {} catch {
// permit may have already been front-run -- check allowance
require(token.allowance(msg.sender, address(this)) >= amount, "Insufficient allowance");
}
token.transferFrom(msg.sender, address(this), amount);
}
Examples
Sample Sigvex Output
{
"detector_id": "permit-vulnerabilities",
"severity": "medium",
"confidence": 0.72,
"description": "permit() call at offset 0x48 followed by transferFrom() at offset 0x7c. If the permit is front-run and the approval is consumed by another contract, the transferFrom will fail, causing DoS.",
"location": { "function": "depositWithPermit(uint256,uint8,bytes32,bytes32)", "offset": 72 }
}
Detection Methodology
- Permit call detection: Identifies calls with the
permitselector (ERC-2612). - Atomicity check: Verifies whether
permitandtransferFromoccur atomically or can be separated. - Error handling: Checks for try/catch around permit calls to handle front-running gracefully.
- Deadline validation: Ensures deadline parameter is checked and not set to
type(uint256).max.
Limitations
- Off-chain permit signature leakage is not detectable at the bytecode level.
- DAI-style non-standard permit implementations may not be recognized.
Related Detectors
- Permit Frontrunning — permit nonce mismanagement
- Front Running — general front-running
- Signature Replay — signature replay