JavaScript 不可用。

我们检测到浏览器禁用了 JavaScript。请启用 JavaScript 或改用支持的浏览器来继续访问

Edgeware Solidity 锁仓合约的判断失误[条件竞争攻击]

作者:Anban Chu

发表日期:2019年06月22日

所属目录:黑客攻击

合约地址

场景描述

这是一个未产生损失的合约,引起的是一个生成代码。

参与者可以通过 Edgeware 发布在以太坊上的 Lockdrop 合约进行锁仓,成功后会生成一份属于自己权限控制下的独立 Lock 合约。

function lock(Term term, bytes calldata edgewareAddr, bool isValidator)
    external
    payable
    didStart
    didNotEnd
{
    uint256 eth = msg.value;
    address owner = msg.sender;
    uint256 unlockTime = unlockTimeForTerm(term);
    // Create ETH lock contract
    Lock lockAddr = (new Lock).value(eth)(owner, unlockTime);
    // ensure lock contract has all ETH, or fail
    // ❌ 这一行可能会因为攻击而导致失败
    assert(address(lockAddr).balance == msg.value);
    emit Locked(owner, eth, lockAddr, term, edgewareAddr, isValidator, now);
}

Lock 合约的金额必须等于参与者锁仓时发送的金额,如果不等于,交易失败。这个失败会导致参与者的 Lock 合约瘫痪而形成拒绝服务,直接后果就是:假如攻击持续着,Edgeware 这个 Lockdrop 机制将不再可用。但这个漏洞对参与者的资金无影响。

攻击者可以通过 以太坊黄皮书 提前推测出参与者的 Lock 合约地址,只需提前往参与者的 Lock 合约地址随便转点 ETH 就好。这样用户的资金和合约内的 ETH 只要金额不想等,就会失败。

修复方式

assert(address(lockAddr).balance == msg.value);

改为:

assert(address(lockAddr).balance >= msg.value);

反思

尽量使用代理合约,可以实现合约升级。





以上就是本篇文章的全部内容了,希望对你有帮助。

>> 本站不提供评论服务,技术交流请在 Twitter 上找我 @anbang_account