ratePerSecond
field in the Stream
struct should be of type int256
instead of UD21x18
. This will allow for negative values, which can represent a decrease in tokens owed to the recipient.What is a negative rate per second?
A negative rate per second (rps) represents a decrease in tokens owed to the recipient over time. In other words, the recipient is essentially "paying back" tokens to the sender at a certain rate.
How does a negative rate per second work?
When a stream has a negative rps, the recipient's balance decreases over time. The rate at which the balance decreases is determined by the magnitude of the negative rps.
For example, let's say we have a stream with a negative rps of -10 tokens per second. This means that the recipient's balance will decrease by 10 tokens every second.
Why would we want to allow negative rates per second?
Allowing negative rates per second provides more flexibility in the protocol. Here are a few scenarios where negative rates might be useful:
Repayment of debt: A negative rate per second can be used to represent the repayment of debt. For example, if a recipient owes a sender 100 tokens, a negative rate per second can be used to gradually pay back the debt over time.
Penalty for non-payment: A negative rate per second can be used to impose a penalty on a recipient who fails to make payments on time. For example, if a recipient misses a payment, a negative rate per second can be applied to their balance to reflect the penalty.
Interest on loans: A negative rate per second can be used to represent interest on loans. For example, if a recipient borrows 100 tokens at an interest rate of 10% per annum, a negative rate per second can be used to calculate the interest owed over time.
This contract has three functions:
createStream
: Creates a new stream with the specified parameters.
updateBalance
: Updates the balance of the specified stream based on the rate per second and time elapsed.
getBalance
: Returns the current balance of the specified stream.
The updateBalance
function applies the rate per second to the balance, taking into account whether the rate is positive or negative. If the rate is negative, it subtracts the absolute value of the rate multiplied by the time elapsed from the balance. If the rate is positive, it adds the rate multiplied by the time elapsed to the balance.
The contract also ensures that the balance does not go below zero by setting it to zero if the new balance would be negative.
You can test this contract by creating a new stream with a negative rate per second, updating the balance, and then checking the balance to see how it has changed.
Here's an example of how you could test the contract:
This test creates a new stream with a negative rate per second, updates the balance, and then checks that the balance is less than the initial balance.
int256
for the ratePerSecond
variable, but instead use an unsigned integer type like uint256
, the impact would be that we cannot represent negative rates.Here are some potential issues that could arise:
Loss of functionality: By not allowing negative rates, we would be limiting the functionality of the Flow protocol. Negative rates can be useful in certain scenarios, such as when a recipient needs to repay a debt or when a penalty needs to be imposed.
Incorrect calculations: If we try to represent a negative rate using an unsigned integer type, the value would be interpreted as a very large positive number. This could lead to incorrect calculations and unexpected behavior in the protocol.
Overflow errors: When performing arithmetic operations on unsigned integers, overflow errors can occur if the result exceeds the maximum value that can be represented. This could happen if we try to calculate the balance of a stream with a large negative rate.
Security vulnerabilities: By not properly handling negative rates, we may introduce security vulnerabilities into the protocol. For example, an attacker could potentially exploit the protocol by creating a stream with a negative rate that causes the balance to overflow or underflow.
To illustrate the impact of not using int256
for the ratePerSecond
variable, let's consider an example:
In this example, we try to represent a negative rate using an unsigned integer type. However, the value is interpreted as a very large positive number, which leads to an incorrect calculation of the balance.
int256
for ratePerSecond
: In your codebase, you have a struct Stream
with a field ratePerSecond
of type UD21x18
. However, UD21x18
is a custom fixed-point type, and it may not be able to handle negative values. To allow for negative rates, it is recommended to use int256
as the type for ratePerSecond
. This will enable the representation of both positive and negative rates.Handle overflow and underflow: In your codebase, you have calculations involving ratePerSecond
and the balance of a stream. It is important to handle potential overflow and underflow scenarios. You can use safe arithmetic operations or libraries like OpenZeppelin's SafeMath to handle these scenarios.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.