We are trying to add liquidity using smart contract. we have deflationary tokens which charge fee on buy and sell of token. but when we are trying to addLiquidity using uniswap or pancake swap its also charging tax fee ,So to overcome this issue and to have add liquidity tax free we want to create custom addLiquidity function with disable fee and addLiquidity page on our own website so user can addLiquidity using that website .
function addLiquidity() external onlyOwner() {
_approve(address(this), address(uniswapV2Router), _tTotal);
uniswapV2Router.addLiquidityETH{value: address(this).balance}(address(this),balanceOf(address(this)),0,0,owner(),block.timestamp);
swapEnabled = true;
liquidityAdded = true;
// feeEnabled = true;
limitTX = true;
_maxTxAmount = 100000000 * 10**9; // 1%
_maxBuyAmount = 20000000 * 10**9; //0.2% buy cap
IERC20(pancakeswapPair).approve(address(uniswapV2Router),type(uint256).max);
}
function addLiquidityCustome1(address _tokenA,address _tokenB,uint _amountA,uint _amountB) external {
bool _temp_feeEnabled = feeEnabled;
feeEnabled = false;
IERC20(_tokenA).transferFrom(msg.sender, address(this), _amountA);
IERC20(_tokenB).transferFrom(msg.sender, address(this), _amountB);
IERC20(_tokenA).approve(routerAddress, _amountA);
IERC20(_tokenB).approve(routerAddress, _amountB);
(uint amountA, uint amountB, uint liquidity)=uniswapV2Router.addLiquidity(_tokenA,_tokenB,_amountA,_amountB,1,1,address(msg.sender),block.timestamp);
feeEnabled = _temp_feeEnabled;
emit CustomeAddLiquidityEvent(msg.sender,amountA,amountB,liquidity);
}
function addLiquidityCustome2(uint _tokenAmount,uint _ethAmount) external {
bool _temp_feeEnabled = feeEnabled;
feeEnabled = false;
_approve(address(this), address(uniswapV2Router), _tokenAmount);
(uint amountA, uint amountB, uint liquidity) = uniswapV2Router.addLiquidityETH{value: _ethAmount}(address(this),_tokenAmount,0,0,msg.sender,block.timestamp);
feeEnabled = _temp_feeEnabled;
emit CustomeAddLiquidityEvent(msg.sender,amountA,amountB,liquidity);
}
So for this
We have created 3 addliquidity functions showing above code 1st one is for only owner to set the initial price of token . 2nd and 3rd function addLiquidityCustome1 ,addLiquidityCustome2 are custom function. where user can addliquidity directly using our own website so we turn off fee while adding liquidity. but this functions are not working and throwing an error as -- Warning! Error encountered during contract execution [execution reverted]
please guide us how we can implement custom addLiquidity function in smart contract .so we can remove fee while adding liquidity and make it tax free . please help me out to solve this issue will really be a great help. as struggling on this from long. thank you so much in advance
please find error screenshot
error screenshot
Related
I am newbie to this field, and just learning some courses online about solidity and creating a simple contract, I would like to ask about a simple project that I try but not successful yet.
I want to create a swap function that can swap between 2 tokens that I created from ERC20, WITHOUT using uniswap or something like that, just dev a new function that swap between token A and token B, for example with the rate of 1 token A = 3 token B, the rate was ask to save in a mapping and got config at first, but I dont really know how to setting up the rate for swapping.
Could anyone help me out with this, many thanks guys.
Existed Code of Swap contract, just temporary :
// SPDX-License-Identifier: MIT
pragma solidity >= 0.7.0 <0.9.0;
import "./Token.sol";
import "./safemath.sol";
contract SwapToken {
using SafeMath for uint;
Token public token1;
address public owner1;
Token public token2;
address public owner2;
uint public amount1;
uint public amount2;
uint public swapRate;
constructor(
address _token1,
address _owner1,
address _token2,
address _owner2,
uint _amount1
) {
token1 = Token(_token1);
owner1 = _owner1;
token2 = Token(_token2);
owner2 = _owner2;
swapRate = 3;
amount1 = _amount1;
amount2 = _amount1.mul(swapRate);
}
function swap() public {
require(msg.sender == owner1 || msg.sender == owner2, "Not authorized from owners");
require(
token1.allowance(owner1, address(this)) >= amount1,
"Token 1 allowance too low"
);
require(
token2.allowance(owner2, address(this)) >= amount2,
"Token 2 allowance too low"
);
_safeTransferFrom(token1, owner1, owner2, amount1);
_safeTransferFrom(token2, owner2, owner1, amount2);
}
function _safeTransferFrom(
Token token,
address sender,
address recipient,
uint amount
) private {
bool sent = token.transferFrom(sender, recipient, amount);
require(sent, "Token transfer failed");
}
}
Let's start with a general answer and we'll build on it as we understand the question better.
I think you are not trying to create a swapping solution with a liquidity pool, but instead, want to match 2 people(?) that want to swap tokens.
A very simplistic approach to it could be
// have a mapping, as your tutor said. This will store information about how a token (token's contract address) and another token (again, contract address) rate against each other.
mapping(address => mapping (address => uint256)) rates;
function setRating(address memory token1, address memory token2, uint256 rate) public {
rates[token1][token2] = rate;
}
Then, while swapping, check the rate and calculate accordingly.
// you need to pass which token to swap and how much swap
function swap(address tokenIn, uint amountIn) public {
// you want only either of two owners call
require(
msg.sender == owner1 || msg.sender == owner2,
"Not authorized from owners"
);
require(
token1.allowance(owner1, address(this)) >= amount1,
"Token 1 allowance too low"
);
require(
token2.allowance(owner2, address(this)) >= amount2,
"Token 2 allowance too low"
);
// you need to require tokenIn is only token1 or token2 that you store in storage
require(
tokenIn == address(token1) || tokenIn == address(token2),
"Invalid token"
);
// make sure you pass positive amount
require(_amountIn > 0, "invalid amount");
// define token1 and token2 based on function arg tokenIn
bool isToken1 = tokenIn == address(token1);
( // you are using Token as type instead of IERC20
Token tokenIn,
Token tokenOut,
// reserve1 and reserve2 how many each tokens holds. you should be setting in state
uint reserve1,
uint reserve2
) = isToken1
? (token1, token2, reserve1, reserve2)
: (token2, token1, reserve2, reserve1);
// instead token1, tokenIn should be transferred
// I believe this is what it does
_safeTransferFrom(tokenIn, owner1, owner2, amount1);
// calculate the tokenOut including the fee=0.3%. user who wants to swap has to pay for fee
uint amountInAfterFee = (_amountIn * 997) / 1000;
// here you need to calculate how much y token will be taken out
// this is the formula dy=(y*dx)/(x+dx) y and x are reserves, dx is amountInAfterFee
amountOut =
(reserve2 * amountInAfterFee) /
(reserve1 + amountInAfterFee);
// now you need to send this amountOut to tokenOut or token2 in your contract
token2.transfer(msg.sender,amountOut)
// here update the reserves
// I dont think that you need this
// _safeTransferFrom(token2, owner2, owner1, amount2);
}
we are trying to add liquidity using smart contract.we have deflationary tokens which charge fee on buy and sell of token .but when we trying to addLiquidity using uniswap it also charge fee to overcome this issue we want to create custome addLiquidity function with disable fee and addLiquidity page on our own website so user can addLiquidity using that website .
function addLiquidity() external onlyOwner() {
_approve(address(this), address(uniswapV2Router), _tTotal);
uniswapV2Router.addLiquidityETH{value: address(this).balance}(address(this),balanceOf(address(this)),0,0,owner(),block.timestamp);
swapEnabled = true;
liquidityAdded = true;
// feeEnabled = true;
limitTX = true;
_maxTxAmount = 100000000 * 10**9; // 1%
_maxBuyAmount = 20000000 * 10**9; //0.2% buy cap
IERC20(pancakeswapPair).approve(address(uniswapV2Router),type(uint256).max);
}
function addLiquidityCustome1(address _tokenA,address _tokenB,uint _amountA,uint _amountB) external {
bool _temp_feeEnabled = feeEnabled;
feeEnabled = false;
IERC20(_tokenA).transferFrom(msg.sender, address(this), _amountA);
IERC20(_tokenB).transferFrom(msg.sender, address(this), _amountB);
IERC20(_tokenA).approve(routerAddress, _amountA);
IERC20(_tokenB).approve(routerAddress, _amountB);
(uint amountA, uint amountB, uint liquidity)=uniswapV2Router.addLiquidity(_tokenA,_tokenB,_amountA,_amountB,1,1,address(msg.sender),block.timestamp);
feeEnabled = _temp_feeEnabled;
emit CustomeAddLiquidityEvent(msg.sender,amountA,amountB,liquidity);
}
function addLiquidityCustome2(uint _tokenAmount,uint _ethAmount) external {
bool _temp_feeEnabled = feeEnabled;
feeEnabled = false;
_approve(address(this), address(uniswapV2Router), _tokenAmount);
(uint amountA, uint amountB, uint liquidity) = uniswapV2Router.addLiquidityETH{value: _ethAmount}(address(this),_tokenAmount,0,0,msg.sender,block.timestamp);
feeEnabled = _temp_feeEnabled;
emit CustomeAddLiquidityEvent(msg.sender,amountA,amountB,liquidity);
}
we have create 3 addliquidity functions 1st one is for onlyowener for set the initial price of token .
2nd and 3rd function addLiquidityCustome1 ,addLiquidityCustome2 are custome function. whare user can addliquidity directly using our own website so we turn off fee while adding liquidity.
function are not working.it throws an error .
Warning! Error encountered during contract execution [execution reverted]
please guide us how we can implement custome addLiquidity function in smart contract .so we can can remove fee while adding liquidity .
please help me out to solve this issue.it's much appreciated.
below error screen short attached please check.
enter image description here
I'm dealing with a strange issue with the safeTransferETH helper function in Uniswap V2's router contract.
I'm trying to swap tokens held by the contract to Uniswap for Ether, using the swapExactTokensForETH function provided by the Uniswap V2 router. (The function code is present on Uniswap's github in router1). The function being called is:
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
override
ensure(deadline)
returns (uint[] memory amounts)
{
require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH');
amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path);
require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT');
TransferHelper.safeTransferFrom(path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]);
_swap(amounts, path, address(this));
IWETH(WETH).withdraw(amounts[amounts.length - 1]);
TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
}
The only part of this code that is throwing an error is the TransferHelper.safeTransferETH function, which is:
function safeTransferETH(address to, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
}
My code is:
function uniV2ReceiveETH(address _token0, uint _amount0) public payable returns (uint[] memory amountsReceived) {
require(_amount0 > 0, "Must provide tokens if we want tokens in return!");
address[] memory path = new address[](2);
path[0] = _token0;
path[1] = WETH;
IERC20 token;
token = IERC20(_token0);
if (token.balanceOf(address(this)) > 0) {
_amount0 = token.balanceOf(address(this));
}
require(token.approve(address(uniV2Router), _amount0 + 10000), "approval failed");
// Swap logic
uint amountOutMin = UniswapV2Library.getAmountsOut(address(uniV2Factory), _amount0, path)[1];
amountsReceived = uniV2Router.swapExactTokensForETH(_amount0, amountOutMin, path, address(this), deadline);
uint endBalance = address(this).balance;
// Let everyone know we're done!
emit Swap(msg.sender, _amount0, endBalance);
}
A few other notes are:
The contract does receive ETH from other addresses without issue.
I am using hardhat, and a forked version of the mainnet to test.
The contract also works with the Uniswap router's other swap functions, including SwapExactETHForTokens and SwapExactTokensForTokens.
I solved this issue by having a payable fallback function by defining it as:
fallback() external payable { }
inside my smart contract.
Add to your contract.
receive() external payable {}
fallback() external payable {}
I'm using HashLips' new LowGasFees smart contract. I'm deploying on Polygon network, and I´m minting all NFTs into my opensea to sell later on in batches. So no DAPP involved.
For me to be safe in terms of avoiding free-minters, I put the cost to 100 ether, that would be 100 matic. But whenever I test through Remix or even through contract itself on polygon scan, it never shows the cost added, only gas fees. Which are way above normal price on mainnet don't know why (~0,47 MATIC when normal is like ~0,005-0,007 MATIC).
What could be the reason of this? Is this normal? I don't want anyone to snipe my nfts for pennies whenever I unpause the contract.
This is how I set up my public props
string public uriPrefix = "";
string public uriSuffis = ".json";
string public hiddenMetadataUri;
uint256 public cost = 100 ether;
uint256 public maxSupply = 10000;
uint256 public maxMintAmountPerTx = 50;
bool public paused = true;
bool public revealed = true;
This is how the mint works:
function mint(uint256 _mintAmount) public payable mintCompliance(_mintAmount) {
require(!paused, "Contract is paused");
if (msg.sender != owner()) {
require(msg.value >= cost * _mintAmount, "Insufficient funds!");
}
_mintLoop(msg.sender, _mintAmount);
}
function _mintLoop(address _receiver, uint256 _mintAmount) internal {
for(uint256 i = 0; i < _mintAmount; i++) {
supply.increment();
_safeMint(_receiver, supply.current());
}
}
I also wish to be able to modify the maxSupply on runtime, so I made this setter function, not really sure if it's okay or if there's something else to check on that I could have missed.
function setMaxSupply(uint256 _maxSupply) public onlyOwner {
require(_maxSupply >= supply.current(), "You can't set a value lower than current supply minted!");
maxSupply = _maxSupply;
}
Thanks in advance.
thats because your contract is paused, making it unusable. You need to transact on your deployed contract to make pause = false. It will let you mint normally and the gas will drop to realistic prices.
I'm writing an NFT smart contract using the OpenZeppelin ERC721Full contract. I'm able to mint NFTs, but I want to have a button that enables them to be bought. I'm trying writing this function:
function buyNFT(uint _id) public payable{
//Get NFT owner address
address payable _seller = ownerOf(_id);
// aprove nft sell
approve(_seller, _id);
setApprovalForAll(msg.sender, true);
//transfer NFT
transferFrom(_seller, msg.sender, _id);
// transfer price in ETH
address(_seller).transfer(msg.value);
emit NftBought(_seller, msg.sender, msg.value);
}
This does not work because function approve must be called by the owner or an already approved address. I have no clue on how a buy function should be built. I know that I must use some requirements but first I want the function to work on tests and then I'll write the requirements.
How should a buy function be coded? Because the only solution I have found is to overwrite the approve function and omit the require of who can call this function. But it looks like it isn't the way it should be done.
Thank you!
You can use just the _transfer() function, see my buy() function for an example of implementation.
The approvals for sale can be done using a custom mapping - in my example tokenIdToPrice. If the value is non-zero, the token ID (mapping key) is for sale.
This is a basic code that allows selling an NTF. Feel free to expand on my code to allow "give away for free", "whitelist buyers" or any other feature.
pragma solidity ^0.8.4;
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol';
contract MyToken is ERC721 {
event NftBought(address _seller, address _buyer, uint256 _price);
mapping (uint256 => uint256) public tokenIdToPrice;
constructor() ERC721('MyToken', 'MyT') {
_mint(msg.sender, 1);
}
function allowBuy(uint256 _tokenId, uint256 _price) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
require(_price > 0, 'Price zero');
tokenIdToPrice[_tokenId] = _price;
}
function disallowBuy(uint256 _tokenId) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
tokenIdToPrice[_tokenId] = 0;
}
function buy(uint256 _tokenId) external payable {
uint256 price = tokenIdToPrice[_tokenId];
require(price > 0, 'This token is not for sale');
require(msg.value == price, 'Incorrect value');
address seller = ownerOf(_tokenId);
_transfer(seller, msg.sender, _tokenId);
tokenIdToPrice[_tokenId] = 0; // not for sale anymore
payable(seller).transfer(msg.value); // send the ETH to the seller
emit NftBought(seller, msg.sender, msg.value);
}
}
How to simulate the sale:
The contract deployer (msg.sender) gets token ID 1.
Execute allowBuy(1, 2) that will allow anyone to buy token ID 1 for 2 wei.
From a second address, execute buy(1) sending along 2 wei, to buy the token ID 1.
Call (the parent ERC721) function ownerOf(1) to validate that the owner is now the second address.
If you let anyone call the approve function, it would allow anyone to approve themselves to take NFTs! The purpose of approve is to give the owner of an asset the ability to give someone else permission to transfer that asset as if it was theirs.
The basic premise of any sale is that you want to make sure that you get paid, and that the buyer receives the goods in return for the sale. Petr Hedja's solution takes care of this by having the buy function not only transfer the NFT, but also include the logic for sending the price of the token. I'd like to recommend a similar structure with a few changes. One is so that the function will also work with ERC20 tokens, the other is to prevent an edge case where if gas runs out during execution, the buyer could end up with their NFT for free. This is building on his answer, though, and freely uses some of the code in that answer for architecture.
Ether can still be set as the accepted currency by inputting the zero address (address(0)) as the contract address of the token.
If the sale is in an ERC20 token, the buyer will need to approve the NFT contract to spend the amount of the sale since the contract will be pulling the funds from the buyer's account directly.
pragma solidity ^0.8.4;
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol';
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol';
contract MyToken is ERC721 {
event NftBought(address _seller, address _buyer, uint256 _price);
mapping (uint256 => uint256) public tokenIdToPrice;
mapping (uint256 => address) public tokenIdToTokenAddress;
constructor() ERC721('MyToken', 'MyT') {
_mint(msg.sender, 1);
}
function setPrice(uint256 _tokenId, uint256 _price, address _tokenAddress) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
tokenIdToPrice[_tokenId] = _price;
tokenIdToTokenAddress[_tokenId] = _tokenAddress;
}
function allowBuy(uint256 _tokenId, uint256 _price) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
require(_price > 0, 'Price zero');
tokenIdToPrice[_tokenId] = _price;
}
function disallowBuy(uint256 _tokenId) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
tokenIdToPrice[_tokenId] = 0;
}
function buy(uint256 _tokenId) external payable {
uint256 price = tokenIdToPrice[_tokenId];
require(price > 0, 'This token is not for sale');
require(msg.value == price, 'Incorrect value');
address seller = ownerOf(_tokenId);
address tokenAddress = tokenIdToTokenAddress[_tokenId];
if(address != address(0){
IERC20 tokenContract = IERC20(tokenAddress);
require(tokenContract.transferFrom(msg.sender, address(this), price),
"buy: payment failed");
} else {
payable(seller).transfer(msg.value);
}
_transfer(seller, msg.sender, _tokenId);
tokenIdToPrice[_tokenId] = 0;
emit NftBought(seller, msg.sender, msg.value);
}
}
// mapping is for fast lookup. the longer operation, the more gas
mapping(uint => NftItem) private _idToNftItem;
function buyNft(uint tokenId) public payable{
uint price=_idToNftItem[tokenId].price;
// this is set in erc721 contract
// Since contracts are inheriting, I want to make sure I use this method in ERC721
address owner=ERC721.ownerOf(tokenId);
require(msg.sender!=owner,"You already own this nft");
require(msg.value==price,"Please submit the asking price");
// since this is purchased, it is not for sale anymore
_idToNftItem[tokenId].isListed=false;
_listedItems.decrement();
// this is defined in ERC721
// this already sets owner _owners[tokenId] = msg.sender;
_transfer(owner,msg.sender,tokenId);
payable(owner).transfer(msg.value);
}
this is Nft struct
struct NftItem{
uint tokenId;
uint price;
// creator and owner are not same. creator someone who minted. creator does not change
address creator;
bool isListed;
}