mirror of
https://github.com/status-im/github-oracle.git
synced 2026-08-27 18:01:09 +00:00
fix token bank
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user