#34836 [SC-Medium] Malicious party can make it impossible for debt to be completely repaid by donating a few tbtc to `stBTC.sol`
Submitted on Aug 28th 2024 at 19:29:25 UTC by @Dliteofficial for Audit Comp | Acre
Report ID: #34836
Report Type: Smart Contract
Report severity: Medium
Target: https://sepolia.etherscan.io/address/0x7e184179b1F95A9ca398E6a16127f06b81Cb37a3
Impacts:
Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Description
Brief/Intro
Vulnerability Details
`stBTC.sol` is Acre's staking contract that allows user to deposit threshold btc (tbtc) in exchange for stBTC. At the pleasure of the owner address, with due diligence I would assume, an address can be granted the permission to mint stBTC without depositing tbtc into the contract. According to the NatSpec in `stBTC::totalAssets()`, this mechanism can also be used to balance the conversion rate between tbtc and stBTC.
However, as obtainable in the codebase, the change in conversion rate, artificial or natural, is not accounted for when the debtor tries to repay the debt in `stBTC::repayDebt()`. An attacker can take advantage of this, donate to the contract, effectively increasing the conversion rate. This way, when the debtor decides to repay the debt owed, they will be unable to repay because the value of the shares borrowed converted to asset is higher than what was initially borrowed when the function is expecting the original asset value.
```solidity function repayDebt( uint256 shares ) public whenNotPaused returns (uint256 assets) { assets = convertToAssets(shares);
>>> if (currentDebt[msg.sender] < assets) { revert ExcessiveDebtRepayment( msg.sender, currentDebt[msg.sender], assets ); }
>>> currentDebt[msg.sender] -= assets;
>>> totalDebt -= assets;
```
Impact Details
This is purely a griefing attack. This attack is quite cheap to execute (10 wei of tbtc as shown in the POC) but the impact is quite low. The attackers stands to gain nothing. At most, the conversion rate and total assets is inflated, and the debtor is unable to completely return the borrowed shares.
Recommendation
The code works for partial repayment, however, for full repayment, the debtor's current debt should be set to zero and totalDebt should also be set to zero if the debtor's repayment is last for all the borrowed assets.
References
Proof of Concept
``` // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0;
import { stBTC } from "contracts/stBTC.sol"; import "forge-std/Test.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract TDCDTest is Test{
} ```
Run this in your console:
``` forge test --match-contract DonationAttackTest --fork-url <FORK-URL> --fork-block-number 6237648 -vv ```