Closed sherlock-admin closed 1 year ago
Hi foxb868, we appreciate the description you've provided above. Unfortunately, we were unable to follow the reasoning here and are requesting clarification if you don't mind. Specifically, we're having trouble with the following assumptions:
The _redeemYT() function in the "codebase" uses the fdivUp() function to calculate the target balance, which can result in rounding errors that can be exploited by an attacker to drain funds from the contract. Specifically, the issue occurs when calculating the number of tokens to transfer from the adapter to the user when the "PTs" are at a loss and "YTs" had their principal cut to help cover the shortfall.
It is our understanding that fdivUp
is only used to calculate rewards with notify, not to determine how many Target tokens to transfer
In this case, the function calculates the remaining balance of YT tokens using the _reweightLScale() function, which returns a value that can be rounded down due to the division by integers, however, the fdivUp() function is used instead of fdiv() to round up the result, which can cause an error in favor of the attacker.
We don't believe _reweightLScale is used for this purpose, but only to update lscale
values for issuance, and for when somebody receives YTs
Closing based on Sponsor comments.
foxb868
high
'fdivUp()' function is used to calculate the target balance, which can result in rounding errors that an attacker can exploit to drain funds from the contract.
Summary
_redeemYT()
function uses thefdivUp()
function to calculate the target balance, this calculation can result in rounding errors that can be exploited by an attacker to drain funds from the contract.Vulnerability Detail
The
_redeemYT()
function in the "codebase" uses thefdivUp()
function to calculate the target balance, which can result in rounding errors that can be exploited by an attacker to drain funds from the contract. Specifically, the issue occurs when calculating the number of tokens to transfer from the adapter to the user when the "PTs" are at a loss and "YTs" had their principal cut to help cover the shortfall. In this case, the function calculates the remaining balance of YT tokens using the_reweightLScale()
function, which returns a value that can be rounded down due to the division by integers, however, thefdivUp()
function is used instead offdiv()
to round up the result, which can cause an error in favor of the attacker.Here is how an attacker can exploit and steal funds from the contract:
_reweightLScale()
function to calculate the remaining balance of YT tokens:(1,000 + 0) / ((1,000 / 10,000) + (0 / 5,000)) = 5,000
.1,000.fdivUp(10,000 / 5,000) = 500
. However, the correct number of tokens to transfer should be 1,000, since the contract still holds 5,000 PT tokens.The attacker repeats this process until they drain all the PT tokens from the contract.
Impact
The vulnerability could allow attackers to exploit rounding errors in the
_redeemYT()
function to steal funds from the contract.Code Snippet
https://github.com/sense-finance/sense-v1/blob/82abac25404d83b7aefaaeb46631f1d050dc4a4e/pkg/core/src/Divider.sol#L459 https://github.com/sense-finance/sense-v1/blob/82abac25404d83b7aefaaeb46631f1d050dc4a4e/pkg/core/src/Divider.sol#L459-L489
Tool used
Manual Review
Recommendation
The
_redeemYT()
function should use thefdiv()
function instead offdivUp()
to calculate the number of tokens to transfer.