#48747 [SC-Insight] Consider emitting BucketConsumed for infinite buckets in RateLimiter
Submitted on Jul 7th 2025 at 15:05:33 UTC by @Blobism for Audit Comp | Folks Smart Contract Library
Report ID: #48747
Report Type: Smart Contract
Report severity: Insight
Target: https://github.com/Folks-Finance/algorand-smart-contract-library/blob/main/contracts/library/RateLimiter.py
Impacts:
Description
Brief/Intro
The RateLimiter method _consume_amount
currently does not emit a BucketConsumed
event. An off-chain system monitoring these events would never see consumption from infinite buckets, which could be misleading.
Vulnerability Details
The _consume_amount
method has an early return for infinite buckets (buckets with zero duration), shown below. It would be ideal to either emit a BucketConsumed
event at the early return, or clearly specify in the documentation that these events will not be emitted for infinite buckets.
def _consume_amount(self, bucket_id: Bytes32, amount: UInt256) -> None:
"""Consumes an amount inside a bucket.
Args:
bucket_id: The bucket to consume from.
amount: The amount to consume.
Raises:
AssertionError: If the bucket is unknown.
AssertionError: If there is insufficient capacity.
"""
# fails if bucket is unknown
self._update_capacity(bucket_id)
# ignore if duration is zero
rate_limit_bucket = self._get_bucket(bucket_id)
if not rate_limit_bucket.duration.native:
# <-------------- consider emitting BucketConsumed here
return
# ensure there is enough capacity
assert amount <= rate_limit_bucket.current_capacity, "Insufficient capacity to consume"
# consume amount
new_capacity = rate_limit_bucket.current_capacity.native - amount.native
self.rate_limit_buckets[bucket_id].current_capacity = ARC4UInt256(new_capacity)
emit(BucketConsumed(bucket_id, amount))
Impact Details
This is an insight for a code/documentation improvement, but does not have any security implications aside from impacting off-chain monitoring systems.
References
See contracts/library/RateLimiter.py
Proof of Concept
Proof of Concept
Observing the early return above should be sufficient to see that the event is not emitted for infinite buckets.
Was this helpful?