题目信息
- 挑战名称: 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



















暂无评论内容