OnlyPwner - Proof of Work Writeup

OnlyPwner - Proof of Work Writeup-魔法少女雪殇
OnlyPwner - Proof of Work Writeup
此内容为付费阅读,请付费后查看
30
立即购买
您当前未登录!建议登陆后购买,可保存购买订单
付费阅读

题目信息

  • 挑战名称: Proof of Work
  • 作者: 3doc
  • 目标: 窃取至少一半的 DRK 代币供应量(≥ 10 ether)

题目背景

A friend told you about this weird DAO, folks raving all the time about vampires and darkness. They even created a DRK token. In one of their latest deliriums, they ended up claiming to have invented the concept of proof of work...

题目设置了一个看似复杂的"工作量证明"系统,用户需要通过 submitAssignment 和 checkAssignment 来完成挑战并成为合约的 owner。

合约分析

核心合约结构

contract ProofOfWork is IProofOfWork, Ownable {
    IERC20 public immutable darkToken;
    uint256 public immutable assignmentDuration;  // 1 分钟
    
    uint256 private difficulty;         // 初始值 uint64.max
    uint256 private minimumDarkness;    // 15 ether
    mapping(address => Assignment) assignment;
}

关键函数

submitAssignment:

function submitAssignment(address newOwner, uint256 referralCode) external {
    // 1. 创建 assignment
    newAssignment.challenge = uint256(blockhash(block.number - 1)) ^ block.timestamp;
    newAssignment.difficulty = difficulty;
    newAssignment.deadline = block.timestamp + assignmentDuration;
    assignment[newOwner] = newAssignment;
    
    // 2. 更新 difficulty(只增不减)
    unchecked {
        difficulty = difficulty << 1;
        difficulty += 1;
    }
    
    // 3. 调用 newOwner 的回调函数
    uint256 bet = IDireOwner(newOwner).workMyDirefulOwner(
        referralCode,
        newAssignment.challenge & newAssignment.difficulty
    );
    
    require(bet > 0);
    assignment[newOwner].bet = bet;
}

误导性分析

乍一看,这道题似乎需要暴力破解 proof:

require(
    uint256(keccak256(abi.encode(assignment[newOwner].challenge, proof))) &
    assignment[newOwner].difficulty == 0
);

difficulty 初始值为 uint64.max(64 位全 1),意味着需要找到一个 proof 使得 keccak256(challenge, proof) 的低 64 位全为 0。

  • 期望尝试次数:2^64 ≈ 1.8×10^19
  • 即使每秒计算 100 万次哈希,也需要约 58 万年

显然,暴力破解不是正确的解法。

漏洞发现

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容