Hi!
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:
- msg.sender (user who will pay the membership).
- receiver (project address).
- 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.