// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {Script, console} from "forge-std/Script.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC3156FlashBorrower} from "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol"; import {SimpleERC3156FlashVault} from "../../contracts/flash/SimpleERC3156FlashVault.sol"; import {MinimalERC3156FlashBorrower} from "../../contracts/flash/MinimalERC3156FlashBorrower.sol"; /** * @title TestScaledFlash * @notice Sequential flashes: 1, 10, 100, 1000 USDT (6 decimals) against FLASH_VAULT. One borrower, fee prefunded per step. * * Env: PRIVATE_KEY, FLASH_VAULT; optional FLASH_VAULT_TOKEN (default official USDT 138). * * If vault.borrowerAllowlistEnabled(), deployer must be vault owner so the script can setBorrowerApproved. * * Usage: * forge script script/flash/TestScaledFlash.s.sol:TestScaledFlash --rpc-url $RPC_URL_138 --broadcast -vvvv */ contract TestScaledFlash is Script { address internal constant DEFAULT_USDT_138 = 0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1; function run() external { uint256 pk = vm.envUint("PRIVATE_KEY"); address deployer = vm.addr(pk); address vaultAddr = vm.envAddress("FLASH_VAULT"); address token = vm.envOr("FLASH_VAULT_TOKEN", DEFAULT_USDT_138); SimpleERC3156FlashVault vault = SimpleERC3156FlashVault(vaultAddr); require(!vault.borrowerAllowlistEnabled() || vault.owner() == deployer, "allowlist on: deployer must be vault owner"); uint256[4] memory amounts = [ uint256(1_000_000), uint256(10_000_000), uint256(100_000_000), uint256(1_000_000_000) ]; vm.startBroadcast(pk); MinimalERC3156FlashBorrower borrower = new MinimalERC3156FlashBorrower(vaultAddr); console.log("Borrower:", address(borrower)); if (vault.borrowerAllowlistEnabled()) { vault.setBorrowerApproved(address(borrower), true); } for (uint256 i = 0; i < amounts.length; i++) { uint256 amount = amounts[i]; uint256 fee = vault.previewFlashFee(token, amount); uint256 vb = IERC20(token).balanceOf(vaultAddr); require(vb >= amount, "vault liquidity < amount"); console.log("--- step", i + 1); console.log("amount (raw):", amount); console.log("fee (raw):", fee); console.log("vault before (raw):", vb); IERC20(token).transfer(address(borrower), fee); vault.flashLoan(IERC3156FlashBorrower(address(borrower)), token, amount, ""); console.log("vault after (raw):", IERC20(token).balanceOf(vaultAddr)); } vm.stopBroadcast(); console.log("Scaled ladder complete."); } }