ETH Price: $2,532.15 (+0.65%)

Transaction Decoder

Block:
22524986 at May-20-2025 03:21:35 PM +UTC
Transaction Fee:
0.0001205997 ETH $0.31
Gas Used:
30,923 Gas / 3.9 Gwei

Emitted Events:

433 OwnedUpgradeabilityProxy.0xc3776b472ebf54114339eec9e4dc924e7ce307a97f5c1ee72b6d474e6e5e8b7c( 0xc3776b472ebf54114339eec9e4dc924e7ce307a97f5c1ee72b6d474e6e5e8b7c, 0x0000000000000000000000000f2ce24ae9367d76cb6a85f4b3ca91fa781e31ef )

Account State Difference:

  Address   Before After State Difference Code
(Titan Builder)
8.231082430482436669 Eth8.231128806332438648 Eth0.000046375850001979
0x5B27e985...3f702f634
(OKX 110)
6.258879948103 Eth
Nonce: 38743
6.258759348403 Eth
Nonce: 38744
0.0001205997
0x75231F58...14342a86c

Execution Trace

OwnedUpgradeabilityProxy.45c8b1a6( )
  • OKBImplementation.unfreeze( _addr=0x0f2cE24ae9367D76cB6a85F4b3Ca91fa781E31EF )
    File 1 of 2: OwnedUpgradeabilityProxy
    {"Address.sol":{"content":"pragma solidity ^0.4.24;\n\nlibrary Address {\n    /**\n     * Returns whether the target address is a contract\n     * @dev This function will return false if invoked during the constructor of a contract,\n     * as the code is not actually created until after the constructor finishes.\n     * @param account address of the account to check\n     * @return whether the target address is a contract\n     */\n    function isContract(address account) internal view returns (bool) {\n        uint256 size;\n        // XXX Currently there is no better way to check if there is a contract in an address\n        // than to check the size of the code at that address.\n        // See https://ethereum.stackexchange.com/a/14016/36603\n        // for more details about how this works.\n        // TODO Check this again before the Serenity release, because all addresses will be\n        // contracts then.\n        // solhint-disable-next-line no-inline-assembly\n        assembly { size := extcodesize(account) }\n        return size \u003e 0;\n    }\n}"},"OwnedUpgradeabilityProxy.sol":{"content":"pragma solidity ^0.4.24;\n\nimport \u0027./UpgradeabilityProxy.sol\u0027;\n\n\n/**\n * @title OwnedUpgradeabilityProxy\n * @dev This contract combines an upgradeability proxy with basic authorization control functionalities\n */\ncontract OwnedUpgradeabilityProxy is UpgradeabilityProxy {\n  /**\n  * @dev Event to show ownership has been transferred\n  * @param previousOwner representing the address of the previous owner\n  * @param newOwner representing the address of the new owner\n  */\n  event ProxyOwnershipTransferred(address previousOwner, address newOwner);\n\n  // Storage position of the owner of the contract\n  bytes32 private constant proxyOwnerPosition = keccak256(\"org.zeppelinos.proxy.owner\");\n\n  /**\n  * @dev the constructor sets the original owner of the contract to the sender account.\n  */\n  constructor() public {\n    setUpgradeabilityOwner(msg.sender);\n  }\n\n  /**\n  * @dev Throws if called by any account other than the owner.\n  */\n  modifier onlyProxyOwner() {\n    require(msg.sender == proxyOwner());\n    _;\n  }\n\n  /**\n   * @dev Tells the address of the owner\n   * @return the address of the owner\n   */\n  function proxyOwner() public view returns (address owner) {\n    bytes32 position = proxyOwnerPosition;\n    assembly {\n      owner := sload(position)\n    }\n  }\n\n  /**\n   * @dev Sets the address of the owner\n   */\n  function setUpgradeabilityOwner(address newProxyOwner) internal {\n    bytes32 position = proxyOwnerPosition;\n    assembly {\n      sstore(position, newProxyOwner)\n    }\n  }\n\n  /**\n   * @dev Allows the current owner to transfer control of the contract to a newOwner.\n   * @param newOwner The address to transfer ownership to.\n   */\n  function transferProxyOwnership(address newOwner) public onlyProxyOwner {\n    require(newOwner != address(0));\n    emit ProxyOwnershipTransferred(proxyOwner(), newOwner);\n    setUpgradeabilityOwner(newOwner);\n  }\n\n  /**\n   * @dev Allows the proxy owner to upgrade the current version of the proxy.\n   * @param implementation representing the address of the new implementation to be set.\n   */\n  function upgradeTo(address implementation) public onlyProxyOwner {\n    _upgradeTo(implementation);\n  }\n\n  /**\n   * @dev Allows the proxy owner to upgrade the current version of the proxy and call the new implementation\n   * to initialize whatever is needed through a low level call.\n   * @param implementation representing the address of the new implementation to be set.\n   * @param data represents the msg.data to bet sent in the low level call. This parameter may include the function\n   * signature of the implementation to be called with the needed payload\n   */\n  function upgradeToAndCall(address implementation, bytes data) payable public onlyProxyOwner {\n    upgradeTo(implementation);\n    require(implementation.delegatecall(data));\n}\n}"},"Proxy.sol":{"content":"pragma solidity ^0.4.24;\n\n/**\n * @title Proxy\n * @dev Gives the possibility to delegate any call to a foreign implementation.\n */\ncontract Proxy {\n  /**\n  * @dev Tells the address of the implementation where every call will be delegated.\n  * @return address of the implementation to which it will be delegated\n  */\n  function implementation() public view returns (address);\n\n  /**\n  * @dev Fallback function allowing to perform a delegatecall to the given implementation.\n  * This function will return whatever the implementation call returns\n  */\n  function () payable public {\n    address _impl = implementation();\n    require(_impl != address(0));\n\n    assembly {\n      let ptr := mload(0x40)\n      calldatacopy(ptr, 0, calldatasize)\n      let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0)\n      let size := returndatasize\n      returndatacopy(ptr, 0, size)\n\n      switch result\n      case 0 { revert(ptr, size) }\n      default { return(ptr, size) }\n    }\n  }\n}"},"UpgradeabilityProxy.sol":{"content":"pragma solidity ^0.4.24;\n\nimport \u0027./Proxy.sol\u0027;\nimport \u0027./Address.sol\u0027;\n\n\n/**\n * @title UpgradeabilityProxy\n * @dev This contract represents a proxy where the implementation address to which it will delegate can be upgraded\n */\ncontract UpgradeabilityProxy is Proxy {\n  /**\n   * @dev This event will be emitted every time the implementation gets upgraded\n   * @param implementation representing the address of the upgraded implementation\n   */\n  event Upgraded(address indexed implementation);\n\n  // Storage position of the address of the current implementation\n  bytes32 private constant implementationPosition = keccak256(\"org.zeppelinos.proxy.implementation\");\n\n  /**\n   * @dev Constructor function\n   */\n  constructor() public {}\n\n  /**\n   * @dev Tells the address of the current implementation\n   * @return address of the current implementation\n   */\n  function implementation() public view returns (address impl) {\n    bytes32 position = implementationPosition;\n    assembly {\n      impl := sload(position)\n    }\n  }\n\n  /**\n   * @dev Sets the address of the current implementation\n   * @param newImplementation address representing the new implementation to be set\n   */\n  function setImplementation(address newImplementation) internal {\n    require(Address.isContract(newImplementation),\"newImplementation is not a contractAddress\");\n    bytes32 position = implementationPosition;\n    assembly {\n      sstore(position, newImplementation)\n    }\n  }\n\n  /**\n   * @dev Upgrades the implementation address\n   * @param newImplementation representing the address of the new implementation to be set\n   */\n  function _upgradeTo(address newImplementation) internal {\n    address currentImplementation = implementation();\n    require(currentImplementation != newImplementation);\n    setImplementation(newImplementation);\n    emit Upgraded(newImplementation);\n  }\n}"}}

    File 2 of 2: OKBImplementation
    {"OKb.sol":{"content":"pragma solidity ^0.4.24;\n\n\nimport \"./SafeMath.sol\";\n\n\n\n/**\n * @title OKBImplementation\n * @dev this contract is a Pausable ERC20 token with Burn and Mint\n * controleld by a central SupplyController. By implementing OKBImplementation\n * this contract also includes external methods for setting\n * a new implementation contract for the Proxy.\n * NOTE: The storage defined here will actually be held in the Proxy\n * contract and all calls to this contract should be made through\n * the proxy, including admin actions done as owner or supplyController.\n * Any call to transfer against this contract should fail\n * with insufficient funds since no tokens will be issued there.\n */\ncontract OKBImplementation {\n\n    /**\n     * MATH\n     */\n\n    using SafeMath for uint256;\n\n    /**\n     * DATA\n     */\n\n    // INITIALIZATION DATA\n    bool private initialized = false;\n\n    // ERC20 BASIC DATA\n    mapping(address =\u003e uint256) internal balances;\n    uint256 internal totalSupply_;\n    string public constant name = \"OKB\"; // solium-disable-line uppercase\n    string public constant symbol = \"OKB\"; // solium-disable-line uppercase\n    uint8 public constant decimals = 18; // solium-disable-line uppercase\n\n    // ERC20 DATA\n    mapping (address =\u003e mapping (address =\u003e uint256)) internal _allowed;\n\n    // OWNER DATA\n    address public owner;\n\n    // PAUSABILITY DATA\n    bool public paused = false;\n\n    // LAW ENFORCEMENT DATA\n    address public lawEnforcementRole;\n    mapping(address =\u003e bool) internal frozen;\n\n    // SUPPLY CONTROL DATA\n\n\n\n    address public supplyController;\n\n    /**\n     * EVENTS\n     */\n\n    // ERC20 BASIC EVENTS\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    // ERC20 EVENTS\n    event Approval(\n        address indexed owner,\n        address indexed spender,\n        uint256 value\n    );\n\n    // OWNABLE EVENTS\n    event OwnershipTransferred(\n        address indexed oldOwner,\n        address indexed newOwner\n    );\n\n    // PAUSABLE EVENTS\n    event Pause();\n    event Unpause();\n\n    // LAW ENFORCEMENT EVENTS\n    event AddressFrozen(address indexed addr);\n    event AddressUnfrozen(address indexed addr);\n    event FrozenAddressWiped(address indexed addr);\n    event LawEnforcementRoleSet (\n        address indexed oldLawEnforcementRole,\n        address indexed newLawEnforcementRole\n    );\n\n    // SUPPLY CONTROL EVENTS\n    event SupplyIncreased(address indexed to, uint256 value);\n    event SupplyDecreased(address indexed from, uint256 value);\n    event SupplyControllerSet(\n        address indexed oldSupplyController,\n        address indexed newSupplyController\n    );\n\n    /**\n     * FUNCTIONALITY\n     */\n\n    // INITIALIZATION FUNCTIONALITY\n\n    /**\n     * @dev sets 0 initials tokens, the owner, and the supplyController.\n     * this serves as the constructor for the proxy but compiles to the\n     * memory model of the Implementation contract.\n     */\n    function initialize() public {\n        require(!initialized, \"already initialized\");\n        owner = msg.sender;\n        lawEnforcementRole = address(0);\n        totalSupply_ = 0;\n        supplyController = msg.sender;\n        initialized = true;\n    }\n\n    /**\n     * The constructor is used here to ensure that the implementation\n     * contract is initialized. An uncontrolled implementation\n     * contract might lead to misleading state\n     * for users who accidentally interact with it.\n     */\n    constructor() public {\n        initialize();\n        pause();\n    }\n\n    // ERC20 BASIC FUNCTIONALITY\n\n    /**\n    * @dev Total number of tokens in existence\n    */\n    function totalSupply() public view returns (uint256) {\n        return totalSupply_;\n    }\n\n    /**\n    * @dev Transfer token for a specified address\n    * @param _to The address to transfer to.\n    * @param _value The amount to be transferred.\n    */\n    function transfer(address _to, uint256 _value) public whenNotPaused returns (bool) {\n        require(_to != address(0), \"cannot transfer to address zero\");\n        require(!frozen[_to] \u0026\u0026 !frozen[msg.sender], \"address frozen\");\n        require(_value \u003c= balances[msg.sender], \"insufficient funds\");\n\n        balances[msg.sender] = balances[msg.sender].sub(_value);\n        balances[_to] = balances[_to].add(_value);\n        emit Transfer(msg.sender, _to, _value);\n        return true;\n    }\n\n    /**\n    * @dev Gets the balance of the specified address.\n    * @param _addr The address to query the the balance of.\n    * @return An uint256 representing the amount owned by the passed address.\n    */\n    function balanceOf(address _addr) public view returns (uint256) {\n        return balances[_addr];\n    }\n\n    // ERC20 FUNCTIONALITY\n\n    /**\n     * @dev Transfer tokens from one address to another\n     * @param _from address The address which you want to send tokens from\n     * @param _to address The address which you want to transfer to\n     * @param _value uint256 the amount of tokens to be transferred\n     */\n    function transferFrom(address _from,address _to,uint256 _value) public whenNotPaused returns (bool)\n    {\n        require(_to != address(0), \"cannot transfer to address zero\");\n        require(!frozen[_to] \u0026\u0026 !frozen[_from] \u0026\u0026 !frozen[msg.sender], \"address frozen\");\n        require(_value \u003c= balances[_from], \"insufficient funds\");\n        require(_value \u003c= _allowed[_from][msg.sender], \"insufficient allowance\");\n\n        balances[_from] = balances[_from].sub(_value);\n        balances[_to] = balances[_to].add(_value);\n        _allowed[_from][msg.sender] = _allowed[_from][msg.sender].sub(_value);\n        emit Transfer(_from, _to, _value);\n        return true;\n    }\n\n   /**\n    * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.\n    * Beware that changing an allowance with this method brings the risk that someone may use both the old\n    * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this\n    * race condition is to first reduce the spender\u0027s allowance to 0 and set the desired value afterwards:\n    * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n    * @param spender The address which will spend the funds.\n    * @param value The amount of tokens to be spent.\n    */\n    function approve(address spender, uint256 value) public whenNotPaused returns (bool) {\n        _approve(msg.sender, spender, value);\n        return true;\n    }\n    /**\n     * @dev Approve an address to spend another addresses\u0027 tokens.\n     * @param _owner The address that owns the tokens.\n     * @param spender The address that will spend the tokens.\n     * @param value The number of tokens that can be spent.\n     */\n     function _approve(address _owner, address spender, uint256 value) internal {\n         require(!frozen[spender] \u0026\u0026 !frozen[_owner], \"address frozen\");\n         require(spender != address(0) \u0026\u0026 _owner != address(0),\"not address(0)\");\n         _allowed[_owner][spender] = value;\n         emit Approval(_owner, spender, value);\n     }\n\n    /**\n     * @dev Function to check the amount of tokens that an owner allowed to a spender.\n     * @param _owner address The address which owns the funds.\n     * @param spender address The address which will spend the funds.\n     * @return A uint256 specifying the amount of tokens still available for the spender.\n     */\n    function allowance(address _owner, address spender) public view returns (uint256) {\n        return _allowed[_owner][spender];\n    }\n\n     /**\n     * @dev Increase the amount of tokens that an owner allowed to a spender.\n     * approve should be called when _allowed[msg.sender][spender] == 0. To increment\n     * allowed value is better to use this function to avoid 2 calls (and wait until\n     * the first transaction is mined)\n     * From MonolithDAO Token.sol\n     * Emits an Approval event.\n     * @param spender The address which will spend the funds.\n     * @param addedValue The amount of tokens to increase the allowance by.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public whenNotPaused returns (bool) {\n        _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue));\n        return true;\n    }\n\n    /**\n     * @dev Decrease the amount of tokens that an owner allowed to a spender.\n     * approve should be called when _allowed[msg.sender][spender] == 0. To decrement\n     * allowed value is better to use this function to avoid 2 calls (and wait until\n     * the first transaction is mined)\n     * From MonolithDAO Token.sol\n     * Emits an Approval event.\n     * @param spender The address which will spend the funds.\n     * @param subtractedValue The amount of tokens to decrease the allowance by.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public whenNotPaused returns (bool) {\n        _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue));\n        return true;\n    }\n\n    // OWNER FUNCTIONALITY\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"onlyOwner\");\n        _;\n    }\n\n    /**\n     * @dev Allows the current owner to transfer control of the contract to a newOwner.\n     * @param _newOwner The address to transfer ownership to.\n     */\n    function transferOwnership(address _newOwner) public onlyOwner {\n        require(_newOwner != address(0), \"cannot transfer ownership to address zero\");\n        emit OwnershipTransferred(owner, _newOwner);\n        owner = _newOwner;\n    }\n\n    // PAUSABILITY FUNCTIONALITY\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     */\n    modifier whenNotPaused() {\n        require(!paused, \"whenNotPaused\");\n        _;\n    }\n\n    /**\n     * @dev called by the owner to pause, triggers stopped state\n     */\n    function pause() public onlyOwner {\n        require(!paused, \"already paused\");\n        paused = true;\n        emit Pause();\n    }\n\n    /**\n     * @dev called by the owner to unpause, returns to normal state\n     */\n    function unpause() public onlyOwner {\n        require(paused, \"already unpaused\");\n        paused = false;\n        emit Unpause();\n    }\n\n    // LAW ENFORCEMENT FUNCTIONALITY\n\n    /**\n     * @dev Sets a new law enforcement role address.\n     * @param _newLawEnforcementRole The new address allowed to freeze/unfreeze addresses and seize their tokens.\n     */\n    function setLawEnforcementRole(address _newLawEnforcementRole) public {\n        require(_newLawEnforcementRole != address(0),\"lawEnforcementRole cannot address(0)\");\n        require(msg.sender == lawEnforcementRole || msg.sender == owner, \"only lawEnforcementRole or Owner\");\n        emit LawEnforcementRoleSet(lawEnforcementRole, _newLawEnforcementRole);\n        lawEnforcementRole = _newLawEnforcementRole;\n    }\n\n    modifier onlyLawEnforcementRole() {\n        require(msg.sender == lawEnforcementRole, \"onlyLawEnforcementRole\");\n        _;\n    }\n\n    /**\n     * @dev Freezes an address balance from being transferred.\n     * @param _addr The new address to freeze.\n     */\n    function freeze(address _addr) public onlyLawEnforcementRole {\n        require(!frozen[_addr], \"address already frozen\");\n        frozen[_addr] = true;\n        emit AddressFrozen(_addr);\n    }\n\n    /**\n     * @dev Unfreezes an address balance allowing transfer.\n     * @param _addr The new address to unfreeze.\n     */\n    function unfreeze(address _addr) public onlyLawEnforcementRole {\n        require(frozen[_addr], \"address already unfrozen\");\n        frozen[_addr] = false;\n        emit AddressUnfrozen(_addr);\n    }\n\n    /**\n     * @dev Wipes the balance of a frozen address, burning the tokens\n     * @param _addr The new frozen address to wipe.\n     */\n    function wipeFrozenAddress(address _addr) public onlyLawEnforcementRole {\n        require(frozen[_addr], \"address is not frozen\");\n        uint256 _balance = balances[_addr];\n        balances[_addr] = 0;\n        totalSupply_ = totalSupply_.sub(_balance);\n        emit FrozenAddressWiped(_addr);\n        emit SupplyDecreased(_addr, _balance);\n        emit Transfer(_addr, address(0), _balance);\n    }\n\n    /**\n    * @dev Gets the balance of the specified address.\n    * @param _addr The address to check if frozen.\n    * @return A bool representing whether the given address is frozen.\n    */\n    function isFrozen(address _addr) public view returns (bool) {\n        return frozen[_addr];\n    }\n\n    // SUPPLY CONTROL FUNCTIONALITY\n\n    /**\n     * @dev Sets a new supply controller address.\n     * @param _newSupplyController The address allowed to burn/mint tokens to control supply.\n     */\n    function setSupplyController(address _newSupplyController) public {\n        require(msg.sender == supplyController || msg.sender == owner, \"only SupplyController or Owner\");\n        require(_newSupplyController != address(0), \"cannot set supply controller to address zero\");\n        emit SupplyControllerSet(supplyController, _newSupplyController);\n        supplyController = _newSupplyController;\n    }\n\n    modifier onlySupplyController() {\n        require(msg.sender == supplyController, \"onlySupplyController\");\n        _;\n    }\n\n    /**\n     * @dev Increases the total supply by minting the specified number of tokens to the supply controller account.\n     * @param _value The number of tokens to add.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function increaseSupply(uint256 _value) public onlySupplyController returns (bool success) {\n        totalSupply_ = totalSupply_.add(_value);\n        balances[supplyController] = balances[supplyController].add(_value);\n        emit SupplyIncreased(supplyController, _value);\n        emit Transfer(address(0), supplyController, _value);\n        return true;\n    }\n\n    /**\n     * @dev Decreases the total supply by burning the specified number of tokens from the supply controller account.\n     * @param _value The number of tokens to remove.\n     * @return A boolean that indicates if the operation was successful.\n     */\n    function decreaseSupply(uint256 _value) public onlySupplyController returns (bool success) {\n        require(_value \u003c= balances[supplyController], \"not enough supply\");\n        balances[supplyController] = balances[supplyController].sub(_value);\n        totalSupply_ = totalSupply_.sub(_value);\n        emit SupplyDecreased(supplyController, _value);\n        emit Transfer(supplyController, address(0), _value);\n        return true;\n    }\n}\n"},"SafeMath.sol":{"content":"pragma solidity ^0.4.24;\n\n\n/**\n * @title SafeMath\n * @dev Math operations with safety checks that throw on error\n */\nlibrary SafeMath {\n    /**\n    * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n    */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b \u003c= a);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n    * @dev Adds two numbers, reverts on overflow.\n    */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c \u003e= a);\n\n        return c;\n    }\n}\n"}}