ERC20Receiver.sol
1 pragma solidity >=0.5.0 <0.7.0; 2 3 import "./ERC20Token.sol"; 4 5 contract ERC20Receiver { 6 7 event TokenDeposited(address indexed token, address indexed sender, uint256 amount); 8 event TokenWithdrawn(address indexed token, address indexed sender, uint256 amount); 9 10 mapping (address => mapping(address => uint256)) tokenBalances; 11 12 constructor() public { 13 14 } 15 16 function depositToken( 17 ERC20Token _token 18 ) 19 external 20 { 21 _depositToken( 22 msg.sender, 23 _token, 24 _token.allowance( 25 msg.sender, 26 address(this) 27 ) 28 ); 29 } 30 31 function withdrawToken( 32 ERC20Token _token, 33 uint256 _amount 34 ) 35 external 36 { 37 _withdrawToken(msg.sender, _token, _amount); 38 } 39 40 function depositToken( 41 ERC20Token _token, 42 uint256 _amount 43 ) 44 external 45 { 46 require(_token.allowance(msg.sender, address(this)) >= _amount, "Bad argument"); 47 _depositToken(msg.sender, _token, _amount); 48 } 49 50 function tokenBalanceOf( 51 ERC20Token _token, 52 address _from 53 ) 54 external 55 view 56 returns(uint256 fromTokenBalance) 57 { 58 return tokenBalances[address(_token)][_from]; 59 } 60 61 function _depositToken( 62 address _from, 63 ERC20Token _token, 64 uint256 _amount 65 ) 66 private 67 { 68 require(_amount > 0, "Bad argument"); 69 if (_token.transferFrom(_from, address(this), _amount)) { 70 tokenBalances[address(_token)][_from] += _amount; 71 emit TokenDeposited(address(_token), _from, _amount); 72 } 73 } 74 75 function _withdrawToken( 76 address _from, 77 ERC20Token _token, 78 uint256 _amount 79 ) 80 private 81 { 82 require(_amount > 0, "Bad argument"); 83 require(tokenBalances[address(_token)][_from] >= _amount, "Insufficient funds"); 84 tokenBalances[address(_token)][_from] -= _amount; 85 require(_token.transfer(_from, _amount), "Transfer fail"); 86 emit TokenWithdrawn(address(_token), _from, _amount); 87 } 88 89 90 }