diff --git a/src/adapters/MorphoRUSDAdapter.sol b/src/adapters/MorphoRUSDAdapter.sol index 02f79ac..352a19f 100644 --- a/src/adapters/MorphoRUSDAdapter.sol +++ b/src/adapters/MorphoRUSDAdapter.sol @@ -6,6 +6,7 @@ import {AccessControl} from "openzeppelin-contracts/contracts/access/AccessContr import {IERC4626} from "openzeppelin-contracts/contracts/interfaces/IERC4626.sol"; import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; +import {SafeCast} from "openzeppelin-contracts/contracts/utils/math/SafeCast.sol"; import {Stablecoin} from "../Stablecoin.sol"; import {IOracle} from "src/interfaces/IOracle.sol"; @@ -60,10 +61,15 @@ contract MorphoRUSDAdapter is IAssetAdapter, AccessControl { function redeem(uint256 shares) public onlyRole(CONTROLLER) { Stablecoin underlyingStablecoin = Stablecoin(address(underlying)); + + uint256 initialBalance = underlyingStablecoin.balanceOf(address(this)); + vault.redeem(shares, address(this), address(this)); - underlyingStablecoin.burn( - underlyingStablecoin.balanceOf(address(this)) - ); + + uint256 receivedAmount = underlyingStablecoin.balanceOf(address(this)) - + initialBalance; + + underlyingStablecoin.burn(receivedAmount); emit Redeem(msg.sender, shares, block.timestamp); } @@ -187,13 +193,13 @@ contract MorphoRUSDAdapter is IAssetAdapter, AccessControl { { int256 latestAnswer = underlyingPriceOracle.latestAnswer(); - return latestAnswer > 0 ? uint256(latestAnswer) : 0; + return latestAnswer > 0 ? SafeCast.toUint256(latestAnswer) : 0; } function _fundPriceOracleLatestAnswer() private view returns (uint256) { int256 latestAnswer = fundPriceOracle.latestAnswer(); - return latestAnswer > 0 ? uint256(latestAnswer) : 0; + return latestAnswer > 0 ? SafeCast.toUint256(latestAnswer) : 0; } function recover(address _token) external onlyRole(MANAGER) { diff --git a/test/morpho/MorphoRUSDAdapter.t.sol b/test/morpho/MorphoRUSDAdapter.t.sol index 4f548e7..8db5bca 100644 --- a/test/morpho/MorphoRUSDAdapter.t.sol +++ b/test/morpho/MorphoRUSDAdapter.t.sol @@ -255,6 +255,25 @@ contract MorphoRUSDAdapterTest is Test { assertEq(adapter.fundBalance(), metamorpho.balanceOf(address(adapter))); } + function test_redeem_with_accidental_sent_tokens( + uint256 depositAmount, + uint256 redeemAmount, + uint256 accidentalySentAmount + ) external { + vm.assume(depositAmount <= 1_000_000_000e18); + vm.assume(redeemAmount <= depositAmount); + vm.assume(accidentalySentAmount <= 1_000_000_000e18); + + adapter.deposit(depositAmount); + + deal(address(rusd), address(this), accidentalySentAmount, true); + rusd.transfer(address(adapter), accidentalySentAmount); + + adapter.redeem(redeemAmount); + + assertEq(rusd.balanceOf(address(adapter)), accidentalySentAmount); + } + //! DONT KNOW WHATS THE REAL CAP // function testDepositMoreThenCap(uint256 amount) external { // vm.assume(amount > CAP); @@ -330,4 +349,25 @@ contract MorphoRUSDAdapterTest is Test { vm.expectRevert(); adapter.setFundRiskWeight(riskWeight); } + + function test_recover(uint256 _amount) external { + ERC20 testToken = new ERC20("Test Token", "TTT"); + + deal(address(testToken), address(adapter), _amount); + + assertEq(testToken.balanceOf(address(this)), 0); + assertEq(testToken.balanceOf(address(adapter)), _amount); + + adapter.recover(address(testToken)); + + assertEq(testToken.balanceOf(address(this)), _amount); + assertEq(testToken.balanceOf(address(adapter)), 0); + } + + function test_recover_as_non_owner() external { + adapter.revokeRole(adapter.MANAGER(), address(this)); + + vm.expectRevert(); + adapter.recover(address(rusd)); + } }