1

I am tying to do a simple deposit into an Aave V2 pool with Python Brownie and Solidity on a mainnet-fork but my transaction keeps getting reverted and I dont know why.

In brownie, I call my function send_to_aave() to deploy my main contract, which I pass in a Weth address and Aave Pool registry address.

Then, I approve the aave pool, weth erc20 address, my address and an amount all with brownie functions.

After that, I call my solidity function transferToAave() with brownie to deposit() the funds into an Aave pool.

A majority of this code I grabbed from Patrick Collins Aave tutorial, so I know the Brownie code will deposit if I uncomment out this line in my transfer_to_aave() function : # aave_pool.deposit(erc20_address, amount, account.address, 0, {"from": account})

I've read the aave docs and made a bunch of different changes in my solidity contract, but i cant figure out what the issue is.

The only problem I've been able to detect is that the Weth ERC20 address that gets approved in Brownie 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 is a different checksum inside the solidity contract 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2. The Erc20 address becomes tokenUsedForPayment inside the solidity contract. I pasted my event log output below.

Error

Transaction sent: 0x9158e07b307a9c77974bec4e7182ad7aae24e8f18d80b09de60ac22c637dcd55
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 5
  LandLord.transferToAave confirmed (SafeERC20: low-level call failed)   Block: 14774532   Gas used: 173499 (1.45%)

  File "brownie/_cli/run.py", line 51, in main
    return_value, frame = run(
  File "brownie/project/scripts.py", line 103, in run
    return_value = f_locals[method_name](*args, **kwargs)
  File "./scripts/deploy.py", line 272, in main
    send_to_aave()
  File "./scripts/deploy.py", line 250, in send_to_aave
    transfer_to_aave(
  File "./scripts/deploy.py", line 219, in transfer_to_aave
    tx = land_contract.transferToAave(amount, {"from": account})
  File "brownie/network/contract.py", line 1710, in __call__
    return self.transact(*args)
  File "brownie/network/contract.py", line 1583, in transact
    return tx["from"].transfer(
  File "brownie/network/account.py", line 682, in transfer
    receipt._raise_if_reverted(exc)
  File "brownie/network/transaction.py", line 446, in _raise_if_reverted
    raise exc._with_attr(
VirtualMachineError: revert: SafeERC20: low-level call failed
Trace step -1, program counter 263:
  File "contracts/LandLord.sol", line 63, in LandLord.transferToAave:    
        // Deposit the _amount in the LendingPool

        //emit seeme(address(aavePool), _amount, address(msg.sender), address(tokenUsedForPayments));
        aavePool.deposit(address(tokenUsedForPayments), _amount, address(msg.sender), 0);
        //tokenUsedForPayments.approve(address(aavePool), rent);
        //lendingService.depositFunds(rent);
    }
Terminating local RPC client...

Brownie code

def get_lending_pool():
    lending_pool_addresses_provider = interface.ILendingPoolAddressesProvider(
        config["networks"][network.show_active()]["lending_pool_addresses_provider"]
    )
    lending_pool_address = lending_pool_addresses_provider.getLendingPool()
    lending_pool = interface.ILendingPool(lending_pool_address)
    return lending_pool, lending_pool_address


def approve_erc20(amount, spender, erc20_address, account):
    print("Approving ERC20 token...")
    erc20 = interface.IERC20(erc20_address)
    tx = erc20.approve(spender, amount, {"from": account})
    tx.wait(1)
    print("Approved!")
    return tx


def transfer_to_aave(amount, erc20_address, aave_pool, account):
    
    land_contract = LandLord[-1]

    print(f"AAVVEE ADDRESS: {aave_pool.address}!!!\n")
    print(f"ERC20 ADDRESS: {erc20_address}!!!\n")
    print(f"Aacount ADDRESS: {account.address}!!!\n")

    approve_erc20(amount, aave_pool.address, erc20_address, account)

    # aave_pool.deposit(erc20_address, amount, account.address, 0, {"from": account})
    tx = land_contract.transferToAave(amount, {"from": account})
    tx.wait(1)
    print(tx.events)
    print("Deposited!")


def send_to_aave():

    # set amount
    amount = Web3.toWei(0.001, "ether")

    # get account
    account = get_account()

    # get weth token
    erc20_address = config["networks"][network.show_active()]["weth_token"]

    # fund account
    if network.show_active() in ["mainnet-fork"]:
        get_weth(account=account)

    # get pool and address
    aave_pool, lending_pool_address = get_lending_pool()
    
    # deploy contract and pass in lending_pool regsitry address
    LandLord.deploy(
        erc20_address,
        lending_pool_address,
        {"from": account},
    )

    # call to deposit into aave
    transfer_to_aave(
        amount=amount,
        erc20_address=erc20_address,
        aave_pool=aave_pool,
        account=account,
    )

Solidity Code

pragma solidity >=0.6.6 <0.8.0;

import { IERC20 } from "../interfaces/IERC20.sol";

import { ILendingPool } from "../interfaces/ILendingPool.sol";

contract LandLord {

    IERC20 public tokenUsedForPayments;
    ILendingPool public aavePool;

    event printme(address aavePool, uint256 _amount, address sender, address tokenUsedForPayments);

    constructor (
        address _tokenUsedToPay,
        address _lendingService /*uint updateInterval*/
    ) public {
        tokenUsedForPayments = IERC20(_tokenUsedToPay);
        aavePool = ILendingPool(_lendingService);
    }

    function transferToAave(uint256 _amount) public {
        // require(tokenUsedForPayments.allowance(tenant, address(this)) >= rent, "No Allowance");
        //tokenUsedForPayments.transferFrom(msg.sender, address(aavePool), _amount);
        
        //tokenUsedForPayments.approve(address(aavePool), _amount);
        // Deposit the _amount in the LendingPool

        aavePool.deposit(address(tokenUsedForPayments), _amount, address(msg.sender), 0);

        emit printme(address(aavePool), _amount, address(msg.sender), address(tokenUsedForPayments));

    }

Output of function transferToAave() when I comment out aave.deposit() to emit event

Launching 'ganache-cli --chain.vmErrorsOnRPCResponse true --wallet.totalAccounts 10 --hardfork istanbul --fork.url https://mainnet.infura.io/v3/762bffe1e537416580c803e6ae57d3f7 --miner.blockGasLimit 12000000 --wallet.mnemonic brownie --server.port 8545 --chain.chainId 1'...

Running 'scripts/deploy.py::main'...
Transaction sent: 0x76e785736e8b1c4f8eb0f1342753c3dae770570968d25d12f13eeb8ea5f8379f
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 2
  Transaction confirmed   Block: 14774659   Gas used: 43738 (0.36%)

Received 1e+17 WETH
Transaction sent: 0x4773bc855f919f18964568cd3e34068c9fa6527e78a225030757890a1af49ed0
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 3
  LandLord.constructor confirmed   Block: 14774660   Gas used: 163924 (1.37%)
  LandLord deployed at: 0x6951b5Bd815043E3F842c1b026b0Fa888Cc2DD85

AAVVEE ADDRESS: 0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9!!!

ERC20 ADDRESS: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2!!!

Aacount ADDRESS: 0x66aB6D9362d4F35596279692F0251Db635165871!!!

Approving ERC20 token...
Transaction sent: 0xe59e66cc0fe9216757498e4f3f8602e39bca89fa66132e6188eccaeaa1410778
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 4
  Transaction confirmed   Block: 14774661   Gas used: 43952 (0.37%)

  Transaction confirmed   Block: 14774661   Gas used: 43952 (0.37%)

Approved!
Transaction sent: 0x9158e07b307a9c77974bec4e7182ad7aae24e8f18d80b09de60ac22c637dcd55
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 5
  LandLord.transferToAave confirmed   Block: 14774662   Gas used: 24950 (0.21%)

  LandLord.transferToAave confirmed   Block: 14774662   Gas used: 24950 (0.21%)

{'printme': [OrderedDict([('aavePool', '0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9'), ('_amount', 1000000000000000), ('sender', '0x66aB6D9362d4F35596279692F0251Db635165871'), ('tokenUsedForPayments', '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2')])]}
Deposited!
Terminating local RPC client...

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.