Hey mates,
I seem to have hit a bit of a roadblock, and I was wondering if someone could lend me a hand here.
My goal is as follows:
I want to create a transfer function that charges a tax, but instead of taxing the token amount, the tax should be derived from the gas fee. For instance, when I initiate a transfer call for ERC20 tokens, the transaction would include the gas fee plus a tax (some percentage of the gas fee), and that tax amount would be sent to a designated taxFeeReceiverWallet.
Here’s the implementation I’ve attempted so far:
function transferPayable (
address sender,
address recipient,
uint256 amount
) external payable returns(bool)
{
uint256 fee = msg.value/(taxFeePercentage*100);
bool success = super._transfer(sender, recipient, amount);
super._transfer(sender, taxFeeRecieverWallet, fee); // Send the tax to the designated wallet.
return success;
}
function transfer(
address recipient,
uint256 amount
) public override returns(bool) {
address sender = msg.sender;
if(msg.sender.hasRole(WHITELIST_ROLE)) {
bool success = super._transfer(sender, recipient, amount);
require(success, "Transaction not successful");
return success;
}
else {
bool success = transferPayable(msg.sender, recipient, amount); // Call the function here.
require(success, "Transaction not successful");
super._transfer( sender, recipient, amount);
return success;
}
}
As you can observe from my code, the point of interaction is the transfer function, which I have overridden from the original function. There are two categories to consider:
- Whitelisted addresses (
msg.senderswith a whitelist role): These addresses are exempt from paying the tax. - All other addresses: These users need to pay the tax.
Initially, I attempted to make the transfer function itself payable, but that caused an issue since it would alter the mutability of the function from nonpayable to payable, resulting in an error.
Hence, I decided to create a new function, transferPayable, which is a payable function intended to handle the tax from the gas fee. However, I’m now facing two major issues with this approach:
- Visibility issue: I want
transferPayableto be aninternalfunction, as I don’t want it to be accessible publicly. However,payablefunctions cannot haveinternalvisibility, so I’ve had to make itexternal. But I need this function to be callable only by the addresses that invoke thetransferfunction and are not whitelisted. - Undeclared identifier error: When trying to call
transferPayable, I receive the error:
"Undeclared identifier. 'transferPayable' is not (or not yet) visible at this point."
I suspect this could be due to a recursive call within the transfer function, but I’m unsure.
In short, I’d greatly appreciate help with the following:
- How can I make the
transferPayablefunction accessible only to addresses calling thetransferfunction and who are not whitelisted? - How can I resolve the "not visible" error for
transferPayable? - Or, is there perhaps an alternative approach to achieve my intended functionality?
Thanks in advance for your guidance!