Skip to content
This repository has been archived by the owner on Sep 17, 2023. It is now read-only.

bytes032 - Accounting error in _disburseTau can lead to inflated rewards #64

Closed
sherlock-admin opened this issue Mar 13, 2023 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label High A valid High severity issue Reward A payout will be made for this issue

Comments

@sherlock-admin
Copy link
Contributor

sherlock-admin commented Mar 13, 2023

bytes032

high

Accounting error in _disburseTau can lead to inflated rewards

Summary

This function _disburseTau() manages the distribution of tokens (Tau) to the holders of another token (collateralToken). The function is responsible for calculating and distributing the Tau tokens to the collateralToken holders based on the amount of collateral they hold.

The function first checks if there are any Tau tokens that have been withheld, meaning they have not yet been distributed to the collateralToken holders. If there are Tau tokens to distribute, the function proceeds to calculate the amount of Tau tokens to be distributed based on the amount of collateral currently held by the smart contract.

The calculation takes into account the time since the last disbursement and ensures that the disbursement occurs at a fixed interval (DRIP_DURATION). If the time elapsed since the last disbursement exceeds the fixed interval, then all of the Tau tokens withheld will be disbursed. Otherwise, a proportionate amount of Tau tokens will be disbursed based on the time elapsed.

The function then calculates the extra reward that each unit of collateral will receive based on the amount of Tau tokens to be disbursed and the current amount of collateral held by the contract. This reward is then added to the cumulative reward per unit of collateral.

Finally, the function updates the timestamp for the last disbursement and returns control to the calling function. Overall, the function ensures that the distribution of Tau tokens to collateralToken holders is fair and proportional to the amount of collateral they hold.

However, the function is not designed to work with collateral tokens where their decimals != 18.

Vulnerability Detail

 uint256 _currentCollateral = IERC20(collateralToken).balanceOf(address(this));

The function first fetches the collateral balance, which is later used to calculate the extraRewardPerCollateral

uint256 _extraRewardPerCollateral = (_tokensToDisburse * Constants.PRECISION) / _currentCollateral;

In order to prove the point, I've grabbed some values form the TauDripFeed test suite.
https://github.com/sherlock-audit/2023-03-taurus/blob/main/taurus-contracts/test-hh/Vault/00_RewardDripFeed.ts#L19

$$extraRewardPerCollateral = \dfrac{tokensToDisburse * 1e18}{currentCollateral}$$

So, using the formula for the extraRewardPerCollateral would be ~10000 tokens, if the collateral token is using 18 decimals.

$$10 001,6203703704e18 = \dfrac{50008101851851851851851 * 1e18}{5e18}$$

However, if the collateral is in any amount of decimals that is not 18, it would absolutely shatter the result.

$$10 001 620 370 370 370,3703702e18= \dfrac{50 008,1018518519e18 * 1e18}{5e6}$$

Impact

The reward system of the protocol will be broken if the collateral token decimals != 18.

Code Snippet

https://github.com/sherlock-audit/2023-03-taurus/blob/main/taurus-contracts/contracts/Vault/TauDripFeed.sol#L96
https://github.com/sherlock-audit/2023-03-taurus/blob/main/taurus-contracts/contracts/Vault/TauDripFeed.sol#L79

Tool used

Manual review

Recommendation

Multiply the tokensToDisburse by the decimals of the collateralToken.
(50008101851851851851851 * 1en) / 5en / 1e18 = 10 001,6203703704

- uint256 _extraRewardPerCollateral = (_tokensToDisburse * Constants.PRECISION) / _currentCollateral;
+ uint256 _extraRewardPerCollateral = (_tokensToDisburse * IERC20(collateralToken).decimals()) / _currentCollateral;

Duplicate of #35

@github-actions github-actions bot added High A valid High severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Mar 21, 2023
@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label Apr 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label High A valid High severity issue Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

1 participant