Ingresos extra fácil desde Aave en Solidity 💸
Published: 2023-08-29 16:43:55

---
title: Ingresos extra fácil desde Aave en Solidity 💸
published: true
description: 
tags: 
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xz6hizcjnp3f8nz83p2g.png
# Use a ratio of 100:42 for best results.
# published_at: 2023-08-07 00:00 +0000
---

¿Es posible generar ingresos pasivos en el tesoro de tu DAO? ¿O durante tu preventa de tokens, subasta o en cualquier proyecto donde tengas tokens ERC20 inactivos en un contrato? En esta guía, lanzaremos un contrato de staking que realiza préstamos en AAVE en segundo plano.

Vamos a lanzar este contrato en Scroll Sepolia, pero también te mostraré qué se debe hacer para lanzarlo en cualquier otra red donde esté desplegado AAVE.

**Nota:** Vamos a usar Remix y Etherscan para lanzar e interactuar con los contratos. También puedes usar [este repo](https://github.com/Turupawn/AaveLenderDemo) como alternativa que incluye [comentarios de código](https://github.com/Turupawn/AaveLenderDemo/blob/master/src/AaveLender.sol), [unit tests en foundry](https://github.com/Turupawn/AaveLenderDemo/blob/master/test/AaveLender.t.sol), y una [github action](https://github.com/Turupawn/AaveLenderDemo/blob/master/.github/workflows/test.yml).

## Paso1: Lanza el contrato Aave Lender

![Aave Pool Supply](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hfqqf6pavnbucw8guo9o.png)

Si no lo has hecho aún, necesitarás instalar una wallet como [Metamask](https://metamask.io/), [conectar tu wallet a Scroll Sepolia](https://chainlist.org/chain/534351), y obtener fondos desde un [faucet](https://docs.scroll.io/en/user-guide/faucet/).

Lanza el siguiente contrato en [Remix](https://remix.ethereum.org/) pasando las direcciones `aavePoolAddress` y `stakedTokenAddress` como parámetros en el constructor, en Scroll Sepolia estas son:
* `aavePoolAddress`: `0x48914C788295b5db23aF2b5F0B3BE775C4eA9440`
* `stakedTokenAddress`: `0x7984E363c38b590bB4CA35aEd5133Ef2c6619C40`, el DAI testnet en Scroll Sepolia

```javascript
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

library DataTypes {
  struct ReserveConfigurationMap {
    uint256 data;
  }

  struct ReserveData {
    ReserveConfigurationMap configuration;
    uint128 liquidityIndex;
    uint128 currentLiquidityRate;
    uint128 variableBorrowIndex;
    uint128 currentVariableBorrowRate;
    uint128 currentStableBorrowRate;
    uint40 lastUpdateTimestamp;
    uint16 id;
    address aTokenAddress;
    address stableDebtTokenAddress;
    address variableDebtTokenAddress;
    address interestRateStrategyAddress;
    uint128 accruedToTreasury;
    uint128 unbacked;
    uint128 isolationModeTotalDebt;
  }
}

interface IPool {
    function borrow(
        address asset,
        uint256 amount,
        uint256 interestRateMode, // 1 for Stable, 2 for Variable
        uint16 referralCode,
        address onBehalfOf) external;

    function supply(
        address asset,
        uint256 amount,
        address onBehalfOf,
        uint16 referralCode) external;

    function withdraw(
        address asset,
        uint256 amount,
        address to) external returns (uint256);

    function getReserveData(
        address asset) external view returns (DataTypes.ReserveData memory);
}

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 value) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

contract AaveLender {
    address public immutable AAVE_POOL_ADDRESS;
    address public immutable STAKED_TOKEN_ADDRESS;
    address public immutable ATOKEN_ADDRESS;
    address public immutable OWNER;
    mapping(address account => uint amount) public stakeByAccount;
    uint public totalStake;

    constructor(address aavePoolAddress, address stakedTokenAddress) {
        AAVE_POOL_ADDRESS = aavePoolAddress;
        STAKED_TOKEN_ADDRESS = stakedTokenAddress;
        OWNER = msg.sender;
        ATOKEN_ADDRESS = IPool(aavePoolAddress).getReserveData(stakedTokenAddress).aTokenAddress;
    }

    function stake(uint amount) public {
        totalStake += amount;
        stakeByAccount[msg.sender] += amount;
        IERC20(STAKED_TOKEN_ADDRESS).transferFrom(msg.sender, address(this), amount);
        IERC20(STAKED_TOKEN_ADDRESS).approve(AAVE_POOL_ADDRESS, amount);
        IPool(AAVE_POOL_ADDRESS).supply(
            STAKED_TOKEN_ADDRESS,
            amount,
            address(this),
            0);
    }

    function unstake(uint amount) public {
        require(amount <= stakeByAccount[msg.sender], "Not enough stake");
        totalStake -= amount;
        stakeByAccount[msg.sender] -= amount;
        IPool(AAVE_POOL_ADDRESS).withdraw(
          STAKED_TOKEN_ADDRESS,
          amount,
          msg.sender
        );
    }

    function yieldEarned() public view returns(uint){
        return IERC20(ATOKEN_ADDRESS).balanceOf(address(this)) - totalStake;
    }

    function withdraw(uint amount) public {
        require(msg.sender == OWNER, "Sender is not owner");
        require(amount <= yieldEarned(), "Maximum withdraw exceeded");
        IPool(AAVE_POOL_ADDRESS).withdraw(
          STAKED_TOKEN_ADDRESS,
          amount,
          msg.sender
        );
    }
}
```

## Paso 2: Mintea DAI en testnet

Dirígete ahora al [Faucet de Aave](https://app.aave.com/faucet/) y conecta tu wallet desde Scroll Sepolia. Haz click en el botón Faucet de DAI y confirma la transacción.

![Faucet de Aave](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfu89tcoqm7o1m4qo31a.png)

Una vez confirmada la transacción podrás ver en tu wallet tus DAIs en testnet si agregas su address de token `0x7984E363c38b590bB4CA35aEd5133Ef2c6619C40`.

Recuerda que no puedes hacer borrow y lending de cualquier token en Aave, únicamente de los que el protocolo le haya dado soporte de antemano. Y también toma nota que esta versión de DAI testnet en Scroll Sepolia no es la misma que la oficial circulando en los demás protocolos de Sepolia y Scroll Sepolia como [Uniswap v3](https://uniswap-showcase.sepolia.scroll.xyz/#/swap). Esta es una versión especial deployada por Aave y es la única versión compatible con Aave en el Testnet de Scroll. Si estás en cualquier red en mainnet sí deberás usar la versión oficial del token.

## Paso 3: Aprueba el contrato de Aave Lending

Necesitamos aprobar el contrato de staking que recién lanzamos para que pueda acceder a los fondos.

Esto lo vamos a hacer en el [Scroll-Etherscan](https://sepolia.scrollscan.dev/address/0x7984E363c38b590bB4CA35aEd5133Ef2c6619C40#writeContract).

En el contrato de DAI en: `0x7984E363c38b590bB4CA35aEd5133Ef2c6619C40`, conecta tu wallet y pasa los siguientes parámetros en la función `approve`.

* `spender`: El address del contrato de staking que recién lanzamos
* `amount`: `100000000000000000000` que es 100 DAI en el formato wei.

![Approve AaveLender contract](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwv04xqaxwii7jwi60ks.png)

## Paso 4: Obtener ganancias

Ahora puedes stakear llamando la función `stake` y pasando como párametro la cantidad de DAI que aprobaste.

![stake and lend on AAVE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j5ln5h7vyf9z1m61on6o.png)

En cada bloque, las ganancias (el yield) irán aumentando poco a poco. Las puedes observar llamando la función `yieldEarned`. Las ganancias pueden ser enviadas al owner llamando la función `withdraw`.

![withdraw yield earned on aave](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3l1kdu476870kl3cu19x.png)

## Próximos pasos

Este tutorial muestra cómo prestar en AAVE desde un smart contract con el código mínimo necesario. Ahora depende de ti utilizarlo para mejorar un proyecto existente o crear algo nuevo. Personalmente, me gustaría agregar este contrato a un sistema de lotería en el que estoy trabajando, donde mientras se elige el ganador el contrato deposita todas las recaudaciones en Aave. Déjame saber en los comentarios si tienes ideas o preguntas sobre este tutorial.

Conoce más sobre Aave desde la [documentación oficial](https://docs.aave.com/developers/getting-started/readme).

**¡Gracias por ver este tutorial!**

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