---
# System prepended metadata

title: '[2022-05-factory-dao] User can''t withdraw their deposit token if deposit token is a "Fee on transfer" token (PermissionlessBasicPoolFactory.sol)'
tags: [2022-05-factory dao, medium, c4]

---

# [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;
```