Dria

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

Amount is not refunded when `LLMOracleRegistry::unregister` is called

Summary

In LLMOracleRegistry whenever register is called an amount is transferred from sender to the contract. However when user calls unregister that amount of stake sent when registering is not refunded.

Vulnerability Details

In LLMOracleRegistry::register() we can see that the user transfers a stake amount to the contract when registering

function register(LLMOracleKind kind) public {
uint256 amount = getStakeAmount(kind);
// ensure the user is not already registered
if (isRegistered(msg.sender, kind)) {
revert AlreadyRegistered(msg.sender);
}
// ensure the user has enough allowance to stake
if (token.allowance(msg.sender, address(this)) < amount) {
revert InsufficientFunds();
}
@--> token.transferFrom(msg.sender, address(this), amount);
// register the user
registrations[msg.sender][kind] = amount;
emit Registered(msg.sender, kind);
}

But when we observe the unregister function we see that the allowance is being restored to msg.sender i.e the stake has been re-approved, After that there's no transfer of stake amount back to user.

So when the user registers an oracle, unregisters it and try to register the oracle back looking at `register` the user will pay another stake amount making the user pay the stake amount 2x, which is not right.

For instance:
Bob calls register(LLMOracleKind), it executes successfully then Bob calls unregister
it also executes successfully but when Bob tries to call register again with the same Oracle kind
the register function will check for allowance and try to send the same stake amount from msg.sender to contract, making him pay stake amount twice.

function unregister(LLMOracleKind kind) public returns (uint256 amount) {
amount = registrations[msg.sender][kind];
// ensure the user is registered
if (amount == 0) {
revert NotRegistered(msg.sender);
}
// unregister the user
delete registrations[msg.sender][kind];
emit Unregistered(msg.sender, kind);
// approve its stake back
token.approve(msg.sender, token.allowance(address(this), msg.sender) + amount);
//@audit amount is not refunded back
}

Impact

User will lose his stake amount when he calls unregister.

Tools Used

manual review

Recommendations

Refund stake amount back to user when he calls unregister and add a fee mechanism to protect the implementation

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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