-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: update the FOT detector to check for external fees (#24)
* Add support for checking if token has external fees * use factoryV2 as sentinel test address * Add mock fot token and test cases * flat fee for external fees token and fix tests * detect external transfer failure * Rename to feeTakenOnTransfer and add mock token test * forge fmt * comment * remove debug logs * foundry.toml fix * fix foundry toml * remove rpc in foundry toml * comments * nit readability * forge fmt * custom error and comment * func name * comments - readability * var names * bubble up reason in unknown transfer error case * nit readability --------- Co-authored-by: ConjunctiveNormalForm <[email protected]>
- Loading branch information
1 parent
6101960
commit 4ce5b58
Showing
4 changed files
with
233 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity =0.8.19; | ||
|
||
import {ERC20} from "solmate/tokens/ERC20.sol"; | ||
|
||
contract MockFotTokenWithExternalFees is ERC20 { | ||
uint256 public taxBps; | ||
address public pair; | ||
|
||
constructor(uint256 _taxBps) ERC20("MockFotToken", "MFOT", 18) { | ||
taxBps = _taxBps; | ||
} | ||
|
||
function setPair(address _pair) external { | ||
pair = _pair; | ||
} | ||
|
||
function mint(address to, uint256 amount) external { | ||
_mint(to, amount); | ||
} | ||
|
||
// this token takes fees on ALL transfers, treating transfers to other addresses as sells | ||
function transfer(address to, uint256 amount) public override returns (bool) { | ||
balanceOf[msg.sender] -= amount; | ||
|
||
// Cannot overflow because the sum of all user | ||
// balances can't exceed the max uint256 value. | ||
uint256 feeAmount; | ||
unchecked { | ||
feeAmount = amount * taxBps / 10000; | ||
balanceOf[to] += amount - feeAmount; | ||
balanceOf[address(this)] += feeAmount; | ||
} | ||
|
||
emit Transfer(msg.sender, to, amount - feeAmount); | ||
|
||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity =0.8.19; | ||
|
||
import {ERC20} from "solmate/tokens/ERC20.sol"; | ||
import "v2-core/interfaces/IUniswapV2Pair.sol"; | ||
|
||
contract MockReentrancyFotToken is ERC20 { | ||
uint256 public taxBps; | ||
address public pair; | ||
|
||
constructor(uint256 _taxBps) ERC20("MockReentrancyFotToken", "MFOT", 18) { | ||
taxBps = _taxBps; | ||
} | ||
|
||
function setPair(address _pair) external { | ||
pair = _pair; | ||
} | ||
|
||
function mint(address to, uint256 amount) external { | ||
_mint(to, amount); | ||
} | ||
|
||
// this token takes a fee on all transfers, and swaps the fee on the V2 pair for external transfers (not buy/sells) | ||
function transfer(address to, uint256 amount) public override returns (bool) { | ||
balanceOf[msg.sender] -= amount; | ||
|
||
// Cannot overflow because the sum of all user | ||
// balances can't exceed the max uint256 value. | ||
uint256 feeAmount; | ||
unchecked { | ||
feeAmount = amount * taxBps / 10000; | ||
balanceOf[to] += amount - feeAmount; | ||
balanceOf[address(this)] += feeAmount; | ||
} | ||
|
||
// Only add in extra swap if is not buy/sell on the pair | ||
if (to != pair && msg.sender != pair) { | ||
IUniswapV2Pair(pair).token0() == address(this) | ||
? IUniswapV2Pair(pair).swap(0, feeAmount, address(this), new bytes(0)) | ||
: IUniswapV2Pair(pair).swap(feeAmount, 0, address(this), new bytes(0)); | ||
} | ||
|
||
emit Transfer(msg.sender, to, amount - feeAmount); | ||
|
||
return true; | ||
} | ||
} |