Transaction Hash:
Block:
10651346 at Aug-13-2020 11:28:01 AM +UTC
Transaction Fee:
0.01581408 ETH
$40.54
Gas Used:
43,928 Gas / 360 Gwei
Emitted Events:
226 |
EURXProxy.0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef( 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000ffec0067f5a79cff07527f63d83dd5462ccf8ba4, 00000000000000000000000000000000000000000000032d26d12e980b600000 )
|
227 |
EURXProxy.0xab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8( 0xab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8, 0000000000000000000000000031e147a79c45f24319dc02ca860cb6142fcba1, 000000000000000000000000ffec0067f5a79cff07527f63d83dd5462ccf8ba4, 00000000000000000000000000000000000000000000032d26d12e980b600000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x0031e147...6142FCBA1 | (Nexo 3) |
90.124166280472063039 Eth
Nonce: 379652
|
90.108352200472063039 Eth
Nonce: 379653
| 0.01581408 | |
0x5A0b54D5...D3E029c4c
Miner
| (Spark Pool) | 254.815171524652125909 Eth | 254.830985604652125909 Eth | 0.01581408 | |
0xEfa6D996...55E77b553 |
Execution Trace
EURXProxy.40c10f19( )

-
EURX.mint( to=0xFfec0067F5a79CFf07527f63D83dD5462cCf8BA4, tokens=15000000000000000000000 ) => ( True )
File 1 of 2: EURXProxy
File 2 of 2: EURX
// File: zos-lib/contracts/upgradeability/Proxy.sol pragma solidity ^0.4.24; /** * @title Proxy * @dev Implements delegation of calls to other contracts, with proper * forwarding of return values and bubbling of failures. * It defines a fallback function that delegates all calls to the address * returned by the abstract _implementation() internal function. */ contract Proxy { /** * @dev Fallback function. * Implemented entirely in `_fallback`. */ function () payable external { _fallback(); } /** * @return The Address of the implementation. */ function _implementation() internal view returns (address); /** * @dev Delegates execution to an implementation contract. * This is a low level function that doesn't return to its internal call site. * It will return to the external caller whatever the implementation returns. * @param implementation Address to delegate. */ function _delegate(address implementation) internal { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize) } default { return(0, returndatasize) } } } /** * @dev Function that is run as the first thing in the fallback function. * Can be redefined in derived contracts to add functionality. * Redefinitions must call super._willFallback(). */ function _willFallback() internal { } /** * @dev fallback implementation. * Extracted to enable manual triggering. */ function _fallback() internal { _willFallback(); _delegate(_implementation()); } } // File: zos-lib/contracts/utils/Address.sol pragma solidity ^0.4.24; /** * Utility library of inline functions on addresses * * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.0.0/contracts/utils/Address.sol * This contract is copied here and renamed from the original to avoid clashes in the compiled artifacts * when the user imports a zos-lib contract (that transitively causes this contract to be compiled and added to the * build/artifacts folder) as well as the vanilla Address implementation from an openzeppelin version. */ library ZOSLibAddress { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param account address of the account to check * @return whether the target address is a contract */ function isContract(address account) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solium-disable-next-line security/no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } // File: zos-lib/contracts/upgradeability/UpgradeabilityProxy.sol pragma solidity ^0.4.24; /** * @title UpgradeabilityProxy * @dev This contract implements a proxy that allows to change the * implementation address to which it will delegate. * Such a change is called an implementation upgrade. */ contract UpgradeabilityProxy is Proxy { /** * @dev Emitted when the implementation is upgraded. * @param implementation Address of the new implementation. */ event Upgraded(address indexed implementation); /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "org.zeppelinos.proxy.implementation", and is * validated in the constructor. */ bytes32 private constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3; /** * @dev Contract constructor. * @param _implementation Address of the initial implementation. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ constructor(address _implementation, bytes _data) public payable { assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation")); _setImplementation(_implementation); if(_data.length > 0) { require(_implementation.delegatecall(_data)); } } /** * @dev Returns the current implementation. * @return Address of the current implementation */ function _implementation() internal view returns (address impl) { bytes32 slot = IMPLEMENTATION_SLOT; assembly { impl := sload(slot) } } /** * @dev Upgrades the proxy to a new implementation. * @param newImplementation Address of the new implementation. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Sets the implementation address of the proxy. * @param newImplementation Address of the new implementation. */ function _setImplementation(address newImplementation) private { require(ZOSLibAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address"); bytes32 slot = IMPLEMENTATION_SLOT; assembly { sstore(slot, newImplementation) } } } // File: zos-lib/contracts/upgradeability/AdminUpgradeabilityProxy.sol pragma solidity ^0.4.24; /** * @title AdminUpgradeabilityProxy * @dev This contract combines an upgradeability proxy with an authorization * mechanism for administrative tasks. * All external functions in this contract must be guarded by the * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity * feature proposal that would enable this to be done automatically. */ contract AdminUpgradeabilityProxy is UpgradeabilityProxy { /** * @dev Emitted when the administration has been transferred. * @param previousAdmin Address of the previous admin. * @param newAdmin Address of the new admin. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "org.zeppelinos.proxy.admin", and is * validated in the constructor. */ bytes32 private constant ADMIN_SLOT = 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b; /** * @dev Modifier to check whether the `msg.sender` is the admin. * If it is, it will run the function. Otherwise, it will delegate the call * to the implementation. */ modifier ifAdmin() { if (msg.sender == _admin()) { _; } else { _fallback(); } } /** * Contract constructor. * @param _implementation address of the initial implementation. * @param _admin Address of the proxy administrator. * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. */ constructor(address _implementation, address _admin, bytes _data) UpgradeabilityProxy(_implementation, _data) public payable { assert(ADMIN_SLOT == keccak256("org.zeppelinos.proxy.admin")); _setAdmin(_admin); } /** * @return The address of the proxy admin. */ function admin() external view ifAdmin returns (address) { return _admin(); } /** * @return The address of the implementation. */ function implementation() external view ifAdmin returns (address) { return _implementation(); } /** * @dev Changes the admin of the proxy. * Only the current admin can call this function. * @param newAdmin Address to transfer proxy administration to. */ function changeAdmin(address newAdmin) external ifAdmin { require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address"); emit AdminChanged(_admin(), newAdmin); _setAdmin(newAdmin); } /** * @dev Upgrade the backing implementation of the proxy. * Only the admin can call this function. * @param newImplementation Address of the new implementation. */ function upgradeTo(address newImplementation) external ifAdmin { _upgradeTo(newImplementation); } /** * @dev Upgrade the backing implementation of the proxy and call a function * on the new implementation. * This is useful to initialize the proxied contract. * @param newImplementation Address of the new implementation. * @param data Data to send as msg.data in the low level call. * It should include the signature and the parameters of the function to be called, as described in * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. */ function upgradeToAndCall(address newImplementation, bytes data) payable external ifAdmin { _upgradeTo(newImplementation); require(newImplementation.delegatecall(data)); } /** * @return The admin slot. */ function _admin() internal view returns (address adm) { bytes32 slot = ADMIN_SLOT; assembly { adm := sload(slot) } } /** * @dev Sets the address of the proxy admin. * @param newAdmin Address of the new proxy admin. */ function _setAdmin(address newAdmin) internal { bytes32 slot = ADMIN_SLOT; assembly { sstore(slot, newAdmin) } } /** * @dev Only fall back when the sender is not the admin. */ function _willFallback() internal { require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin"); super._willFallback(); } } pragma solidity ^0.4.24; contract EURXProxy is AdminUpgradeabilityProxy { constructor(address _implementation, address _admin, bytes _data) public AdminUpgradeabilityProxy(_implementation, _admin, _data) { } }
File 2 of 2: EURX
// File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol pragma solidity ^0.5.2; /** * @title ERC20 interface * @dev see https://eips.ethereum.org/EIPS/eip-20 */ interface IERC20 { function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.2; /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two unsigned integers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol pragma solidity ^0.5.2; /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://eips.ethereum.org/EIPS/eip-20 * Originally based on code by FirstBlood: * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol * * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for * all accounts just by listening to said events. Note that this isn't required by the specification, and other * compliant implementations may not do it. */ contract ERC20 is IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowed; uint256 private _totalSupply; /** * @dev Total number of tokens in existence */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev Gets the balance of the specified address. * @param owner The address to query the balance of. * @return A uint256 representing the amount owned by the passed address. */ function balanceOf(address owner) public view returns (uint256) { return _balances[owner]; } /** * @dev Function to check the amount of tokens that 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 uint256 specifying the amount of tokens still available for the spender. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowed[owner][spender]; } /** * @dev Transfer token to a specified address * @param to The address to transfer to. * @param value The amount to be transferred. */ function transfer(address to, uint256 value) public returns (bool) { _transfer(msg.sender, to, value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. */ function approve(address spender, uint256 value) public returns (bool) { _approve(msg.sender, spender, value); return true; } /** * @dev Transfer tokens from one address to another. * Note that while this function emits an Approval event, this is not required as per the specification, * and other compliant implementations may not emit the event. * @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 uint256 the amount of tokens to be transferred */ function transferFrom(address from, address to, uint256 value) public returns (bool) { _transfer(from, to, value); _approve(from, msg.sender, _allowed[from][msg.sender].sub(value)); return true; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. * approve should be called when _allowed[msg.sender][spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * Emits an Approval event. * @param spender The address which will spend the funds. * @param addedValue The amount of tokens to increase the allowance by. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue)); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. * approve should be called when _allowed[msg.sender][spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * Emits an Approval event. * @param spender The address which will spend the funds. * @param subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue)); return true; } /** * @dev Transfer token for a specified addresses * @param from The address to transfer from. * @param to The address to transfer to. * @param value The amount to be transferred. */ function _transfer(address from, address to, uint256 value) internal { require(to != address(0)); _balances[from] = _balances[from].sub(value); _balances[to] = _balances[to].add(value); emit Transfer(from, to, value); } /** * @dev Internal function that mints an amount of the token and assigns it to * an account. This encapsulates the modification of balances such that the * proper events are emitted. * @param account The account that will receive the created tokens. * @param value The amount that will be created. */ function _mint(address account, uint256 value) internal { require(account != address(0)); _totalSupply = _totalSupply.add(value); _balances[account] = _balances[account].add(value); emit Transfer(address(0), account, value); } /** * @dev Internal function that burns an amount of the token of a given * account. * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burn(address account, uint256 value) internal { require(account != address(0)); _totalSupply = _totalSupply.sub(value); _balances[account] = _balances[account].sub(value); emit Transfer(account, address(0), value); } /** * @dev Approve an address to spend another addresses' tokens. * @param owner The address that owns the tokens. * @param spender The address that will spend the tokens. * @param value The number of tokens that can be spent. */ function _approve(address owner, address spender, uint256 value) internal { require(spender != address(0)); require(owner != address(0)); _allowed[owner][spender] = value; emit Approval(owner, spender, value); } /** * @dev Internal function that burns an amount of the token of a given * account, deducting from the sender's allowance for said account. Uses the * internal burn function. * Emits an Approval event (reflecting the reduced allowance). * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burnFrom(address account, uint256 value) internal { _burn(account, value); _approve(account, msg.sender, _allowed[account][msg.sender].sub(value)); } } // File: contracts/Ownable.sol pragma solidity ^0.5.2; contract Ownable { // Owner of the contract address private _owner; // Potential owner of the contract address private _potentialOwner; /** * @dev Event to show that a new potential owner has been set * @param previousOwner representing the address of the previous owner * @param potentialOwner representing the address of the potential owner */ event NewPotentialOwner(address previousOwner, address potentialOwner); /** * @dev Event to show ownership has been claimed * Triggered when potentialOwner has claimed his ownership * @param previousOwner representing the address of the previous owner * @param newOwner representing the address of the new owner */ event OwnershipClaimed(address previousOwner, address newOwner); /** * @return the address of the owner */ function owner() public view returns (address) { return _owner; } /** * @return the address of the potential owner */ function potentialOwner() public view returns (address) { return _potentialOwner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner()); _; } /** * @dev Sets a new owner address * Called only when initializing the EURX contract */ function setOwner(address newOwner) internal { _owner = newOwner; } /** * @dev Allows the current owner to transfer control of the contract to a potential owner. * @param newOwner The address to transfer ownership to. */ function setPotentialOwner(address newOwner) public onlyOwner { require(newOwner != address(0)); _potentialOwner = newOwner; emit NewPotentialOwner(owner(), potentialOwner()); } /** * @dev Allows the potential owner to claim ownership. */ function claimOwnership() public { require(msg.sender == potentialOwner()); _owner = _potentialOwner; _potentialOwner = address(0); emit OwnershipClaimed(owner(), potentialOwner()); } } // File: contracts/Pausable.sol pragma solidity ^0.5.2; /** * @title Pausable * @dev Base contract which allows children to implement an emergency stop mechanism. * Based on openzeppelin tag v2.2 commit: 9ed1b4486519113ee05fa648acb4ebcecd070cbf * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/lifecycle/Pausable.sol * Modifications: * 1) Remove address pauser from events Pause and Unpause * 2) Added pauser role, switched pause/unpause to be onlyPauser * 3) Removed whenNotPaused/whenPaused from pause/unpause * 4) Removed whenPaused modifier * 5) Inherit from Ownable contract * 6) Remove constructor */ contract Pausable is Ownable { event Pause(); event Unpause(); event PauserChanged(address indexed newAddress); address private _pauser; bool private _paused; /** * @return True if the contract is paused, false otherwise. */ function paused() public view returns (bool) { return _paused; } /** * @return address of pauser */ function pauser() public view returns (address) { return _pauser; } /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!_paused); _; } /** * @dev throws if called by any account other than the pauser */ modifier onlyPauser() { require(msg.sender == pauser()); _; } /** * @dev called by the owner to pause, triggers stopped state */ function pause() onlyPauser public { _paused = true; emit Pause(); } /** * @dev called by the owner to unpause, returns to normal state */ function unpause() onlyPauser public { _paused = false; emit Unpause(); } /** * @dev update the pauser role */ function updatePauser(address _newPauser) onlyOwner public { require(_newPauser != address(0)); _pauser = _newPauser; emit PauserChanged(pauser()); } } pragma solidity ^0.5.2; contract EURX is ERC20, Ownable, Pausable { string constant public name = 'EUR Stablecoin'; string constant public symbol = 'EURX'; uint8 constant public decimals = 18; address public masterMinter; address public minter; bool private initialized; event Mint(address minter, address to, uint256 amount); event Burn(address from, uint256 amount); // Set initialized state to true to prevent tampering with implementation contract constructor() public { setOwner(msg.sender); initialized = true; } function initialize(address _owner, address _pauser, address _masterMinter, address _minter) public { require(!initialized); require(_owner != address(0)); require(_pauser != address(0)); require(_masterMinter != address(0)); require(_minter != address(0)); setOwner(_owner); updatePauser(_pauser); masterMinter = _masterMinter; minter = _minter; initialized = true; } function transfer(address to, uint256 tokens) public whenNotPaused returns (bool) { return super.transfer(to, tokens); } function transferFrom(address from, address to, uint256 tokens) public whenNotPaused returns (bool) { return super.transferFrom(from, to, tokens); } function approve(address spender, uint256 tokens) public whenNotPaused returns (bool) { return super.approve(spender, tokens); } function increaseAllowance(address spender, uint addedTokens) public whenNotPaused returns (bool success) { return super.increaseAllowance(spender, addedTokens); } function decreaseAllowance(address spender, uint subtractedTokens) public whenNotPaused returns (bool success) { return super.decreaseAllowance(spender, subtractedTokens); } /** * @dev Function to change masterMinter address. * @param _masterMinter Address of new masterMinter. * @return A boolean that indicates if operation was successful. */ function updateMasterMinter(address _masterMinter) onlyOwner public returns (bool) { require(_masterMinter != address(0)); masterMinter = _masterMinter; return true; } /** * @dev Function to change minter address. * @param _minter Address of new masterMinter. * @return A boolean that indicates if operation was successful. */ function updateMinter(address _minter) onlyOwner public returns (bool) { require(_minter != address(0)); minter = _minter; return true; } /** * @dev Function to mint tokens. * @param to The address to mint tokens to. * @param tokens The amount of tokens to mint. * @return A boolean that indicates if the operation was successful. */ function mint(address to, uint256 tokens) public returns (bool) { require(msg.sender == minter || msg.sender == masterMinter); require(tokens > 0); if(msg.sender == minter && minter != masterMinter) { require(to == owner()); } _mint(to, tokens); emit Mint(msg.sender, to, tokens); return true; } /** * @dev Function to burn tokens. * Tokens are burned from caller address. * @param tokens The amount of tokens to burn. * @return A boolean that indicates if the operation was successful. */ function burn(uint256 tokens) public returns (bool) { require(tokens > 0); require(balanceOf(msg.sender) >= tokens); if(msg.sender != owner()) { require(!paused()); } _burn(msg.sender, tokens); emit Burn(msg.sender, tokens); return true; } // Owner can transfer out any accidentally sent ERC20 tokens function transferERC20Token(IERC20 _token, address _to, uint256 _value) public onlyOwner returns (bool success) { require(_token.balanceOf(address(this)) >= _value); uint256 receiverBalance = _token.balanceOf(_to); require(_token.transfer(_to, _value)); uint256 receiverNewBalance = _token.balanceOf(_to); assert(receiverNewBalance == receiverBalance.add(_value)); return true; } }