# [2022-05-factory-dao] User can't withdraw their deposit token if deposit token is a "Fee on transfer" token (PermissionlessBasicPoolFactory.sol) ###### tags: `c4`, `2022-05-factory dao`, `medium` ## Affected code * https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/PermissionlessBasicPoolFactory.sol#L180-L202 * https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/PermissionlessBasicPoolFactory.sol#L233 ## Impact User can withdraw their deposit amount and their reward ## Proof of Concept There are ERC20 tokens that may make certain customizations to their ERC20 contracts. One type of these tokens is deflationary tokens that charge a certain fee for every ```transfer()``` or ```transferFrom()``` So assume that the ```depositToken``` of ```PermissionlessBasicPool``` is a deflationary token, and there is just a user who deposits to the pool. Because ```pool.depositToken``` will take a fee on ```transferFrom()```, so after the [line](https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/PermissionlessBasicPoolFactory.sol#L198), the actual amount of ```depositToken``` that pool has gained will be less than ```receipt.amountDepositedWei```. ```solidity= IERC20(pool.depositToken).balaceOf(address(this)) < receipt.amountDepositedWei ``` This will lead to a bad scenario when the user tries to call ```withdraw()``` function, because the [transfer](https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/PermissionlessBasicPoolFactory.sol#L233) will be reverted (or return false) since there are not enough deposit tokens to transfer to the user. ## Tools Used Manual review ## Recommended Mitigation Steps Instead of setting ```receipt.amountDepositedWei = amount```, we can set it equal to the differences between ```IERC20(pool.depositToken).balanceOf(address(this))``` before and after ```transferFrom()``` [call](https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/PermissionlessBasicPoolFactory.sol#L198) ```solidity= // This code was modified from https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/PermissionlessBasicPoolFactory.sol#L192-L199 Receipt storage receipt = pool.receipts[pool.numReceipts]; receipt.id = pool.numReceipts; // don't set ```receipt.amountDepositedWei``` here // receipt.amountDepositedWei = amount; receipt.timeDeposited = block.timestamp; receipt.owner = msg.sender; uint balanceBefore = IERC20(pool.depositToken).balanceOf(address(this)); bool success = IERC20(pool.depositToken).transferFrom(msg.sender, address(this), amount); uint balanceAfter = IERC20(pool.depositToken).balanceOf(address(this)); require(success, 'Token transfer failed'); // set ```receipt.amountDepositedWei``` here receipt.amountDepositedWei = balanceAfter - balanceBefore; ```