0

I'm creating a paid membership in my contract and I'm using Binance USD as payment token. This is the method:

function PayMembership(uint256 membershipID) external
{
    require(msg.sender != address(0), 'Invalid user address');
    require(Members[msg.sender] < membershipID, 'User have a higher membership.');
    
    Membership storage membership = Memberships[membershipID];
    
    require(membership.Token != address(0), 'Membership ID is not valid.');
    
    IERC20 ercToken = IERC20(membership.Token);

    if(ercToken.transferFrom(msg.sender, receiverAddress, membership.Amount))
    {
        Members[msg.sender] = membershipID;
        emit NewMember(msg.sender, membershipID);   
    }
}

Membership.Token corresponds to Binance USD contract address.

If I use this method I get errors about the allowance. So I changed the code to add a call to approve method:

if(ercToken.approve(msg.sender, membership.Amount))
{
    if(ercToken.transferFrom(msg.sender, CriptoManagerAddress, membership.Amount))
    {
       Members[msg.sender] = membershipID;
       emit NewMember(msg.sender, membershipID);   
    }   
}

But I still getting the same error. Those are the methods in Binance USD contract code.

function approve(address spender, uint256 amount) external returns (bool) {
   _approve(_msgSender(), spender, amount);
   return true;
}

function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {
   _transfer(sender, recipient, amount);
   _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "BEP20: transfer amount exceeds allowance"));
   return true;
 }

 function _transfer(address sender, address recipient, uint256 amount) internal {
   require(sender != address(0), "BEP20: transfer from the zero address");
   require(recipient != address(0), "BEP20: transfer to the zero address");

   _balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");
   _balances[recipient] = _balances[recipient].add(amount);
   emit Transfer(sender, recipient, amount);
 }

 function _approve(address owner, address spender, uint256 amount) internal {
   require(owner != address(0), "BEP20: approve from the zero address");
   require(spender != address(0), "BEP20: approve to the zero address");

   _allowances[owner][spender] = amount;
   emit Approval(owner, spender, amount);
 }

Looking at those methods I can see that my code will never work but I don't know how to solve it.

Let's say that there is 3 address involved in my payment method:

1.msg.sender (user who will pay the membership).

2.receiver (project address).

3.my contract address (the contract that user will call to use the payment method).

Following the code, the call to approve and transferFrom from my contract will have the next result:

Call to approve:

approve(userAddress, amount);
_approve(myContractAddress (as the msg.sender), userAddress, amount);
//Result _allowances[myContractAddress][UserAddress]

Call to transferFrom:

transferFrom(userAddress, receiver, amount);
_transfer(userAddress, receiver, amount); //balances are modified without problem
_approve(userAddress, myContractAddress, _allowances[userAddress][myContractAddress].sub(amount, "BEP20: transfer amount exceeds allowance"));
//Result error because it tries to substract the amount from _allowances[userAddress][myContractAddress] but when we called the approve mehtod before, the method saves the entry as _allowances[myContractAddress][UserAddress], the opposite

This is the problems with the allowance and I can't do anything from my side because is the token code who save and compares the allowances like this.

0