From 0f53db65ee230c92ac2de35a19c2dac8c05ab5a9 Mon Sep 17 00:00:00 2001 From: Ricardo Guilherme Schmidt <3esmit@gmail.com> Date: Tue, 20 Jun 2017 22:48:03 -0300 Subject: [PATCH] fix token bank --- contracts/bank/TokenBank.sol | 141 ++++++++++++++++------------------- 1 file changed, 65 insertions(+), 76 deletions(-) diff --git a/contracts/bank/TokenBank.sol b/contracts/bank/TokenBank.sol index 41abb0d..fcb2729 100644 --- a/contracts/bank/TokenBank.sol +++ b/contracts/bank/TokenBank.sol @@ -1,4 +1,4 @@ -import "../token/ERC23.sol"; +import "./Token.sol"; pragma solidity ^0.4.11; @@ -9,16 +9,14 @@ pragma solidity ^0.4.11; **/ contract TokenBank is ERC23Receiver, ApproveAndCallFallBack { - event Withdrawn(address reciever, uint amount); - event Deposited(address sender, uint value); - event TokenWithdrawn(address token, address reciever, uint amount); - event TokenDeposited(address token, address sender, uint value); + event Withdrawn(address token, address reciever, uint amount); + event Deposited(address token, address sender, uint value); - mapping (uint => Deposit) public deposits; + mapping (address => mapping (address => uint)) public deposits; mapping (address => uint) public tokenBalances; address[] public tokens; - uint public nonce; + uint private nonce; struct Deposit { address sender; @@ -28,65 +26,59 @@ contract TokenBank is ERC23Receiver, ApproveAndCallFallBack { /** * @notice deposit ether in bank - * @return reciept that can be used for refund + * @param _data might be used by child implementations **/ - function deposit() payable returns (uint receipt) { - address sender = msg.sender; - uint amount = msg.value; - if(amount > 0){ - return _deposited(0x0, sender, amount); - } + function depositEther(bytes _data) payable { + _deposited(msg.sender, msg.value, 0x0, _data); } /** * @notice deposit a ERC20 token. The amount of deposit is the allowance set to this contract. - * @param _tokenAddr the token contract address - * @return reciept that can be used for refund - **/ - function tokenDeposit(address _tokenAddr) returns (uint reciept) { - address sender = msg.sender; - ERC20 token = ERC20(_tokenAddr); - uint amount = token.allowance(sender, this); - if(amount == 0) throw; + * @param _token the token contract address + * @param _data might be used by child implementations + **/ + function depositToken(address _token, bytes _data){ + address sender = msg.sender; + uint amount = ERC20(_token).allowance(sender, this); + deposit(sender, amount, _token, _data); + } + + /** + * @notice deposit a ERC20 token. The amount of deposit is the allowance set to this contract. + * @param _token the token contract address + * @param _data might be used by child implementations + **/ + function deposit(address _from, uint256 _amount, address _token, bytes _data) { + if(_from == address(this)) return; uint _nonce = nonce; - if(!token.transferFrom(sender, this, amount)) throw; - if(!token.approve(this, amount)) throw; - if(nonce == _nonce){ - reciept = _deposited(_tokenAddr, sender, amount); - }else{ - reciept = _nonce; //ERC23 executed _deposited tokenFallback by + ERC20 token = ERC20(_token); + if(!token.transferFrom(_from, this, _amount)) throw; + if(nonce == _nonce){ //ERC23 not executed _deposited tokenFallback by + _deposited(_from, _amount, _token, _data); } } - + /** * @notice watches for balance in a token contract * @param _tokenAddr the token contract address **/ - function watch(address _tokenAddr){ - bool neverSeen = false; - if(tokenBalances[_tokenAddr] == 0) neverSeen = true; - uint amount = ERC20(_tokenAddr).balanceOf(this); - if(amount > 0){ - if(!ERC20(_tokenAddr).approve(this, amount)) throw; - if(neverSeen) tokens.push(_tokenAddr); - tokenBalances[_tokenAddr] = amount; + function watch(address _tokenAddr) { + uint oldBal = tokenBalances[_tokenAddr]; + uint newBal = ERC20(_tokenAddr).balanceOf(this); + if(newBal > oldBal){ + _deposited(0x0,newBal-oldBal,_tokenAddr,new bytes(0)); } } /** * @notice refunds a deposit. - * @param _nonce the reciept you want to refund + * @param _token the token you want to refund **/ - function refund(uint _nonce) returns (bool) { - if(msg.sender != deposits[_nonce].sender) throw; - uint amount = deposits[_nonce].amount; - address token = deposits[_nonce].token; - delete deposits[_nonce]; - if(token == 0x0){ - withdraw(msg.sender,amount); - } else { - withdraw(ERC20(token), msg.sender, amount); - } + function refund(address _token) returns (bool) { + address _sender = msg.sender; + uint amount = deposits[_sender][_token]; + delete deposits[_sender][_token]; + withdraw(_token, _sender, amount); return true; } @@ -95,60 +87,57 @@ contract TokenBank is ERC23Receiver, ApproveAndCallFallBack { * @param _from address incoming token * @param _amount incoming amount **/ - function tokenFallback(address _from, uint _amount, bytes) { - _deposited(msg.sender, _from, _amount); + function tokenFallback(address _from, uint _amount, bytes _data) { + _deposited(_from, _amount, msg.sender, _data); } /** - * @notice Called MiniMeToken approvesAndCall to this contract + * @notice Called MiniMeToken approvesAndCall to this contract, calls deposit. * @param _from address incoming token * @param _amount incoming amount * @param _token the token contract address + * @param _data (might be used by child classes) */ - function receiveApproval(address _from, uint256 _amount, address _token, bytes){ - _deposited(_token, _from, _amount); + function receiveApproval(address _from, uint256 _amount, address _token, bytes _data){ + deposit(_from, _amount, _token, _data); } - + /** * @dev register the deposit to refundings **/ - function _deposited(address _tokenAddr, address _sender, uint _amount) - internal returns (uint receipt) { + function _deposited(address _sender, uint _amount, address _tokenAddr, bytes _data) + internal { + Deposited(_tokenAddr, _sender, _amount); if(_tokenAddr != 0x0){ - TokenDeposited(_tokenAddr, _sender, _amount); if(tokenBalances[_tokenAddr] == 0){ tokens.push(_tokenAddr); tokenBalances[_tokenAddr] = ERC20(_tokenAddr).balanceOf(this); }else{ tokenBalances[_tokenAddr] += _amount; } - }else{ - Deposited(_sender, _amount); } - receipt = nonce; - nonce++; - deposits[receipt] = Deposit({sender: _sender, amount: _amount, token: _tokenAddr}); + deposits[_sender][_tokenAddr] += _amount; } - /** - * @dev withdraw amount wei to dest - **/ - function withdraw(address _dest, uint _amount) - internal { - _dest.transfer(_amount); - Withdrawn(msg.sender, _amount); - } - /** * @dev withdraw token amount to dest **/ function withdraw(address _tokenAddr, address _dest, uint _amount) - internal { - if(!ERC20(_tokenAddr).transferFrom(this, _dest, _amount)) throw; - tokenBalances[_tokenAddr] -= _amount; - TokenWithdrawn(_tokenAddr, _dest, _amount); + internal returns (bool){ + Withdrawn(_tokenAddr, _dest, _amount); + if(_tokenAddr == 0x0){ + _dest.transfer(_amount); + return true; + } else { + tokenBalances[_tokenAddr] -= _amount; + ERC20 token = ERC20(_tokenAddr); + token.approve(this, 0); + if(token.approve(this, _amount)){ + return token.transferFrom(this, _dest, _amount); + } + } } - + }