Submitted by Ruhum, also found by immeas, John and rvierdiiev.
https://github.com/code-423n4/2023-04-rubicon/blob/main/contracts/utilities/poolsUtility/Position.sol#L350-L379 https://github.com/code-423n4/2023-04-rubicon/blob/main/contracts/utilities/poolsUtility/Position.sol#L271-L277 https://github.com/code-423n4/2023-04-rubicon/blob/main/contracts/BathHouseV2.sol#L113-L128
In Compound V2, both borrowers and suppliers are eligible to earn rewards. The Position contract allows users to create long/short positions for each market. For that, it both supplies and borrows tokens from a compound market. So while the user is the one who provided the initial tokens to open up a position, its the Position contract that holds the cTokens that earn the rewards. These rewards are not distributed to position owners. Instead, they are locked up as the Position contract never claims them. That also means that anybody else who uses the market has their rewards diluted.
Whenever cTokens are minted, transferred or burned, the Comptroller is notified to distribute rewards. When cTokens are minted, mintFresh() triggers Comptroller.mintAllowed() which distributes rewards through distributeSupplierComp().
The Position contract supplies and borrows tokens from the market when opening up a new position or updating an existing one:
In BathHouseV2 we can see that the protocol expects to use the Comptroller rewards mechanism. It calls claimComp() to harvest those rewards for the caller:
To claim the rewards, the Position contract also has to call claimComp(), but it never does. Thus, the rewards are accrued to the Position contract but never claimed.
The Position contract has to distribute rewards to users.
daoio (Rubicon) confirmed
HickupHH3 (judge) commented:
