1

I tried calling this function :

function createBorrowerCentricService (address _borrowToken) public returns (uint256) {
        BorrowService storage borrowService = borrowingServices[numberOfBorrowingServices];

        ++numberOfBorrowingServices;

        borrowService.lenderAddress = msg.sender;
        borrowService.borrowToken = _borrowToken;

        if (borrowService.borrowToken != 0x0000000000000000000000000000000000000000) {
            borrowService.lenderBalance = IERC20(_borrowToken).balanceOf(msg.sender);
        } else {
            borrowService.lenderBalance = (msg.sender).balance;
        }
        
        borrowService.borrowAmount = 0;
        borrowService.nftCollateral = 0x0000000000000000000000000000000000000000;
        borrowService.borrowPeriod = 0;
        borrowService.serviceID = numberOfBorrowingServices - 1;
     
        return numberOfBorrowingServices - 1;

    }

For _borrowToken, when I passed in 0x0000000000000000000000000000000000000000 (the Ethereum null address), obviously, borrowService.lenderBalance = (msg.sender).balance; is invoked, and the function is succesfully called

But when I passed in the address of an ERC20 token (DAI), I got the error :

revert - The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.

I figured out that there might be an error with the way I'm doing things in

borrowService.lenderBalance = IERC20(_borrowToken).balanceOf(msg.sender);

What is the way to find the balance of a specific ERC20 token for a wallet address in solidity?

Here is the entire code for refrence :

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;

import "@openzeppelin/contracts/interfaces/IERC20.sol";

contract Popcorn {
    
    struct BorrowService {
        address lenderAddress;
        address borrowToken;
        uint256 lenderBalance;
        uint256 borrowAmount;
        address nftCollateral;
        uint256 borrowPeriod;
        uint256 serviceID;
    }

    mapping(uint256 => BorrowService) public borrowingServices;

    uint256 public numberOfBorrowingServices = 0;

    function createBorrowerCentricService (address _borrowToken) public returns (uint256) {
        BorrowService storage borrowService = borrowingServices[numberOfBorrowingServices];

        ++numberOfBorrowingServices;

        borrowService.lenderAddress = msg.sender;
        borrowService.borrowToken = _borrowToken;

        if (borrowService.borrowToken != 0x0000000000000000000000000000000000000000) {
            borrowService.lenderBalance = IERC20(_borrowToken).balanceOf(msg.sender);
        } else {
            borrowService.lenderBalance = (msg.sender).balance;
        }
        
        borrowService.borrowAmount = 0;
        borrowService.nftCollateral = 0x0000000000000000000000000000000000000000;
        borrowService.borrowPeriod = 0;
        borrowService.serviceID = numberOfBorrowingServices - 1;
     
        return numberOfBorrowingServices - 1;

    }

    function getServices() public view returns (BorrowService[] memory) {
        BorrowService[] memory borrowService = new BorrowService[](numberOfBorrowingServices);

        for (uint256 i = 0; i < numberOfBorrowingServices; ++i) {
            BorrowService storage item = borrowingServices[i];
            borrowService[i] = item;
        }
        
        return borrowService;
    }
}

Any help would be appreciated, thanks.

2 Answers 2

1

I've tested your contract, there is no problem I could call your function, maybe you got the wrong address for the Dai token, because there are some different Dai tokens on testnet network (I used goerli), I called function using this address: 0xdc31Ee1784292379Fbb2964b3B9C4124D8F89C60 as a dai contract address, also to define zero address istead of:

borrowService.nftCollateral = 0x0000000000000000000000000000000000000000;

you can define it just like that:

borrowService.nftCollateral = address(0);
2
  • Same here, the code seems fine! Mar 11 at 20:41
  • I just realised that I made a dumb mistake lol. I used the address of the Dai token for mainnet. No wonder it didn't work haha thanks for the comments
    – Anon.eth
    Mar 12 at 3:55
0

the better solution is here, add a validation to check if the address passed is a contract or not. that would handle almost all the challenges for this.

here is the code:

function isContract(address addr) internal view returns (bool) {
        uint size;
        assembly { size := extcodesize(addr) }
        return size > 0;
    }

simply validate the address with !isContract(_borrowToken) || _borrowToken==address(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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.