diff --git a/Makefile b/Makefile index 7782d26..5f1fefa 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ clean :; forge clean # Remove modules remove :; rm -rf .gitmodules && rm -rf .git/modules/* && rm -rf lib && touch .gitmodules && git add . && git commit -m "modules" -install :; forge install cyfrin/foundry-devops@0.0.11 --no-commit && forge install smartcontractkit/chainlink-brownie-contracts@0.6.1 --no-commit && forge install foundry-rs/forge-std@v1.5.3 --no-commit && forge install openzeppelin/openzeppelin-contracts@v4.8.3 --no-commit +install :; forge install cyfrin/foundry-devops@0.1.0 --no-commit && forge install smartcontractkit/chainlink-brownie-contracts@0.6.1 --no-commit && forge install foundry-rs/forge-std@v1.5.3 --no-commit && forge install openzeppelin/openzeppelin-contracts@v4.8.3 --no-commit # Update Dependencies update:; forge update diff --git a/report.md b/report.md new file mode 100644 index 0000000..6188d03 --- /dev/null +++ b/report.md @@ -0,0 +1,208 @@ +# Aderyn Analysis Report + +This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a static analysis tool built by [Cyfrin](https://cyfrin.io), a blockchain security company. This report is not a substitute for manual audit or security review. It should not be relied upon for any purpose other than to assist in the identification of potential security vulnerabilities. +# Table of Contents + +- [Summary](#summary) + - [Files Summary](#files-summary) + - [Files Details](#files-details) + - [Issue Summary](#issue-summary) +- [High Issues](#high-issues) + - [H-1: Arbitrary `from` passed to `transferFrom` (or `safeTransferFrom`)](#h-1-arbitrary-from-passed-to-transferfrom-or-safetransferfrom) +- [Low Issues](#low-issues) + - [L-1: Centralization Risk for trusted owners](#l-1-centralization-risk-for-trusted-owners) + - [L-2: Unsafe ERC20 Operations should not be used](#l-2-unsafe-erc20-operations-should-not-be-used) + - [L-3: Missing checks for `address(0)` when assigning values to address state variables](#l-3-missing-checks-for-address0-when-assigning-values-to-address-state-variables) + - [L-4: `public` functions not used internally could be marked `external`](#l-4-public-functions-not-used-internally-could-be-marked-external) + - [L-5: Event is missing `indexed` fields](#l-5-event-is-missing-indexed-fields) + - [L-6: The `nonReentrant` `modifier` should occur before all other modifiers](#l-6-the-nonreentrant-modifier-should-occur-before-all-other-modifiers) + + +# Summary + +## Files Summary + +| Key | Value | +| --- | --- | +| .sol Files | 3 | +| Total nSLOC | 321 | + + +## Files Details + +| Filepath | nSLOC | +| --- | --- | +| src/DSCEngine.sol | 269 | +| src/DecentralizedStableCoin.sol | 29 | +| src/libraries/OracleLib.sol | 23 | +| **Total** | **321** | + + +## Issue Summary + +| Category | No. of Issues | +| --- | --- | +| High | 1 | +| Low | 6 | + + +# High Issues + +## H-1: Arbitrary `from` passed to `transferFrom` (or `safeTransferFrom`) + +Passing an arbitrary `from` address to `transferFrom` (or `safeTransferFrom`) can lead to loss of funds, because anyone can transfer tokens from the `from` address if an approval is made. + +- Found in src/DSCEngine.sol [Line: 308](src/DSCEngine.sol#L308) + + ```solidity + bool success = i_dsc.transferFrom(dscFrom, address(this), amountDscToBurn); + ``` + + + +# Low Issues + +## L-1: Centralization Risk for trusted owners + +Contracts have owners with privileged rights to perform admin tasks and need to be trusted to not perform malicious updates or drain funds. + +- Found in src/DecentralizedStableCoin.sol [Line: 42](src/DecentralizedStableCoin.sol#L42) + + ```solidity + contract DecentralizedStableCoin is ERC20Burnable, Ownable { + ``` + +- Found in src/DecentralizedStableCoin.sol [Line: 57](src/DecentralizedStableCoin.sol#L57) + + ```solidity + function burn(uint256 _amount) public override onlyOwner { + ``` + +- Found in src/DecentralizedStableCoin.sol [Line: 68](src/DecentralizedStableCoin.sol#L68) + + ```solidity + function mint(address _to, uint256 _amount) external onlyOwner returns (bool) { + ``` + + + +## L-2: Unsafe ERC20 Operations should not be used + +ERC20 functions may not behave as expected. For example: return values are not always meaningful. It is recommended to use OpenZeppelin's SafeERC20 library. + +- Found in src/DSCEngine.sol [Line: 280](src/DSCEngine.sol#L280) + + ```solidity + bool success = IERC20(tokenCollateralAddress).transferFrom(msg.sender, address(this), amountCollateral); + ``` + +- Found in src/DSCEngine.sol [Line: 299](src/DSCEngine.sol#L299) + + ```solidity + bool success = IERC20(tokenCollateralAddress).transfer(to, amountCollateral); + ``` + +- Found in src/DSCEngine.sol [Line: 308](src/DSCEngine.sol#L308) + + ```solidity + bool success = i_dsc.transferFrom(dscFrom, address(this), amountDscToBurn); + ``` + + + +## L-3: Missing checks for `address(0)` when assigning values to address state variables + +Check for `address(0)` when assigning values to address state variables. + +- Found in src/DSCEngine.sol [Line: 256](src/DSCEngine.sol#L256) + + ```solidity + s_DSCMinted[msg.sender] += amountDscToMint; + ``` + +- Found in src/DSCEngine.sol [Line: 278](src/DSCEngine.sol#L278) + + ```solidity + s_collateralDeposited[msg.sender][tokenCollateralAddress] += amountCollateral; + ``` + +- Found in src/DSCEngine.sol [Line: 297](src/DSCEngine.sol#L297) + + ```solidity + s_collateralDeposited[from][tokenCollateralAddress] -= amountCollateral; + ``` + +- Found in src/DSCEngine.sol [Line: 306](src/DSCEngine.sol#L306) + + ```solidity + s_DSCMinted[onBehalfOf] -= amountDscToBurn; + ``` + + + +## L-4: `public` functions not used internally could be marked `external` + +Instead of marking a function as `public`, consider marking it as `external` if it is not used internally. + +- Found in src/DecentralizedStableCoin.sol [Line: 57](src/DecentralizedStableCoin.sol#L57) + + ```solidity + function burn(uint256 _amount) public override onlyOwner { + ``` + +- Found in src/libraries/OracleLib.sol [Line: 20](src/libraries/OracleLib.sol#L20) + + ```solidity + function staleCheckLatestRoundData(AggregatorV3Interface chainlinkFeed) + ``` + +- Found in src/libraries/OracleLib.sol [Line: 37](src/libraries/OracleLib.sol#L37) + + ```solidity + function getTimeout(AggregatorV3Interface /* chainlinkFeed */ ) public pure returns (uint256) { + ``` + + + +## L-5: Event is missing `indexed` fields + +Index event fields make the field more quickly accessible to off-chain tools that parse events. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields). Each event should use three indexed fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three fields, all of the fields should be indexed. + +- Found in src/DSCEngine.sol [Line: 95](src/DSCEngine.sol#L95) + + ```solidity + event CollateralRedeemed(address indexed redeemFrom, address indexed redeemTo, address token, uint256 amount); // if + ``` + + + +## L-6: The `nonReentrant` `modifier` should occur before all other modifiers + +This is a best-practice to protect against reentrancy in other modifiers. + +- Found in src/DSCEngine.sol [Line: 183](src/DSCEngine.sol#L183) + + ```solidity + nonReentrant + ``` + +- Found in src/DSCEngine.sol [Line: 222](src/DSCEngine.sol#L222) + + ```solidity + nonReentrant + ``` + +- Found in src/DSCEngine.sol [Line: 255](src/DSCEngine.sol#L255) + + ```solidity + function mintDsc(uint256 amountDscToMint) public moreThanZero(amountDscToMint) nonReentrant { + ``` + +- Found in src/DSCEngine.sol [Line: 275](src/DSCEngine.sol#L275) + + ```solidity + nonReentrant + ``` + + + diff --git a/test/fuzz/continueOnRevert/ContinueOnRevertHandler.t.sol b/test/fuzz/continueOnRevert/ContinueOnRevertHandler.t.sol index 0c89b9c..01f7067 100644 --- a/test/fuzz/continueOnRevert/ContinueOnRevertHandler.t.sol +++ b/test/fuzz/continueOnRevert/ContinueOnRevertHandler.t.sol @@ -4,136 +4,112 @@ pragma solidity ^0.8.19; -// import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -// import {Test} from "forge-std/Test.sol"; +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { Test } from "forge-std/Test.sol"; // import { ERC20Mock } from "@openzeppelin/contracts/mocks/ERC20Mock.sol"; Updated mock location -// import { ERC20Mock } from "../../mocks/ERC20Mock.sol"; - -// import {MockV3Aggregator} from "../../mocks/MockV3Aggregator.sol"; -// import {DSCEngine, AggregatorV3Interface} from "../../../src/DSCEngine.sol"; -// import {DecentralizedStableCoin} from "../../../src/DecentralizedStableCoin.sol"; -// import {Randomish, EnumerableSet} from "../Randomish.sol"; -// import {MockV3Aggregator} from "../../mocks/MockV3Aggregator.sol"; -// import {console} from "forge-std/console.sol"; - -// contract ContinueOnRevertHandler is Test { -// using EnumerableSet for EnumerableSet.AddressSet; -// using Randomish for EnumerableSet.AddressSet; - -// // Deployed contracts to interact with -// DSCEngine public dscEngine; -// DecentralizedStableCoin public dsc; -// MockV3Aggregator public ethUsdPriceFeed; -// MockV3Aggregator public btcUsdPriceFeed; -// ERC20Mock public weth; -// ERC20Mock public wbtc; - -// // Ghost Variables -// uint96 public constant MAX_DEPOSIT_SIZE = type(uint96).max; - -// constructor(DSCEngine _dscEngine, DecentralizedStableCoin _dsc) { -// dscEngine = _dscEngine; -// dsc = _dsc; - -// address[] memory collateralTokens = dscEngine.getCollateralTokens(); -// weth = ERC20Mock(collateralTokens[0]); -// wbtc = ERC20Mock(collateralTokens[1]); - -// ethUsdPriceFeed = MockV3Aggregator( -// dscEngine.getCollateralTokenPriceFeed(address(weth)) -// ); -// btcUsdPriceFeed = MockV3Aggregator( -// dscEngine.getCollateralTokenPriceFeed(address(wbtc)) -// ); -// } - -// // FUNCTOINS TO INTERACT WITH - -// /////////////// -// // DSCEngine // -// /////////////// -// function mintAndDepositCollateral( -// uint256 collateralSeed, -// uint256 amountCollateral -// ) public { -// amountCollateral = bound(amountCollateral, 0, MAX_DEPOSIT_SIZE); -// ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); -// collateral.mint(msg.sender, amountCollateral); -// dscEngine.depositCollateral(address(collateral), amountCollateral); -// } - -// function redeemCollateral( -// uint256 collateralSeed, -// uint256 amountCollateral -// ) public { -// amountCollateral = bound(amountCollateral, 0, MAX_DEPOSIT_SIZE); -// ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); -// dscEngine.redeemCollateral(address(collateral), amountCollateral); -// } - -// function burnDsc(uint256 amountDsc) public { -// amountDsc = bound(amountDsc, 0, dsc.balanceOf(msg.sender)); -// dsc.burn(amountDsc); -// } - -// function mintDsc(uint256 amountDsc) public { -// amountDsc = bound(amountDsc, 0, MAX_DEPOSIT_SIZE); -// dsc.mint(msg.sender, amountDsc); -// } - -// function liquidate( -// uint256 collateralSeed, -// address userToBeLiquidated, -// uint256 debtToCover -// ) public { -// ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); -// dscEngine.liquidate( -// address(collateral), -// userToBeLiquidated, -// debtToCover -// ); -// } - -// ///////////////////////////// -// // DecentralizedStableCoin // -// ///////////////////////////// -// function transferDsc(uint256 amountDsc, address to) public { -// amountDsc = bound(amountDsc, 0, dsc.balanceOf(msg.sender)); -// vm.prank(msg.sender); -// dsc.transfer(to, amountDsc); -// } - -// ///////////////////////////// -// // Aggregator // -// ///////////////////////////// -// function updateCollateralPrice( -// uint128 newPrice, -// uint256 collateralSeed -// ) public { -// // int256 intNewPrice = int256(uint256(newPrice)); -// int256 intNewPrice = 0; -// ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); -// MockV3Aggregator priceFeed = MockV3Aggregator( -// dscEngine.getCollateralTokenPriceFeed(address(collateral)) -// ); - -// priceFeed.updateAnswer(intNewPrice); -// } - -// /// Helper Functions -// function _getCollateralFromSeed( -// uint256 collateralSeed -// ) private view returns (ERC20Mock) { -// if (collateralSeed % 2 == 0) { -// return weth; -// } else { -// return wbtc; -// } -// } - -// function callSummary() external view { -// console.log("Weth total deposited", weth.balanceOf(address(dscEngine))); -// console.log("Wbtc total deposited", wbtc.balanceOf(address(dscEngine))); -// console.log("Total supply of DSC", dsc.totalSupply()); -// } -// } +import { ERC20Mock } from "../../mocks/ERC20Mock.sol"; + +import { MockV3Aggregator } from "../../mocks/MockV3Aggregator.sol"; +import { DSCEngine, AggregatorV3Interface } from "../../../src/DSCEngine.sol"; +import { DecentralizedStableCoin } from "../../../src/DecentralizedStableCoin.sol"; +// import {Randomish, EnumerableSet} from "../Randomish.sol"; // Randomish is not found in the codebase, EnumerableSet +// is imported from openzeppelin +import { MockV3Aggregator } from "../../mocks/MockV3Aggregator.sol"; +import { console } from "forge-std/console.sol"; + +contract ContinueOnRevertHandler is Test { + // using EnumerableSet for EnumerableSet.AddressSet; + // using Randomish for EnumerableSet.AddressSet; + + // Deployed contracts to interact with + DSCEngine public dscEngine; + DecentralizedStableCoin public dsc; + MockV3Aggregator public ethUsdPriceFeed; + MockV3Aggregator public btcUsdPriceFeed; + ERC20Mock public weth; + ERC20Mock public wbtc; + + // Ghost Variables + uint96 public constant MAX_DEPOSIT_SIZE = type(uint96).max; + + constructor(DSCEngine _dscEngine, DecentralizedStableCoin _dsc) { + dscEngine = _dscEngine; + dsc = _dsc; + + address[] memory collateralTokens = dscEngine.getCollateralTokens(); + weth = ERC20Mock(collateralTokens[0]); + wbtc = ERC20Mock(collateralTokens[1]); + + ethUsdPriceFeed = MockV3Aggregator(dscEngine.getCollateralTokenPriceFeed(address(weth))); + btcUsdPriceFeed = MockV3Aggregator(dscEngine.getCollateralTokenPriceFeed(address(wbtc))); + } + + // FUNCTOINS TO INTERACT WITH + + /////////////// + // DSCEngine // + /////////////// + function mintAndDepositCollateral(uint256 collateralSeed, uint256 amountCollateral) public { + amountCollateral = bound(amountCollateral, 0, MAX_DEPOSIT_SIZE); + ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); + collateral.mint(msg.sender, amountCollateral); + dscEngine.depositCollateral(address(collateral), amountCollateral); + } + + function redeemCollateral(uint256 collateralSeed, uint256 amountCollateral) public { + amountCollateral = bound(amountCollateral, 0, MAX_DEPOSIT_SIZE); + ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); + dscEngine.redeemCollateral(address(collateral), amountCollateral); + } + + function burnDsc(uint256 amountDsc) public { + amountDsc = bound(amountDsc, 0, dsc.balanceOf(msg.sender)); + dsc.burn(amountDsc); + } + + function mintDsc(uint256 amountDsc) public { + amountDsc = bound(amountDsc, 0, MAX_DEPOSIT_SIZE); + dsc.mint(msg.sender, amountDsc); + } + + function liquidate(uint256 collateralSeed, address userToBeLiquidated, uint256 debtToCover) public { + ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); + dscEngine.liquidate(address(collateral), userToBeLiquidated, debtToCover); + } + + ///////////////////////////// + // DecentralizedStableCoin // + ///////////////////////////// + function transferDsc(uint256 amountDsc, address to) public { + amountDsc = bound(amountDsc, 0, dsc.balanceOf(msg.sender)); + vm.prank(msg.sender); + dsc.transfer(to, amountDsc); + } + + ///////////////////////////// + // Aggregator // + ///////////////////////////// + function updateCollateralPrice(uint128, /* newPrice */ uint256 collateralSeed) public { + // int256 intNewPrice = int256(uint256(newPrice)); + int256 intNewPrice = 0; + ERC20Mock collateral = _getCollateralFromSeed(collateralSeed); + MockV3Aggregator priceFeed = MockV3Aggregator(dscEngine.getCollateralTokenPriceFeed(address(collateral))); + + priceFeed.updateAnswer(intNewPrice); + } + + /// Helper Functions + function _getCollateralFromSeed(uint256 collateralSeed) private view returns (ERC20Mock) { + if (collateralSeed % 2 == 0) { + return weth; + } else { + return wbtc; + } + } + + function callSummary() external view { + console.log("Weth total deposited", weth.balanceOf(address(dscEngine))); + console.log("Wbtc total deposited", wbtc.balanceOf(address(dscEngine))); + console.log("Total supply of DSC", dsc.totalSupply()); + } +} diff --git a/test/fuzz/continueOnRevert/ContinueOnRevertInvariants.t.sol b/test/fuzz/continueOnRevert/ContinueOnRevertInvariants.t.sol index 8d5b237..17fdc8f 100644 --- a/test/fuzz/continueOnRevert/ContinueOnRevertInvariants.t.sol +++ b/test/fuzz/continueOnRevert/ContinueOnRevertInvariants.t.sol @@ -9,71 +9,69 @@ pragma solidity ^0.8.19; // // users cant create stablecoins with a bad health factor // // a user should only be able to be liquidated if they have a bad health factor -// import {Test} from "forge-std/Test.sol"; -// import {StdInvariant} from "forge-std/StdInvariant.sol"; -// import {DSCEngine} from "../../../src/DSCEngine.sol"; -// import {DecentralizedStableCoin} from "../../../src/DecentralizedStableCoin.sol"; -// import {HelperConfig} from "../../../script/HelperConfig.s.sol"; -// import {DeployDSC} from "../../../script/DeployDSC.s.sol"; +import { Test } from "forge-std/Test.sol"; +import { StdInvariant } from "forge-std/StdInvariant.sol"; +import { DSCEngine } from "../../../src/DSCEngine.sol"; +import { DecentralizedStableCoin } from "../../../src/DecentralizedStableCoin.sol"; +import { HelperConfig } from "../../../script/HelperConfig.s.sol"; +import { DeployDSC } from "../../../script/DeployDSC.s.sol"; // import { ERC20Mock } from "@openzeppelin/contracts/mocks/ERC20Mock.sol"; Updated mock location -// import { ERC20Mock } from "../../mocks/ERC20Mock.sol"; -// import {ContinueOnRevertHandler} from "./ContinueOnRevertHandler.t.sol"; -// import {console} from "forge-std/console.sol"; - -// contract ContinueOnRevertInvariants is StdInvariant, Test { -// DSCEngine public dsce; -// DecentralizedStableCoin public dsc; -// HelperConfig public helperConfig; - -// address public ethUsdPriceFeed; -// address public btcUsdPriceFeed; -// address public weth; -// address public wbtc; - -// uint256 amountCollateral = 10 ether; -// uint256 amountToMint = 100 ether; - -// uint256 public constant STARTING_USER_BALANCE = 10 ether; -// address public constant USER = address(1); -// uint256 public constant MIN_HEALTH_FACTOR = 1e18; -// uint256 public constant LIQUIDATION_THRESHOLD = 50; - -// // Liquidation -// address public liquidator = makeAddr("liquidator"); -// uint256 public collateralToCover = 20 ether; - -// ContinueOnRevertHandler public handler; - -// function setUp() external { -// DeployDSC deployer = new DeployDSC(); -// (dsc, dsce, helperConfig) = deployer.run(); -// (ethUsdPriceFeed, btcUsdPriceFeed, weth, wbtc) = helperConfig -// .activeNetworkConfig(); -// handler = new ContinueOnRevertHandler(dsce, dsc); -// targetContract(address(handler)); -// // targetContract(address(ethUsdPriceFeed)); Why can't we just do this? -// } - -// function invariant_protocolMustHaveMoreValueThatTotalSupplyDollars() -// public -// view -// { -// uint256 totalSupply = dsc.totalSupply(); -// uint256 wethDeposted = ERC20Mock(weth).balanceOf(address(dsce)); -// uint256 wbtcDeposited = ERC20Mock(wbtc).balanceOf(address(dsce)); - -// uint256 wethValue = dsce.getUsdValue(weth, wethDeposted); -// uint256 wbtcValue = dsce.getUsdValue(wbtc, wbtcDeposited); - -// console.log("wethValue: %s", wethValue); -// console.log("wbtcValue: %s", wbtcValue); - -// assert(wethValue + wbtcValue >= totalSupply); -// } - -// // function invariant_userCantCreateStabelcoinWithPoorHealthFactor() public {} - -// function invariant_callSummary() public view { -// handler.callSummary(); -// } -// } +import { ERC20Mock } from "../../mocks/ERC20Mock.sol"; +import { ContinueOnRevertHandler } from "./ContinueOnRevertHandler.t.sol"; +import { console } from "forge-std/console.sol"; + +contract ContinueOnRevertInvariants is StdInvariant, Test { + DSCEngine public dsce; + DecentralizedStableCoin public dsc; + HelperConfig public helperConfig; + + address public ethUsdPriceFeed; + address public btcUsdPriceFeed; + address public weth; + address public wbtc; + + uint256 amountCollateral = 10 ether; + uint256 amountToMint = 100 ether; + + uint256 public constant STARTING_USER_BALANCE = 10 ether; + address public constant USER = address(1); + uint256 public constant MIN_HEALTH_FACTOR = 1e18; + uint256 public constant LIQUIDATION_THRESHOLD = 50; + + // Liquidation + address public liquidator = makeAddr("liquidator"); + uint256 public collateralToCover = 20 ether; + + ContinueOnRevertHandler public handler; + + function setUp() external { + DeployDSC deployer = new DeployDSC(); + (dsc, dsce, helperConfig) = deployer.run(); + (ethUsdPriceFeed, btcUsdPriceFeed, weth, wbtc,) = helperConfig.activeNetworkConfig(); + handler = new ContinueOnRevertHandler(dsce, dsc); + targetContract(address(handler)); + // targetContract(address(ethUsdPriceFeed));// Why can't we just do this? + } + + /// forge-config: default.invariant.fail-on-revert = false + function invariant_protocolMustHaveMoreValueThatTotalSupplyDollars() public view { + uint256 totalSupply = dsc.totalSupply(); + uint256 wethDeposted = ERC20Mock(weth).balanceOf(address(dsce)); + uint256 wbtcDeposited = ERC20Mock(wbtc).balanceOf(address(dsce)); + + uint256 wethValue = dsce.getUsdValue(weth, wethDeposted); + uint256 wbtcValue = dsce.getUsdValue(wbtc, wbtcDeposited); + + console.log("wethValue: %s", wethValue); + console.log("wbtcValue: %s", wbtcValue); + + assert(wethValue + wbtcValue >= totalSupply); + } + + // function invariant_userCantCreateStabelcoinWithPoorHealthFactor() public {} + + /// forge-config: default.invariant.fail-on-revert = false + function invariant_callSummary() public view { + handler.callSummary(); + } +} diff --git a/test/fuzz/failOnRevert/StopOnRevertHandler.t.sol b/test/fuzz/failOnRevert/StopOnRevertHandler.t.sol index e0903f3..a4a175a 100644 --- a/test/fuzz/failOnRevert/StopOnRevertHandler.t.sol +++ b/test/fuzz/failOnRevert/StopOnRevertHandler.t.sol @@ -61,7 +61,7 @@ contract StopOnRevertHandler is Test { uint256 maxCollateral = dscEngine.getCollateralBalanceOfUser(msg.sender, address(collateral)); amountCollateral = bound(amountCollateral, 0, maxCollateral); - vm.prank(msg.sender); + //vm.prank(msg.sender); if (amountCollateral == 0) { return; }