Contract Source Code:
File 1 of 1 : AirDropper
pragma solidity 0.4.26;
/*
Owned contract interface
*/
contract IOwned {
// this function isn't abstract since the compiler emits automatically generated getter functions as external
function owner() public view returns (address) {this;}
function transferOwnership(address _newOwner) public;
function acceptOwnership() public;
}
/*
ERC20 Standard Token interface
*/
contract IERC20Token {
// these functions aren't abstract since the compiler emits automatically generated getter functions as external
function name() public view returns (string) {this;}
function symbol() public view returns (string) {this;}
function decimals() public view returns (uint8) {this;}
function totalSupply() public view returns (uint256) {this;}
function balanceOf(address _owner) public view returns (uint256) {_owner; this;}
function allowance(address _owner, address _spender) public view returns (uint256) {_owner; _spender; this;}
function transfer(address _to, uint256 _value) public returns (bool success);
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
function approve(address _spender, uint256 _value) public returns (bool success);
}
/*
ERC20 Standard Token interface which doesn't return true/false for transfer, transferFrom and approve
*/
contract INonStandardERC20 {
// these functions aren't abstract since the compiler emits automatically generated getter functions as external
function name() public view returns (string) {this;}
function symbol() public view returns (string) {this;}
function decimals() public view returns (uint8) {this;}
function totalSupply() public view returns (uint256) {this;}
function balanceOf(address _owner) public view returns (uint256) {_owner; this;}
function allowance(address _owner, address _spender) public view returns (uint256) {_owner; _spender; this;}
function transfer(address _to, uint256 _value) public;
function transferFrom(address _from, address _to, uint256 _value) public;
function approve(address _spender, uint256 _value) public;
}
contract IBancorX {
function xTransfer(bytes32 _toBlockchain, bytes32 _to, uint256 _amount, uint256 _id) public;
function getXTransferAmount(uint256 _xTransferId, address _for) public view returns (uint256);
}
/*
Token Holder interface
*/
contract ITokenHolder is IOwned {
function withdrawTokens(IERC20Token _token, address _to, uint256 _amount) public;
}
/**
* @dev Utilities & Common Modifiers
*/
contract Utils {
/**
* constructor
*/
constructor() public {
}
// verifies that an amount is greater than zero
modifier greaterThanZero(uint256 _amount) {
require(_amount > 0);
_;
}
// validates an address - currently only checks that it isn't null
modifier validAddress(address _address) {
require(_address != address(0));
_;
}
// verifies that the address is different than this contract address
modifier notThis(address _address) {
require(_address != address(this));
_;
}
}
/**
* @dev Provides support and utilities for contract ownership
*/
contract Owned is IOwned {
address public owner;
address public newOwner;
/**
* @dev triggered when the owner is updated
*
* @param _prevOwner previous owner
* @param _newOwner new owner
*/
event OwnerUpdate(address indexed _prevOwner, address indexed _newOwner);
/**
* @dev initializes a new Owned instance
*/
constructor() public {
owner = msg.sender;
}
// allows execution by the owner only
modifier ownerOnly {
require(msg.sender == owner);
_;
}
/**
* @dev allows transferring the contract ownership
* the new owner still needs to accept the transfer
* can only be called by the contract owner
*
* @param _newOwner new contract owner
*/
function transferOwnership(address _newOwner) public ownerOnly {
require(_newOwner != owner);
newOwner = _newOwner;
}
/**
* @dev used by a new owner to accept an ownership transfer
*/
function acceptOwnership() public {
require(msg.sender == newOwner);
emit OwnerUpdate(owner, newOwner);
owner = newOwner;
newOwner = address(0);
}
}
/**
* @dev We consider every contract to be a 'token holder' since it's currently not possible
* for a contract to deny receiving tokens.
*
* The TokenHolder's contract sole purpose is to provide a safety mechanism that allows
* the owner to send tokens that were sent to the contract by mistake back to their sender.
*
* Note that we use the non standard ERC-20 interface which has no return value for transfer
* in order to support both non standard as well as standard token contracts.
* see https://github.com/ethereum/solidity/issues/4116
*/
contract TokenHolder is ITokenHolder, Owned, Utils {
/**
* @dev initializes a new TokenHolder instance
*/
constructor() public {
}
/**
* @dev withdraws tokens held by the contract and sends them to an account
* can only be called by the owner
*
* @param _token ERC20 token contract address
* @param _to account to receive the new amount
* @param _amount amount to withdraw
*/
function withdrawTokens(IERC20Token _token, address _to, uint256 _amount)
public
ownerOnly
validAddress(_token)
validAddress(_to)
notThis(_to)
{
INonStandardERC20(_token).transfer(_to, _amount);
}
}
contract AirDropper is TokenHolder {
enum State {
storeEnabled,
storeDisabled,
transferEnabled
}
address public agent;
State public state;
bytes32 public storedBalancesCRC;
mapping (address => uint256) public storedBalances;
mapping (address => uint256) public transferredBalances;
constructor() TokenHolder() public {
state = State.storeEnabled;
}
function setAgent(address _agent) external ownerOnly {
agent = _agent;
}
function setState(State _state) external ownerOnly {
state = _state;
}
function storeBatch(address[] _targets, uint256[] _amounts) external {
bytes32 crc = 0;
require(msg.sender == agent && state == State.storeEnabled);
uint256 length = _targets.length;
require(length == _amounts.length);
for (uint256 i = 0; i < length; i++) {
address target = _targets[i];
uint256 amount = _amounts[i];
require(storedBalances[target] == 0);
storedBalances[target] = amount;
crc ^= keccak256(abi.encodePacked(_targets[i], _amounts[i]));
}
storedBalancesCRC ^= crc;
}
function transferEth(IERC20Token _token, address[] _targets, uint256[] _amounts) external {
require(msg.sender == agent && state == State.transferEnabled);
uint256 length = _targets.length;
require(length == _amounts.length);
for (uint256 i = 0; i < length; i++) {
address target = _targets[i];
uint256 amount = _amounts[i];
require(storedBalances[target] == amount);
require(transferredBalances[target] == 0);
require(_token.transfer(target, amount));
transferredBalances[target] = amount;
}
}
function transferEos(IBancorX _bancorX, bytes32 _target, uint256 _amount) external {
require(msg.sender == agent && state == State.transferEnabled);
require(storedBalances[_bancorX] == _amount);
require(transferredBalances[_bancorX] == 0);
_bancorX.xTransfer("eos", _target, _amount, 0);
transferredBalances[_bancorX] = _amount;
}
}