#StackBounty: #javascript #ethereum #solidity #web3 Supply ETH to Aave through solidity

Bounty: 200

I’m trying programatically deposit using into Aave V2 Contract Aave’s Code Examples

// SPDX-License-Identifier: MIT
pragma solidity >= 0.4.22 < 0.8.7;

import { IERC20, ILendingPool, IProtocolDataProvider, IStableDebtToken } from './Interfaces.sol';
import { SafeERC20 } from './Libraries.sol';

/**
* This is a proof of concept starter contract, showing how uncollaterised loans are possible
* using Aave v2 credit delegation.
* This example supports stable interest rate borrows.
* It is not production ready (!). User permissions and user accounting of loans should be implemented.
* See @dev comments
*/

contract MyV2CreditDelegation {
    using SafeERC20 for IERC20;
    
    ILendingPool constant lendingPool = ILendingPool(address(0x9FE532197ad76c5a68961439604C037EB79681F0)); // Kovan
    IProtocolDataProvider constant dataProvider = IProtocolDataProvider(address(0x744C1aaA95232EeF8A9994C4E0b3a89659D9AB79)); // Kovan
    
    address owner;

    constructor () public {
        owner = msg.sender;
    }

    /**
    * Deposits collateral into the Aave, to enable credit delegation
    * This would be called by the delegator.
    * @param asset The asset to be deposited as collateral
    * @param amount The amount to be deposited as collateral
    * @param isPull Whether to pull the funds from the caller, or use funds sent to this contract
    *  User must have approved this contract to pull funds if `isPull` = true
    * 
    */
    function depositCollateral(address asset, uint256 amount, bool isPull) public {
        if (isPull) {
            IERC20(asset).safeTransferFrom(msg.sender, address(this), amount);
        }
        IERC20(asset).safeApprove(address(lendingPool), amount);
        lendingPool.deposit(asset, amount, address(this), 0);
    }

    /**
    * Approves the borrower to take an uncollaterised loan
    * @param borrower The borrower of the funds (i.e. delgatee)
    * @param amount The amount the borrower is allowed to borrow (i.e. their line of credit)
    * @param asset The asset they are allowed to borrow
    * 
    * Add permissions to this call, e.g. only the owner should be able to approve borrowers!
    */
    function approveBorrower(address borrower, uint256 amount, address asset) public {
        (, address stableDebtTokenAddress,) = dataProvider.getReserveTokensAddresses(asset);
        IStableDebtToken(stableDebtTokenAddress).approveDelegation(borrower, amount);
    }
    
    /**
    * Repay an uncollaterised loan
    * @param amount The amount to repay
    * @param asset The asset to be repaid
    * 
    * User calling this function must have approved this contract with an allowance to transfer the tokens
    * 
    * You should keep internal accounting of borrowers, if your contract will have multiple borrowers
    */
    function repayBorrower(uint256 amount, address asset) public {
        IERC20(asset).safeTransferFrom(msg.sender, address(this), amount);
        IERC20(asset).safeApprove(address(lendingPool), amount);
        lendingPool.repay(asset, amount, 1, address(this));
    }
    
    /**
    * Withdraw all of a collateral as the underlying asset, if no outstanding loans delegated
    * @param asset The underlying asset to withdraw
    * 
    * Add permissions to this call, e.g. only the owner should be able to withdraw the collateral!
    */
    function withdrawCollateral(address asset) public {
        (address aTokenAddress,,) = dataProvider.getReserveTokensAddresses(asset);
        uint256 assetBalance = IERC20(aTokenAddress).balanceOf(address(this));
        lendingPool.withdraw(asset, assetBalance, owner);
    }
}

I have code which consumes this like so:

App = {
  web3Provider: null,
  contracts: {},

  init: async function() {
    return await App.initWeb3();
  },

  initWeb3: async function() {
    // Modern dapp browsers...
    if (window.ethereum) {
      App.web3Provider = window.ethereum;
      try {
        // Request account access
        await window.ethereum.enable();
      } catch (error) {
        // User denied account access...
        console.error("User denied account access")
      }
    }
    // Legacy dapp browsers...
    else if (window.web3) {
      App.web3Provider = window.web3.currentProvider;
    }
    // If no injected web3 instance is detected, fall back to Ganache
    else {
      App.web3Provider = new Web3.providers.HttpProvider('http://localhost:8545');
    }
    web3 = new Web3(App.web3Provider);

    return App.initContract();
  },

  initContract: function() {
    $.getJSON('MyV2CreditDelegation.json', function(data) {
      // Get the necessary contract artifact file and instantiate it with @truffle/contract
      var safeYieldArtifact = data;
      App.contracts.MyV2CreditDelegation = TruffleContract(safeYieldArtifact);
    
      // Set the provider for our contract
      App.contracts.MyV2CreditDelegation.setProvider(App.web3Provider);
    });
    

    

    return App.bindEvents();
  },

  bindEvents: function() {
    $(document).on('click', '.btn-deposit', App.handleDeposit);
    $(document).on('click', '.btn-withdrawl', App.handleWithdrawl);
  },

  handleDeposit: function(event) {
    event.preventDefault();
    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }
    
      var account = accounts[0];

      App.contracts.MyV2CreditDelegation.deployed().then(function(instance) {
        creditDelegatorInstance = instance;
        const mockETHAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
        // Execute adopt as a transaction by sending account
        return creditDelegatorInstance.depositCollateral(mockETHAddress, 1, true);
      }).then(function(result) {
        //return App.markAdopted();
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleWithdrawl: function(event) {
    event.preventDefault();
  },
};

$(function() {
  $(window).load(function() {
    App.init();
  });
});

When attempting to supply, Metamask displays an error:

ALERT: Transaction Error. Exception thrown in contract code.

I’m running ganache

ganache-cli --fork https://mainnet.infura.io/v3/{{MyProjectId}}

The only error I see in the console is:

Transaction: 0x9961f8a187c09fd7c9ebf803771fa161c9939268bb01552a1598807bcfdc13ff
Gas usage: 24813
Block Number: 12905002
Block Time: Mon Jul 26 2021 20:38:30 GMT-0400 (Eastern Daylight Time)
Runtime Error: revert

My guess is that I’m not calling the contract from Web3 appropiately

How can programatically supply Eth (Or any other token) to aave?


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.