Hi , im getting subtract overflow on my masterchef contract, im doing the mint directly to masterchef not using sousChef.
i have even took apart staked users tokens and minted tokens, but depending on the amount it gives the error like, when a user deposit 10k tokens, and try to withdraw.
Code:
Code to reproduce
// Update reward variables of the given pool to be up-to-date.
function updatePool(uint256 _pid) public validatePool(_pid) {
PoolInfo storage pool = poolInfo[_pid];
if (block.number <= pool.lastRewardBlock) {
return;
}
if (pool.totalLp == 0 || pool.allocPoint == 0) {
pool.lastRewardBlock = block.number;
return;
}
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 zaifReward = multiplier.mul(zaifPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
uint256 totalRewardFees = zaifReward.mul(1500).div(10000);
//Total - 15% fees
uint256 zaifRewardUsers = zaifReward.sub(totalRewardFees);
uint256 totalminted = zaif.totalMinted();
if(totalminted >= 170000000000000000000000000){
pool.accZaifPerShare = 0;
}else{
zaif.mint(address(this),zaifRewardUsers);
//1% dev fee
zaif.mint(devaddr,zaifReward.mul(blockDevFee).div(10000));
//4% salary fee
zaif.mint(salaryAddress,zaifReward.mul(blockSalaryFee).div(10000));
//10% marketing fee
zaif.mint(marktAddress,zaifReward.div(10));
pool.accZaifPerShare = pool.accZaifPerShare.add(zaifRewardUsers.mul(1e12).div(pool.totalLp));
pool.lastRewardBlock = block.number;
}
}
// Deposit LP tokens to MasterZai for ZAIF allocation.
function deposit(uint256 _pid, uint256 _amount) public validatePool(_pid) nonReentrant {
require(block.number >= startBlock, "MasterChef:: Can not deposit before farm start");
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
updatePool(_pid);
if (user.amount > 0) {
uint256 pending = user.amount.mul(pool.accZaifPerShare).div(1e12).sub(user.rewardDebt);
if(pending > 0) {
safeZaifTransfer(msg.sender, pending);
}
}
if (_amount > 0) {
uint256 beforeDeposit = pool.lpToken.balanceOf(address(this));
pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount);
uint256 afterDeposit = pool.lpToken.balanceOf(address(this));
_amount = afterDeposit.sub(beforeDeposit);
if (pool.depositFeeBP > 0) {
uint256 depositFee = _amount.mul(pool.depositFeeBP).div(10000);
pool.lpToken.safeTransfer(feeAddress, depositFee);
if (address(pool.lpToken) == address(zaif)) {
totalZaifInPools = totalZaifInPools.add(_amount).sub(depositFee);
}
user.amount = user.amount.add(_amount).sub(depositFee);
pool.totalLp = pool.totalLp.add(_amount).sub(depositFee);
} else {
if (address(pool.lpToken) == address(zaif)) {
totalZaifInPools = totalZaifInPools.add(_amount);
}
user.amount = user.amount.add(_amount);
pool.totalLp = pool.totalLp.add(_amount);
}
}
user.rewardDebt = user.amount.mul(pool.accZaifPerShare).div(1e12);
emit Deposit(msg.sender, _pid, _amount);
}
// Withdraw LP tokens from MasterZai.
function withdraw(uint256 _pid, uint256 _amount) public validatePool(_pid) nonReentrant {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount >= _amount, "withdraw: not good");
//this will make sure that user can only withdraw from his pool
//cannot withdraw more than pool's balance and from MasterChef's token
require(pool.totalLp >= _amount, "Withdraw: Pool total LP not enough");
updatePool(_pid);
uint256 pending = user.amount.mul(pool.accZaifPerShare).div(1e12).sub(user.rewardDebt);
if(pending > 0) {
safeZaifTransfer(msg.sender, pending);
}
if(_amount > 0) {
user.amount = user.amount.sub(_amount);
pool.totalLp = pool.totalLp.sub(_amount);
if (address(pool.lpToken) == address(zaif)) {
totalZaifInPools = totalZaifInPools.sub(_amount);
}
pool.lpToken.safeTransfer(address(msg.sender), _amount);
}
user.rewardDebt = user.amount.mul(pool.accZaifPerShare).div(1e12);
emit Withdraw(msg.sender, _pid, _amount);
}
// Safe zaif transfer function, just in case if rounding error causes pool to not have enough ZAIFs.
function safeZaifTransfer(address _to, uint256 _amount) internal {
if(zaif.balanceOf(address(this)) > totalZaifInPools){
//zaifBal = total zaif in MasterChef - total zaif in zaif pools, this will make sure that MasterChef never transfer rewards from deposited zaif pools
uint256 zaifBal = zaif.balanceOf(address(this)).sub(totalZaifInPools);
if (_amount >= zaifBal) {
zaif.transfer(_to, zaifBal);
} else if (_amount > 0) {
zaif.transfer(_to, _amount);
}
}
}