Dria

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

Rewards are Not Actually Sent Just Allowance is Increased in `LLMOracleCoordinator` Contract

Summary

In the LLMOracleCoordinator contract, functions that “send rewards” to users increase the allowance for reward recipients instead of transferring the rewards directly. This allowance-based system requires recipients to perform additional steps to claim their rewards, as they must initiate another transaction to transfer the approved tokens from the contract to their own address. While this approach is not a vulnerability, it could lead to user confusion, higher gas costs, and potential operational inefficiencies. This report highlights all instances of this allowance-based reward system in the contract, analyzes its impact, and provides recommendations for improving usability.

Vulnerability Details

The contract uses an internal function, _increaseAllowance, to increase the allowance of reward recipients instead of directly transferring tokens to them. Here’s the _increaseAllowance function:

/// Increases the allowance by setting the approval to the sum of the current allowance and the additional amount.
/// @param spender spender address
/// @param amount additional amount of allowance
function _increaseAllowance(address spender, uint256 amount) internal {
feeToken.approve(spender, feeToken.allowance(address(this), spender) + amount);
}

The function increments the allowance for spender by the specified amount, enabling the recipient to spend the approved tokens from the contract address. However, the contract does not transfer these tokens immediately, leaving it up to the recipient to complete the transfer.

This approach is applied in several functions where the contract aims to “send rewards” to participants. Below are the main instances:

In finalizeValidation Function: In the finalizeValidation function, validators who submit scores within the desired threshold receive rewards via an increased allowance instead of a direct transfer.

if (generationScores[g_i] >= mean - generationDeviationFactor * stddev) {
_increaseAllowance(responses[taskId][g_i].responder, task.generatorFee);
}

Here, _increaseAllowance increments the responder’s allowance by task.generatorFee. However, the responder must perform an additional transaction to transfer the approved tokens from the contract to their own address.

In respond Function: When no validation is required for a task, the respond function provides rewards directly to the responder by increasing their allowance:

if (task.parameters.numValidations == 0) {
_increaseAllowance(msg.sender, task.generatorFee);
}

This allowance increase enables the responder to claim their reward without a validation process. However, the responder still needs an extra step to transfer the tokens, rather than receiving them directly.

In validate Function: Validators who submit valid scores receive their reward through an increased allowance, set in the validate function.

_increaseAllowance(validations[taskId][v_i].validator, task.validatorFee);

Here, each validator who meets the validation requirements has their allowance increased by task.validatorFee. As with other functions, the validator must then execute another transaction to claim the reward.

Impact

Since rewards are only set as allowances rather than transfers, unclaimed allowances could accumulate within the contract, leading to inconsistencies between the contract’s actual token balance and the expected reward allocations. The allowance-based model may conflict with the typical expectation of direct reward transfers. Most users expect rewards to be automatically delivered to their wallets without needing further action.

Tools Used

Manual Review

Recommendations

To enhance usability and align with user expectations, it’s recommended to replace the allowance-based reward system with direct token transfers wherever “send rewards” is intended.

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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