code-423n4 / 2021-11-streaming-findings

0 stars 0 forks source link

Incorrect rewards are given to users #225

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

Handle

csanuragjain

Vulnerability details

Impact

More than expected rewards will be distributed to users

Proof of Concept

  1. Assume that user stake amount 10 using stake function of Stream contract
function stake(uint112 amount) public lock updateStream(msg.sender) {

...

        uint256 virtualBal = dilutedBalance(trueDepositAmt);
        ts.virtualBalance += virtualBal;
        totalVirtualBalance += virtualBal;
...

}
  1. Here we obtain virtual balance using dilutedBalance function which is like below:
function dilutedBalance(uint112 amount) internal view returns (uint256) {
        // duration / timeRemaining * amount
        if (block.timestamp < startTime) {
            return amount;
        } else {
            uint32 timeRemaining = endStream - uint32(block.timestamp);
            return ((uint256(streamDuration) * amount * 10**6) / timeRemaining) / 10**6;
        }
    }
  1. Since the amount here is 10 and assume Stream Duration was 100 and timeRemaining is 50 so the final formula would look like:
            uint32 timeRemaining = 50;
            return ((100 * 10 * 10**6) / 50) / 10**6;     // this returns 20
  1. As we can see the virtual balance is returned as 20. Virtual balance increases as stream go closer to end

  2. This is incorrect as now the earned function will give more rewards for this user even though he staked very late

Recommended Mitigation Steps

Virtual balance should be calculated properly

brockelmore commented 2 years ago

Incorrect understanding of the math. See here for some background: https://github.com/code-423n4/2021-11-streaming-findings/issues/82#issuecomment-985844418

The user is suppose to receive more than others because they are streaming their depositTokens faster than others

0xean commented 2 years ago

dupe of #82 (also invalid)