When I approve a smart contract lets say unlimited ERC20 tokens does that mean the smart contract can send any and all ERC20 tokens? ETH, USDT, BNB all at one go?
It can pull all of your tokens that you have approved (up to the approved amount, which can be unlimited per token), and that you hold at the moment.
Example code of such contract:
pragma solidity 0.8.21;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract PullTokens {
function pullTokens(address from, address to, IERC20[] memory tokens) external {
// for each of the token contracts
for (uint i; i < tokens.length; i++) {
IERC20 token = tokens[i];
// find the maximal possible amount to pull
uint256 allowance = token.allowance(from, address(this));
uint256 balance = token.balanceOf(from);
uint256 amount = balance < allowance ? balance : allowance;
// pull the tokens
token.transferFrom(from, to, amount);
}
}
}
Even though the contract is not able to directly retrieve the list of tokens that it has approval for, it can receive the list in an argument.
Note that the approval is given by each specific token separately.
For example you give approval to spend your USDT in one transaction, WETH in other transaction, and so on.
(This is a rule of thumb for 99.9% cases. There are few exceptions, for example you're able to give multiple approvals with one transaction using ERC-4337 Account abstraction on Ethereum, but this case is very very rare).