Transaction Hash:
Block:
17599737 at Jul-01-2023 02:15:59 PM +UTC
Transaction Fee:
0.010844173227847089 ETH
$26.49
Gas Used:
216,501 Gas / 50.088328589 Gwei
Emitted Events:
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0xd1917932...c2734763F | (Bulksender.app) | ||||
0xdAC17F95...13D831ec7 | |||||
0xe688b84b...2CDB71127
Miner
| (Fee Recipient: 0xe68...127) | 45.99369351947196524 Eth | 45.99412652147196524 Eth | 0.000433002 | |
0xf5491f79...F66c4b40B |
2.857705482745647211 Eth
Nonce: 6774
|
2.846861309517800122 Eth
Nonce: 6775
| 0.010844173227847089 |
Execution Trace
BulksenderProxy.f6fff9bd( )
0xcfd68b6c4da7a17c494817e4994a7999e7dc830e.f6fff9bd( )
-
TetherToken.transferFrom( _from=0xf5491f793D47A6Ea22f5e0B9AD3990CF66c4b40B, _to=0xd1917932A7Db6Af687B523D5Db5d7f5c2734763F, _value=9551250000 )
-
TetherToken.transfer( _to=0xa129ED83605C7b733f5f244371219cf11E24F863, _value=6995000000 )
-
TetherToken.transfer( _to=0x77e7b9f0B5A54aaDF53Dc30C8a5bb3844C7F5F62, _value=995000000 )
-
TetherToken.transfer( _to=0x7AA042125a4a0B1D720dC3eB40781b9d087e90C3, _value=495000000 )
-
TetherToken.transfer( _to=0xff06c2f313e4693B91861d81ea65877393C39dE0, _value=495000000 )
-
TetherToken.transfer( _to=0xA6E6CcaF8763Ce80CA6C40a6c4c70B3269450D3e, _value=245000000 )
-
TetherToken.transfer( _to=0x5f70218D45ee9A26f5A27cFd867f33709396D9f3, _value=195000000 )
-
TetherToken.transfer( _to=0x7752D2285E5C5c2346ef898385496De7c207a5C9, _value=88750000 )
-
TetherToken.transfer( _to=0xdDb51Aaa730b3F403ae4C7213cCDECCAB501922b, _value=20000000 )
-
TetherToken.transfer( _to=0xAF6513ce171891C2a4E7b861e463785bdC0DfB09, _value=7500000 )
-
TetherToken.transfer( _to=0xb802A671F7fcC7111f756347154b82e01051bC9e, _value=7500000 )
-
TetherToken.transfer( _to=0xfFB134F11ba6F8C71e5e194aa2A22344B6aFa859, _value=7500000 )
-
File 1 of 2: BulksenderProxy
File 2 of 2: TetherToken
/** * @title Bulksender, support ETH and ERC20 Tokens * @dev To Use this Dapp: https://bulksender.app */ pragma solidity 0.4.24; /** * @title Proxy * @dev Gives the possibility to delegate any call to a foreign implementation. */ contract Proxy { /** * @dev Tells the address of the implementation where every call will be delegated. * @return address of the implementation to which it will be delegated */ function implementation() public view returns (address); /** * @dev Tells the version of the current implementation * @return version of the current implementation */ function version() public view returns (string); /** * @dev Fallback function allowing to perform a delegatecall to the given implementation. * This function will return whatever the implementation call returns */ function () payable public { address _impl = implementation(); require(_impl != address(0)); assembly { let ptr := mload(0x40) calldatacopy(ptr, 0, calldatasize) let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0) let size := returndatasize returndatacopy(ptr, 0, size) switch result case 0 { revert(ptr, size) } default { return(ptr, size) } } } } pragma solidity 0.4.24; /** * @title UpgradeabilityProxy * @dev This contract represents a proxy where the implementation address to which it will delegate can be upgraded */ contract UpgradeabilityProxy is Proxy { /** * @dev This event will be emitted every time the implementation gets upgraded * @param implementation representing the address of the upgraded implementation */ event Upgraded(address indexed implementation, string version); // Storage position of the address of the current implementation bytes32 private constant implementationPosition = keccak256("bulksender.app.proxy.implementation"); //Version name of the current implementation string internal _version; /** * @dev Constructor function */ constructor() public {} /** * @dev Tells the version name of the current implementation * @return string representing the name of the current version */ function version() public view returns (string) { return _version; } /** * @dev Tells the address of the current implementation * @return address of the current implementation */ function implementation() public view returns (address impl) { bytes32 position = implementationPosition; assembly { impl := sload(position) } } /** * @dev Sets the address of the current implementation * @param _newImplementation address representing the new implementation to be set */ function _setImplementation(address _newImplementation) internal { bytes32 position = implementationPosition; assembly { sstore(position, _newImplementation) } } /** * @dev Upgrades the implementation address * @param _newImplementation representing the address of the new implementation to be set */ function _upgradeTo(address _newImplementation, string _newVersion) internal { address currentImplementation = implementation(); require(currentImplementation != _newImplementation); _setImplementation(_newImplementation); _version = _newVersion; emit Upgraded( _newImplementation, _newVersion); } } pragma solidity 0.4.24; /** * @title BulksenderProxy * @dev This contract combines an upgradeability proxy with basic authorization control functionalities */ contract BulksenderProxy is UpgradeabilityProxy { /** * @dev Event to show ownership has been transferred * @param previousOwner representing the address of the previous owner * @param newOwner representing the address of the new owner */ event ProxyOwnershipTransferred(address previousOwner, address newOwner); // Storage position of the owner of the contract bytes32 private constant proxyOwnerPosition = keccak256("bulksender.app.proxy.owner"); /** * @dev the constructor sets the original owner of the contract to the sender account. */ constructor(address _implementation, string _version) public { _setUpgradeabilityOwner(msg.sender); _upgradeTo(_implementation, _version); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyProxyOwner() { require(msg.sender == proxyOwner()); _; } /** * @dev Tells the address of the owner * @return the address of the owner */ function proxyOwner() public view returns (address owner) { bytes32 position = proxyOwnerPosition; assembly { owner := sload(position) } } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function transferProxyOwnership(address _newOwner) public onlyProxyOwner { require(_newOwner != address(0)); _setUpgradeabilityOwner(_newOwner); emit ProxyOwnershipTransferred(proxyOwner(), _newOwner); } /** * @dev Allows the proxy owner to upgrade the current version of the proxy. * @param _implementation representing the address of the new implementation to be set. */ function upgradeTo(address _implementation, string _newVersion) public onlyProxyOwner { _upgradeTo(_implementation, _newVersion); } /** * @dev Allows the proxy owner to upgrade the current version of the proxy and call the new implementation * to initialize whatever is needed through a low level call. * @param _implementation representing the address of the new implementation to be set. * @param _data represents the msg.data to bet sent in the low level call. This parameter may include the function * signature of the implementation to be called with the needed payload */ function upgradeToAndCall(address _implementation, string _newVersion, bytes _data) payable public onlyProxyOwner { _upgradeTo(_implementation, _newVersion); require(address(this).call.value(msg.value)(_data)); } /* * @dev Sets the address of the owner */ function _setUpgradeabilityOwner(address _newProxyOwner) internal { bytes32 position = proxyOwnerPosition; assembly { sstore(position, _newProxyOwner) } } }
File 2 of 2: TetherToken
pragma solidity ^0.4.17; /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } } /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address public owner; /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ function Ownable() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { if (newOwner != address(0)) { owner = newOwner; } } } /** * @title ERC20Basic * @dev Simpler version of ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ contract ERC20Basic { uint public _totalSupply; function totalSupply() public constant returns (uint); function balanceOf(address who) public constant returns (uint); function transfer(address to, uint value) public; event Transfer(address indexed from, address indexed to, uint value); } /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ contract ERC20 is ERC20Basic { function allowance(address owner, address spender) public constant returns (uint); function transferFrom(address from, address to, uint value) public; function approve(address spender, uint value) public; event Approval(address indexed owner, address indexed spender, uint value); } /** * @title Basic token * @dev Basic version of StandardToken, with no allowances. */ contract BasicToken is Ownable, ERC20Basic { using SafeMath for uint; mapping(address => uint) public balances; // additional variables for use if transaction fees ever became necessary uint public basisPointsRate = 0; uint public maximumFee = 0; /** * @dev Fix for the ERC20 short address attack. */ modifier onlyPayloadSize(uint size) { require(!(msg.data.length < size + 4)); _; } /** * @dev transfer token for a specified address * @param _to The address to transfer to. * @param _value The amount to be transferred. */ function transfer(address _to, uint _value) public onlyPayloadSize(2 * 32) { uint fee = (_value.mul(basisPointsRate)).div(10000); if (fee > maximumFee) { fee = maximumFee; } uint sendAmount = _value.sub(fee); balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(sendAmount); if (fee > 0) { balances[owner] = balances[owner].add(fee); Transfer(msg.sender, owner, fee); } Transfer(msg.sender, _to, sendAmount); } /** * @dev Gets the balance of the specified address. * @param _owner The address to query the the balance of. * @return An uint representing the amount owned by the passed address. */ function balanceOf(address _owner) public constant returns (uint balance) { return balances[_owner]; } } /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * @dev https://github.com/ethereum/EIPs/issues/20 * @dev Based oncode by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol */ contract StandardToken is BasicToken, ERC20 { mapping (address => mapping (address => uint)) public allowed; uint public constant MAX_UINT = 2**256 - 1; /** * @dev Transfer tokens from one address to another * @param _from address The address which you want to send tokens from * @param _to address The address which you want to transfer to * @param _value uint the amount of tokens to be transferred */ function transferFrom(address _from, address _to, uint _value) public onlyPayloadSize(3 * 32) { var _allowance = allowed[_from][msg.sender]; // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met // if (_value > _allowance) throw; uint fee = (_value.mul(basisPointsRate)).div(10000); if (fee > maximumFee) { fee = maximumFee; } if (_allowance < MAX_UINT) { allowed[_from][msg.sender] = _allowance.sub(_value); } uint sendAmount = _value.sub(fee); balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(sendAmount); if (fee > 0) { balances[owner] = balances[owner].add(fee); Transfer(_from, owner, fee); } Transfer(_from, _to, sendAmount); } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * @param _spender The address which will spend the funds. * @param _value The amount of tokens to be spent. */ function approve(address _spender, uint _value) public onlyPayloadSize(2 * 32) { // To change the approve amount you first have to reduce the addresses` // allowance to zero by calling `approve(_spender, 0)` if it is not // already 0 to mitigate the race condition described here: // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 require(!((_value != 0) && (allowed[msg.sender][_spender] != 0))); allowed[msg.sender][_spender] = _value; Approval(msg.sender, _spender, _value); } /** * @dev Function to check the amount of tokens than an owner allowed to a spender. * @param _owner address The address which owns the funds. * @param _spender address The address which will spend the funds. * @return A uint specifying the amount of tokens still available for the spender. */ function allowance(address _owner, address _spender) public constant returns (uint remaining) { return allowed[_owner][_spender]; } } /** * @title Pausable * @dev Base contract which allows children to implement an emergency stop mechanism. */ contract Pausable is Ownable { event Pause(); event Unpause(); bool public paused = false; /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!paused); _; } /** * @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(paused); _; } /** * @dev called by the owner to pause, triggers stopped state */ function pause() onlyOwner whenNotPaused public { paused = true; Pause(); } /** * @dev called by the owner to unpause, returns to normal state */ function unpause() onlyOwner whenPaused public { paused = false; Unpause(); } } contract BlackList is Ownable, BasicToken { /////// Getters to allow the same blacklist to be used also by other contracts (including upgraded Tether) /////// function getBlackListStatus(address _maker) external constant returns (bool) { return isBlackListed[_maker]; } function getOwner() external constant returns (address) { return owner; } mapping (address => bool) public isBlackListed; function addBlackList (address _evilUser) public onlyOwner { isBlackListed[_evilUser] = true; AddedBlackList(_evilUser); } function removeBlackList (address _clearedUser) public onlyOwner { isBlackListed[_clearedUser] = false; RemovedBlackList(_clearedUser); } function destroyBlackFunds (address _blackListedUser) public onlyOwner { require(isBlackListed[_blackListedUser]); uint dirtyFunds = balanceOf(_blackListedUser); balances[_blackListedUser] = 0; _totalSupply -= dirtyFunds; DestroyedBlackFunds(_blackListedUser, dirtyFunds); } event DestroyedBlackFunds(address _blackListedUser, uint _balance); event AddedBlackList(address _user); event RemovedBlackList(address _user); } contract UpgradedStandardToken is StandardToken{ // those methods are called by the legacy contract // and they must ensure msg.sender to be the contract address function transferByLegacy(address from, address to, uint value) public; function transferFromByLegacy(address sender, address from, address spender, uint value) public; function approveByLegacy(address from, address spender, uint value) public; } contract TetherToken is Pausable, StandardToken, BlackList { string public name; string public symbol; uint public decimals; address public upgradedAddress; bool public deprecated; // The contract can be initialized with a number of tokens // All the tokens are deposited to the owner address // // @param _balance Initial supply of the contract // @param _name Token Name // @param _symbol Token symbol // @param _decimals Token decimals function TetherToken(uint _initialSupply, string _name, string _symbol, uint _decimals) public { _totalSupply = _initialSupply; name = _name; symbol = _symbol; decimals = _decimals; balances[owner] = _initialSupply; deprecated = false; } // Forward ERC20 methods to upgraded contract if this one is deprecated function transfer(address _to, uint _value) public whenNotPaused { require(!isBlackListed[msg.sender]); if (deprecated) { return UpgradedStandardToken(upgradedAddress).transferByLegacy(msg.sender, _to, _value); } else { return super.transfer(_to, _value); } } // Forward ERC20 methods to upgraded contract if this one is deprecated function transferFrom(address _from, address _to, uint _value) public whenNotPaused { require(!isBlackListed[_from]); if (deprecated) { return UpgradedStandardToken(upgradedAddress).transferFromByLegacy(msg.sender, _from, _to, _value); } else { return super.transferFrom(_from, _to, _value); } } // Forward ERC20 methods to upgraded contract if this one is deprecated function balanceOf(address who) public constant returns (uint) { if (deprecated) { return UpgradedStandardToken(upgradedAddress).balanceOf(who); } else { return super.balanceOf(who); } } // Forward ERC20 methods to upgraded contract if this one is deprecated function approve(address _spender, uint _value) public onlyPayloadSize(2 * 32) { if (deprecated) { return UpgradedStandardToken(upgradedAddress).approveByLegacy(msg.sender, _spender, _value); } else { return super.approve(_spender, _value); } } // Forward ERC20 methods to upgraded contract if this one is deprecated function allowance(address _owner, address _spender) public constant returns (uint remaining) { if (deprecated) { return StandardToken(upgradedAddress).allowance(_owner, _spender); } else { return super.allowance(_owner, _spender); } } // deprecate current contract in favour of a new one function deprecate(address _upgradedAddress) public onlyOwner { deprecated = true; upgradedAddress = _upgradedAddress; Deprecate(_upgradedAddress); } // deprecate current contract if favour of a new one function totalSupply() public constant returns (uint) { if (deprecated) { return StandardToken(upgradedAddress).totalSupply(); } else { return _totalSupply; } } // Issue a new amount of tokens // these tokens are deposited into the owner address // // @param _amount Number of tokens to be issued function issue(uint amount) public onlyOwner { require(_totalSupply + amount > _totalSupply); require(balances[owner] + amount > balances[owner]); balances[owner] += amount; _totalSupply += amount; Issue(amount); } // Redeem tokens. // These tokens are withdrawn from the owner address // if the balance must be enough to cover the redeem // or the call will fail. // @param _amount Number of tokens to be issued function redeem(uint amount) public onlyOwner { require(_totalSupply >= amount); require(balances[owner] >= amount); _totalSupply -= amount; balances[owner] -= amount; Redeem(amount); } function setParams(uint newBasisPoints, uint newMaxFee) public onlyOwner { // Ensure transparency by hardcoding limit beyond which fees can never be added require(newBasisPoints < 20); require(newMaxFee < 50); basisPointsRate = newBasisPoints; maximumFee = newMaxFee.mul(10**decimals); Params(basisPointsRate, maximumFee); } // Called when new token are issued event Issue(uint amount); // Called when tokens are redeemed event Redeem(uint amount); // Called when contract is deprecated event Deprecate(address newAddress); // Called if contract ever adds fees event Params(uint feeBasisPoints, uint maxFee); }