Open aress31 opened 3 years ago
This is clearly an issue with your code (as seen by the UniswapV2: TRANSFER_FAILED
).
An rgrep
for this yields one result :
$ rgrep "TRANSFER_FAILED" uniswap-v2-*
uniswap-v2-core/contracts/UniswapV2Pair.sol: require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
This is in the safeTransfer
function :
This mean uniswap is attempting to call transfer
but it's failing somehow (not enough balance, your token has a reentrency lock , ... who knows ?).
I have a few issues with this code tho :
0
minimums / maximums are criminally dangerous, this allows an attacker to sandwich your transactions, raising / lowering the price around yours, stealing all the money from your users. There are multiple way to get accurate prices, either ask your users to provide a price they are ok with themself (as how swaps are done on the router) or use an oracle.If you want to debug this better I think you would need to fork uniswap and removing the bytes override in the safe transfers (so you could get a meaning full revert message) (or use something like the javascript VM and debug opcode by opcode the transaction). I think the best advice I can give is just to read uniswap V2's code, it is probably way simpler that you think, it will remove all questions you have about uniswap V2 (how to compute tokens after a swap, how to do a swap / liquidity add) (all the hard part of bullet proofing and maths has already been done, just reading it mostly everything makes sense).
@Jorropo thanks for this complete answer. My first post litterally contains all the relavant code, not sure if the following code will make things clearer:
function _transfer(
address sender,
address recipient,
uint256 amount
) internal override notNull(amount) {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
require(
sender != recipient,
"_transfer: 'sender' cannot also be 'recipient'"
);
if (!_isExcludedFromPayingFees[sender]) {
amount = _beforeTokenTransfer(sender, amount);
}
uint256 senderBalance = _balances[sender];
require(
senderBalance >= amount,
"ERC20: transfer amount exceeds balance"
);
_balances[sender] = senderBalance - amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_,
uint256 totalSupply_,
address router_,
uint8 liquidityTax_
) ERC20(name_, symbol_) {
_decimals = decimals_;
_liquidityTax = liquidityTax_;
_minTokensRequiredBeforeSwap = 10**6 * 10**_decimals;
_uniswapV2Router = IUniswapV2Router02(router_);
address pair =
IUniswapV2Factory(_uniswapV2Router.factory()).getPair(
_uniswapV2Router.WETH(),
address(this)
);
// Pair not yet created
if (pair == address(0)) {
_uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
.createPair(_uniswapV2Router.WETH(), address(this));
} else {
_uniswapV2Pair = pair;
}
setIsExcludedFromPayingFees(address(this), true);
setIsExcludedFromPayingFees(owner(), true);
_mint(_msgSender(), totalSupply_ * (10**decimals_));
}
Its a really interesting suggestion that you made about using the pair directly rather than the router, however the pair doesn't export any swapping or liquifying function.
Also I vaguely heard about sandwich attacks and oracles but in a first time I would like to make this basic swap and liquify token works.
As you can see there is no lock
and the balance should be sufficient for the swap.
Does this additional code speaks to you?
EDIT: I tried to troubleshot the code a bit by commenting out the liquify function and the issue comes indeed from the swap
function... This is really weird since I meet all the requirements for the function to work!
I am in the process of implementing an ERC20 token with a basic add to liquidity feature, this is the relevant code snippet:
When deploying this token to ropsten and after having manually added liquidity to the pool, I am unable to buy the token.
See:
The contract address is: https://ropsten.etherscan.io/address/0x50c39e87a915910520e8cc2cf594ae2cc547b5d6
Could anyone please assist with this?