xanoutas/solidity-security-findings huggingface dataset:
"minimumRedemptionAmount"  and "minimumDepositAmount"   can be set low.
Audit: 2024-03-ondo-finance-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/ousgInstantManager.sol#L581
https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/ousgInstantManager.sol#L599


# Vulnerability details

## Impact
Detailed description of the impact of this finding.
_mint and  _redeem will be affected by setting the minimumDepositAmount and minimumRedemptionAmoun very low.
## Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.


here minimumDepositAmount and minimumRedemptionAmoun is initially initialized as
 100_000e6 and 50_000e6 respectfully.

  uint256 public constant FEE_GRANULARITY = 10_000;
 uint256 public minimumDepositAmount = 100_000e6;

 
  uint256 public minimumRedemptionAmount = 50_000e6;


here we are comparing minimumDepositAmount and minimumRedemptionAmount with respect to  FEE_GRANULARITY but There is a power of 10^6 difference between minimumDepositAmount and FEE_GRANULARITY. so we can set minimumDepositAmount very less.

 function setMinimumDepositAmount(
    uint256 _minimumDepositAmount
  ) external override onlyRole(CONFIGURER_ROLE) {
    require(
 @>>     _minimumDepositAmount >= FEE_GRANULARITY,
      "setMinimumDepositAmount: Amount too small"
    );

    emit MinimumDepositAmountSet(minimumDepositAmount, _minimumDepositAmount);
    minimumDepositAmount = _minimumDepositAmount;
  }


 function setMinimumRedemptionAmount(
    uint256 _minimumRedemptionAmount
  ) external override onlyRole(CONFIGURER_ROLE) {
    require(
 @>>     _minimumRedemptionAmount >= FEE_GRANULARITY,
      "setMinimumRedemptionAmount: Amount too small"
    );
    emit MinimumRedemptionAmountSet(
      minimumRedemptionAmount,
      _minimumRedemptionAmount
    );
    minimumRedemptionAmount = _minimumRedemptionAmount;
  }


