Xinmin's Blog
AdminRSS
全部AIDeFiSolidity以太坊公链实战区块链行业观察
Admin
RSS

【以太坊】聊聊智能合约的闪电贷攻击

以太坊·2025年3月13日·1 次阅读·约 14 分钟
© 2026·

闪电贷攻击是个啥东东?

先打个生活中的比方:

想象一下你去银行借了一大笔钱,条件是得在离开柜台前还清。你坐在柜台前,拿这钱顺手跟旁边的人做了笔生意,赚了差价,再把钱还给银行,几分钟倒腾下来,口袋里就多了利润(当然这种操作是不现实的,这里只是帮助理解闪电贷——就是速借速还)。

闪电贷(Flash Loan)就类似这样:在区块链上,你能瞬间借入巨额资金,只要在同一笔交易里还回去就行,不需要抵押。听起来很妙吧?但这玩意儿要是没管好,就成了黑客掏空DeFi协议的“作案利器”。

闪电贷是DeFi里的一种创新工具,允许用户在单次以太坊交易中借入资金,用完后立即归还。如果还不上,交易就回滚,像没发生过。因为无需抵押,它常用于套利、清算等操作,但黑客也能利用它瞬间操控市场、搞乱价格,甚至洗劫资金池。今天我们就拿2021年的CREAM Finance攻击案,拆解这场“闪电贷血案”,看看是咋回事,又该咋防?

闪电贷攻击引发的“血案”

起因:DeFi协议的复杂设计

CREAM Finance是个借贷协议,2021年时在DeFi圈挺火。

它允许用户存入资产借贷,依赖多个协议(如去中心化交易所DEX和预言机)来定价和清算。但复杂的交互设计让它成了黑客眼中的目标。

2021年10月,黑客盯上了它的价格更新机制,策划了一场闪电贷攻击。

经过:漏洞被掏空

2021年10月27日,黑客对CREAM Finance发起攻击,几分钟内卷走超1.3亿美元。具体咋干的?

攻击者钱包地址:

0x24354d31bc9d90f62fe5f2454709c32049cf866b

攻击者合约地址:

https://etherscan.io/address/0x961d2b694d9097f35cfffa363ef98823928a330d#code

第一步:借入巨资

黑客从Aave借了价值约5亿美元的资产(包括ETH等多种代币),通过闪电贷瞬间拿到这笔巨资。

交易现场:

https://etherscan.io/tx/0x0fe2542079644e107cbf13690eb9c2c6594ccb7901be4f2275b3d2e2a1aa518d

第二步:搞乱价格

黑客用借来的ETH在Uniswap等DEX上大量交易CREAM相关代币,推高这些代币的价格,制造市场偏差。CREAM的预言机没及时更新,协议还以为一切正常。

第三步:套利跑路

趁着价格偏差,黑客在CREAM用高估的价格借出更多代币,趁市场高价卖出,低价回购后赚差价,最后还掉闪电贷,净赚1.3亿多美元。

影响:资金蒸发,信任崩盘

这次攻击让CREAM损失了1.3亿美元,用户资金被洗劫,协议信誉一落千丈。社区炸了锅,大家开始质疑DeFi的安全性,其他协议也赶紧加强防御。这事儿成了2021年DeFi史上的一大教训。

“血案”现场

想看攻击细节?戳这儿:

https://etherscan.io/tx/0x0fe2542079644e107cbf13690eb9c2c6594ccb7901be4f2275b3d2e2a1aa518d

关键手法:价格操纵

黑客的核心是借闪电贷瞬间砸盘,搞乱DEX价格,再趁CREAM反应慢套利,具体过程参考下方的简化代码。

致命漏洞:

CREAM依赖单一DEX价格或预言机更新太慢,黑客用闪电贷放大操作,在几秒内完成“借-砸-赚-还”。

还原攻击现场

漏洞合约(简版复现)

contract CreamVulnerable {
    address dex;        // DEX地址
    address token;      // 目标代币
    uint256 tokenPrice; // 代币价格

    constructor(address _dex, address _token) {
        dex = _dex;
        token = _token;
    }

    function updatePrice() public {
        tokenPrice = IDex(dex).getPrice(token); // 从DEX取即时价格
    }

    function borrow(uint256 amount) external {
        require(IERC20(token).balanceOf(address(this)) >= amount, "Not enough funds");
        IERC20(token).transfer(msg.sender, amount); // 借出代币
    }
}

contract FlashLoanAttack {
    address lendingPool;
    address dex;
    address cream;
    address token;

    constructor(address _lendingPool, address _dex, address _cream, address _token) {
        lendingPool = _lendingPool;
        dex = _dex;
        cream = _cream;
        token = _token;
    }

    function startAttack(uint256 amount) external {
        ILendingPool(lendingPool).flashLoan(amount);
    }

    function onFlashLoan(uint256 amount) external {
        // 1. 操纵DEX价格
        IERC20(token).approve(dex, amount);
        IDex(dex).swap(token, amount); // 推高价格
        // 2. 从Cream借出更多代币
        CreamVulnerable(cream).borrow(amount * 2);
        // 3. 套利并还款
        IDex(dex).swap(token, amount * 2); // 卖出赚差价
        ILendingPool(lendingPool).repayLoan(amount);
    }
}

