Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: low
Invalid

Unsafe ERC20 Token Approval Pattern in Unregister Function

Summary

The unregister function in LLMOracleRegistry uses the unsafe ERC20 approval pattern by directly setting a new allowance without first setting it to zero.

This can lead to front-running vulnerabilities with certain ERC20 tokens.

Vulnerability Details

The contract increases allowance without first resetting it to zero:

function unregister(LLMOracleKind kind) public returns (uint256 amount) {
amount = registrations[msg.sender][kind];
if (amount == 0) {
revert NotRegistered(msg.sender);
}
delete registrations[msg.sender][kind];
emit Unregistered(msg.sender, kind);
// Unsafe: directly increases allowance without first setting to zero
token.approve(msg.sender, token.allowance(address(this), msg.sender) + amount);
}

Impact

Double-spend of tokens possible

Excess withdrawals beyond intended amounts

Direct loss of funds for the protocol

Tools Used

Manual Review

Recommendations

Use SafeERC20's safeApprove/safeIncreaseAllowance:

import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract LLMOracleRegistry is OwnableUpgradeable, UUPSUpgradeable {
using SafeERC20 for ERC20;
function unregister(LLMOracleKind kind) public returns (uint256 amount) {
amount = registrations[msg.sender][kind];
if (amount == 0) {
revert NotRegistered(msg.sender);
}
delete registrations[msg.sender][kind];
emit Unregistered(msg.sender, kind);
// Safely increase allowance
token.safeIncreaseAllowance(msg.sender, amount);
}
}

or Implement reset-and-approve pattern:

function unregister(LLMOracleKind kind) public returns (uint256 amount) {
amount = registrations[msg.sender][kind];
if (amount == 0) {
revert NotRegistered(msg.sender);
}
delete registrations[msg.sender][kind];
emit Unregistered(msg.sender, kind);
// Reset approval to 0 first
token.approve(msg.sender, 0);
// Then set to desired amount
token.approve(msg.sender, amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

[KNOWN] - Low-35 Unsafe use of transfer()/transferFrom() with IERC20

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.