An ERC-20 in Vyper combines everything so far: a `HashMap` for balances, a nested `HashMap` for allowances, `Transfer`/`Approval` events, and `transfer`/`approve`/`transferFrom` functions that enforce balance and allowance checks.
balanceOf: public(HashMap[address, uint256])
allowance: public(HashMap[address, HashMap[address, uint256]])
event Transfer:
sender: indexed(address)
receiver: indexed(address)
value: uint256
@external
def transfer(to: address, amount: uint256) -> bool:
assert self.balanceOf[msg.sender] >= amount, "insufficient balance"
self.balanceOf[msg.sender] -= amount
self.balanceOf[to] += amount
log Transfer(sender=msg.sender, receiver=to, value=amount)
return True`transferFrom` additionally checks and decrements the caller's allowance before moving tokens on behalf of someone else.