0

I apologize if this question might seem a bit simple beforehand. I'm trying call the deposit function from my frontend, but it gives me the error mentioned above. I am confused as to if this is a problem on my next.js front-end or on my smart contracts.

This is what the relevant parts of my front end looks like:

async function depositToJuniorPool(amount) {
  if (typeof window.ethereum !== 'undefined') {
      const provider = new ethers.providers.Web3Provider(window.ethereum)
      const signer = provider.getSigner()
      const juniorPool = new ethers.Contract(juniorPoolAddress, JuniorPool.abi, signer)
      console.log('juniorPool: ', juniorPool)
      try {
        
          const val = await juniorPool.deposit(amount)
          console.log('val: ', val)
        } catch (err) {
          console.log('Error: ', err)
        }
}
        <div className={buttonContainer}>
                <button className={buttonStyle}
                type='button'
                onClick={() => depositToJuniorPool(110)}>Stake
                </button>
        </div>

This is what the relevant parts of my smart contracts look like:

 function deposit(uint256 amount) external override whenNotPaused withinTransactionLimit(amount) nonReentrant {
    require(amount >= 110, "Must deposit 110 or more");
    // Check if the amount of new shares to be added is within limits
    uint256 depositShares = getNumShares(amount);
    uint256 potentialNewTotalShares = totalShares().add(depositShares);
    require(poolWithinLimit(potentialNewTotalShares), "Deposit would put the Pool over the total limit.");
    emit DepositMade(msg.sender, amount, depositShares);
    bool success = doUSDCTransfer(msg.sender, address(this), amount);
    require(success, "Failed to transfer for deposit");


    config.getJuniorToken().juniorPoolMintTo(msg.sender, depositShares);
  }

  function doUSDCTransfer(
    address from,
    address to,
    uint256 amount
  ) internal returns (bool) {
    require(to != address(0), "Can't send to zero address");
    IERC20withDec usdc = config.getUSDC();
    usdc.approve(from, amount);
    return usdc.transferFrom(from, to, amount);
  }

1 Answer 1

0
usdc.approve(from, amount);

What this is doing is having juniorPool itself call approve for usdc, where it's giving from an allowance to move amount from the juniorPool's own balance. Take a look at OpenZeppelin's ERC20.sol

function approve(address spender, uint256 amount) public virtual override returns (bool) {
    address owner = _msgSender();
    _approve(owner, spender, amount);
    return true;
}

msg.sender approves spender to move amount. juniorPool is the one calling approve, so juniorPool is msg.sender in this case and is allowing the address calling await juniorPool.deposit(amount) to move tokens from the the contract.

You want the address calling await juniorPool.deposit(amount) to approve juniorPool. In ethers create a USDC contract instance, with USDC's ABI or a generic ERC20 ABI, and then call deposit with your contract instance.

// signer approves the contract to move amount
await usdc.approve(<juniorPool address>, amount)

// signer calls deposit from contract
await juniorPool.deposit(amount)
3
  • 1
    I want to mention you could also call <contract>.connect(<address of user or contract>).approve() to change the user context (in other words the address of msg.sender)
    – Gleichmut
    Sep 8, 2022 at 11:25
  • Can you explain how this would work @Gleichmut ? The contract (juniorPool) is already connected to the signer's address. From there, juniorPool calls a USDC contract instance. The msg.sender for that USDC contract call from within juniorPool would still be juniorPool
    – Ryan Sea
    Sep 11, 2022 at 18:30
  • There is no disagreement between you and me in understanding of this. What I would like to point out in comment above is ether.js provides an option where you can explicitly tell from which account you would like to call this contract function.
    – Gleichmut
    Sep 13, 2022 at 4:48

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.