#35026 [SC-Low] `repayDebt` in stbtc returns a worng value
Submitted on Sep 2nd 2024 at 22:15:07 UTC by @Bx4 for Audit Comp | Acre
Report ID: #35026
Report Type: Smart Contract
Report severity: Low
Target: https://sepolia.etherscan.io/address/0x7e184179b1F95A9ca398E6a16127f06b81Cb37a3
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
wrong return value
Description
Brief/Intro
from our preview function and natspec comment we can deduce that `repayDebt` is supposed to return assets but it returns shares
Vulnerability Details
from the preview equivalent of the function; ```solidity function previewRepayDebt(uint256 shares) public view returns (uint256) { return convertToAssets(shares); } ``` we can see that the final return statement returns assets by converting from shares to assets
furthermore when we read the comments of `repayDebt` we will find this line; ` /// @return assets The amount of debt in asset paid off.` meaning the final return value that will be expected is assets, however there is `return shares;` at the end of the function overwriting everything and returning shares
Impact Details
This returns a wrong value to the caller
References
repayDebt comment - https://github.com/thesis/acre/blob/c3790ef2d4a5a11ae1cadcdaf72ce538b8d67dd3/solidity/contracts/stBTC.sol#L346
previewRepayDebt - https://github.com/thesis/acre/blob/c3790ef2d4a5a11ae1cadcdaf72ce538b8d67dd3/solidity/contracts/stBTC.sol#L533-L535
Proof of Concept
Proof of Concept
looking at `repayDebt` below ```solidity function repayDebt( uint256 shares @-> ) public whenNotPaused returns (uint256 assets) { assets = convertToAssets(shares);
...
... super._burn(msg.sender, shares); //@audit func is supposed to return debt in assets paid off but rather it returns shares
@-> return shares; } ``` we can tell from the function declaration that the function is supposed to return `assets`. However the last line returns shares which will overwrite previous intent of returning assets.
Another concept is; when you look at `previewRepayDebt` below; ```solidity /// @notice Previews the amount of assets that will be burned for the given /// amount of repaid shares. function previewRepayDebt(uint256 shares) public view returns (uint256) { return convertToAssets(shares); } ``` we will observe that the preview function return assets correctly unlike `repayDebt`. The reason why a reference is being made to `previewRepaydebt()` is because of the comments below; ``` /// @dev The debtor has to approve the transfer of the shares. To determine /// the asset debt that is going to be repaid, the caller can use /// the `previewRepayDebt` function. ``` from the comments we can deduce that the caller is supposed to use the preview function as a point of reference to determine the asset debt that is going to be repaid.
Hence, the outcome of `previewRepayDebt` is assets in debt to be repaid which is supposed to similar `repayDebt` but per our analysis we can see this is not true