Now we can redeem "usdcAmountToRedeem" can be very less ,around 0.1 USDC(FEE_GRANULARITY).

  function _redeem(
    uint256 ousgAmountIn
  ) internal returns (uint256 usdcAmountOut) {
    require(
      IERC20Metadata(address(usdc)).decimals() == 6,
      "OUSGInstantManager::_redeem: USDC decimals must be 6"
    );
    require(
      IERC20Metadata(address(buidl)).decimals() == 6,
      "OUSGInstantManager::_redeem: BUIDL decimals must be 6"
    );
    uint256 ousgPrice = getOUSGPrice();
    uint256 usdcAmountToRedeem = _getRedemptionAmount(ousgAmountIn, ousgPrice);

    require(
  @>>    usdcAmountToRedeem >= minimumRedemptionAmount,
      "OUSGInstantManager::_redeem: Redemption amount too small"
    );
    _checkAndUpdateInstantRedemptionLimit(usdcAmountToRedeem);

    if (address(investorBasedRateLimiter) != address(0)) {
      investorBasedRateLimiter.checkAndUpdateRedeemLimit(
        msg.sender,
        usdcAmountToRedeem
      );
    }

same thing with these 
function _mint(
    uint256 usdcAmountIn,
    address to
  ) internal returns (uint256 ousgAmountOut) {
    require(
Balance check in `_redeemBUIDL()` can cause `redeem()` to fail
Audit: 2024-03-ondo-finance-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/ousgInstantManager.sol#L388
https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/ousgInstantManager.sol#L458


# Vulnerability details

## Impact
When swapping BUIDL for USDC in `_redeemBUIDL()`, balance after check can potentially cause function to revert.

## Proof of Concept
Users are able to `redeem()` OUSG for USDC. In cases where OUSGInstantManager.sol does not hold enough USDC, BUIDL tokens are swapped for USDC.
>To source the USDC liquidity, this contract will hold the BUIDL token and interact with a currently unknown third party contract that swaps BUIDL for USDC. Unfortunately, the third party BUIDL-to-USDC swap functionality is not yet verified or confirmed as this time, but for the sake of this audit it can be assumed to be correct. The interface that this contract uses for BUIDL-to-USDC swaps has been inferred from public transactions on Etherscan. 1 BUIDL can always be assumed to be worth 1 USDC.

```solidity
    if (usdcAmountToRedeem >= minBUIDLRedeemAmount) {
      // amount of USDC needed is over minBUIDLRedeemAmount, do a BUIDL redemption
      // to cover the full amount
      _redeemBUIDL(usdcAmountToRedeem);
    } else if (usdcAmountToRedeem > usdcBalance) {
      // There isn't enough USDC held by this contract to cover the redemption,
      // so we perform a BUIDL redemption of BUIDL's minimum required amount.
      // The remaining amount of USDC will be held in the contract for future redemptions.
      _redeemBUIDL(minBUIDLRedeemAmount);
      emit MinimumBUIDLRedemption(
        msg.sender,
        minBUIDLRedeemAmount,
        usdcBalance + minBUIDLRedeemAmount - usdcAmountToRedeem
      );
    } else {
      // We have enough USDC sitting in this contract already, so use it
      // to cover the redemption and fees without redeeming more BUIDL.
      emit BUIDLRedemptionSkipped(
        msg.sender,
        usdcAmountToRedeem,
        usdcBalance - usdcAmountToRedeem
      );
    }
```
Within `_redeemBUIDL()`, the function keeps track of `usdcBalanceBefore` to ensure that the balance afterward equals `usdcBalanceBefore + buidlAmountToRedeem`.  However, this check poses a significant risk as it could potentially cause the entire function to revert. While the third party contract that swaps BUIDL for USDC is unknown. It is highly improbable for any liquidity pool to maintain a precisely 1:1 ratio for USDC/BUIDL. Consequently, even a minor discrepancy, such as a difference of 1 wei in the swap amount, could lead to the failure of the function.

## Tools Used
Manual Review
## Recommended Mitigation Steps
`_redeemBUIDL()` should make sure balance after is equal or greater than `usdcBalanceBefore + buidlAmountToRedeem`
```solidity
  function _redeemBUIDL(uint256 buidlAmountToRedeem) internal {
    require(
      buidl.balanceOf(address(this)) >= minBUIDLRedeemAmount,
      "OUSGInstantManager::_redeemBUIDL: I
Malicious KYC’d Users can Front-run Wrap/Unwrap Transactions in Their Favour
Audit: 2024-03-ondo-finance-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/rOUSG.sol#L415
https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/rOUSG.sol#L431


# Vulnerability details

## Impact
The `wrap` and `unwrap` functions allow users to exchange OUSG tokens for rOUSG tokens and vice versa. These functions calculate the number of rOUSG tokens to mint or burn based on the current price of OUSG tokens, as provided by an oracle. However, the contract does not implement any mechanisms to mitigate front-running.

Attackers could observe a large wrap or unwrap transaction in the mempool and execute trades that move the price of OUSG in their favor before the observed transaction is confirmed. This could allow the attacker to profit from the price change at the expense of the user performing the wrap or unwrap.

For users, the lack of front-running mitigation means the price they expect for their wrap or unwrap operation may not be the price they receive. This discrepancy can be exploited by front-runners to cause users to receive less value than anticipated.

## Proof of Concept
[Loc:](https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/rOUSG.sol#L415)
```solidity
function wrap(uint256 _OUSGAmount) external whenNotPaused {
    require(_OUSGAmount > 0, "rOUSG: can't wrap zero OUSG tokens");
    uint256 ousgSharesAmount = _OUSGAmount * OUSG_TO_ROUSG_SHARES_MULTIPLIER;
    _mintShares(msg.sender, ousgSharesAmount);
    ousg.transferFrom(msg.sender, address(this), _OUSGAmount);
    emit Transfer(address(0), msg.sender, getROUSGByShares(ousgSharesAmount));
    emit TransferShares(address(0), msg.sender, ousgSharesAmount);
  }
```

[Loc:](https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/rOUSG.sol#L431)
```solidity
function unwrap(uint256 _rOUSGAmount) external whenNotPaused {
    require(_rOUSGAmount > 0, "rOUSG: can't unwrap zero rOUSG tokens");
    uint256 ousgSharesAmount = getSharesByROUSG(_rOUSGAmount);
    if (ousgSharesAmount < OUSG_TO_ROUSG_SHARES_MULTIPLIER)
      revert UnwrapTooSmall();
    _burnShares(msg.sender, ousgSharesAmount);
    ousg.transfer(
      msg.sender,
      ousgSharesAmount / OUSG_TO_ROUSG_SHARES_MULTIPLIER
    );
    emit Transfer(msg.sender, address(0), _rOUSGAmount);
    emit TransferShares(msg.sender, address(0), ousgSharesAmount);
  }
```

### Scenario Setup

- Alice (a KYC'd user) intends to `wrap` a significant amount of OUSG tokens into rOUSG tokens, aiming to benefit from the interest-bearing mechanism of rOUSG.
- Eve (another KYC'd user with malicious intent) has set up a system to monitor the blockchain's mempool for significant `wrap` or `unwrap` transactions to execute a front-running attack.


### PoC Scenario Steps

1. Alice decides to `wrap` 10,000 OUSG tokens into rOUSG tokens. She creates the transaction and sends it to the blockchain network. The transaction enters the mempool but is not yet confirmed.

2. Eve's sy
OUSGInstantManager.sol incorrectly assumes 18 decimal from oracle 
Audit: 2024-03-ondo-finance-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/ousgInstantManager.sol#L479
https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/ousgInstantManager.sol#L278
https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/ousgInstantManager.sol#L388


# Vulnerability details

## Impact
OUSGInstantManager.sol relies on the [SHV ETF](https://etherscan.io/address/0xc04611C43842220fd941515F86d1DDdB15F04e46#readContract) price feed from Chainlink. However, the contract incorrectly assumes 18 decimals instead of 8 decimals. Consequently, the functions `_mint()` and `_redeem()` are likely to consistently fail. If no failures occur, the incorrect conversion rate between USDC and OUSG will lead to significant losses.

## Proof of Concept
OUSGInstantManager.sol utilizes RWAOracleExternalComparisonCheck.sol, which fetches the price feed from Chainlink to calculate the conversion rate between USDC and OUSG.
```solidity
  function getOUSGPrice() public view returns (uint256 price) {
    (price, ) = oracle.getPriceData();
    require(
      price > MINIMUM_OUSG_PRICE,
      "OUSGInstantManager::getOUSGPrice: Price unexpectedly low"
    );
  }
```
The function `getOUSGPrice()` incorporates a Minimum OUSG check to prevent the use of bad data by verifying `price` against `MINIMUM_OUSG_PRICE`. Notably, the constant `MINIMUM_OUSG_PRICE = 105e18` is defined in 18 decimals. However, the [SHV ETF](https://etherscan.io/address/0xc04611C43842220fd941515F86d1DDdB15F04e46#readContract) returns price values in 8 decimals.

This significant discrepancy is likely to cause `_mint()` and `_redeem()` to revert almost all the time. It is improbable for the SHV/USD price to increase by this much.

n the rare event of such occurrence, `_mint()` calculates a significantly larger `ousgAmountOut` in `_getMintAmount()`, where the price feed is incorrectly assumed to be in 18 decimals.

```solidity
  function _getMintAmount(
    uint256 usdcAmountIn,
    uint256 price
  ) internal view returns (uint256 ousgAmountOut) {
    uint256 amountE36 = _scaleUp(usdcAmountIn) * 1e18;
    ousgAmountOut = amountE36 / price;
  }
```

Conversely, for `_redeem()`, a significantly smaller `usdcAmountToRedeem` is calculated by `_getRedemptionAmount()` due to the incorrectly assumed 18 decimal price feed.
```solidity
  function _getRedemptionAmount(
    uint256 ousgAmountBurned,
    uint256 price
  ) internal view returns (uint256 usdcOwed) {
    uint256 amountE36 = ousgAmountBurned * price;
    usdcOwed = _scaleDown(amountE36 / 1e18); 
  }
```

## Tools Used
Manual Review
## Recommended Mitigation Steps
`MINIMUM_OUSG_PRICE` should be 105e8.
`_getMintAmount()` and `_getRedemptionAmount()` should also adjust accordingly.


## Assessed type

Decimal
In function mintRebasingOUSG()::approve can be exploited by once approval granted. [ FILE NAME :  ousgInstantManager.sol ]
Audit: 2024-03-ondo-finance-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L254-L276


# Vulnerability details

## Impact
Once approval granted it can be invoked at any time. and previously approved assets are drained by attacker contract.



## Proof of Concept
1.https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L254-L276

## Tools Used
Manual Audit

## Recommended Mitigation Steps
1.it’s best practice to call the safeIncreaseAllowance and safeDecreaseAllowance functions, as defined in OpenZeppelin's SafeERC20.


## Assessed type

Other
In function mintRebasingOUSG()::transfer() false returns are not able to be handled by this function.
Audit: 2024-03-ondo-finance-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L269
https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L451
https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L455
https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L824


# Vulnerability details

## Impact
Tokens not compliant with the ERC20 specification could return false from the transfer function call to indicate the transfer fails, while the calling contract would not notice the failure if the return value is not checked. Checking the return value is a requirement

## Proof of Concept
1.https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L269

2.https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L451

3.https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L455

4.https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L824

## Tools Used
Manual Audit

## Recommended Mitigation Steps
1.By using safeTransferFrom() to prevent this risk.





## Assessed type

ETH-Transfer
Incorrect Balance Check for BUIDL Redemptions Will Lead to Reverts and Partial Redemption Fulfillments
Audit: 2024-03-ondo-finance-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/ousgInstantManager.sol#L458


# Vulnerability details

## Impact
The `_redeemBUIDL` function checks if the contract holds at least minBUIDLRedeemAmount of BUIDL tokens before proceeding with a redemption operation. However, if the buidlAmountToRedeem is greater than the contract's BUIDL balance (but the balance is still above minBUIDLRedeemAmount), the contract might initiate a redemption operation that it cannot fulfill. This discrepancy could result in failed transactions, leading to operational delays and potentially causing a loss of user confidence.

By not verifying the contract's ability to cover the exact amount of buidlAmountToRedeem, there's a risk of financial inaccuracy. For example, the contract might promise more to the users than it can deliver based on its current BUIDL holdings, leading to discrepancies in the expected vs. actual transaction outcomes.

## Proof of Concept
[Loc:](https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/ousgInstantManager.sol#L458)

```solidity
function _redeemBUIDL(uint256 buidlAmountToRedeem) internal {
    require(
      buidl.balanceOf(address(this)) >= minBUIDLRedeemAmount,
      "OUSGInstantManager::_redeemBUIDL: Insufficient BUIDL balance"
    );
```

### Scenario Setup

Bob is an investor in the Ondo Finance ecosystem and holds rOUSG tokens. He is aware of the `OUSGInstantManager` contract's feature allowing the redemption of BUIDL tokens for USDC. Bob decides to utilize this feature, expecting a straightforward process as outlined by the platform.


### PoC Scenario Steps

1. Bob decides to redeem a substantial amount of BUIDL tokens through the `OUSGInstantManager` contract. He checks his rOUSG balance and prepares to initiate the redemption process.
2. Bob initiates the redemption transaction via the `OUSGInstantManager` contract, specifying an amount of BUIDL to redeem that, unbeknownst to him, exceeds the contract's current BUIDL balance.
3. Bob expects the smart contract to either process his redemption request successfully if sufficient BUIDL tokens are available or to fail gracefully, informing him of insufficient funds.
4. The `OUSGInstantManager` contract checks if it has at least `minBUIDLRedeemAmount` of BUIDL, not the actual `buidlAmountToRedeem` specified by Bob.
5. Given the incorrect balance check, the contract attempts to redeem the specified amount of BUIDL for USDC, despite not having enough BUIDL to fulfill Bob's request.

## Tools Used
Manual

## Recommended Mitigation Steps
The contract should implement a more precise balance check that compares the contract’s BUIDL balance directly against buidlAmountToRedeem rather than minBUIDLRedeemAmount. This ensures that the contract can only proceed with redemptions when it has enough BUIDL to cover the specific redemption request.


## Assessed type

Invalid Validation
Potential permanent DOS on `OUSGInstantManager::_redeem()` due to unupdated `usdcBalance`
Audit: 2024-03-ondo-finance-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L388-L456


# Vulnerability details

## Impact
Let's scrutinize the conditional statements in the code below. 

- [_redeem()](https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L388-L456)
	```solidity	
	function _redeem(
		uint256 ousgAmountIn
	) internal returns (uint256 usdcAmountOut) {
		...    
		uint256 usdcAmountToRedeem = _getRedemptionAmount(ousgAmountIn, ousgPrice);
		...
		uint256 usdcBalance = usdc.balanceOf(address(this));

		if (usdcAmountToRedeem >= minBUIDLRedeemAmount) {
			// amount of USDC needed is over minBUIDLRedeemAmount, do a BUIDL redemption
			// to cover the full amount
			_redeemBUIDL(usdcAmountToRedeem);
		} else if (usdcAmountToRedeem > usdcBalance) { // @audit `usdcBalance` should have been updated before reaching this point
			// There isn't enough USDC held by this contract to cover the redemption,
			// so we perform a BUIDL redemption of BUIDL's minimum required amount.
			// The remaining amount of USDC will be held in the contract for future redemptions.
			_redeemBUIDL(minBUIDLRedeemAmount);
			emit MinimumBUIDLRedemption(
				msg.sender,
				minBUIDLRedeemAmount,
				usdcBalance + minBUIDLRedeemAmount - usdcAmountToRedeem
			);
		} else {
			// We have enough USDC sitting in this contract already, so use it
			// to cover the redemption and fees without redeeming more BUIDL.
			emit BUIDLRedemptionSkipped(
				msg.sender,
				usdcAmountToRedeem,
				usdcBalance - usdcAmountToRedeem
			);
		}
		...
		usdc.transfer(msg.sender, usdcAmountOut);
	}
	```
If `usdcAmountToRedeem` happens to be greater than `minBUIDLRedeemAmount` and `usdcBalance`, it will satisfy two conditional statements. 

```solidity
if (usdcAmountToRedeem >= minBUIDLRedeemAmount) {
	_redeemBUIDL(usdcAmountToRedeem);
}
```
```solidity
else if (usdcAmountToRedeem > usdcBalance) {
	_redeemBUIDL(minBUIDLRedeemAmount);
	...
}
```
As you can see `_redeemBUIDL` will be invoked twice and transfers will be done twice as well. `usdcBalance` should have been updated prior to executing the second conditional statement `if (usdcAmountToRedeem > usdcBalance)`. If this scenario happens multiple times, this may cause permanent denial-of-service because more funds are forced to get transferred than what is necessary. 

## Proof of Concept
## Tools Used
Manual Review

## Recommended Mitigation Steps
Update the `usdcBalance` via `usdc.balanceOf(address(this))` just before it proceeds to the next conditional statement.


## Assessed type

DoS
Strict equality check on `OUSGInstantManager::_redeemBUIDL()` may cause denial-of-service
Audit: 2024-03-ondo-finance-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L458-L470


# Vulnerability details

## Impact
Let's inspect the code below. 
- [`_redeemBUIDL()`](https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L458-L470)
  ```solidity
  function _redeemBUIDL(uint256 buidlAmountToRedeem) internal {
      require(
        buidl.balanceOf(address(this)) >= minBUIDLRedeemAmount,
        "OUSGInstantManager::_redeemBUIDL: Insufficient BUIDL balance"
      );
      uint256 usdcBalanceBefore = usdc.balanceOf(address(this));
      buidl.approve(address(buidlRedeemer), buidlAmountToRedeem);
      buidlRedeemer.redeem(buidlAmountToRedeem);
      require(
        usdc.balanceOf(address(this)) == usdcBalanceBefore + buidlAmountToRedeem, // @audit dangerous strict equality check
        "OUSGInstantManager::_redeemBUIDL: BUIDL:USDC not 1:1"
      );
    }
  ```
Let's take a snippet out of the code above.
  - [`_redeemBUIDL() @ line 464-470`](https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/ousgInstantManager.sol#L464-L470)
    ```solidity
    buidlRedeemer.redeem(buidlAmountToRedeem);
    require(
      usdc.balanceOf(address(this)) == usdcBalanceBefore + buidlAmountToRedeem,
      "OUSGInstantManager::_redeemBUIDL: BUIDL:USDC not 1:1"
    );
    ```
Clearly, `buidlRedeemer.redeem(buidlAmountToRedeem)` is expected to transfer a USDC amount to `OUSGInstantManager` contract. Should there be calculations on `buidlRedeemer.redeem()` that slightly modifies `buidlAmountToRedeem` (even by tiniest dust figure) the function will revert. 

I understand that BUIDLRedeemer contract is out-of-scope but doing strict equality checks is generally not a good practice because the slightest "dust" discrepancies will revert the function.

## Proof of Concept
## Tools Used
Manual Review

## Recommended Mitigation Steps
1. Decide how much `DUST` is acceptable to maintain `BUIDL:USDC @ 1:1`.
2. Reimplement the `require` statement where `usdc.balanceOf(address(this))` fits within the range of `usdcBalanceBefore + buidlAmountToRedeem - DUST` and `usdcBalanceBefore + buidlAmountToRedeem + DUST`. If not, it should revert. 





## Assessed type

DoS