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%,所以最后攻击者还是的损失代币,不过是题目初始的,并不用担心)
其他的不用去纠结那么多,就是考察这个货币有没有通货紧缩代币支持