Transaction Hash:
Block:
4780666 at Dec-23-2017 05:05:41 AM +UTC
Transaction Fee:
0.00106466488162304 ETH
$3.91
Gas Used:
24,439 Gas / 43.56417536 Gwei
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x26C7e66E...90e622E85 |
0.023020533717056 Eth
Nonce: 9
|
0.02195586883543296 Eth
Nonce: 10
| 0.00106466488162304 | ||
0x829BD824...93333A830
Miner
| (F2Pool Old) | 5,768.288175064200957702 Eth | 5,768.289239729082580742 Eth | 0.00106466488162304 |
Execution Trace
JNTViewERC20.transfer( _to=0xE292221664BBf17b34622D84D311a67F79b1Db8F, _value=12577000000000000000000 )
/* Author: Victor Mezrin [email protected] */ pragma solidity ^0.4.18; /** * @title CommonModifiers * @dev Base contract which contains common checks. */ contract CommonModifiersInterface { /** * @dev Assemble the given address bytecode. If bytecode exists then the _addr is a contract. */ function isContract(address _targetAddress) internal constant returns (bool); /** * @dev modifier to allow actions only when the _targetAddress is a contract. */ modifier onlyContractAddress(address _targetAddress) { require(isContract(_targetAddress) == true); _; } } /** * @title CommonModifiers * @dev Base contract which contains common checks. */ contract CommonModifiers is CommonModifiersInterface { /** * @dev Assemble the given address bytecode. If bytecode exists then the _addr is a contract. */ function isContract(address _targetAddress) internal constant returns (bool) { require (_targetAddress != address(0x0)); uint256 length; assembly { //retrieve the size of the code on target address, this needs assembly length := extcodesize(_targetAddress) } return (length > 0); } } /** * @title AssetIDInterface * @dev Interface of a contract that assigned to an asset (JNT, jUSD etc.) * @dev Contracts for the same asset (like JNT, jUSD etc.) will have the same AssetID. * @dev This will help to avoid misconfiguration of contracts */ contract AssetIDInterface { function getAssetID() public constant returns (string); function getAssetIDHash() public constant returns (bytes32); } /** * @title AssetID * @dev Base contract implementing AssetIDInterface */ contract AssetID is AssetIDInterface { /* Storage */ string assetID; /* Constructor */ function AssetID(string _assetID) public { require(bytes(_assetID).length > 0); assetID = _assetID; } /* Getters */ function getAssetID() public constant returns (string) { return assetID; } function getAssetIDHash() public constant returns (bytes32) { return keccak256(assetID); } } /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract OwnableInterface { /** * @dev The getter for "owner" contract variable */ function getOwner() public constant returns (address); /** * @dev Throws if called by any account other than the current owner. */ modifier onlyOwner() { require (msg.sender == getOwner()); _; } } /** * @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 is OwnableInterface { /* Storage */ address owner = address(0x0); address proposedOwner = address(0x0); /* Events */ event OwnerAssignedEvent(address indexed newowner); event OwnershipOfferCreatedEvent(address indexed currentowner, address indexed proposedowner); event OwnershipOfferAcceptedEvent(address indexed currentowner, address indexed proposedowner); event OwnershipOfferCancelledEvent(address indexed currentowner, address indexed proposedowner); /** * @dev The constructor sets the initial `owner` to the passed account. */ function Ownable() public { owner = msg.sender; OwnerAssignedEvent(owner); } /** * @dev Old owner requests transfer ownership to the new owner. * @param _proposedOwner The address to transfer ownership to. */ function createOwnershipOffer(address _proposedOwner) external onlyOwner { require (proposedOwner == address(0x0)); require (_proposedOwner != address(0x0)); require (_proposedOwner != address(this)); proposedOwner = _proposedOwner; OwnershipOfferCreatedEvent(owner, _proposedOwner); } /** * @dev Allows the new owner to accept an ownership offer to contract control. */ //noinspection UnprotectedFunction function acceptOwnershipOffer() external { require (proposedOwner != address(0x0)); require (msg.sender == proposedOwner); address _oldOwner = owner; owner = proposedOwner; proposedOwner = address(0x0); OwnerAssignedEvent(owner); OwnershipOfferAcceptedEvent(_oldOwner, owner); } /** * @dev Old owner cancels transfer ownership to the new owner. */ function cancelOwnershipOffer() external { require (proposedOwner != address(0x0)); require (msg.sender == owner || msg.sender == proposedOwner); address _oldProposedOwner = proposedOwner; proposedOwner = address(0x0); OwnershipOfferCancelledEvent(owner, _oldProposedOwner); } /** * @dev The getter for "owner" contract variable */ function getOwner() public constant returns (address) { return owner; } /** * @dev The getter for "proposedOwner" contract variable */ function getProposedOwner() public constant returns (address) { return proposedOwner; } } /** * @title ManageableInterface * @dev Contract that allows to grant permissions to any address * @dev In real life we are no able to perform all actions with just one Ethereum address * @dev because risks are too high. * @dev Instead owner delegates rights to manage an contract to the different addresses and * @dev stay able to revoke permissions at any time. */ contract ManageableInterface { /** * @dev Function to check if the manager can perform the action or not * @param _manager address Manager`s address * @param _permissionName string Permission name * @return True if manager is enabled and has been granted needed permission */ function isManagerAllowed(address _manager, string _permissionName) public constant returns (bool); /** * @dev Modifier to use in derived contracts */ modifier onlyAllowedManager(string _permissionName) { require(isManagerAllowed(msg.sender, _permissionName) == true); _; } } contract Manageable is OwnableInterface, ManageableInterface { /* Storage */ mapping (address => bool) managerEnabled; // hard switch for a manager - on/off mapping (address => mapping (string => bool)) managerPermissions; // detailed info about manager`s permissions /* Events */ event ManagerEnabledEvent(address indexed manager); event ManagerDisabledEvent(address indexed manager); event ManagerPermissionGrantedEvent(address indexed manager, string permission); event ManagerPermissionRevokedEvent(address indexed manager, string permission); /* Configure contract */ /** * @dev Function to add new manager * @param _manager address New manager */ function enableManager(address _manager) external onlyOwner onlyValidManagerAddress(_manager) { require(managerEnabled[_manager] == false); managerEnabled[_manager] = true; ManagerEnabledEvent(_manager); } /** * @dev Function to remove existing manager * @param _manager address Existing manager */ function disableManager(address _manager) external onlyOwner onlyValidManagerAddress(_manager) { require(managerEnabled[_manager] == true); managerEnabled[_manager] = false; ManagerDisabledEvent(_manager); } /** * @dev Function to grant new permission to the manager * @param _manager address Existing manager * @param _permissionName string Granted permission name */ function grantManagerPermission( address _manager, string _permissionName ) external onlyOwner onlyValidManagerAddress(_manager) onlyValidPermissionName(_permissionName) { require(managerPermissions[_manager][_permissionName] == false); managerPermissions[_manager][_permissionName] = true; ManagerPermissionGrantedEvent(_manager, _permissionName); } /** * @dev Function to revoke permission of the manager * @param _manager address Existing manager * @param _permissionName string Revoked permission name */ function revokeManagerPermission( address _manager, string _permissionName ) external onlyOwner onlyValidManagerAddress(_manager) onlyValidPermissionName(_permissionName) { require(managerPermissions[_manager][_permissionName] == true); managerPermissions[_manager][_permissionName] = false; ManagerPermissionRevokedEvent(_manager, _permissionName); } /* Getters */ /** * @dev Function to check manager status * @param _manager address Manager`s address * @return True if manager is enabled */ function isManagerEnabled( address _manager ) public constant onlyValidManagerAddress(_manager) returns (bool) { return managerEnabled[_manager]; } /** * @dev Function to check permissions of a manager * @param _manager address Manager`s address * @param _permissionName string Permission name * @return True if manager has been granted needed permission */ function isPermissionGranted( address _manager, string _permissionName ) public constant onlyValidManagerAddress(_manager) onlyValidPermissionName(_permissionName) returns (bool) { return managerPermissions[_manager][_permissionName]; } /** * @dev Function to check if the manager can perform the action or not * @param _manager address Manager`s address * @param _permissionName string Permission name * @return True if manager is enabled and has been granted needed permission */ function isManagerAllowed( address _manager, string _permissionName ) public constant onlyValidManagerAddress(_manager) onlyValidPermissionName(_permissionName) returns (bool) { return (managerEnabled[_manager] && managerPermissions[_manager][_permissionName]); } /* Helpers */ /** * @dev Modifier to check manager address */ modifier onlyValidManagerAddress(address _manager) { require(_manager != address(0x0)); _; } /** * @dev Modifier to check name of manager permission */ modifier onlyValidPermissionName(string _permissionName) { require(bytes(_permissionName).length != 0); _; } } /** * @title PausableInterface * @dev Base contract which allows children to implement an emergency stop mechanism. * @dev Based on zeppelin's Pausable, but integrated with Manageable * @dev Contract is in paused state by default and should be explicitly unlocked */ contract PausableInterface { /** * Events */ event PauseEvent(); event UnpauseEvent(); /** * @dev called by the manager to pause, triggers stopped state */ function pauseContract() public; /** * @dev called by the manager to unpause, returns to normal state */ function unpauseContract() public; /** * @dev The getter for "paused" contract variable */ function getPaused() public constant returns (bool); /** * @dev modifier to allow actions only when the contract IS paused */ modifier whenContractNotPaused() { require(getPaused() == false); _; } /** * @dev modifier to allow actions only when the contract IS NOT paused */ modifier whenContractPaused { require(getPaused() == true); _; } } /** * @title Pausable * @dev Base contract which allows children to implement an emergency stop mechanism. * @dev Based on zeppelin's Pausable, but integrated with Manageable * @dev Contract is in paused state by default and should be explicitly unlocked */ contract Pausable is ManageableInterface, PausableInterface { /** * Storage */ bool paused = true; /** * @dev called by the manager to pause, triggers stopped state */ function pauseContract() public onlyAllowedManager('pause_contract') whenContractNotPaused { paused = true; PauseEvent(); } /** * @dev called by the manager to unpause, returns to normal state */ function unpauseContract() public onlyAllowedManager('unpause_contract') whenContractPaused { paused = false; UnpauseEvent(); } /** * @dev The getter for "paused" contract variable */ function getPaused() public constant returns (bool) { return paused; } } /** * @title BytecodeExecutorInterface interface * @dev Implementation of a contract that execute any bytecode on behalf of the contract * @dev Last resort for the immutable and not-replaceable contract :) */ contract BytecodeExecutorInterface { /* Events */ event CallExecutedEvent(address indexed target, uint256 suppliedGas, uint256 ethValue, bytes32 transactionBytecodeHash); event DelegatecallExecutedEvent(address indexed target, uint256 suppliedGas, bytes32 transactionBytecodeHash); /* Functions */ function executeCall(address _target, uint256 _suppliedGas, uint256 _ethValue, bytes _transactionBytecode) external; function executeDelegatecall(address _target, uint256 _suppliedGas, bytes _transactionBytecode) external; } /** * @title BytecodeExecutor * @dev Implementation of a contract that execute any bytecode on behalf of the contract * @dev Last resort for the immutable and not-replaceable contract :) */ contract BytecodeExecutor is ManageableInterface, BytecodeExecutorInterface { /* Storage */ bool underExecution = false; /* BytecodeExecutorInterface */ function executeCall( address _target, uint256 _suppliedGas, uint256 _ethValue, bytes _transactionBytecode ) external onlyAllowedManager('execute_call') { require(underExecution == false); underExecution = true; // Avoid recursive calling _target.call.gas(_suppliedGas).value(_ethValue)(_transactionBytecode); underExecution = false; CallExecutedEvent(_target, _suppliedGas, _ethValue, keccak256(_transactionBytecode)); } function executeDelegatecall( address _target, uint256 _suppliedGas, bytes _transactionBytecode ) external onlyAllowedManager('execute_delegatecall') { require(underExecution == false); underExecution = true; // Avoid recursive calling _target.delegatecall.gas(_suppliedGas)(_transactionBytecode); underExecution = false; DelegatecallExecutedEvent(_target, _suppliedGas, keccak256(_transactionBytecode)); } } /** * @title CrydrControllerERC20Interface interface * @dev Interface of a contract that implement business-logic of an ERC20 CryDR */ contract CrydrControllerERC20Interface { /* ERC20 support. _msgsender - account that invoked CrydrView */ function transfer(address _msgsender, address _to, uint256 _value) public; function getTotalSupply() public constant returns (uint256); function getBalance(address _owner) public constant returns (uint256); function approve(address _msgsender, address _spender, uint256 _value) public; function transferFrom(address _msgsender, address _from, address _to, uint256 _value) public; function getAllowance(address _owner, address _spender) public constant returns (uint256); } contract CrydrViewBaseInterface { /* Events */ event CrydrControllerChangedEvent(address indexed crydrcontroller); /* Configuration */ function setCrydrController(address _crydrController) external; function getCrydrController() public constant returns (address); function getCrydrViewStandardName() public constant returns (string); function getCrydrViewStandardNameHash() public constant returns (bytes32); } contract CrydrViewBase is CommonModifiersInterface, AssetIDInterface, ManageableInterface, PausableInterface, CrydrViewBaseInterface { /* Storage */ address crydrController = address(0x0); string crydrViewStandardName = ''; /* Constructor */ function CrydrViewBase(string _crydrViewStandardName) public { require(bytes(_crydrViewStandardName).length > 0); crydrViewStandardName = _crydrViewStandardName; } /* CrydrViewBaseInterface */ function setCrydrController( address _crydrController ) external onlyContractAddress(_crydrController) onlyAllowedManager('set_crydr_controller') whenContractPaused { require(crydrController != _crydrController); crydrController = _crydrController; CrydrControllerChangedEvent(_crydrController); } function getCrydrController() public constant returns (address) { return crydrController; } function getCrydrViewStandardName() public constant returns (string) { return crydrViewStandardName; } function getCrydrViewStandardNameHash() public constant returns (bytes32) { return keccak256(crydrViewStandardName); } /* PausableInterface */ /** * @dev Override method to ensure that contract properly configured before it is unpaused */ function unpauseContract() public { require(isContract(crydrController) == true); require(getAssetIDHash() == AssetIDInterface(crydrController).getAssetIDHash()); super.unpauseContract(); } } /** * @title CrydrViewERC20Interface * @dev ERC20 interface to use in applications */ contract CrydrViewERC20Interface { event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); function transfer(address _to, uint256 _value) external returns (bool); function totalSupply() external constant returns (uint256); function balanceOf(address _owner) external constant returns (uint256); function approve(address _spender, uint256 _value) external returns (bool); function transferFrom(address _from, address _to, uint256 _value) external returns (bool); function allowance(address _owner, address _spender) external constant returns (uint256); } contract CrydrViewERC20 is PausableInterface, CrydrViewBaseInterface, CrydrViewERC20Interface { /* ERC20Interface */ function transfer( address _to, uint256 _value ) external whenContractNotPaused onlyPayloadSize(2 * 32) returns (bool) { CrydrControllerERC20Interface(getCrydrController()).transfer(msg.sender, _to, _value); return true; } function totalSupply() external constant returns (uint256) { return CrydrControllerERC20Interface(getCrydrController()).getTotalSupply(); } function balanceOf(address _owner) external constant onlyPayloadSize(1 * 32) returns (uint256) { return CrydrControllerERC20Interface(getCrydrController()).getBalance(_owner); } function approve( address _spender, uint256 _value ) external whenContractNotPaused onlyPayloadSize(2 * 32) returns (bool) { CrydrControllerERC20Interface(getCrydrController()).approve(msg.sender, _spender, _value); return true; } function transferFrom( address _from, address _to, uint256 _value ) external whenContractNotPaused onlyPayloadSize(3 * 32) returns (bool) { CrydrControllerERC20Interface(getCrydrController()).transferFrom(msg.sender, _from, _to, _value); return true; } function allowance( address _owner, address _spender ) external constant onlyPayloadSize(2 * 32) returns (uint256) { return CrydrControllerERC20Interface(getCrydrController()).getAllowance(_owner, _spender); } /* Helpers */ /** * @dev Fix for the ERC20 short address attack. */ modifier onlyPayloadSize(uint256 size) { require(msg.data.length == (size + 4)); _; } } /** * @title CrydrViewERC20LoggableInterface * @dev Contract is able to create Transfer/Approval events with the cal from controller */ contract CrydrViewERC20LoggableInterface { function emitTransferEvent(address _from, address _to, uint256 _value) external; function emitApprovalEvent(address _owner, address _spender, uint256 _value) external; } contract CrydrViewERC20Loggable is PausableInterface, CrydrViewBaseInterface, CrydrViewERC20Interface, CrydrViewERC20LoggableInterface { function emitTransferEvent( address _from, address _to, uint256 _value ) external { require(msg.sender == getCrydrController()); Transfer(_from, _to, _value); } function emitApprovalEvent( address _owner, address _spender, uint256 _value ) external { require(msg.sender == getCrydrController()); Approval(_owner, _spender, _value); } } /** * @title CrydrViewERC20MintableInterface * @dev Contract is able to create Mint/Burn events with the cal from controller */ contract CrydrViewERC20MintableInterface { event MintEvent(address indexed owner, uint256 value); event BurnEvent(address indexed owner, uint256 value); function emitMintEvent(address _owner, uint256 _value) external; function emitBurnEvent(address _owner, uint256 _value) external; } contract CrydrViewERC20Mintable is PausableInterface, CrydrViewBaseInterface, CrydrViewERC20MintableInterface { function emitMintEvent( address _owner, uint256 _value ) external { require(msg.sender == getCrydrController()); MintEvent(_owner, _value); } function emitBurnEvent( address _owner, uint256 _value ) external { require(msg.sender == getCrydrController()); BurnEvent(_owner, _value); } } /** * @title CrydrViewERC20NamedInterface * @dev Contract is able to set name/symbol/decimals */ contract CrydrViewERC20NamedInterface { function name() external constant returns (string); function symbol() external constant returns (string); function decimals() external constant returns (uint8); function getNameHash() external constant returns (bytes32); function getSymbolHash() external constant returns (bytes32); function setName(string _name) external; function setSymbol(string _symbol) external; function setDecimals(uint8 _decimals) external; } contract CrydrViewERC20Named is ManageableInterface, PausableInterface, CrydrViewERC20NamedInterface { /* Storage */ string tokenName = ''; string tokenSymbol = ''; uint8 tokenDecimals = 0; /* Constructor */ function CrydrViewERC20Named(string _name, string _symbol, uint8 _decimals) public { require(bytes(_name).length > 0); require(bytes(_symbol).length > 0); tokenName = _name; tokenSymbol = _symbol; tokenDecimals = _decimals; } /* CrydrViewERC20NamedInterface */ function name() external constant returns (string) { return tokenName; } function symbol() external constant returns (string) { return tokenSymbol; } function decimals() external constant returns (uint8) { return tokenDecimals; } function getNameHash() external constant returns (bytes32){ return keccak256(tokenName); } function getSymbolHash() external constant returns (bytes32){ return keccak256(tokenSymbol); } function setName( string _name ) external whenContractPaused onlyAllowedManager('set_crydr_name') { require(bytes(_name).length > 0); tokenName = _name; } function setSymbol( string _symbol ) external whenContractPaused onlyAllowedManager('set_crydr_symbol') { require(bytes(_symbol).length > 0); tokenSymbol = _symbol; } function setDecimals( uint8 _decimals ) external whenContractPaused onlyAllowedManager('set_crydr_decimals') { tokenDecimals = _decimals; } } contract JCashCrydrViewERC20 is CommonModifiers, AssetID, Ownable, Manageable, Pausable, BytecodeExecutor, CrydrViewBase, CrydrViewERC20, CrydrViewERC20Loggable, CrydrViewERC20Mintable, CrydrViewERC20Named { function JCashCrydrViewERC20(string _assetID, string _name, string _symbol, uint8 _decimals) public AssetID(_assetID) CrydrViewBase('erc20') CrydrViewERC20Named(_name, _symbol, _decimals) { } } contract JNTViewERC20 is JCashCrydrViewERC20 { function JNTViewERC20() public JCashCrydrViewERC20('JNT', 'Jibrel Network Token', 'JNT', 18) {} }