Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perform additional swap at the moment the 'transfer' function of a solidity contract is triggered #130

Open
aghering23 opened this issue Sep 4, 2022 · 0 comments

Comments

@aghering23
Copy link

aghering23 commented Sep 4, 2022

Question: is it possible to perform an additional swap at the moment the 'transfer' function of a solidity contract is triggered?

Network: Ethereum
Uniswap Pair: V2

Case:
I have a smartcontract with an erc20 token and user swaps (w)eth for erc20, this triggers the 'transfer' function on the smartcontract. In the smartcontract 'transfer' function, i want to trigger an additional swap call where the smartcontract sells some of its erc20 to (w)eth. Using a modifier and conditions statements to prevent the initial call to infinite loop.

I have read some documentation on multicalls, but can't seem to find if this will work for uniswap v2 pairs


Solidity:
`// SPDX-License-Identifier: Unlicensed

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";

import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";

pragma solidity ^0.8.16;

contract SOL is ERC20, ERC20Burnable, Ownable {
using Address for address;

// IDEX - Interface Decentralised Exchange
address public IDEXFactory;
address public IDEXRouter;
address public IDEXWrapped;
address public IDEXPair;

uint256 public contractBalanceNative;
uint256 public contractBalanceToken;


constructor() ERC20("SOLIDITY6", "SOL6") {
    IDEXFactory = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
    IDEXRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    IDEXWrapped = 0xc778417E063141139Fce010982780140Aa0cD5Ab;
            
    _approve(address(this), address(IDEXFactory), type(uint256).max);
    _approve(address(this), address(IDEXRouter), type(uint256).max);


    _mint(address(this), 1000 * 10 ** decimals());
    
    dexCreatePair();
}




bool inSwap;

modifier lockTheSwap {
    inSwap = true;
    _;
    inSwap = false;
}


function _transfer(address from, address to, uint256 amount) internal override returns (bool) {     
    
    require(from != address(0), "");
    require(to != address(0), "");
    require(_balances[from] - amount >= 0, "");

    if(inSwap)
    { 
        return _basicTransfer(from, to, amount); 
    }
    else
    {
        if (contractBalanceToken > 1000) { dexSellTokensForNativeLock(contractBalanceToken); }
        super._transfer(from, to, amount);
        return true;
    }
}






function _basicTransfer(address from, address to, uint256 amount) internal returns (bool) {
    
    _balances[from] = _balances[from] - amount;
    _balances[to] = _balances[to] + amount;
    emit Transfer(from, to, amount);
    return true;
}

function dexCreatePair() internal {
    
    address WETHaddress = IUniswapV2Router02(IDEXRouter).WETH();
    IDEXWrapped = WETHaddress;

    address uniswapV2Pair = IUniswapV2Factory(IDEXFactory).createPair(address(this), WETHaddress);
    IDEXPair = uniswapV2Pair;
}

function dexSellTokensForNativeLock(uint256 amountTokens) internal lockTheSwap {
    
    _approve(address(this), address(IDEXRouter), type(uint256).max);

    address[] memory path = new address[](2);
    path[0] = address(this);
    path[1] = IDEXWrapped;

    IUniswapV2Router02(IDEXRouter).swapExactTokensForETHSupportingFeeOnTransferTokens(amountTokens, 0, path, address(this), block.timestamp);
}

function _afterTokenTransfer() internal virtual {    
    contractBalanceCheck();
}

function contractBalanceCheck() public returns(uint, uint){        
    contractBalanceNative = address(this).balance;
    contractBalanceToken = balanceOf(address(this));
    return(contractBalanceNative, contractBalanceToken);
}

receive() external payable {}

}`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant