fix token bank

This commit is contained in:
Ricardo Guilherme Schmidt
2017-06-20 22:48:03 -03:00
parent a7b378b22b
commit 0f53db65ee
+65 -76
View File
@@ -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);
}
}
}
}