题目信息
- 题目: 13th Airdrop
- 作者: bobface
- 目标: 使 Airdrop 合约余额 <= 30 ETH
- 初始状态: Airdrop 有 60 ETH(6 个用户各 10 ETH)
漏洞分析
合约结构
contract Airdrop is IAirdrop {
mapping(address => uint256) public balances;
uint256 private savedContractBalance;
bool private entered = false;
function claim(address recipient) external notContract(recipient) {
savedContractBalance = address(this).balance;
require(!entered, "ReentrancyGuard: reentrant call");
entered = true;
(bool success, ) = msg.sender.call{value: balances[msg.sender]}("");
require(success, "Transfer failed.");
entered = false;
updateUserBalance();
}
function updateUserBalance() internal {
assembly {
function checkFunds(originalUserBalance, originalContractBalance)
-> newUserBalance
{
let expectedBalance := sub(originalContractBalance, originalUserBalance)
if iszero(gt(balance(address()), expectedBalance)) {
let diff := sub(expectedBalance, balance(address()))
newUserBalance := sub(newUserBalance, diff)
leave
}
return(0, 0) // 关键漏洞点!
}
mstore(0x0, caller())
mstore(0x20, 0)
let slot := keccak256(0x0, 0x40)
let originalContractBalance := sload(1)
let originalUserBalance := sload(slot)
sstore(slot, 0) // 先设为 0
let newUserBalance := checkFunds(originalUserBalance, originalContractBalance)
sstore(slot, newUserBalance) // 如果 return(0,0) 执行,这行不执行
}
}
}
漏洞点
在 updateUserBalance() 的 assembly 代码中:
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
















暂无评论内容