【问题标题】:Allowance is returned zero even after approval批准后津贴归零
【发布时间】:2022-11-28 01:46:16
【问题描述】:

我正在对我的合同进行单元测试,在测试中我批准智能合同应该能够使用 msg.sender(所有者)的令牌,然后尝试使用 transferFrom 函数将令牌从 msg.sender 转移到合同.但是,我遇到的第一个障碍是当我调用 transferFrom 函数时,津贴返回为零。现在我能够重新了解到 transferFrom 函数应该是另一个事务才能工作并且我控制台记录了所有变量以确保在调用 approve 函数时更改了津贴。但是,当我想起 transferFrom 时,错误仍然存​​在并显示余额不足!

` 这是我的存款功能,只有在批准成功时才会调用 transferFrom

/**
     * @notice addEth is a user function where the user chooses the pool and sends eth to it, funding it
     * @param depositAmount is the eth being sent from the user to the pool
     * @param poolId_ is the address of the pool being chosen by the user
     */
    function deposit(uint256 depositAmount, uint256 poolId_) public{
        
        // Check if the pool is either closed or paused or exists
        Pool storage p = checkIfPoolExistsOrClosed(poolId_);

        // Make sure the eth being sent is not equal to zero
        if (depositAmount <= 0) revert WrongAmount();

        // Check if the pool is empty, if it is the price of token is 1
        if(p.valueInPool == 0) {
            tokensForUser = depositAmount;
        }else {
            // Get the amount of tokens to be minted to the user
            tokensForUser = (depositAmount /
                (p.valueInPool/
                IProperSubsetERC20(p.poolTokenAddress).totalSupply()));
        }
        
        // check if the approval was a success
        if(!contractIsApproved[msg.sender]) revert ApprovalFailed();

        // Send the USDC tokens to the fund contract
        bool transfer  = IProperSubsetUSDC(usdcAddress).transferFrom(msg.sender, address(this), depositAmount);

        // Send the USDC tokens to the fund contract
        // (bool success,)=usdcAddress.delegatecall(abi.encodeWithSignature('transfer(address,uint256)', address(this), depositAmount));

        // Call the ERC20 contract to mint tokens to user
        IProperSubsetERC20(p.poolTokenAddress).mint(msg.sender, tokensForUser);

        // Update the amount of liquidity in the pool
        p.valueInPool = p.valueInPool + depositAmount;

        // Emit event after adding eth to pool
        emit Deposit(msg.sender, poolId_, depositAmount);
    }

这是我的批准功能,我调用批准功能来添加津贴

    /**
     * @notice function to approve contract to spend the user's USDC tokens
     * @param amount of usdt willing to give the contract approval for spending
     */
    function approveUser(uint256 amount) public returns(bool){

        // Approve spending the msg.sender tokens
        (bool success,) =    usdcAddress.delegatecall(abi.encodeWithSignature('approve(address,uint256)', address(this), amount));

        // If the approve function is succesfull we update the map to show that this address is approved
        if(success){
            contractIsApproved[msg.sender] = true;
        }
        // Return if the function is successfull
        return success;
    }

`

现在这些是调用 approve 和 transferFrom 函数的测试

it("Try approving for user 1 the transfer of their tokens from the contract", async function() {
      await deployFunds.connect(signers[1]).approveUser(1000);
    })

    it("Try depositing and the price of the pool tokens should be equal to one since it is new", async function() {
      const tx = await deployFunds.connect(signers[1]).deposit(1000, 2);
      const receipt = await tx.wait();
      
      filter = receipt.events?.filter((x) => {return x.event == "Deposit"});
      poolId = filter.length > 0 ? filter[0].args[1] : '0x000';
      tokensForUser = filter.length > 0 ? filter[0].args[2]: "0";
      mintedTokens = await deployERC20.balanceOf(user1);
      expect(filter.length).above(0);
      expect(poolId).to.equal(2);
      expect(tokensForUser).to.equal(1000);
    })

我尝试在控制台记录所有在 approve 函数中更改的变量,并且一切都在检查,但是当我在控制台记录调用 transferFrom 时的津贴被打印为零。然后我尝试将 approve 函数和 transferFrom 单独放在每笔交易中,但错误仍然存​​在,因为津贴不足

【问题讨论】:

    标签: solidity smartcontracts erc20


    【解决方案1】:
    (bool success,) =    usdcAddress.delegatecall(abi.encodeWithSignature('approve(address,uint256)', address(this), amount));
    

    Delegatecall 将状态更改(更新存储槽)存储在您的合约中 - 而不是在 usdcAddress 合约中。

    为了获得用户的批准,他们需要发送一个单独的交易,直接在usdcAddress合约上执行approve()函数——而不是通过任何其他合约。

    【讨论】:

      猜你喜欢
      • 2013-10-03
      • 1970-01-01
      • 2022-12-05
      • 2014-09-18
      • 2023-01-18
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多