攻击步骤

  1. 1. 第一步:借入巨资
    • 黑客从Aave借入5亿美元资产(包括ETH等多种代币)。
  2. 2. 第二步:搞乱价格
    • 用借来的ETH在DEX上大量交易,推高token价格。
  3. 3. 第三步:套利提款
    • 在CREAM用高估的价格借出更多代币,趁市场高价卖出,低价回购后赚差价。
  4. 4. 第四步:还贷跑路
    • 还掉闪电贷,利润归己。

通俗理解:黑客是咋赚钱的?

黑客就像在店里(CREAM合约)借了10个“账面200块”的包包,在市场上卖了500块(砸低市场价到50块),用250块(低价)回购5个包包还店里(店里以为值1000块,即CREAM合约的价格预言机还没更新到市场价),赚了250块。循环几次,赚翻了。这就是“高价借低价卖”的套路:用CREAM的高估价格借一堆,市场低价卖掉,再低价买回少量还债,差价就是利润。

被攻击的本质原因

  • 价格预言机缺陷:CREAM依赖自身更新较慢的价格预言机,容易被操纵。
  • 闪电贷放大效应:瞬间借贷让黑客能快速掌控市场。

咋防闪电贷攻击?

搞清楚漏洞在哪,就得堵上。以下是几招实用办法:

1. 用靠谱的预言机

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract SafeCream {
    AggregatorV3Interface priceFeed;

    constructor(address _priceFeed) {
        priceFeed = AggregatorV3Interface(_priceFeed);
    }

    function getPrice() public view returns (uint256) {
        (, int256 price,,,) = priceFeed.latestRoundData();
        return uint256(price);
    }
}

效果:用Chainlink等多源预言机,避开单一DEX价格风险。

2. 采用时间加权平均价格

contract TWAPCream {
    uint256[] prices;
    uint256 lastUpdate;

    function updatePrice(uint256 newPrice) external {
        if (block.timestamp - lastUpdate > 1 hours) {
            prices.push(newPrice);
            lastUpdate = block.timestamp;
        }
    }

    function getTWAP() public view returns (uint256) {
        uint256 sum = 0;
        for (uint256 i = 0; i < prices.length; i++) {
            sum += prices[i];
        }
        return sum / prices.length;
    }
}

效果:用时间加权平均价格(TWAP),防短期操纵。

3. 限制闪电贷规模

contract LimitedLendingPool {
    uint256 maxLoan = 1000 ether;

    function flashLoan(uint256 amount) external {
        require(amount <= maxLoan, "Loan too large");
        // 借贷逻辑
    }
}

效果:限制借款上限,降低市场冲击力。

4. 检查调用来源

contract SafeBorrow {
    function borrow(uint256 amount) external {
        require(msg.sender == tx.origin, "No external contract calls"); // 防闪电贷,注:tx.origin可被代理合约绕过,实际应使用更强防护
        IERC20(token).transfer(msg.sender, amount);
    }
}

效果:限制外部合约调用,挡住闪电贷入口(注:tx.origin易绕过,改为更安全检查)。

总结

闪电贷攻击是DeFi“快钱”带来的隐患。在CREAM事件里,黑客用5亿美元资产瞬间砸盘,套走1.3亿美元,暴露了CREAM依赖自身更新较慢的价格预言机的致命弱点。闪电贷本身无罪,关键看协议怎么设计。选用靠谱的预言机、限制借款规模,才能让这把‘双刃剑’趋利避害,为 DeFi 生态创造更多价值。


继续阅读

基于全文检索与主题相似度

以太坊2025年3月15日

【以太坊】聊聊智能合约的时间戳依赖攻击

说在前面 生活中,我们习惯了依赖时间来安排一切。闹钟提醒我们起床,高铁准点发车,考试到点交卷,股票交易精确到毫秒撮合…… 在 Web2 世界里,软件系统同样靠精准的时间戳来自动执行任务,比如定时扣款、会员到期、订单结算,这一切都建立在可信的时间基础上。但到了 Web3 世界里,时间居然能被“调表”!

以太坊2025年3月14日

【以太坊】聊聊智能合约的0转账钓鱼攻击

0转账钓鱼攻击是个啥? 0转账钓鱼攻击(Zero Transfer Phishing Attack)是一种简单却阴险的骗术,虽然技术含量不高,但在币圈屡屡得手,甚至酿成过惊天大案(见下文)。 每次听说这种攻击得逞,连我都忍不住暗想:这黑客咋不是我呢? 先打个生活中的比方: 假设你和好友张三经常通过银

以太坊2025年3月14日

【以太坊】聊聊智能合约的Permit2钓鱼攻击

说在前面 玩过币的人都知道,ERC20是以太坊上一个常见的代币标准(支持钱包交易交互),里面有个类似开支票的功能——approve授权和transferFrom转账兑现。 如同现实生活中你给人开了一张支票,写上金额,对方拿着支票去银行就能把钱取走。你账户里的钱少了,他的账户里钱多了。 在智能合约里,