Flow

Sablier
FoundryDeFi
20,000 USDC
View results
Submission Details
Severity: medium
Invalid

Metadata Update Handling

Summary

Unconditional emission of metadata update events leads to unnecessary gas costs, impacting contract usability.

Finding Description

The updateMetadata modifier is applied to the _update function, which is called whenever a stream is transferred. This modifier emits a MetadataUpdate event every time an update occurs, regardless of whether the underlying metadata needs to be refreshed. This can lead to inflated transaction costs for users, especially when transferring streams repeatedly without any actual change to the NFT metadata.

The security guarantee that is broken here is the efficiency of the contract operations. While this does not create a vulnerability in the traditional sense (e.g., reentrancy, overflow), it does create a usability issue by forcing users to incur higher gas fees.

A malicious user could exploit this inefficiency by creating a loop that repeatedly transfers streams to themselves, generating numerous metadata update events and thus escalating gas costs unnecessarily.

Vulnerability Details

  • Event Emission: The event emission is unconditional within the modifier.

  • Gas Efficiency: Each emission contributes to the gas used, leading to increased costs for users performing legitimate transactions.

Impact

This issue has been assessed as medium impact because while it does not directly compromise the security or integrity of the contract, it can severely affect user experience and operational costs, potentially discouraging users from interacting with the contract. Users may refrain from executing multiple legitimate transactions due to high costs.

Proof of Concept

modifier updateMetadata(uint256 streamId) {
_;
emit MetadataUpdate({ _tokenId: streamId });
}

In the above code, the metadata update is emitted every time the modifier is used, irrespective of whether the underlying data has changed.

Recommendations

To mitigate this issue, consider implementing conditional logic that checks if the metadata actually needs to be updated before emitting the event. This could involve comparing the current state of the NFT with the new state before triggering the event.

Suggested Code Snippet

modifier updateMetadata(uint256 streamId) {
address currentOwner = _ownerOf(streamId);
// Check if the stream metadata has changed before emitting the event
if (hasMetadataChanged(streamId, currentOwner)) {
emit MetadataUpdate({ _tokenId: streamId });
}
_;
}
// Helper function to determine if the metadata has changed
function hasMetadataChanged(uint256 streamId, address currentOwner) internal view returns (bool) {
// Implement logic to compare current metadata with the expected metadata
// Return true if there is a change; false otherwise
}

In this code, the hasMetadataChanged function would need to be implemented to actually check the state of the metadata and determine if it has changed before emitting the MetadataUpdate event.

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 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.