If I understand correctly, you need to write a contract that can only accept approved tokens. There are several ways to write such a contract, for example:
pragma solidity ^0.8.0;
import { IERC20 } from "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
contract MyContract {
// Import the ERC20 interface
IERC20 public token;
constructor(address _tokenAddress) public {
// Set the address of the ERC20 token contract
token = IERC20(_tokenAddress);
}
function receivePayment(address _from, uint256 _value) public {
// Require that the payment is made with an ERC20 token
require(token.transferFrom(_from, address(this), _value), "ERC20: transfer failed");
}
}
So when you deploy this contract you specify in arguments what ERC20 token it should use. The receivePayment
function then requires that the payment is made with an ERC20 token by calling the transferFrom function on the token instance.
This is a basic contract that can be upgraded to accept several different tokens.
Let's assume that we want to be able to accept several tokens at once:
pragma solidity ^0.8.0;
import { IERC20 } from "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
contract MyContract {
// Import the ERC20 interface
IERC20 public token;
// Array of accepted ERC20 token addresses
address[] public acceptedTokens;
constructor(address[] memory _acceptedTokens) public {
// Set the array of accepted ERC20 token addresses
acceptedTokens = _acceptedTokens;
}
function receivePayment(address _from, uint256 _value, address _token) public {
// Require that the payment is made with an accepted ERC20 token
require(isAcceptedToken(_token), "ERC20: token not accepted");
// Set the token instance to the provided token address
token = IERC20(_token);
// Require that the payment is made with the correct amount of tokens
require(token.transferFrom(_from, address(this), _value), "ERC20: transfer failed");
}
function isAcceptedToken(address _token) public view returns (bool) {
// Check if the provided token address is in the acceptedTokens array
for (uint256 i = 0; i < acceptedTokens.length; i++) {
if (acceptedTokens[i] == _token) {
return true;
}
}
return false;
}
}
Here we have the variable acceptedTokens
, which also in the constructor sets what tokens can be used in the contract.
There is also a special helper function called isAcceptedToken
, which allows you to check whether the token can be used or not