Dria

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

Enhancing balance validation in oracle registration and swan contract to improve robustness and user experience

Summary

The register function in the LLMOracleRegistry contract and purchase function in the Swan contract only checks the token allowance of the user before attempting to transfer the required stake. It does not verify if the user has a sufficient token balance, which can lead to unnecessary transaction reverts and wasted gas. Adding a balance check ensures a smoother user experience and robust contract functionality.

Vulnerability Details

The current implementation of the register function verifies that the user has allowed the contract to transfer the required stake amount. However, it does not check if the user’s token balance meets the stake requirement. If the balance is insufficient, the transferFrom function will revert, causing the transaction to fail and resulting in wasted gas. This check is necessary for a reliable and predictable registration process.

https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/llm/LLMOracleRegistry.sol#L106

https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/swan/Swan.sol#L298

like

https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/llm/LLMOracleCoordinator.sol#L165-L168

Add checking balance.

Impact

  • Gas Wastage: Users with sufficient allowance but insufficient balance will experience a transaction revert at the point of transfer, leading to unnecessary gas costs.

  • Poor User Experience: Without a balance check, users may face unexpected reverts and lack clarity on the reason for transaction failure, causing confusion and potentially affecting user trust.

Tools Used

Recommendations

Update the register function to include a balance check before attempting the token transfer. Here’s the modified code:

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);
}
// Check if the user has enough balance and allowance to stake
+ if (token.balanceOf(msg.sender) < amount) {
+ revert InsufficientFunds();
+ }
if (token.allowance(msg.sender, address(this)) < amount) {
revert InsufficientFunds();
}
// Transfer the tokens from the user to the contract
token.transferFrom(msg.sender, address(this), amount);
// Register the user
registrations[msg.sender][kind] = amount;
emit Registered(msg.sender, kind);
}

This ensures that the contract checks both balance and allowance, improving the user experience by providing clear, early feedback on registration requirements.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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