CTF-MasterChef

题目源码;点击

要求是:
有一个 MasterChef 合约,它接受 MULA 代币并向质押者铸造 MUNY 作为奖励。

MULA 具有通缩转账税机制,每次转账会销毁 5% 的数量,以有效激励长期持有者。

你的任务是欺骗 MasterChef,使其为你铸造分配给所有质押者的所有 MUNY。你开始时拥有 10,000 MULA。

看到有源代码,和之前的质押合约很像,存款获得奖励,而我们就是要获得这个MdsterChef合约中全部的奖励,看到题目说有5%的手续费,初步想法就是会不会是溢出啥的,但是看到存取代码时,我并没有看见有对5%的手续费的说明

//_pid是流动池的ID
function deposit(uint256 _pid, uint256 _amount) public {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
updatePool(_pid);
if (user.amount > 0) {
uint256 pending =
user.amount.mul(pool.accMunyPerShare).div(1e12).sub(
user.rewardDebt
);
safeMunyTransfer(msg.sender, pending);
}
pool.lpToken.safeTransferFrom(
address(msg.sender),
address(this),
_amount
);
user.amount = user.amount.add(_amount);
user.rewardDebt = user.amount.mul(pool.accMunyPerShare).div(1e12);
emit Deposit(msg.sender, _pid, _amount);
}

// Withdraw LP tokens from MasterChef.
function withdraw(uint256 _pid, uint256 _amount) public {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount >= _amount, "withdraw: not good");
updatePool(_pid);
uint256 pending =
user.amount.mul(pool.accMunyPerShare).div(1e12).sub(
user.rewardDebt
);
safeMunyTransfer(msg.sender, pending);
user.amount = user.amount.sub(_amount);
user.rewardDebt = user.amount.mul(pool.accMunyPerShare).div(1e12);
pool.lpToken.safeTransfer(address(msg.sender), _amount);
emit Withdraw(msg.sender, _pid, _amount);
}

那么是不是就可以执行循环存取款,(题目也说了我们有10,000 MULA),获得奖励

攻击思路:就是通过循环存取款,获得奖励(注意,因为MulaToken合约中有自带的损失5%,所以最后攻击者还是的损失代币,不过是题目初始的,并不用担心)

其他的不用去纠结那么多,就是考察这个货币有没有通货紧缩代币支持