Autoliquidity para Tokens Fuertototes
Published: 2022-05-11 16:14:05

---
title: Autoliquidity para Tokens Fuertototes
published: true
description: 
tags: 
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ultlxu0ym2ic93utm3b.png
---

Siempre buscamos maneras de mantener nuestros ecosistemas saludables y a prueba de futuro. Para eso en este video agregamos al funcionalidad de Autoliquidez a un token ERC-20. Este sistema toma un porcentaje de cada transacción y lo agrega automáticamente al par de liquidez, respaldándolo con ether, o con cualquier otra moneda. Esto ayuda a darle la seguridad a los participantes del mercado que siempre y cuando el token esté en movimiento este estará respaldado con nueva liquidez.

https://www.youtube.com/watch?v=qII2ePpp-qA

Toma en cuenta que este material está dirigido para oyentes avanzados por lo que te recomendaría profundizar sobre [cómo hacer swaps](https://dev.to/turupawn/swap-intercambiar-tokens-desde-solidity-2loj) y [cómo agregar liqudiez](https://dev.to/turupawn/agregar-liquidez-desde-un-smart-contract-oo9) desde un smart contract luego de ver este video.

## Antes de iniciar

Asegurate de instalar [Metamask](https://metamask.io/), conectar tu wallet a [Polygon Mainnet](https://docs.polygon.technology/docs/develop/metamask/config-polygon-on-metamask/) y conseguir MATIC desde algún exchange. Pero este video es compatible también con cualquier blockchain compatible con la Ethereum Virtual Machine.

## Lanzamos el contrato

Nota que debes seleccionar la wallet de liquidez (`liquidityWallet`) y el address correcto del `router`, este dependará de dónde deseas lanzar el contrato:

* Polygon Quickswap: `0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff`
* Ethereum Uniswap V2: `0x10ED43C718714eb63d5aA57B78B54704E256024E`
* BSC Mainnet Pancake: `0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D`
* BSC Testnet Pancake: `0xD99D1c33F9fC3444f8101754aBC46c52416550D1`

```solidity
// SPDX-License-Identifier: MIT

pragma solidity 0.8.13;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

interface IUniswapV2Router02 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );
}

interface IUniswapV2Factory {
    function createPair(address tokenA, address tokenB) external returns (address pair);
}

contract MyToken is ERC20
{
    address public liquidityWallet;

    IUniswapV2Router02 router;
    address public pair;

    uint public feeDecimal = 2;
    uint public feePercentage;

    uint256 public minTokensBeforeSwap;

    mapping(address => bool) public isTaxless;

    bool private isLocked;

    constructor () ERC20("My Token", "TKN")
    {
        router = IUniswapV2Router02(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff);
        pair = IUniswapV2Factory(router.factory()).createPair(address(this), router.WETH());

        // Edit here
        liquidityWallet = 0x0000000000000000000000000000000000000000;
        uint supply = 1_000_000 ether;
        feePercentage = 100; // 1.00% tx fee
        minTokensBeforeSwap = 10 ether;
        // End edit

        isTaxless[msg.sender] = true;
        isTaxless[liquidityWallet] = true;
        isTaxless[address(this)] = true;
        isTaxless[address(0)] = true;

        _mint(msg.sender, supply);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint amount
    ) internal virtual override(ERC20)
    {
        super._beforeTokenTransfer(from, to, amount);

        if(!isLocked)
        {
            isLocked = true;
            if(balanceOf(address(this)) >= minTokensBeforeSwap && from != pair)
                autoLiquidity();
            isLocked = false;
        }
    }

    function _afterTokenTransfer(
        address from,
        address to,
        uint amount
    ) internal virtual override(ERC20)
    {
        super._afterTokenTransfer(from, to, amount);

        if(!isLocked)
        {
            if (!isTaxless[from]) {
                uint feesCollected = calculateFee(amount);
                if(feesCollected > 0)
                {
                    isLocked = true;
                    _transfer(to, address(this), feesCollected);
                    isLocked = false;
                }
            }
        }
    }

    function autoLiquidity() internal
    {
        // Let's swap half collected tokens for eth
        uint amountToSwap = balanceOf(address(this)) / 2;

        address[] memory sellPath = new address[](2);
        sellPath[0] = address(this);
        sellPath[1] = router.WETH();       

        _approve(address(this), address(router), amountToSwap);
        router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            amountToSwap,
            0,
            sellPath,
            address(this),
            block.timestamp
        );

        // Now we are ready to send to LP
        uint256 amountETHLiquidity = address(this).balance;
        if(balanceOf(address(this)) > 0) {
            _approve(address(this), address(router), balanceOf(address(this)));
            router.addLiquidityETH{value: amountETHLiquidity}(
                address(this),
                balanceOf(address(this)),
                0,
                0,
                liquidityWallet,
                block.timestamp
            );
        }
    }

    function calculateFee(uint amount) internal view returns(uint) {
        return (amount * feePercentage)  / (10**(feeDecimal + 2));
    }

    fallback() external payable {}
    receive() external payable {}
}
```

**Gracias por ver este tutorial!**

Sígannos en dev.to y en [Youtube](https://www.youtube.com/channel/UCNRB4tgwp09z4391JRjEsRA) para todo lo relacionado al desarrollo en Blockchain en Español.