Sponsored:   Temco - Join the Largest VC Backed ICO on the Bitcoin Network! TEMCO KYC Whitelist Starts Now!!
Contract Overview
Balance: 0 Ether
Ether Value: $0
Transactions: 14114 txns
Token Tracker: Havven (HAV)
Misc:
Address Watch: Add To Watch List
Contract Creator: 0xb10c85274d2a58ddec72c1d826e75256ff93deadat txn 0xd71402e7e06c669867f2ece75a5cdcbdd8bae764847bbc089d6fc549af1ad232
 Latest 25 transactions from a total of 14114 transactions

TxHash Age From To Value [TxFee]
0x10ca306d0011a8531b1a9c4aa3f4cb78fa342e88d45bfae6d0a1bcc0c7efe9b75 days 16 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.00019452
0x4d8ed033eeb429c3102d96904d74a6f14c6208b8e9107f454f9145aff48313f45 days 17 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.00019452
0x5db8a8d4a7a1f7ab676cdad0fc03453a163713bf1de32100db93a07e2b4621a35 days 17 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000272328
0x062a87f50b4053bae0e2cac9d4a16ab24e036fc49e66333779cf1a9e001e95355 days 18 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000311232
0xb4e3598ecb149236efbf11ef8c863fbbf6a70174967cb05ab398cd7b06cd45fe5 days 18 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000233424
0x924f13f179b800c4a654c73fe7e88e42dcef4044cdd6594f0a18ad6e072bb50d5 days 19 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000272328
0xe93d1588f9fbd9bd248f55c6fa47fdb0fdac98e081c55b66b9de86d5246c11ac5 days 19 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.00038904
0x2cb538a4c5d1623b598260eb87d11bc6a6d85ccbff819093c1b4be3e39b068d75 days 20 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000350136
0x105ac50f104daf3cf6b4b35f4c6171bffac694a7f4d2b071f4d91cc076a0c3895 days 20 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000311232
0xbe0203d01e6cb7272d816259dca5cab17fce89db0a68d4a36f5ad9e8c2e09ae65 days 23 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000233424
0xa1cb9d7b837fae25cadd3260b9cb7e382a081373e7a72eb04b6bda6614af20455 days 23 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.00019452
0x883f5df07a8b4ba16c3aee9b00beacddf4074d46a3719b13e31305189bef7ca96 days 35 mins ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000233424
0x686c137da4d103dc8d040596dce8196d6fd93eca0752f72f5fde59694ed6047c6 days 1 hr ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.00019452
0xc3c8aa80c0bf322e8828f7163f7c8bf81bb0723b9f9a6dd11c6e2a3724edebd16 days 1 hr ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.00019452
0xcbb5bf9633b241508501aeb1b76908129e4145db172b69dec0ca24e4486cfa466 days 2 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000350136
0xd8766fdb531bf6893d9ad9ab7d1b2aef3217b446b58a88da9370d94412a808476 days 2 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000233424
0xca2c0a403db6c83188b09d71a376bb73b6de2a43b6a08fd707413646366daaac6 days 3 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000311232
0x2d04059e33fa1ce4ace48b480067a95a5759e592346ca93fac8198355b4611216 days 3 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000350136
0x99016b9a1e91d170e5ed8ab01ff63815752fd19bc72b6caa2fe948c9bca2f0ba6 days 4 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000311232
0xdb5828d94c592e55de9709e67352ec3ce2c615472e40674bf904564dd99251ac6 days 4 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000311232
0xb848ec5f8a751c301a0c1017d9fced433d31f207851320e5b8112e117dd9fbe76 days 5 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.00038904
0x96c452ee6ee5276f095e9f91c8cdf6864f290de05e0b457926296743fa9c7e406 days 5 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.00019452
0x3f185b5e5c272d4a7f435a6467772dc26fc35134074073fbf36e22d13921bfa06 days 6 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000350136
0x47d3b9ec313a557e1d310a72489d1eb7a3e738581377d0f95c36acc469d6e6cf6 days 6 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.00019452
0xe31ecffa9bb7e2fd99671fa6f653e9d5109837acd84442cf80dc0ed8b6fe21d86 days 7 hrs ago0xac1ed4fabbd5204e02950d68b6fc8c446ac95362  IN   0xd989a04ad891528b571ef73dacaefeb0402a65b30 Ether0.000233424
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
View All
ParentTxHash Block Age From To Value
Warning: The Compiled Contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity) SolidityCompiler Bugs.

Contract Source Code Verified (Exact Match)
Contract Name: Havven
Compiler Text: v0.4.24+commit.e67f0147
Optimization Enabled: Yes
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

/*
 * Havven Contract
 *
 * The collateral token of the Havven stablecoin system.
 *
 * version: nUSDa.1
 * date: 29 Jun 2018
 * url: https://github.com/Havven/havven/releases/tag/nUSDa.1
 *
 * MIT License
 * ===========
 *
 * Copyright (c) 2018 Havven
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 */
 
 
pragma solidity 0.4.24;
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       SafeDecimalMath.sol
version:    1.0
author:     Anton Jurisevic
 
date:       2018-2-5
 
checked:    Mike Spain
approved:   Samuel Brooks
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
A fixed point decimal library that provides basic mathematical
operations, and checks for unsafe arguments, for example that
would lead to overflows.
 
Exceptions are thrown whenever those unsafe operations
occur.
 
-----------------------------------------------------------------
*/
 
 
/**
 * @title Safely manipulate unsigned fixed-point decimals at a given precision level.
 * @dev Functions accepting uints in this contract and derived contracts
 * are taken to be such fixed point decimals (including fiat, ether, and nomin quantities).
 */
contract SafeDecimalMath {
 
    /* Number of decimal places in the representation. */
    uint8 public constant decimals = 18;
 
    /* The number representing 1.0. */
    uint public constant UNIT = 10 ** uint(decimals);
 
    /**
     * @return True iff adding x and y will not overflow.
     */
    function addIsSafe(uint x, uint y)
        pure
        internal
        returns (bool)
    {
        return x + y >= y;
    }
 
    /**
     * @return The result of adding x and y, throwing an exception in case of overflow.
     */
    function safeAdd(uint x, uint y)
        pure
        internal
        returns (uint)
    {
        require(x + y >= y);
        return x + y;
    }
 
    /**
     * @return True iff subtracting y from x will not overflow in the negative direction.
     */
    function subIsSafe(uint x, uint y)
        pure
        internal
        returns (bool)
    {
        return y <= x;
    }
 
    /**
     * @return The result of subtracting y from x, throwing an exception in case of overflow.
     */
    function safeSub(uint x, uint y)
        pure
        internal
        returns (uint)
    {
        require(y <= x);
        return x - y;
    }
 
    /**
     * @return True iff multiplying x and y would not overflow.
     */
    function mulIsSafe(uint x, uint y)
        pure
        internal
        returns (bool)
    {
        if (x == 0) {
            return true;
        }
        return (x * y) / x == y;
    }
 
    /**
     * @return The result of multiplying x and y, throwing an exception in case of overflow.
     */
    function safeMul(uint x, uint y)
        pure
        internal
        returns (uint)
    {
        if (x == 0) {
            return 0;
        }
        uint p = x * y;
        require(p / x == y);
        return p;
    }
 
    /**
     * @return The result of multiplying x and y, interpreting the operands as fixed-point
     * decimals. Throws an exception in case of overflow.
     *
     * @dev A unit factor is divided out after the product of x and y is evaluated,
     * so that product must be less than 2**256.
     * Incidentally, the internal division always rounds down: one could have rounded to the nearest integer,
     * but then one would be spending a significant fraction of a cent (of order a microether
     * at present gas prices) in order to save less than one part in 0.5 * 10^18 per operation, if the operands
     * contain small enough fractional components. It would also marginally diminish the
     * domain this function is defined upon.
     */
    function safeMul_dec(uint x, uint y)
        pure
        internal
        returns (uint)
    {
        /* Divide by UNIT to remove the extra factor introduced by the product. */
        return safeMul(x, y) / UNIT;
 
    }
 
    /**
     * @return True iff the denominator of x/y is nonzero.
     */
    function divIsSafe(uint x, uint y)
        pure
        internal
        returns (bool)
    {
        return y != 0;
    }
 
    /**
     * @return The result of dividing x by y, throwing an exception if the divisor is zero.
     */
    function safeDiv(uint x, uint y)
        pure
        internal
        returns (uint)
    {
        /* Although a 0 denominator already throws an exception,
         * it is equivalent to a THROW operation, which consumes all gas.
         * A require statement emits REVERT instead, which remits remaining gas. */
        require(y != 0);
        return x / y;
    }
 
    /**
     * @return The result of dividing x by y, interpreting the operands as fixed point decimal numbers.
     * @dev Throws an exception in case of overflow or zero divisor; x must be less than 2^256 / UNIT.
     * Internal rounding is downward: a similar caveat holds as with safeDecMul().
     */
    function safeDiv_dec(uint x, uint y)
        pure
        internal
        returns (uint)
    {
        /* Reintroduce the UNIT factor that will be divided out by y. */
        return safeDiv(safeMul(x, UNIT), y);
    }
 
    /**
     * @dev Convert an unsigned integer to a unsigned fixed-point decimal.
     * Throw an exception if the result would be out of range.
     */
    function intToDec(uint i)
        pure
        internal
        returns (uint)
    {
        return safeMul(i, UNIT);
    }
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       Owned.sol
version:    1.1
author:     Anton Jurisevic
            Dominic Romanowski
 
date:       2018-2-26
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
An Owned contract, to be inherited by other contracts.
Requires its owner to be explicitly set in the constructor.
Provides an onlyOwner access modifier.
 
To change owner, the current owner must nominate the next owner,
who then has to accept the nomination. The nomination can be
cancelled before it is accepted by the new owner by having the
previous owner change the nomination (setting it to 0).
 
-----------------------------------------------------------------
*/
 
 
/**
 * @title A contract with an owner.
 * @notice Contract ownership can be transferred by first nominating the new owner,
 * who must then accept the ownership, which prevents accidental incorrect ownership transfers.
 */
contract Owned {
    address public owner;
    address public nominatedOwner;
 
    /**
     * @dev Owned Constructor
     */
    constructor(address _owner)
        public
    {
        require(_owner != address(0));
        owner = _owner;
        emit OwnerChanged(address(0), _owner);
    }
 
    /**
     * @notice Nominate a new owner of this contract.
     * @dev Only the current owner may nominate a new owner.
     */
    function nominateNewOwner(address _owner)
        external
        onlyOwner
    {
        nominatedOwner = _owner;
        emit OwnerNominated(_owner);
    }
 
    /**
     * @notice Accept the nomination to be owner.
     */
    function acceptOwnership()
        external
    {
        require(msg.sender == nominatedOwner);
        emit OwnerChanged(owner, nominatedOwner);
        owner = nominatedOwner;
        nominatedOwner = address(0);
    }
 
    modifier onlyOwner
    {
        require(msg.sender == owner);
        _;
    }
 
    event OwnerNominated(address newOwner);
    event OwnerChanged(address oldOwner, address newOwner);
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       SelfDestructible.sol
version:    1.2
author:     Anton Jurisevic
 
date:       2018-05-29
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
This contract allows an inheriting contract to be destroyed after
its owner indicates an intention and then waits for a period
without changing their mind. All ether contained in the contract
is forwarded to a nominated beneficiary upon destruction.
 
-----------------------------------------------------------------
*/
 
 
/**
 * @title A contract that can be destroyed by its owner after a delay elapses.
 */
contract SelfDestructible is Owned {
     
    uint public initiationTime;
    bool public selfDestructInitiated;
    address public selfDestructBeneficiary;
    uint public constant SELFDESTRUCT_DELAY = 4 weeks;
 
    /**
     * @dev Constructor
     * @param _owner The account which controls this contract.
     */
    constructor(address _owner)
        Owned(_owner)
        public
    {
        require(_owner != address(0));
        selfDestructBeneficiary = _owner;
        emit SelfDestructBeneficiaryUpdated(_owner);
    }
 
    /**
     * @notice Set the beneficiary address of this contract.
     * @dev Only the contract owner may call this. The provided beneficiary must be non-null.
     * @param _beneficiary The address to pay any eth contained in this contract to upon self-destruction.
     */
    function setSelfDestructBeneficiary(address _beneficiary)
        external
        onlyOwner
    {
        require(_beneficiary != address(0));
        selfDestructBeneficiary = _beneficiary;
        emit SelfDestructBeneficiaryUpdated(_beneficiary);
    }
 
    /**
     * @notice Begin the self-destruction counter of this contract.
     * Once the delay has elapsed, the contract may be self-destructed.
     * @dev Only the contract owner may call this.
     */
    function initiateSelfDestruct()
        external
        onlyOwner
    {
        initiationTime = now;
        selfDestructInitiated = true;
        emit SelfDestructInitiated(SELFDESTRUCT_DELAY);
    }
 
    /**
     * @notice Terminate and reset the self-destruction timer.
     * @dev Only the contract owner may call this.
     */
    function terminateSelfDestruct()
        external
        onlyOwner
    {
        initiationTime = 0;
        selfDestructInitiated = false;
        emit SelfDestructTerminated();
    }
 
    /**
     * @notice If the self-destruction delay has elapsed, destroy this contract and
     * remit any ether it owns to the beneficiary address.
     * @dev Only the contract owner may call this.
     */
    function selfDestruct()
        external
        onlyOwner
    {
        require(selfDestructInitiated && initiationTime + SELFDESTRUCT_DELAY < now);
        address beneficiary = selfDestructBeneficiary;
        emit SelfDestructed(beneficiary);
        selfdestruct(beneficiary);
    }
 
    event SelfDestructTerminated();
    event SelfDestructed(address beneficiary);
    event SelfDestructInitiated(uint selfDestructDelay);
    event SelfDestructBeneficiaryUpdated(address newBeneficiary);
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       State.sol
version:    1.1
author:     Dominic Romanowski
            Anton Jurisevic
 
date:       2018-05-15
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
This contract is used side by side with external state token
contracts, such as Havven and Nomin.
It provides an easy way to upgrade contract logic while
maintaining all user balances and allowances. This is designed
to make the changeover as easy as possible, since mappings
are not so cheap or straightforward to migrate.
 
The first deployed contract would create this state contract,
using it as its store of balances.
When a new contract is deployed, it links to the existing
state contract, whose owner would then change its associated
contract to the new one.
 
-----------------------------------------------------------------
*/
 
 
contract State is Owned {
    // the address of the contract that can modify variables
    // this can only be changed by the owner of this contract
    address public associatedContract;
 
 
    constructor(address _owner, address _associatedContract)
        Owned(_owner)
        public
    {
        associatedContract = _associatedContract;
        emit AssociatedContractUpdated(_associatedContract);
    }
 
    /* ========== SETTERS ========== */
 
    // Change the associated contract to a new address
    function setAssociatedContract(address _associatedContract)
        external
        onlyOwner
    {
        associatedContract = _associatedContract;
        emit AssociatedContractUpdated(_associatedContract);
    }
 
    /* ========== MODIFIERS ========== */
 
    modifier onlyAssociatedContract
    {
        require(msg.sender == associatedContract);
        _;
    }
 
    /* ========== EVENTS ========== */
 
    event AssociatedContractUpdated(address associatedContract);
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       TokenState.sol
version:    1.1
author:     Dominic Romanowski
            Anton Jurisevic
 
date:       2018-05-15
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
A contract that holds the state of an ERC20 compliant token.
 
This contract is used side by side with external state token
contracts, such as Havven and Nomin.
It provides an easy way to upgrade contract logic while
maintaining all user balances and allowances. This is designed
to make the changeover as easy as possible, since mappings
are not so cheap or straightforward to migrate.
 
The first deployed contract would create this state contract,
using it as its store of balances.
When a new contract is deployed, it links to the existing
state contract, whose owner would then change its associated
contract to the new one.
 
-----------------------------------------------------------------
*/
 
 
/**
 * @title ERC20 Token State
 * @notice Stores balance information of an ERC20 token contract.
 */
contract TokenState is State {
 
    /* ERC20 fields. */
    mapping(address => uint) public balanceOf;
    mapping(address => mapping(address => uint)) public allowance;
 
    /**
     * @dev Constructor
     * @param _owner The address which controls this contract.
     * @param _associatedContract The ERC20 contract whose state this composes.
     */
    constructor(address _owner, address _associatedContract)
        State(_owner, _associatedContract)
        public
    {}
 
    /* ========== SETTERS ========== */
 
    /**
     * @notice Set ERC20 allowance.
     * @dev Only the associated contract may call this.
     * @param tokenOwner The authorising party.
     * @param spender The authorised party.
     * @param value The total value the authorised party may spend on the
     * authorising party's behalf.
     */
    function setAllowance(address tokenOwner, address spender, uint value)
        external
        onlyAssociatedContract
    {
        allowance[tokenOwner][spender] = value;
    }
 
    /**
     * @notice Set the balance in a given account
     * @dev Only the associated contract may call this.
     * @param account The account whose value to set.
     * @param value The new balance of the given account.
     */
    function setBalanceOf(address account, uint value)
        external
        onlyAssociatedContract
    {
        balanceOf[account] = value;
    }
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       Proxy.sol
version:    1.3
author:     Anton Jurisevic
 
date:       2018-05-29
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
A proxy contract that, if it does not recognise the function
being called on it, passes all value and call data to an
underlying target contract.
 
This proxy has the capacity to toggle between DELEGATECALL
and CALL style proxy functionality.
 
The former executes in the proxy's context, and so will preserve
msg.sender and store data at the proxy address. The latter will not.
Therefore, any contract the proxy wraps in the CALL style must
implement the Proxyable interface, in order that it can pass msg.sender
into the underlying contract as the state parameter, messageSender.
 
-----------------------------------------------------------------
*/
 
 
contract Proxy is Owned {
 
    Proxyable public target;
    bool public useDELEGATECALL;
 
    constructor(address _owner)
        Owned(_owner)
        public
    {}
 
    function setTarget(Proxyable _target)
        external
        onlyOwner
    {
        target = _target;
        emit TargetUpdated(_target);
    }
 
    function setUseDELEGATECALL(bool value)
        external
        onlyOwner
    {
        useDELEGATECALL = value;
    }
 
    function _emit(bytes callData, uint numTopics,
                   bytes32 topic1, bytes32 topic2,
                   bytes32 topic3, bytes32 topic4)
        external
        onlyTarget
    {
        uint size = callData.length;
        bytes memory _callData = callData;
 
        assembly {
            /* The first 32 bytes of callData contain its length (as specified by the abi).
             * Length is assumed to be a uint256 and therefore maximum of 32 bytes
             * in length. It is also leftpadded to be a multiple of 32 bytes.
             * This means moving call_data across 32 bytes guarantees we correctly access
             * the data itself. */
            switch numTopics
            case 0 {
                log0(add(_callData, 32), size)
            }
            case 1 {
                log1(add(_callData, 32), size, topic1)
            }
            case 2 {
                log2(add(_callData, 32), size, topic1, topic2)
            }
            case 3 {
                log3(add(_callData, 32), size, topic1, topic2, topic3)
            }
            case 4 {
                log4(add(_callData, 32), size, topic1, topic2, topic3, topic4)
            }
        }
    }
 
    function()
        external
        payable
    {
        if (useDELEGATECALL) {
            assembly {
                /* Copy call data into free memory region. */
                let free_ptr := mload(0x40)
                calldatacopy(free_ptr, 0, calldatasize)
 
                /* Forward all gas and call data to the target contract. */
                let result := delegatecall(gas, sload(target_slot), free_ptr, calldatasize, 0, 0)
                returndatacopy(free_ptr, 0, returndatasize)
 
                /* Revert if the call failed, otherwise return the result. */
                if iszero(result) { revert(free_ptr, returndatasize) }
                return(free_ptr, returndatasize)
            }
        } else {
            /* Here we are as above, but must send the messageSender explicitly
             * since we are using CALL rather than DELEGATECALL. */
            target.setMessageSender(msg.sender);
            assembly {
                let free_ptr := mload(0x40)
                calldatacopy(free_ptr, 0, calldatasize)
 
                /* We must explicitly forward ether to the underlying contract as well. */
                let result := call(gas, sload(target_slot), callvalue, free_ptr, calldatasize, 0, 0)
                returndatacopy(free_ptr, 0, returndatasize)
 
                if iszero(result) { revert(free_ptr, returndatasize) }
                return(free_ptr, returndatasize)
            }
        }
    }
 
    modifier onlyTarget {
        require(Proxyable(msg.sender) == target);
        _;
    }
 
    event TargetUpdated(Proxyable newTarget);
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       Proxyable.sol
version:    1.1
author:     Anton Jurisevic
 
date:       2018-05-15
 
checked:    Mike Spain
approved:   Samuel Brooks
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
A proxyable contract that works hand in hand with the Proxy contract
to allow for anyone to interact with the underlying contract both
directly and through the proxy.
 
-----------------------------------------------------------------
*/
 
 
// This contract should be treated like an abstract contract
contract Proxyable is Owned {
    /* The proxy this contract exists behind. */
    Proxy public proxy;
 
    /* The caller of the proxy, passed through to this contract.
     * Note that every function using this member must apply the onlyProxy or
     * optionalProxy modifiers, otherwise their invocations can use stale values. */
    address messageSender;
 
    constructor(address _proxy, address _owner)
        Owned(_owner)
        public
    {
        proxy = Proxy(_proxy);
        emit ProxyUpdated(_proxy);
    }
 
    function setProxy(address _proxy)
        external
        onlyOwner
    {
        proxy = Proxy(_proxy);
        emit ProxyUpdated(_proxy);
    }
 
    function setMessageSender(address sender)
        external
        onlyProxy
    {
        messageSender = sender;
    }
 
    modifier onlyProxy {
        require(Proxy(msg.sender) == proxy);
        _;
    }
 
    modifier optionalProxy
    {
        if (Proxy(msg.sender) != proxy) {
            messageSender = msg.sender;
        }
        _;
    }
 
    modifier optionalProxy_onlyOwner
    {
        if (Proxy(msg.sender) != proxy) {
            messageSender = msg.sender;
        }
        require(messageSender == owner);
        _;
    }
 
    event ProxyUpdated(address proxyAddress);
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       ExternStateToken.sol
version:    1.3
author:     Anton Jurisevic
            Dominic Romanowski
 
date:       2018-05-29
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
A partial ERC20 token contract, designed to operate with a proxy.
To produce a complete ERC20 token, transfer and transferFrom
tokens must be implemented, using the provided _byProxy internal
functions.
This contract utilises an external state for upgradeability.
 
-----------------------------------------------------------------
*/
 
 
/**
 * @title ERC20 Token contract, with detached state and designed to operate behind a proxy.
 */
contract ExternStateToken is SafeDecimalMath, SelfDestructible, Proxyable {
 
    /* ========== STATE VARIABLES ========== */
 
    /* Stores balances and allowances. */
    TokenState public tokenState;
 
    /* Other ERC20 fields.
     * Note that the decimals field is defined in SafeDecimalMath.*/
    string public name;
    string public symbol;
    uint public totalSupply;
 
    /**
     * @dev Constructor.
     * @param _proxy The proxy associated with this contract.
     * @param _name Token's ERC20 name.
     * @param _symbol Token's ERC20 symbol.
     * @param _totalSupply The total supply of the token.
     * @param _tokenState The TokenState contract address.
     * @param _owner The owner of this contract.
     */
    constructor(address _proxy, TokenState _tokenState,
                string _name, string _symbol, uint _totalSupply,
                address _owner)
        SelfDestructible(_owner)
        Proxyable(_proxy, _owner)
        public
    {
        name = _name;
        symbol = _symbol;
        totalSupply = _totalSupply;
        tokenState = _tokenState;
   }
 
    /* ========== VIEWS ========== */
 
    /**
     * @notice Returns the ERC20 allowance of one party to spend on behalf of another.
     * @param owner The party authorising spending of their funds.
     * @param spender The party spending tokenOwner's funds.
     */
    function allowance(address owner, address spender)
        public
        view
        returns (uint)
    {
        return tokenState.allowance(owner, spender);
    }
 
    /**
     * @notice Returns the ERC20 token balance of a given account.
     */
    function balanceOf(address account)
        public
        view
        returns (uint)
    {
        return tokenState.balanceOf(account);
    }
 
    /* ========== MUTATIVE FUNCTIONS ========== */
 
    /**
     * @notice Set the address of the TokenState contract.
     * @dev This can be used to "pause" transfer functionality, by pointing the tokenState at 0x000..
     * as balances would be unreachable.
     */
    function setTokenState(TokenState _tokenState)
        external
        optionalProxy_onlyOwner
    {
        tokenState = _tokenState;
        emitTokenStateUpdated(_tokenState);
    }
 
    function _internalTransfer(address from, address to, uint value)
        internal
        returns (bool)
    {
        /* Disallow transfers to irretrievable-addresses. */
        require(to != address(0));
        require(to != address(this));
        require(to != address(proxy));
 
        /* Insufficient balance will be handled by the safe subtraction. */
        tokenState.setBalanceOf(from, safeSub(tokenState.balanceOf(from), value));
        tokenState.setBalanceOf(to, safeAdd(tokenState.balanceOf(to), value));
 
        emitTransfer(from, to, value);
 
        return true;
    }
 
    /**
     * @dev Perform an ERC20 token transfer. Designed to be called by transfer functions possessing
     * the onlyProxy or optionalProxy modifiers.
     */
    function _transfer_byProxy(address from, address to, uint value)
        internal
        returns (bool)
    {
        return _internalTransfer(from, to, value);
    }
 
    /**
     * @dev Perform an ERC20 token transferFrom. Designed to be called by transferFrom functions
     * possessing the optionalProxy or optionalProxy modifiers.
     */
    function _transferFrom_byProxy(address sender, address from, address to, uint value)
        internal
        returns (bool)
    {
        /* Insufficient allowance will be handled by the safe subtraction. */
        tokenState.setAllowance(from, sender, safeSub(tokenState.allowance(from, sender), value));
        return _internalTransfer(from, to, value);
    }
 
    /**
     * @notice Approves spender to transfer on the message sender's behalf.
     */
    function approve(address spender, uint value)
        public
        optionalProxy
        returns (bool)
    {
        address sender = messageSender;
 
        tokenState.setAllowance(sender, spender, value);
        emitApproval(sender, spender, value);
        return true;
    }
 
    /* ========== EVENTS ========== */
 
    event Transfer(address indexed from, address indexed to, uint value);
    bytes32 constant TRANSFER_SIG = keccak256("Transfer(address,address,uint256)");
    function emitTransfer(address from, address to, uint value) internal {
        proxy._emit(abi.encode(value), 3, TRANSFER_SIG, bytes32(from), bytes32(to), 0);
    }
 
    event Approval(address indexed owner, address indexed spender, uint value);
    bytes32 constant APPROVAL_SIG = keccak256("Approval(address,address,uint256)");
    function emitApproval(address owner, address spender, uint value) internal {
        proxy._emit(abi.encode(value), 3, APPROVAL_SIG, bytes32(owner), bytes32(spender), 0);
    }
 
    event TokenStateUpdated(address newTokenState);
    bytes32 constant TOKENSTATEUPDATED_SIG = keccak256("TokenStateUpdated(address)");
    function emitTokenStateUpdated(address newTokenState) internal {
        proxy._emit(abi.encode(newTokenState), 1, TOKENSTATEUPDATED_SIG, 0, 0, 0);
    }
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       FeeToken.sol
version:    1.3
author:     Anton Jurisevic
            Dominic Romanowski
            Kevin Brown
 
date:       2018-05-29
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
A token which also has a configurable fee rate
charged on its transfers. This is designed to be overridden in
order to produce an ERC20-compliant token.
 
These fees accrue into a pool, from which a nominated authority
may withdraw.
 
This contract utilises an external state for upgradeability.
 
-----------------------------------------------------------------
*/
 
 
/**
 * @title ERC20 Token contract, with detached state.
 * Additionally charges fees on each transfer.
 */
contract FeeToken is ExternStateToken {
 
    /* ========== STATE VARIABLES ========== */
 
    /* ERC20 members are declared in ExternStateToken. */
 
    /* A percentage fee charged on each transfer. */
    uint public transferFeeRate;
    /* Fee may not exceed 10%. */
    uint constant MAX_TRANSFER_FEE_RATE = UNIT / 10;
    /* The address with the authority to distribute fees. */
    address public feeAuthority;
    /* The address that fees will be pooled in. */
    address public constant FEE_ADDRESS = 0xfeefeefeefeefeefeefeefeefeefeefeefeefeef;
 
 
    /* ========== CONSTRUCTOR ========== */
 
    /**
     * @dev Constructor.
     * @param _proxy The proxy associated with this contract.
     * @param _name Token's ERC20 name.
     * @param _symbol Token's ERC20 symbol.
     * @param _totalSupply The total supply of the token.
     * @param _transferFeeRate The fee rate to charge on transfers.
     * @param _feeAuthority The address which has the authority to withdraw fees from the accumulated pool.
     * @param _owner The owner of this contract.
     */
    constructor(address _proxy, TokenState _tokenState, string _name, string _symbol, uint _totalSupply,
                uint _transferFeeRate, address _feeAuthority, address _owner)
        ExternStateToken(_proxy, _tokenState,
                         _name, _symbol, _totalSupply,
                         _owner)
        public
    {
        feeAuthority = _feeAuthority;
 
        /* Constructed transfer fee rate should respect the maximum fee rate. */
        require(_transferFeeRate <= MAX_TRANSFER_FEE_RATE);
        transferFeeRate = _transferFeeRate;
    }
 
    /* ========== SETTERS ========== */
 
    /**
     * @notice Set the transfer fee, anywhere within the range 0-10%.
     * @dev The fee rate is in decimal format, with UNIT being the value of 100%.
     */
    function setTransferFeeRate(uint _transferFeeRate)
        external
        optionalProxy_onlyOwner
    {
        require(_transferFeeRate <= MAX_TRANSFER_FEE_RATE);
        transferFeeRate = _transferFeeRate;
        emitTransferFeeRateUpdated(_transferFeeRate);
    }
 
    /**
     * @notice Set the address of the user/contract responsible for collecting or
     * distributing fees.
     */
    function setFeeAuthority(address _feeAuthority)
        public
        optionalProxy_onlyOwner
    {
        feeAuthority = _feeAuthority;
        emitFeeAuthorityUpdated(_feeAuthority);
    }
 
    /* ========== VIEWS ========== */
 
    /**
     * @notice Calculate the Fee charged on top of a value being sent
     * @return Return the fee charged
     */
    function transferFeeIncurred(uint value)
        public
        view
        returns (uint)
    {
        return safeMul_dec(value, transferFeeRate);
        /* Transfers less than the reciprocal of transferFeeRate should be completely eaten up by fees.
         * This is on the basis that transfers less than this value will result in a nil fee.
         * Probably too insignificant to worry about, but the following code will achieve it.
         *      if (fee == 0 && transferFeeRate != 0) {
         *          return _value;
         *      }
         *      return fee;
         */
    }
 
    /**
     * @notice The value that you would need to send so that the recipient receives
     * a specified value.
     */
    function transferPlusFee(uint value)
        external
        view
        returns (uint)
    {
        return safeAdd(value, transferFeeIncurred(value));
    }
 
    /**
     * @notice The amount the recipient will receive if you send a certain number of tokens.
     */
    function amountReceived(uint value)
        public
        view
        returns (uint)
    {
        return safeDiv_dec(value, safeAdd(UNIT, transferFeeRate));
    }
 
    /**
     * @notice Collected fees sit here until they are distributed.
     * @dev The balance of the nomin contract itself is the fee pool.
     */
    function feePool()
        external
        view
        returns (uint)
    {
        return tokenState.balanceOf(FEE_ADDRESS);
    }
 
    /* ========== MUTATIVE FUNCTIONS ========== */
 
    /**
     * @notice Base of transfer functions
     */
    function _internalTransfer(address from, address to, uint amount, uint fee)
        internal
        returns (bool)
    {
        /* Disallow transfers to irretrievable-addresses. */
        require(to != address(0));
        require(to != address(this));
        require(to != address(proxy));
 
        /* Insufficient balance will be handled by the safe subtraction. */
        tokenState.setBalanceOf(from, safeSub(tokenState.balanceOf(from), safeAdd(amount, fee)));
        tokenState.setBalanceOf(to, safeAdd(tokenState.balanceOf(to), amount));
        tokenState.setBalanceOf(FEE_ADDRESS, safeAdd(tokenState.balanceOf(FEE_ADDRESS), fee));
 
        /* Emit events for both the transfer itself and the fee. */
        emitTransfer(from, to, amount);
        emitTransfer(from, FEE_ADDRESS, fee);
 
        return true;
    }
 
    /**
     * @notice ERC20 friendly transfer function.
     */
    function _transfer_byProxy(address sender, address to, uint value)
        internal
        returns (bool)
    {
        uint received = amountReceived(value);
        uint fee = safeSub(value, received);
 
        return _internalTransfer(sender, to, received, fee);
    }
 
    /**
     * @notice ERC20 friendly transferFrom function.
     */
    function _transferFrom_byProxy(address sender, address from, address to, uint value)
        internal
        returns (bool)
    {
        /* The fee is deducted from the amount sent. */
        uint received = amountReceived(value);
        uint fee = safeSub(value, received);
 
        /* Reduce the allowance by the amount we're transferring.
         * The safeSub call will handle an insufficient allowance. */
        tokenState.setAllowance(from, sender, safeSub(tokenState.allowance(from, sender), value));
 
        return _internalTransfer(from, to, received, fee);
    }
 
    /**
     * @notice Ability to transfer where the sender pays the fees (not ERC20)
     */
    function _transferSenderPaysFee_byProxy(address sender, address to, uint value)
        internal
        returns (bool)
    {
        /* The fee is added to the amount sent. */
        uint fee = transferFeeIncurred(value);
        return _internalTransfer(sender, to, value, fee);
    }
 
    /**
     * @notice Ability to transferFrom where they sender pays the fees (not ERC20).
     */
    function _transferFromSenderPaysFee_byProxy(address sender, address from, address to, uint value)
        internal
        returns (bool)
    {
        /* The fee is added to the amount sent. */
        uint fee = transferFeeIncurred(value);
        uint total = safeAdd(value, fee);
 
        /* Reduce the allowance by the amount we're transferring. */
        tokenState.setAllowance(from, sender, safeSub(tokenState.allowance(from, sender), total));
 
        return _internalTransfer(from, to, value, fee);
    }
 
    /**
     * @notice Withdraw tokens from the fee pool into a given account.
     * @dev Only the fee authority may call this.
     */
    function withdrawFees(address account, uint value)
        external
        onlyFeeAuthority
        returns (bool)
    {
        require(account != address(0));
 
        /* 0-value withdrawals do nothing. */
        if (value == 0) {
            return false;
        }
 
        /* Safe subtraction ensures an exception is thrown if the balance is insufficient. */
        tokenState.setBalanceOf(FEE_ADDRESS, safeSub(tokenState.balanceOf(FEE_ADDRESS), value));
        tokenState.setBalanceOf(account, safeAdd(tokenState.balanceOf(account), value));
 
        emitFeesWithdrawn(account, value);
        emitTransfer(FEE_ADDRESS, account, value);
 
        return true;
    }
 
    /**
     * @notice Donate tokens from the sender's balance into the fee pool.
     */
    function donateToFeePool(uint n)
        external
        optionalProxy
        returns (bool)
    {
        address sender = messageSender;
        /* Empty donations are disallowed. */
        uint balance = tokenState.balanceOf(sender);
        require(balance != 0);
 
        /* safeSub ensures the donor has sufficient balance. */
        tokenState.setBalanceOf(sender, safeSub(balance, n));
        tokenState.setBalanceOf(FEE_ADDRESS, safeAdd(tokenState.balanceOf(FEE_ADDRESS), n));
 
        emitFeesDonated(sender, n);
        emitTransfer(sender, FEE_ADDRESS, n);
 
        return true;
    }
 
 
    /* ========== MODIFIERS ========== */
 
    modifier onlyFeeAuthority
    {
        require(msg.sender == feeAuthority);
        _;
    }
 
 
    /* ========== EVENTS ========== */
 
    event TransferFeeRateUpdated(uint newFeeRate);
    bytes32 constant TRANSFERFEERATEUPDATED_SIG = keccak256("TransferFeeRateUpdated(uint256)");
    function emitTransferFeeRateUpdated(uint newFeeRate) internal {
        proxy._emit(abi.encode(newFeeRate), 1, TRANSFERFEERATEUPDATED_SIG, 0, 0, 0);
    }
 
    event FeeAuthorityUpdated(address newFeeAuthority);
    bytes32 constant FEEAUTHORITYUPDATED_SIG = keccak256("FeeAuthorityUpdated(address)");
    function emitFeeAuthorityUpdated(address newFeeAuthority) internal {
        proxy._emit(abi.encode(newFeeAuthority), 1, FEEAUTHORITYUPDATED_SIG, 0, 0, 0);
    }
 
    event FeesWithdrawn(address indexed account, uint value);
    bytes32 constant FEESWITHDRAWN_SIG = keccak256("FeesWithdrawn(address,uint256)");
    function emitFeesWithdrawn(address account, uint value) internal {
        proxy._emit(abi.encode(value), 2, FEESWITHDRAWN_SIG, bytes32(account), 0, 0);
    }
 
    event FeesDonated(address indexed donor, uint value);
    bytes32 constant FEESDONATED_SIG = keccak256("FeesDonated(address,uint256)");
    function emitFeesDonated(address donor, uint value) internal {
        proxy._emit(abi.encode(value), 2, FEESDONATED_SIG, bytes32(donor), 0, 0);
    }
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       Court.sol
version:    1.2
author:     Anton Jurisevic
            Mike Spain
            Dominic Romanowski
 
date:       2018-05-29
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
This provides the nomin contract with a confiscation
facility, if enough havven owners vote to confiscate a target
account's nomins.
 
This is designed to provide a mechanism to respond to abusive
contracts such as nomin wrappers, which would allow users to
trade wrapped nomins without accruing fees on those transactions.
 
In order to prevent tyranny, an account may only be frozen if
users controlling at least 30% of the value of havvens participate,
and a two thirds majority is attained in that vote.
In order to prevent tyranny of the majority or mob justice,
confiscation motions are only approved if the havven foundation
approves the result.
This latter requirement may be lifted in future versions.
 
The foundation, or any user with a sufficient havven balance may
bring a confiscation motion.
A motion lasts for a default period of one week, with a further
confirmation period in which the foundation approves the result.
The latter period may conclude early upon the foundation's decision
to either veto or approve the mooted confiscation motion.
If the confirmation period elapses without the foundation making
a decision, the motion fails.
 
The weight of a havven holder's vote is determined by examining
their average balance over the last completed fee period prior to
the beginning of a given motion.
 
Thus, since a fee period can roll over in the middle of a motion,
we must also track a user's average balance of the last two periods.
This system is designed such that it cannot be attacked by users
transferring funds between themselves, while also not requiring them
to lock their havvens for the duration of the vote. This is possible
since any transfer that increases the average balance in one account
will be reflected by an equivalent reduction in the voting weight in
the other.
 
At present a user may cast a vote only for one motion at a time,
but may cancel their vote at any time except during the confirmation period,
when the vote tallies must remain static until the matter has been settled.
 
A motion to confiscate the balance of a given address composes
a state machine built of the following states:
 
Waiting:
  - A user with standing brings a motion:
    If the target address is not frozen;
    initialise vote tallies to 0;
    transition to the Voting state.
 
  - An account cancels a previous residual vote:
    remain in the Waiting state.
 
Voting:
  - The foundation vetoes the in-progress motion:
    transition to the Waiting state.
 
  - The voting period elapses:
    transition to the Confirmation state.
 
  - An account votes (for or against the motion):
    its weight is added to the appropriate tally;
    remain in the Voting state.
 
  - An account cancels its previous vote:
    its weight is deducted from the appropriate tally (if any);
    remain in the Voting state.
 
Confirmation:
  - The foundation vetoes the completed motion:
    transition to the Waiting state.
 
  - The foundation approves confiscation of the target account:
    freeze the target account, transfer its nomin balance to the fee pool;
    transition to the Waiting state.
 
  - The confirmation period elapses:
    transition to the Waiting state.
 
User votes are not automatically cancelled upon the conclusion of a motion.
Therefore, after a motion comes to a conclusion, if a user wishes to vote
in another motion, they must manually cancel their vote in order to do so.
 
This procedure is designed to be relatively simple.
There are some things that can be added to enhance the functionality
at the expense of simplicity and efficiency:
 
  - Democratic unfreezing of nomin accounts (induces multiple categories of vote)
  - Configurable per-vote durations;
  - Vote standing denominated in a fiat quantity rather than a quantity of havvens;
  - Confiscate from multiple addresses in a single vote;
 
We might consider updating the contract with any of these features at a later date if necessary.
 
-----------------------------------------------------------------
*/
 
 
/**
 * @title A court contract allowing a democratic mechanism to dissuade token wrappers.
 */
contract Court is SafeDecimalMath, Owned {
 
    /* ========== STATE VARIABLES ========== */
 
    /* The addresses of the token contracts this confiscation court interacts with. */
    Havven public havven;
    Nomin public nomin;
 
    /* The minimum issued nomin balance required to be considered to have
     * standing to begin confiscation proceedings. */
    uint public minStandingBalance = 100 * UNIT;
 
    /* The voting period lasts for this duration,
     * and if set, must fall within the given bounds. */
    uint public votingPeriod = 1 weeks;
    uint constant MIN_VOTING_PERIOD = 3 days;
    uint constant MAX_VOTING_PERIOD = 4 weeks;
 
    /* Duration of the period during which the foundation may confirm
     * or veto a motion that has concluded.
     * If set, the confirmation duration must fall within the given bounds. */
    uint public confirmationPeriod = 1 weeks;
    uint constant MIN_CONFIRMATION_PERIOD = 1 days;
    uint constant MAX_CONFIRMATION_PERIOD = 2 weeks;
 
    /* No fewer than this fraction of total available voting power must
     * participate in a motion in order for a quorum to be reached.
     * The participation fraction required may be set no lower than 10%.
     * As a fraction, it is expressed in terms of UNIT, not as an absolute quantity. */
    uint public requiredParticipation = 3 * UNIT / 10;
    uint constant MIN_REQUIRED_PARTICIPATION = UNIT / 10;
 
    /* At least this fraction of participating votes must be in favour of
     * confiscation for the motion to pass.
     * The required majority may be no lower than 50%.
     * As a fraction, it is expressed in terms of UNIT, not as an absolute quantity. */
    uint public requiredMajority = (2 * UNIT) / 3;
    uint constant MIN_REQUIRED_MAJORITY = UNIT / 2;
 
    /* The next ID to use for opening a motion.
     * The 0 motion ID corresponds to no motion,
     * and is used as a null value for later comparison. */
    uint nextMotionID = 1;
 
    /* Mapping from motion IDs to target addresses. */
    mapping(uint => address) public motionTarget;
 
    /* The ID a motion on an address is currently operating at.
     * Zero if no such motion is running. */
    mapping(address => uint) public targetMotionID;
 
    /* The timestamp at which a motion began. This is used to determine
     * whether a motion is: running, in the confirmation period,
     * or has concluded.
     * A motion runs from its start time t until (t + votingPeriod),
     * and then the confirmation period terminates no later than
     * (t + votingPeriod + confirmationPeriod). */
    mapping(uint => uint) public motionStartTime;
 
    /* The tallies for and against confiscation of a given balance.
     * These are set to zero at the start of a motion, and also on conclusion,
     * just to keep the state clean. */
    mapping(uint => uint) public votesFor;
    mapping(uint => uint) public votesAgainst;
 
    /* The last average balance of a user at the time they voted
     * in a particular motion.
     * If we did not save this information then we would have to
     * disallow transfers into an account lest it cancel a vote
     * with greater weight than that with which it originally voted,
     * and the fee period rolled over in between. */
    // TODO: This may be unnecessary now that votes are forced to be
    // within a fee period. Likely possible to delete this.
    mapping(address => mapping(uint => uint)) voteWeight;
 
    /* The possible vote types.
     * Abstention: not participating in a motion; This is the default value.
     * Yea: voting in favour of a motion.
     * Nay: voting against a motion. */
    enum Vote {Abstention, Yea, Nay}
 
    /* A given account's vote in some confiscation motion.
     * This requires the default value of the Vote enum to correspond to an abstention. */
    mapping(address => mapping(uint => Vote)) public vote;
 
 
    /* ========== CONSTRUCTOR ========== */
 
    /**
     * @dev Court Constructor.
     */
    constructor(Havven _havven, Nomin _nomin, address _owner)
        Owned(_owner)
        public
    {
        havven = _havven;
        nomin = _nomin;
    }
 
 
    /* ========== SETTERS ========== */
 
    /**
     * @notice Set the minimum required havven balance to have standing to bring a motion.
     * @dev Only the contract owner may call this.
     */
    function setMinStandingBalance(uint balance)
        external
        onlyOwner
    {
        /* No requirement on the standing threshold here;
         * the foundation can set this value such that
         * anyone or no one can actually start a motion. */
        minStandingBalance = balance;
    }
 
    /**
     * @notice Set the length of time a vote runs for.
     * @dev Only the contract owner may call this. The proposed duration must fall
     * within sensible bounds (3 days to 4 weeks), and must be no longer than a single fee period.
     */
    function setVotingPeriod(uint duration)
        external
        onlyOwner
    {
        require(MIN_VOTING_PERIOD <= duration &&
                duration <= MAX_VOTING_PERIOD);
        /* Require that the voting period is no longer than a single fee period,
         * So that a single vote can span at most two fee periods. */
        require(duration <= havven.feePeriodDuration());
        votingPeriod = duration;
    }
 
    /**
     * @notice Set the confirmation period after a vote has concluded.
     * @dev Only the contract owner may call this. The proposed duration must fall
     * within sensible bounds (1 day to 2 weeks).
     */
    function setConfirmationPeriod(uint duration)
        external
        onlyOwner
    {
        require(MIN_CONFIRMATION_PERIOD <= duration &&
                duration <= MAX_CONFIRMATION_PERIOD);
        confirmationPeriod = duration;
    }
 
    /**
     * @notice Set the required fraction of all Havvens that need to be part of
     * a vote for it to pass.
     */
    function setRequiredParticipation(uint fraction)
        external
        onlyOwner
    {
        require(MIN_REQUIRED_PARTICIPATION <= fraction);
        requiredParticipation = fraction;
    }
 
    /**
     * @notice Set what portion of voting havvens need to be in the affirmative
     * to allow it to pass.
     */
    function setRequiredMajority(uint fraction)
        external
        onlyOwner
    {
        require(MIN_REQUIRED_MAJORITY <= fraction);
        requiredMajority = fraction;
    }
 
 
    /* ========== VIEW FUNCTIONS ========== */
 
    /**
     * @notice There is a motion in progress on the specified
     * account, and votes are being accepted in that motion.
     */
    function motionVoting(uint motionID)
        public
        view
        returns (bool)
    {
        return motionStartTime[motionID] < now && now < motionStartTime[motionID] + votingPeriod;
    }
 
    /**
     * @notice A vote on the target account has concluded, but the motion
     * has not yet been approved, vetoed, or closed. */
    function motionConfirming(uint motionID)
        public
        view
        returns (bool)
    {
        /* These values are timestamps, they will not overflow
         * as they can only ever be initialised to relatively small values.
         */
        uint startTime = motionStartTime[motionID];
        return startTime + votingPeriod <= now &&
               now < startTime + votingPeriod + confirmationPeriod;
    }
 
    /**
     * @notice A vote motion either not begun, or it has completely terminated.
     */
    function motionWaiting(uint motionID)
        public
        view
        returns (bool)
    {
        /* These values are timestamps, they will not overflow
         * as they can only ever be initialised to relatively small values. */
        return motionStartTime[motionID] + votingPeriod + confirmationPeriod <= now;
    }
 
    /**
     * @notice If the motion was to terminate at this instant, it would pass.
     * That is: there was sufficient participation and a sizeable enough majority.
     */
    function motionPasses(uint motionID)
        public
        view
        returns (bool)
    {
        uint yeas = votesFor[motionID];
        uint nays = votesAgainst[motionID];
        uint totalVotes = safeAdd(yeas, nays);
 
        if (totalVotes == 0) {
            return false;
        }
 
        uint participation = safeDiv_dec(totalVotes, havven.totalIssuanceLastAverageBalance());
        uint fractionInFavour = safeDiv_dec(yeas, totalVotes);
 
        /* We require the result to be strictly greater than the requirement
         * to enforce a majority being "50% + 1", and so on. */
        return participation > requiredParticipation &&
               fractionInFavour > requiredMajority;
    }
 
    /**
     * @notice Return if the specified account has voted on the specified motion
     */
    function hasVoted(address account, uint motionID)
        public
        view
        returns (bool)
    {
        return vote[account][motionID] != Vote.Abstention;
    }
 
 
    /* ========== MUTATIVE FUNCTIONS ========== */
 
    /**
     * @notice Begin a motion to confiscate the funds in a given nomin account.
     * @dev Only the foundation, or accounts with sufficient havven balances
     * may elect to start such a motion.
     * @return Returns the ID of the motion that was begun.
     */
    function beginMotion(address target)
        external
        returns (uint)
    {
        /* A confiscation motion must be mooted by someone with standing. */
        require((havven.issuanceLastAverageBalance(msg.sender) >= minStandingBalance) ||
                msg.sender == owner);
 
        /* Require that the voting period is longer than a single fee period,
         * So that a single vote can span at most two fee periods. */
        require(votingPeriod <= havven.feePeriodDuration());
 
        /* There must be no confiscation motion already running for this account. */
        require(targetMotionID[target] == 0);
 
        /* Disallow votes on accounts that are currently frozen. */
        require(!nomin.frozen(target));
 
        /* It is necessary to roll over the fee period if it has elapsed, or else
         * the vote might be initialised having begun in the past. */
        havven.rolloverFeePeriodIfElapsed();
 
        uint motionID = nextMotionID++;
        motionTarget[motionID] = target;
        targetMotionID[target] = motionID;
 
        /* Start the vote at the start of the next fee period */
        uint startTime = havven.feePeriodStartTime() + havven.feePeriodDuration();
        motionStartTime[motionID] = startTime;
        emit MotionBegun(msg.sender, target, motionID, startTime);
 
        return motionID;
    }
 
    /**
     * @notice Shared vote setup function between voteFor and voteAgainst.
     * @return Returns the voter's vote weight. */
    function setupVote(uint motionID)
        internal
        returns (uint)
    {
        /* There must be an active vote for this target running.
         * Vote totals must only change during the voting phase. */
        require(motionVoting(motionID));
 
        /* The voter must not have an active vote this motion. */
        require(!hasVoted(msg.sender, motionID));
 
        /* The voter may not cast votes on themselves. */
        require(msg.sender != motionTarget[motionID]);
 
        uint weight = havven.recomputeLastAverageBalance(msg.sender);
 
        /* Users must have a nonzero voting weight to vote. */
        require(weight > 0);
 
        voteWeight[msg.sender][motionID] = weight;
 
        return weight;
    }
 
    /**
     * @notice The sender casts a vote in favour of confiscation of the
     * target account's nomin balance.
     */
    function voteFor(uint motionID)
        external
    {
        uint weight = setupVote(motionID);
        vote[msg.sender][motionID] = Vote.Yea;
        votesFor[motionID] = safeAdd(votesFor[motionID], weight);
        emit VotedFor(msg.sender, motionID, weight);
    }
 
    /**
     * @notice The sender casts a vote against confiscation of the
     * target account's nomin balance.
     */
    function voteAgainst(uint motionID)
        external
    {
        uint weight = setupVote(motionID);
        vote[msg.sender][motionID] = Vote.Nay;
        votesAgainst[motionID] = safeAdd(votesAgainst[motionID], weight);
        emit VotedAgainst(msg.sender, motionID, weight);
    }
 
    /**
     * @notice Cancel an existing vote by the sender on a motion
     * to confiscate the target balance.
     */
    function cancelVote(uint motionID)
        external
    {
        /* An account may cancel its vote either before the confirmation phase
         * when the motion is still open, or after the confirmation phase,
         * when the motion has concluded.
         * But the totals must not change during the confirmation phase itself. */
        require(!motionConfirming(motionID));
 
        Vote senderVote = vote[msg.sender][motionID];
 
        /* If the sender has not voted then there is no need to update anything. */
        require(senderVote != Vote.Abstention);
 
        /* If we are not voting, there is no reason to update the vote totals. */
        if (motionVoting(motionID)) {
            if (senderVote == Vote.Yea) {
                votesFor[motionID] = safeSub(votesFor[motionID], voteWeight[msg.sender][motionID]);
            } else {
                /* Since we already ensured that the vote is not an abstention,
                 * the only option remaining is Vote.Nay. */
                votesAgainst[motionID] = safeSub(votesAgainst[motionID], voteWeight[msg.sender][motionID]);
            }
            /* A cancelled vote is only meaningful if a vote is running. */
            emit VoteCancelled(msg.sender, motionID);
        }
 
        delete voteWeight[msg.sender][motionID];
        delete vote[msg.sender][motionID];
    }
 
    /**
     * @notice clear all data associated with a motionID for hygiene purposes.
     */
    function _closeMotion(uint motionID)
        internal
    {
        delete targetMotionID[motionTarget[motionID]];
        delete motionTarget[motionID];
        delete motionStartTime[motionID];
        delete votesFor[motionID];
        delete votesAgainst[motionID];
        emit MotionClosed(motionID);
    }
 
    /**
     * @notice If a motion has concluded, or if it lasted its full duration but not passed,
     * then anyone may close it.
     */
    function closeMotion(uint motionID)
        external
    {
        require((motionConfirming(motionID) && !motionPasses(motionID)) || motionWaiting(motionID));
        _closeMotion(motionID);
    }
 
    /**
     * @notice The foundation may only confiscate a balance during the confirmation
     * period after a motion has passed.
     */
    function approveMotion(uint motionID)
        external
        onlyOwner
    {
        require(motionConfirming(motionID) && motionPasses(motionID));
        address target = motionTarget[motionID];
        nomin.freezeAndConfiscate(target);
        _closeMotion(motionID);
        emit MotionApproved(motionID);
    }
 
    /* @notice The foundation may veto a motion at any time. */
    function vetoMotion(uint motionID)
        external
        onlyOwner
    {
        require(!motionWaiting(motionID));
        _closeMotion(motionID);
        emit MotionVetoed(motionID);
    }
 
 
    /* ========== EVENTS ========== */
 
    event MotionBegun(address indexed initiator, address indexed target, uint indexed motionID, uint startTime);
 
    event VotedFor(address indexed voter, uint indexed motionID, uint weight);
 
    event VotedAgainst(address indexed voter, uint indexed motionID, uint weight);
 
    event VoteCancelled(address indexed voter, uint indexed motionID);
 
    event MotionClosed(uint indexed motionID);
 
    event MotionVetoed(uint indexed motionID);
 
    event MotionApproved(uint indexed motionID);
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       Nomin.sol
version:    1.2
author:     Anton Jurisevic
            Mike Spain
            Dominic Romanowski
            Kevin Brown
 
date:       2018-05-29
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
Havven-backed nomin stablecoin contract.
 
This contract issues nomins, which are tokens worth 1 USD each.
 
Nomins are issuable by Havven holders who have to lock up some
value of their havvens to issue H * Cmax nomins. Where Cmax is
some value less than 1.
 
A configurable fee is charged on nomin transfers and deposited
into a common pot, which havven holders may withdraw from once
per fee period.
 
-----------------------------------------------------------------
*/
 
 
contract Nomin is FeeToken {
 
    /* ========== STATE VARIABLES ========== */
 
    // The address of the contract which manages confiscation votes.
    Court public court;
    Havven public havven;
 
    // Accounts which have lost the privilege to transact in nomins.
    mapping(address => bool) public frozen;
 
    // Nomin transfers incur a 15 bp fee by default.
    uint constant TRANSFER_FEE_RATE = 15 * UNIT / 10000;
    string constant TOKEN_NAME = "Nomin USD";
    string constant TOKEN_SYMBOL = "nUSD";
 
    /* ========== CONSTRUCTOR ========== */
 
    constructor(address _proxy, TokenState _tokenState, Havven _havven,
                uint _totalSupply,
                address _owner)
        FeeToken(_proxy, _tokenState,
                 TOKEN_NAME, TOKEN_SYMBOL, _totalSupply,
                 TRANSFER_FEE_RATE,
                 _havven, // The havven contract is the fee authority.
                 _owner)
        public
    {
        require(_proxy != 0 && address(_havven) != 0 && _owner != 0);
        // It should not be possible to transfer to the fee pool directly (or confiscate its balance).
        frozen[FEE_ADDRESS] = true;
        havven = _havven;
    }
 
    /* ========== SETTERS ========== */
 
    function setCourt(Court _court)
        external
        optionalProxy_onlyOwner
    {
        court = _court;
        emitCourtUpdated(_court);
    }
 
    function setHavven(Havven _havven)
        external
        optionalProxy_onlyOwner
    {
        // havven should be set as the feeAuthority after calling this depending on
        // havven's internal logic
        havven = _havven;
        setFeeAuthority(_havven);
        emitHavvenUpdated(_havven);
    }
 
 
    /* ========== MUTATIVE FUNCTIONS ========== */
 
    /* Override ERC20 transfer function in order to check
     * whether the recipient account is frozen. Note that there is
     * no need to check whether the sender has a frozen account,
     * since their funds have already been confiscated,
     * and no new funds can be transferred to it.*/
    function transfer(address to, uint value)
        public
        optionalProxy
        returns (bool)
    {
        require(!frozen[to]);
        return _transfer_byProxy(messageSender, to, value);
    }
 
    /* Override ERC20 transferFrom function in order to check
     * whether the recipient account is frozen. */
    function transferFrom(address from, address to, uint value)
        public
        optionalProxy
        returns (bool)
    {
        require(!frozen[to]);
        return _transferFrom_byProxy(messageSender, from, to, value);
    }
 
    function transferSenderPaysFee(address to, uint value)
        public
        optionalProxy
        returns (bool)
    {
        require(!frozen[to]);
        return _transferSenderPaysFee_byProxy(messageSender, to, value);
    }
 
    function transferFromSenderPaysFee(address from, address to, uint value)
        public
        optionalProxy
        returns (bool)
    {
        require(!frozen[to]);
        return _transferFromSenderPaysFee_byProxy(messageSender, from, to, value);
    }
 
    /* If a confiscation court motion has passed and reached the confirmation
     * state, the court may transfer the target account's balance to the fee pool
     * and freeze its participation in further transactions. */
    function freezeAndConfiscate(address target)
        external
        onlyCourt
    {
         
        // A motion must actually be underway.
        uint motionID = court.targetMotionID(target);
        require(motionID != 0);
 
        // These checks are strictly unnecessary,
        // since they are already checked in the court contract itself.
        require(court.motionConfirming(motionID));
        require(court.motionPasses(motionID));
        require(!frozen[target]);
 
        // Confiscate the balance in the account and freeze it.
        uint balance = tokenState.balanceOf(target);
        tokenState.setBalanceOf(FEE_ADDRESS, safeAdd(tokenState.balanceOf(FEE_ADDRESS), balance));
        tokenState.setBalanceOf(target, 0);
        frozen[target] = true;
        emitAccountFrozen(target, balance);
        emitTransfer(target, FEE_ADDRESS, balance);
    }
 
    /* The owner may allow a previously-frozen contract to once
     * again accept and transfer nomins. */
    function unfreezeAccount(address target)
        external
        optionalProxy_onlyOwner
    {
        require(frozen[target] && target != FEE_ADDRESS);
        frozen[target] = false;
        emitAccountUnfrozen(target);
    }
 
    /* Allow havven to issue a certain number of
     * nomins from an account. */
    function issue(address account, uint amount)
        external
        onlyHavven
    {
        tokenState.setBalanceOf(account, safeAdd(tokenState.balanceOf(account), amount));
        totalSupply = safeAdd(totalSupply, amount);
        emitTransfer(address(0), account, amount);
        emitIssued(account, amount);
    }
 
    /* Allow havven to burn a certain number of
     * nomins from an account. */
    function burn(address account, uint amount)
        external
        onlyHavven
    {
        tokenState.setBalanceOf(account, safeSub(tokenState.balanceOf(account), amount));
        totalSupply = safeSub(totalSupply, amount);
        emitTransfer(account, address(0), amount);
        emitBurned(account, amount);
    }
 
    /* ========== MODIFIERS ========== */
 
    modifier onlyHavven() {
        require(Havven(msg.sender) == havven);
        _;
    }
 
    modifier onlyCourt() {
        require(Court(msg.sender) == court);
        _;
    }
 
    /* ========== EVENTS ========== */
 
    event CourtUpdated(address newCourt);
    bytes32 constant COURTUPDATED_SIG = keccak256("CourtUpdated(address)");
    function emitCourtUpdated(address newCourt) internal {
        proxy._emit(abi.encode(newCourt), 1, COURTUPDATED_SIG, 0, 0, 0);
    }
 
    event HavvenUpdated(address newHavven);
    bytes32 constant HAVVENUPDATED_SIG = keccak256("HavvenUpdated(address)");
    function emitHavvenUpdated(address newHavven) internal {
        proxy._emit(abi.encode(newHavven), 1, HAVVENUPDATED_SIG, 0, 0, 0);
    }
 
    event AccountFrozen(address indexed target, uint balance);
    bytes32 constant ACCOUNTFROZEN_SIG = keccak256("AccountFrozen(address,uint256)");
    function emitAccountFrozen(address target, uint balance) internal {
        proxy._emit(abi.encode(balance), 2, ACCOUNTFROZEN_SIG, bytes32(target), 0, 0);
    }
 
    event AccountUnfrozen(address indexed target);
    bytes32 constant ACCOUNTUNFROZEN_SIG = keccak256("AccountUnfrozen(address)");
    function emitAccountUnfrozen(address target) internal {
        proxy._emit(abi.encode(), 2, ACCOUNTUNFROZEN_SIG, bytes32(target), 0, 0);
    }
 
    event Issued(address indexed account, uint amount);
    bytes32 constant ISSUED_SIG = keccak256("Issued(address,uint256)");
    function emitIssued(address account, uint amount) internal {
        proxy._emit(abi.encode(amount), 2, ISSUED_SIG, bytes32(account), 0, 0);
    }
 
    event Burned(address indexed account, uint amount);
    bytes32 constant BURNED_SIG = keccak256("Burned(address,uint256)");
    function emitBurned(address account, uint amount) internal {
        proxy._emit(abi.encode(amount), 2, BURNED_SIG, bytes32(account), 0, 0);
    }
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       LimitedSetup.sol
version:    1.1
author:     Anton Jurisevic
 
date:       2018-05-15
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
A contract with a limited setup period. Any function modified
with the setup modifier will cease to work after the
conclusion of the configurable-length post-construction setup period.
 
-----------------------------------------------------------------
*/
 
 
/**
 * @title Any function decorated with the modifier this contract provides
 * deactivates after a specified setup period.
 */
contract LimitedSetup {
 
    uint setupExpiryTime;
 
    /**
     * @dev LimitedSetup Constructor.
     * @param setupDuration The time the setup period will last for.
     */
    constructor(uint setupDuration)
        public
    {
        setupExpiryTime = now + setupDuration;
    }
 
    modifier onlyDuringSetup
    {
        require(now < setupExpiryTime);
        _;
    }
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       HavvenEscrow.sol
version:    1.1
author:     Anton Jurisevic
            Dominic Romanowski
            Mike Spain
 
date:       2018-05-29
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
This contract allows the foundation to apply unique vesting
schedules to havven funds sold at various discounts in the token
sale. HavvenEscrow gives users the ability to inspect their
vested funds, their quantities and vesting dates, and to withdraw
the fees that accrue on those funds.
 
The fees are handled by withdrawing the entire fee allocation
for all havvens inside the escrow contract, and then allowing
the contract itself to subdivide that pool up proportionally within
itself. Every time the fee period rolls over in the main Havven
contract, the HavvenEscrow fee pool is remitted back into the
main fee pool to be redistributed in the next fee period.
 
-----------------------------------------------------------------
*/
 
 
/**
 * @title A contract to hold escrowed havvens and free them at given schedules.
 */
contract HavvenEscrow is SafeDecimalMath, Owned, LimitedSetup(8 weeks) {
    /* The corresponding Havven contract. */
    Havven public havven;
 
    /* Lists of (timestamp, quantity) pairs per account, sorted in ascending time order.
     * These are the times at which each given quantity of havvens vests. */
    mapping(address => uint[2][]) public vestingSchedules;
 
    /* An account's total vested havven balance to save recomputing this for fee extraction purposes. */
    mapping(address => uint) public totalVestedAccountBalance;
 
    /* The total remaining vested balance, for verifying the actual havven balance of this contract against. */
    uint public totalVestedBalance;
 
    uint constant TIME_INDEX = 0;
    uint constant QUANTITY_INDEX = 1;
 
    /* Limit vesting entries to disallow unbounded iteration over vesting schedules. */
    uint constant MAX_VESTING_ENTRIES = 20;
 
 
    /* ========== CONSTRUCTOR ========== */
 
    constructor(address _owner, Havven _havven)
        Owned(_owner)
        public
    {
        havven = _havven;
    }
 
 
    /* ========== SETTERS ========== */
 
    function setHavven(Havven _havven)
        external
        onlyOwner
    {
        havven = _havven;
        emit HavvenUpdated(_havven);
    }
 
 
    /* ========== VIEW FUNCTIONS ========== */
 
    /**
     * @notice A simple alias to totalVestedAccountBalance: provides ERC20 balance integration.
     */
    function balanceOf(address account)
        public
        view
        returns (uint)
    {
        return totalVestedAccountBalance[account];
    }
 
    /**
     * @notice The number of vesting dates in an account's schedule.
     */
    function numVestingEntries(address account)
        public
        view
        returns (uint)
    {
        return vestingSchedules[account].length;
    }
 
    /**
     * @notice Get a particular schedule entry for an account.
     * @return A pair of uints: (timestamp, havven quantity).
     */
    function getVestingScheduleEntry(address account, uint index)
        public
        view
        returns (uint[2])
    {
        return vestingSchedules[account][index];
    }
 
    /**
     * @notice Get the time at which a given schedule entry will vest.
     */
    function getVestingTime(address account, uint index)
        public
        view
        returns (uint)
    {
        return getVestingScheduleEntry(account,index)[TIME_INDEX];
    }
 
    /**
     * @notice Get the quantity of havvens associated with a given schedule entry.
     */
    function getVestingQuantity(address account, uint index)
        public
        view
        returns (uint)
    {
        return getVestingScheduleEntry(account,index)[QUANTITY_INDEX];
    }
 
    /**
     * @notice Obtain the index of the next schedule entry that will vest for a given user.
     */
    function getNextVestingIndex(address account)
        public
        view
        returns (uint)
    {
        uint len = numVestingEntries(account);
        for (uint i = 0; i < len; i++) {
            if (getVestingTime(account, i) != 0) {
                return i;
            }
        }
        return len;
    }
 
    /**
     * @notice Obtain the next schedule entry that will vest for a given user.
     * @return A pair of uints: (timestamp, havven quantity). */
    function getNextVestingEntry(address account)
        public
        view
        returns (uint[2])
    {
        uint index = getNextVestingIndex(account);
        if (index == numVestingEntries(account)) {
            return [uint(0), 0];
        }
        return getVestingScheduleEntry(account, index);
    }
 
    /**
     * @notice Obtain the time at which the next schedule entry will vest for a given user.
     */
    function getNextVestingTime(address account)
        external
        view
        returns (uint)
    {
        return getNextVestingEntry(account)[TIME_INDEX];
    }
 
    /**
     * @notice Obtain the quantity which the next schedule entry will vest for a given user.
     */
    function getNextVestingQuantity(address account)
        external
        view
        returns (uint)
    {
        return getNextVestingEntry(account)[QUANTITY_INDEX];
    }
 
 
    /* ========== MUTATIVE FUNCTIONS ========== */
 
    /**
     * @notice Withdraws a quantity of havvens back to the havven contract.
     * @dev This may only be called by the owner during the contract's setup period.
     */
    function withdrawHavvens(uint quantity)
        external
        onlyOwner
        onlyDuringSetup
    {
        havven.transfer(havven, quantity);
    }
 
    /**
     * @notice Destroy the vesting information associated with an account.
     */
    function purgeAccount(address account)
        external
        onlyOwner
        onlyDuringSetup
    {
        delete vestingSchedules[account];
        totalVestedBalance = safeSub(totalVestedBalance, totalVestedAccountBalance[account]);
        delete totalVestedAccountBalance[account];
    }
 
    /**
     * @notice Add a new vesting entry at a given time and quantity to an account's schedule.
     * @dev A call to this should be accompanied by either enough balance already available
     * in this contract, or a corresponding call to havven.endow(), to ensure that when
     * the funds are withdrawn, there is enough balance, as well as correctly calculating
     * the fees.
     * This may only be called by the owner during the contract's setup period.
     * Note; although this function could technically be used to produce unbounded
     * arrays, it's only in the foundation's command to add to these lists.
     * @param account The account to append a new vesting entry to.
     * @param time The absolute unix timestamp after which the vested quantity may be withdrawn.
     * @param quantity The quantity of havvens that will vest.
     */
    function appendVestingEntry(address account, uint time, uint quantity)
        public
        onlyOwner
        onlyDuringSetup
    {
        /* No empty or already-passed vesting entries allowed. */
        require(now < time);
        require(quantity != 0);
 
        /* There must be enough balance in the contract to provide for the vesting entry. */
        totalVestedBalance = safeAdd(totalVestedBalance, quantity);
        require(totalVestedBalance <= havven.balanceOf(this));
 
        /* Disallow arbitrarily long vesting schedules in light of the gas limit. */
        uint scheduleLength = vestingSchedules[account].length;
        require(scheduleLength <= MAX_VESTING_ENTRIES);
 
        if (scheduleLength == 0) {
            totalVestedAccountBalance[account] = quantity;
        } else {
            /* Disallow adding new vested havvens earlier than the last one.
             * Since entries are only appended, this means that no vesting date can be repeated. */
            require(getVestingTime(account, numVestingEntries(account) - 1) < time);
            totalVestedAccountBalance[account] = safeAdd(totalVestedAccountBalance[account], quantity);
        }
 
        vestingSchedules[account].push([time, quantity]);
    }
 
    /**
     * @notice Construct a vesting schedule to release a quantities of havvens
     * over a series of intervals.
     * @dev Assumes that the quantities are nonzero
     * and that the sequence of timestamps is strictly increasing.
     * This may only be called by the owner during the contract's setup period.
     */
    function addVestingSchedule(address account, uint[] times, uint[] quantities)
        external
        onlyOwner
        onlyDuringSetup
    {
        for (uint i = 0; i < times.length; i++) {
            appendVestingEntry(account, times[i], quantities[i]);
        }
 
    }
 
    /**
     * @notice Allow a user to withdraw any havvens in their schedule that have vested.
     */
    function vest()
        external
    {
        uint numEntries = numVestingEntries(msg.sender);
        uint total;
        for (uint i = 0; i < numEntries; i++) {
            uint time = getVestingTime(msg.sender, i);
            /* The list is sorted; when we reach the first future time, bail out. */
            if (time > now) {
                break;
            }
            uint qty = getVestingQuantity(msg.sender, i);
            if (qty == 0) {
                continue;
            }
 
            vestingSchedules[msg.sender][i] = [0, 0];
            total = safeAdd(total, qty);
        }
 
        if (total != 0) {
            totalVestedBalance = safeSub(totalVestedBalance, total);
            totalVestedAccountBalance[msg.sender] = safeSub(totalVestedAccountBalance[msg.sender], total);
            havven.transfer(msg.sender, total);
            emit Vested(msg.sender, now, total);
        }
    }
 
 
    /* ========== EVENTS ========== */
 
    event HavvenUpdated(address newHavven);
 
    event Vested(address indexed beneficiary, uint time, uint value);
}
 
 
/*
-----------------------------------------------------------------
FILE INFORMATION
-----------------------------------------------------------------
 
file:       Havven.sol
version:    1.2
author:     Anton Jurisevic
            Dominic Romanowski
 
date:       2018-05-15
 
-----------------------------------------------------------------
MODULE DESCRIPTION
-----------------------------------------------------------------
 
Havven token contract. Havvens are transferable ERC20 tokens,
and also give their holders the following privileges.
An owner of havvens may participate in nomin confiscation votes, they
may also have the right to issue nomins at the discretion of the
foundation for this version of the contract.
 
After a fee period terminates, the duration and fees collected for that
period are computed, and the next period begins. Thus an account may only
withdraw the fees owed to them for the previous period, and may only do
so once per period. Any unclaimed fees roll over into the common pot for
the next period.
 
== Average Balance Calculations ==
 
The fee entitlement of a havven holder is proportional to their average
issued nomin balance over the last fee period. This is computed by
measuring the area under the graph of a user's issued nomin balance over
time, and then when a new fee period begins, dividing through by the
duration of the fee period.
 
We need only update values when the balances of an account is modified.
This occurs when issuing or burning for issued nomin balances,
and when transferring for havven balances. This is for efficiency,
and adds an implicit friction to interacting with havvens.
A havven holder pays for his own recomputation whenever he wants to change
his position, which saves the foundation having to maintain a pot dedicated
to resourcing this.
 
A hypothetical user's balance history over one fee period, pictorially:
 
      s ____
       |    |
       |    |___ p
       |____|___|___ __ _  _
       f    t   n
 
Here, the balance was s between times f and t, at which time a transfer
occurred, updating the balance to p, until n, when the present transfer occurs.
When a new transfer occurs at time n, the balance being p,
we must:
 
  - Add the area p * (n - t) to the total area recorded so far
  - Update the last transfer time to n
 
So if this graph represents the entire current fee period,
the average havvens held so far is ((t-f)*s + (n-t)*p) / (n-f).
The complementary computations must be performed for both sender and
recipient.
 
Note that a transfer keeps global supply of havvens invariant.
The sum of all balances is constant, and unmodified by any transfer.
So the sum of all balances multiplied by the duration of a fee period is also
constant, and this is equivalent to the sum of the area of every user's
time/balance graph. Dividing through by that duration yields back the total
havven supply. So, at the end of a fee period, we really do yield a user's
average share in the havven supply over that period.
 
A slight wrinkle is introduced if we consider the time r when the fee period
rolls over. Then the previous fee period k-1 is before r, and the current fee
period k is afterwards. If the last transfer took place before r,
but the latest transfer occurred afterwards:
 
k-1       |        k
      s __|_
       |  | |
       |  | |____ p
       |__|_|____|___ __ _  _
          |
       f  | t    n
          r
 
In this situation the area (r-f)*s contributes to fee period k-1, while
the area (t-r)*s contributes to fee period k. We will implicitly consider a
zero-value transfer to have occurred at time r. Their fee entitlement for the
previous period will be finalised at the time of their first transfer during the
current fee period, or when they query or withdraw their fee entitlement.
 
In the implementation, the duration of different fee periods may be slightly irregular,
as the check that they have rolled over occurs only when state-changing havven
operations are performed.
 
== Issuance and Burning ==
 
In this version of the havven contract, nomins can only be issued by
those that have been nominated by the havven foundation. Nomins are assumed
to be valued at $1, as they are a stable unit of account.
 
All nomins issued require a proportional value of havvens to be locked,
where the proportion is governed by the current issuance ratio. This
means for every $1 of Havvens locked up, $(issuanceRatio) nomins can be issued.
i.e. to issue 100 nomins, 100/issuanceRatio dollars of havvens need to be locked up.
 
To determine the value of some amount of havvens(H), an oracle is used to push
the price of havvens (P_H) in dollars to the contract. The value of H
would then be: H * P_H.
 
Any havvens that are locked up by this issuance process cannot be transferred.
The amount that is locked floats based on the price of havvens. If the price
of havvens moves up, less havvens are locked, so they can be issued against,
or transferred freely. If the price of havvens moves down, more havvens are locked,
even going above the initial wallet balance.
 
-----------------------------------------------------------------
*/
 
 
/**
 * @title Havven ERC20 contract.
 * @notice The Havven contracts does not only facilitate transfers and track balances,
 * but it also computes the quantity of fees each havven holder is entitled to.
 */
contract Havven is ExternStateToken {
 
    /* ========== STATE VARIABLES ========== */
 
    /* A struct for handing values associated with average balance calculations */
    struct IssuanceData {
        /* Sums of balances*duration in the current fee period.
        /* range: decimals; units: havven-seconds */
        uint currentBalanceSum;
        /* The last period's average balance */
        uint lastAverageBalance;
        /* The last time the data was calculated */
        uint lastModified;
    }
 
    /* Issued nomin balances for individual fee entitlements */
    mapping(address => IssuanceData) public issuanceData;
    /* The total number of issued nomins for determining fee entitlements */
    IssuanceData public totalIssuanceData;
 
    /* The time the current fee period began */
    uint public feePeriodStartTime;
    /* The time the last fee period began */
    uint public lastFeePeriodStartTime;
 
    /* Fee periods will roll over in no shorter a time than this.
     * The fee period cannot actually roll over until a fee-relevant
     * operation such as withdrawal or a fee period duration update occurs,
     * so this is just a target, and the actual duration may be slightly longer. */
    uint public feePeriodDuration = 4 weeks;
    /* ...and must target between 1 day and six months. */
    uint constant MIN_FEE_PERIOD_DURATION = 1 days;
    uint constant MAX_FEE_PERIOD_DURATION = 26 weeks;
 
    /* The quantity of nomins that were in the fee pot at the time */
    /* of the last fee rollover, at feePeriodStartTime. */
    uint public lastFeesCollected;
 
    /* Whether a user has withdrawn their last fees */
    mapping(address => bool) public hasWithdrawnFees;
 
    Nomin public nomin;
    HavvenEscrow public escrow;
 
    /* The address of the oracle which pushes the havven price to this contract */
    address public oracle;
    /* The price of havvens written in UNIT */
    uint public price;
    /* The time the havven price was last updated */
    uint public lastPriceUpdateTime;
    /* How long will the contract assume the price of havvens is correct */
    uint public priceStalePeriod = 3 hours;
 
    /* A quantity of nomins greater than this ratio
     * may not be issued against a given value of havvens. */
    uint public issuanceRatio = UNIT / 5;
    /* No more nomins may be issued than the value of havvens backing them. */
    uint constant MAX_ISSUANCE_RATIO = UNIT;
 
    /* Whether the address can issue nomins or not. */
    mapping(address => bool) public isIssuer;
    /* The number of currently-outstanding nomins the user has issued. */
    mapping(address => uint) public nominsIssued;
 
    uint constant HAVVEN_SUPPLY = 1e8 * UNIT;
    uint constant ORACLE_FUTURE_LIMIT = 10 minutes;
    string constant TOKEN_NAME = "Havven";
    string constant TOKEN_SYMBOL = "HAV";
     
    /* ========== CONSTRUCTOR ========== */
 
    /**
     * @dev Constructor
     * @param _tokenState A pre-populated contract containing token balances.
     * If the provided address is 0x0, then a fresh one will be constructed with the contract owning all tokens.
     * @param _owner The owner of this contract.
     */
    constructor(address _proxy, TokenState _tokenState, address _owner, address _oracle,
                uint _price, address[] _issuers, Havven _oldHavven)
        ExternStateToken(_proxy, _tokenState, TOKEN_NAME, TOKEN_SYMBOL, HAVVEN_SUPPLY, _owner)
        public
    {
        oracle = _oracle;
        price = _price;
        lastPriceUpdateTime = now;
 
        uint i;
        if (_oldHavven == address(0)) {
            feePeriodStartTime = now;
            lastFeePeriodStartTime = now - feePeriodDuration;
            for (i = 0; i < _issuers.length; i++) {
                isIssuer[_issuers[i]] = true;
            }
        } else {
            feePeriodStartTime = _oldHavven.feePeriodStartTime();
            lastFeePeriodStartTime = _oldHavven.lastFeePeriodStartTime();
 
            uint cbs;
            uint lab;
            uint lm;
            (cbs, lab, lm) = _oldHavven.totalIssuanceData();
            totalIssuanceData.currentBalanceSum = cbs;
            totalIssuanceData.lastAverageBalance = lab;
            totalIssuanceData.lastModified = lm;
 
            for (i = 0; i < _issuers.length; i++) {
                address issuer = _issuers[i];
                isIssuer[issuer] = true;
                uint nomins = _oldHavven.nominsIssued(issuer);
                if (nomins == 0) {
                    // It is not valid in general to skip those with no currently-issued nomins.
                    // But for this release, issuers with nonzero issuanceData have current issuance.
                    continue;
                }
                (cbs, lab, lm) = _oldHavven.issuanceData(issuer);
                nominsIssued[issuer] = nomins;
                issuanceData[issuer].currentBalanceSum = cbs;
                issuanceData[issuer].lastAverageBalance = lab;
                issuanceData[issuer].lastModified = lm;
            }
        }
 
    }
 
    /* ========== SETTERS ========== */
 
    /**
     * @notice Set the associated Nomin contract to collect fees from.
     * @dev Only the contract owner may call this.
     */
    function setNomin(Nomin _nomin)
        external
        optionalProxy_onlyOwner
    {
        nomin = _nomin;
        emitNominUpdated(_nomin);
    }
 
    /**
     * @notice Set the associated havven escrow contract.
     * @dev Only the contract owner may call this.
     */
    function setEscrow(HavvenEscrow _escrow)
        external
        optionalProxy_onlyOwner
    {
        escrow = _escrow;
        emitEscrowUpdated(_escrow);
    }
 
    /**
     * @notice Set the targeted fee period duration.
     * @dev Only callable by the contract owner. The duration must fall within
     * acceptable bounds (1 day to 26 weeks). Upon resetting this the fee period
     * may roll over if the target duration was shortened sufficiently.
     */
    function setFeePeriodDuration(uint duration)
        external
        optionalProxy_onlyOwner
    {
        require(MIN_FEE_PERIOD_DURATION <= duration &&
                               duration <= MAX_FEE_PERIOD_DURATION);
        feePeriodDuration = duration;
        emitFeePeriodDurationUpdated(duration);
        rolloverFeePeriodIfElapsed();
    }
 
    /**
     * @notice Set the Oracle that pushes the havven price to this contract
     */
    function setOracle(address _oracle)
        external
        optionalProxy_onlyOwner
    {
        oracle = _oracle;
        emitOracleUpdated(_oracle);
    }
 
    /**
     * @notice Set the stale period on the updated havven price
     * @dev No max/minimum, as changing it wont influence anything but issuance by the foundation
     */
    function setPriceStalePeriod(uint time)
        external
        optionalProxy_onlyOwner
    {
        priceStalePeriod = time;
    }
 
    /**
     * @notice Set the issuanceRatio for issuance calculations.
     * @dev Only callable by the contract owner.
     */
    function setIssuanceRatio(uint _issuanceRatio)
        external
        optionalProxy_onlyOwner
    {
        require(_issuanceRatio <= MAX_ISSUANCE_RATIO);
        issuanceRatio = _issuanceRatio;
        emitIssuanceRatioUpdated(_issuanceRatio);
    }
 
    /**
     * @notice Set whether the specified can issue nomins or not.
     */
    function setIssuer(address account, bool value)
        external
        optionalProxy_onlyOwner
    {
        isIssuer[account] = value;
        emitIssuersUpdated(account, value);
    }
 
    /* ========== VIEWS ========== */
 
    function issuanceCurrentBalanceSum(address account)
        external
        view
        returns (uint)
    {
        return issuanceData[account].currentBalanceSum;
    }
 
    function issuanceLastAverageBalance(address account)
        external
        view
        returns (uint)
    {
        return issuanceData[account].lastAverageBalance;
    }
 
    function issuanceLastModified(address account)
        external
        view
        returns (uint)
    {
        return issuanceData[account].lastModified;
    }
 
    function totalIssuanceCurrentBalanceSum()
        external
        view
        returns (uint)
    {
        return totalIssuanceData.currentBalanceSum;
    }
 
    function totalIssuanceLastAverageBalance()
        external
        view
        returns (uint)
    {
        return totalIssuanceData.lastAverageBalance;
    }
 
    function totalIssuanceLastModified()
        external
        view
        returns (uint)
    {
        return totalIssuanceData.lastModified;
    }
 
    /* ========== MUTATIVE FUNCTIONS ========== */
 
    /**
     * @notice ERC20 transfer function.
     */
    function transfer(address to, uint value)
        public
        optionalProxy
        returns (bool)
    {
        address sender = messageSender;
        require(nominsIssued[sender] == 0 || value <= transferableHavvens(sender));
        /* Perform the transfer: if there is a problem,
         * an exception will be thrown in this call. */
        _transfer_byProxy(sender, to, value);
 
        return true;
    }
 
    /**
     * @notice ERC20 transferFrom function.
     */
    function transferFrom(address from, address to, uint value)
        public
        optionalProxy
        returns (bool)
    {
        address sender = messageSender;
        require(nominsIssued[from] == 0 || value <= transferableHavvens(from));
        /* Perform the transfer: if there is a problem,
         * an exception will be thrown in this call. */
        _transferFrom_byProxy(sender, from, to, value);
 
        return true;
    }
 
    /**
     * @notice Compute the last period's fee entitlement for the message sender
     * and then deposit it into their nomin account.
     */
    function withdrawFees()
        external
        optionalProxy
    {
        address sender = messageSender;
        rolloverFeePeriodIfElapsed();
        /* Do not deposit fees into frozen accounts. */
        require(!nomin.frozen(sender));
 
        /* Check the period has rolled over first. */
        updateIssuanceData(sender, nominsIssued[sender], nomin.totalSupply());
 
        /* Only allow accounts to withdraw fees once per period. */
        require(!hasWithdrawnFees[sender]);
 
        uint feesOwed;
        uint lastTotalIssued = totalIssuanceData.lastAverageBalance;
 
        if (lastTotalIssued > 0) {
            /* Sender receives a share of last period's collected fees proportional
             * with their average fraction of the last period's issued nomins. */
            feesOwed = safeDiv_dec(
                safeMul_dec(issuanceData[sender].lastAverageBalance, lastFeesCollected),
                lastTotalIssued
            );
        }
 
        hasWithdrawnFees[sender] = true;
 
        if (feesOwed != 0) {
            nomin.withdrawFees(sender, feesOwed);
        }
        emitFeesWithdrawn(messageSender, feesOwed);
    }
 
    /**
     * @notice Update the havven balance averages since the last transfer
     * or entitlement adjustment.
     * @dev Since this updates the last transfer timestamp, if invoked
     * consecutively, this function will do nothing after the first call.
     * Also, this will adjust the total issuance at the same time.
     */
    function updateIssuanceData(address account, uint preBalance, uint lastTotalSupply)
        internal
    {
        /* update the total balances first */
        totalIssuanceData = computeIssuanceData(lastTotalSupply, totalIssuanceData);
 
        if (issuanceData[account].lastModified < feePeriodStartTime) {
            hasWithdrawnFees[account] = false;
        }
 
        issuanceData[account] = computeIssuanceData(preBalance, issuanceData[account]);
    }
 
 
    /**
     * @notice Compute the new IssuanceData on the old balance
     */
    function computeIssuanceData(uint preBalance, IssuanceData preIssuance)
        internal
        view
        returns (IssuanceData)
    {
 
        uint currentBalanceSum = preIssuance.currentBalanceSum;
        uint lastAverageBalance = preIssuance.lastAverageBalance;
        uint lastModified = preIssuance.lastModified;
 
        if (lastModified < feePeriodStartTime) {
            if (lastModified < lastFeePeriodStartTime) {
                /* The balance was last updated before the previous fee period, so the average
                 * balance in this period is their pre-transfer balance. */
                lastAverageBalance = preBalance;
            } else {
                /* The balance was last updated during the previous fee period. */
                /* No overflow or zero denominator problems, since lastFeePeriodStartTime < feePeriodStartTime < lastModified.
                 * implies these quantities are strictly positive. */
                uint timeUpToRollover = feePeriodStartTime - lastModified;
                uint lastFeePeriodDuration = feePeriodStartTime - lastFeePeriodStartTime;
                uint lastBalanceSum = safeAdd(currentBalanceSum, safeMul(preBalance, timeUpToRollover));
                lastAverageBalance = lastBalanceSum / lastFeePeriodDuration;
            }
            /* Roll over to the next fee period. */
            currentBalanceSum = safeMul(preBalance, now - feePeriodStartTime);
        } else {
            /* The balance was last updated during the current fee period. */
            currentBalanceSum = safeAdd(
                currentBalanceSum,
                safeMul(preBalance, now - lastModified)
            );
        }
 
        return IssuanceData(currentBalanceSum, lastAverageBalance, now);
    }
 
    /**
     * @notice Recompute and return the given account's last average balance.
     */
    function recomputeLastAverageBalance(address account)
        external
        returns (uint)
    {
        updateIssuanceData(account, nominsIssued[account], nomin.totalSupply());
        return issuanceData[account].lastAverageBalance;
    }
 
    /**
     * @notice Issue nomins against the sender's havvens.
     * @dev Issuance is only allowed if the havven price isn't stale and the sender is an issuer.
     */
    function issueNomins(uint amount)
        public
        optionalProxy
        requireIssuer(messageSender)
        /* No need to check if price is stale, as it is checked in issuableNomins. */
    {
        address sender = messageSender;
        require(amount <= remainingIssuableNomins(sender));
        uint lastTot = nomin.totalSupply();
        uint preIssued = nominsIssued[sender];
        nomin.issue(sender, amount);
        nominsIssued[sender] = safeAdd(preIssued, amount);
        updateIssuanceData(sender, preIssued, lastTot);
    }
 
    function issueMaxNomins()
        external
        optionalProxy
    {
        issueNomins(remainingIssuableNomins(messageSender));
    }
 
    /**
     * @notice Burn nomins to clear issued nomins/free havvens.
     */
    function burnNomins(uint amount)
        /* it doesn't matter if the price is stale or if the user is an issuer, as non-issuers have issued no nomins.*/
        external
        optionalProxy
    {
        address sender = messageSender;
 
        uint lastTot = nomin.totalSupply();
        uint preIssued = nominsIssued[sender];
        /* nomin.burn does a safeSub on balance (so it will revert if there are not enough nomins). */
        nomin.burn(sender, amount);
        /* This safe sub ensures amount <= number issued */
        nominsIssued[sender] = safeSub(preIssued, amount);
        updateIssuanceData(sender, preIssued, lastTot);
    }
 
    /**
     * @notice Check if the fee period has rolled over. If it has, set the new fee period start
     * time, and record the fees collected in the nomin contract.
     */
    function rolloverFeePeriodIfElapsed()
        public
    {
        /* If the fee period has rolled over... */
        if (now >= feePeriodStartTime + feePeriodDuration) {
            lastFeesCollected = nomin.feePool();
            lastFeePeriodStartTime = feePeriodStartTime;
            feePeriodStartTime = now;
            emitFeePeriodRollover(now);
        }
    }
 
    /* ========== Issuance/Burning ========== */
 
    /**
     * @notice The maximum nomins an issuer can issue against their total havven quantity. This ignores any
     * already issued nomins.
     */
    function maxIssuableNomins(address issuer)
        view
        public
        priceNotStale
        returns (uint)
    {
        if (!isIssuer[issuer]) {
            return 0;
        }
        if (escrow != HavvenEscrow(0)) {
            uint totalOwnedHavvens = safeAdd(tokenState.balanceOf(issuer), escrow.balanceOf(issuer));
            return safeMul_dec(HAVtoUSD(totalOwnedHavvens), issuanceRatio);
        } else {
            return safeMul_dec(HAVtoUSD(tokenState.balanceOf(issuer)), issuanceRatio);
        }
    }
 
    /**
     * @notice The remaining nomins an issuer can issue against their total havven quantity.
     */
    function remainingIssuableNomins(address issuer)
        view
        public
        returns (uint)
    {
        uint issued = nominsIssued[issuer];
        uint max = maxIssuableNomins(issuer);
        if (issued > max) {
            return 0;
        } else {
            return safeSub(max, issued);
        }
    }
 
    /**
     * @notice The total havvens owned by this account, both escrowed and unescrowed,
     * against which nomins can be issued.
     * This includes those already being used as collateral (locked), and those
     * available for further issuance (unlocked).
     */
    function collateral(address account)
        public
        view
        returns (uint)
    {
        uint bal = tokenState.balanceOf(account);
        if (escrow != address(0)) {
            bal = safeAdd(bal, escrow.balanceOf(account));
        }
        return bal;
    }
 
    /**
     * @notice The collateral that would be locked by issuance, which can exceed the account's actual collateral.
     */
    function issuanceDraft(address account)
        public
        view
        returns (uint)
    {
        uint issued = nominsIssued[account];
        if (issued == 0) {
            return 0;
        }
        return USDtoHAV(safeDiv_dec(issued, issuanceRatio));
    }
 
    /**
     * @notice Collateral that has been locked due to issuance, and cannot be
     * transferred to other addresses. This is capped at the account's total collateral.
     */
    function lockedCollateral(address account)
        public
        view
        returns (uint)
    {
        uint debt = issuanceDraft(account);
        uint collat = collateral(account);
        if (debt > collat) {
            return collat;
        }
        return debt;
    }
 
    /**
     * @notice Collateral that is not locked and available for issuance.
     */
    function unlockedCollateral(address account)
        public
        view
        returns (uint)
    {
        uint locked = lockedCollateral(account);
        uint collat = collateral(account);
        return safeSub(collat, locked);
    }
 
    /**
     * @notice The number of havvens that are free to be transferred by an account.
     * @dev If they have enough available Havvens, it could be that
     * their havvens are escrowed, however the transfer would then
     * fail. This means that escrowed havvens are locked first,
     * and then the actual transferable ones.
     */
    function transferableHavvens(address account)
        public
        view
        returns (uint)
    {
        uint draft = issuanceDraft(account);
        uint collat = collateral(account);
        // In the case where the issuanceDraft exceeds the collateral, nothing is free
        if (draft > collat) {
            return 0;
        }
 
        uint bal = balanceOf(account);
        // In the case where the draft exceeds the escrow, but not the whole collateral
        //   return the fraction of the balance that remains free
        if (draft > safeSub(collat, bal)) {
            return safeSub(collat, draft);
        }
        // In the case where the draft doesn't exceed the escrow, return the entire balance
        return bal;
    }
 
    /**
     * @notice The value in USD for a given amount of HAV
     */
    function HAVtoUSD(uint hav_dec)
        public
        view
        priceNotStale
        returns (uint)
    {
        return safeMul_dec(hav_dec, price);
    }
 
    /**
     * @notice The value in HAV for a given amount of USD
     */
    function USDtoHAV(uint usd_dec)
        public
        view
        priceNotStale
        returns (uint)
    {
        return safeDiv_dec(usd_dec, price);
    }
 
    /**
     * @notice Access point for the oracle to update the price of havvens.
     */
    function updatePrice(uint newPrice, uint timeSent)
        external
        onlyOracle  /* Should be callable only by the oracle. */
    {
        /* Must be the most recently sent price, but not too far in the future.
         * (so we can't lock ourselves out of updating the oracle for longer than this) */
        require(lastPriceUpdateTime < timeSent && timeSent < now + ORACLE_FUTURE_LIMIT);
 
        price = newPrice;
        lastPriceUpdateTime = timeSent;
        emitPriceUpdated(newPrice, timeSent);
 
        /* Check the fee period rollover within this as the price should be pushed every 15min. */
        rolloverFeePeriodIfElapsed();
    }
 
    /**
     * @notice Check if the price of havvens hasn't been updated for longer than the stale period.
     */
    function priceIsStale()
        public
        view
        returns (bool)
    {
        return safeAdd(lastPriceUpdateTime, priceStalePeriod) < now;
    }
 
    /* ========== MODIFIERS ========== */
 
    modifier requireIssuer(address account)
    {
        require(isIssuer[account]);
        _;
    }
 
    modifier onlyOracle
    {
        require(msg.sender == oracle);
        _;
    }
 
    modifier priceNotStale
    {
        require(!priceIsStale());
        _;
    }
 
    /* ========== EVENTS ========== */
 
    event PriceUpdated(uint newPrice, uint timestamp);
    bytes32 constant PRICEUPDATED_SIG = keccak256("PriceUpdated(uint256,uint256)");
    function emitPriceUpdated(uint newPrice, uint timestamp) internal {
        proxy._emit(abi.encode(newPrice, timestamp), 1, PRICEUPDATED_SIG, 0, 0, 0);
    }
 
    event IssuanceRatioUpdated(uint newRatio);
    bytes32 constant ISSUANCERATIOUPDATED_SIG = keccak256("IssuanceRatioUpdated(uint256)");
    function emitIssuanceRatioUpdated(uint newRatio) internal {
        proxy._emit(abi.encode(newRatio), 1, ISSUANCERATIOUPDATED_SIG, 0, 0, 0);
    }
 
    event FeePeriodRollover(uint timestamp);
    bytes32 constant FEEPERIODROLLOVER_SIG = keccak256("FeePeriodRollover(uint256)");
    function emitFeePeriodRollover(uint timestamp) internal {
        proxy._emit(abi.encode(timestamp), 1, FEEPERIODROLLOVER_SIG, 0, 0, 0);
    }
 
    event FeePeriodDurationUpdated(uint duration);
    bytes32 constant FEEPERIODDURATIONUPDATED_SIG = keccak256("FeePeriodDurationUpdated(uint256)");
    function emitFeePeriodDurationUpdated(uint duration) internal {
        proxy._emit(abi.encode(duration), 1, FEEPERIODDURATIONUPDATED_SIG, 0, 0, 0);
    }
 
    event FeesWithdrawn(address indexed account, uint value);
    bytes32 constant FEESWITHDRAWN_SIG = keccak256("FeesWithdrawn(address,uint256)");
    function emitFeesWithdrawn(address account, uint value) internal {
        proxy._emit(abi.encode(value), 2, FEESWITHDRAWN_SIG, bytes32(account), 0, 0);
    }
 
    event OracleUpdated(address newOracle);
    bytes32 constant ORACLEUPDATED_SIG = keccak256("OracleUpdated(address)");
    function emitOracleUpdated(address newOracle) internal {
        proxy._emit(abi.encode(newOracle), 1, ORACLEUPDATED_SIG, 0, 0, 0);
    }
 
    event NominUpdated(address newNomin);
    bytes32 constant NOMINUPDATED_SIG = keccak256("NominUpdated(address)");
    function emitNominUpdated(address newNomin) internal {
        proxy._emit(abi.encode(newNomin), 1, NOMINUPDATED_SIG, 0, 0, 0);
    }
 
    event EscrowUpdated(address newEscrow);
    bytes32 constant ESCROWUPDATED_SIG = keccak256("EscrowUpdated(address)");
    function emitEscrowUpdated(address newEscrow) internal {
        proxy._emit(abi.encode(newEscrow), 1, ESCROWUPDATED_SIG, 0, 0, 0);
    }
 
    event IssuersUpdated(address indexed account, bool indexed value);
    bytes32 constant ISSUERSUPDATED_SIG = keccak256("IssuersUpdated(address,bool)");
    function emitIssuersUpdated(address account, bool value) internal {
        proxy._emit(abi.encode(), 3, ISSUERSUPDATED_SIG, bytes32(account), bytes32(value ? 1 : 0), 0);
    }
 
}

    Contract ABI  
[{"constant":false,"inputs":[{"name":"duration","type":"uint256"}],"name":"setFeePeriodDuration","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_issuanceRatio","type":"uint256"}],"name":"setIssuanceRatio","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalIssuanceData","outputs":[{"name":"currentBalanceSum","type":"uint256"},{"name":"lastAverageBalance","type":"uint256"},{"name":"lastModified","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"unlockedCollateral","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initiationTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"issueNomins","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_beneficiary","type":"address"}],"name":"setSelfDestructBeneficiary","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"priceStalePeriod","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"feePeriodDuration","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"hasWithdrawnFees","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"issuanceDraft","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"time","type":"uint256"}],"name":"setPriceStalePeriod","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"burnNomins","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"terminateSelfDestruct","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawFees","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"},{"name":"value","type":"bool"}],"name":"setIssuer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lastPriceUpdateTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nominatedOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nomin","type":"address"}],"name":"setNomin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"recomputeLastAverageBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"nominsIssued","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"issuanceLastAverageBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"feePeriodStartTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_oracle","type":"address"}],"name":"setOracle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"oracle","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"issuer","type":"address"}],"name":"maxIssuableNomins","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newPrice","type":"uint256"},{"name":"timeSent","type":"uint256"}],"name":"updatePrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"isIssuer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"issuanceData","outputs":[{"name":"currentBalanceSum","type":"uint256"},{"name":"lastAverageBalance","type":"uint256"},{"name":"lastModified","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"lockedCollateral","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"rolloverFeePeriodIfElapsed","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalIssuanceLastModified","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_proxy","type":"address"}],"name":"setProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"selfDestruct","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"UNIT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenState","type":"address"}],"name":"setTokenState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"price","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"usd_dec","type":"uint256"}],"name":"USDtoHAV","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SELFDESTRUCT_DELAY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"collateral","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"issuanceRatio","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"selfDestructInitiated","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"setMessageSender","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"initiateSelfDestruct","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lastFeesCollected","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_escrow","type":"address"}],"name":"setEscrow","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalIssuanceLastAverageBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"issuanceCurrentBalanceSum","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"selfDestructBeneficiary","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"issuer","type":"address"}],"name":"remainingIssuableNomins","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastFeePeriodStartTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalIssuanceCurrentBalanceSum","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"issueMaxNomins","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"hav_dec","type":"uint256"}],"name":"HAVtoUSD","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"transferableHavvens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"escrow","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nomin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenState","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"proxy","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"issuanceLastModified","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"priceIsStale","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_proxy","type":"address"},{"name":"_tokenState","type":"address"},{"name":"_owner","type":"address"},{"name":"_oracle","type":"address"},{"name":"_price","type":"uint256"},{"name":"_issuers","type":"address[]"},{"name":"_oldHavven","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newPrice","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"PriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newRatio","type":"uint256"}],"name":"IssuanceRatioUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"FeePeriodRollover","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"duration","type":"uint256"}],"name":"FeePeriodDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"FeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOracle","type":"address"}],"name":"OracleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newNomin","type":"address"}],"name":"NominUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newEscrow","type":"address"}],"name":"EscrowUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":true,"name":"value","type":"bool"}],"name":"IssuersUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newTokenState","type":"address"}],"name":"TokenStateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proxyAddress","type":"address"}],"name":"ProxyUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"SelfDestructTerminated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"beneficiary","type":"address"}],"name":"SelfDestructed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"selfDestructDelay","type":"uint256"}],"name":"SelfDestructInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newBeneficiary","type":"address"}],"name":"SelfDestructBeneficiaryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldOwner","type":"address"},{"indexed":false,"name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"}]

  Contract Creation Code Switch To Opcodes View
60806040526224ea00601055612a306018556702c68af0bb1400006019553480156200002a57600080fd5b5060405162003e4938038062003e498339810160408181528251602080850151838601516060870151608088015160a089015160c08a0151888a01895260068a527f48617676656e0000000000000000000000000000000000000000000000000000878b01528851808a01909952600389527f4841560000000000000000000000000000000000000000000000000000000000968901969096529598939792969195909493019291600091829182918291829182918e918e91906a52b7d2dcc80cd2e40000008f85818080600160a060020a03811615156200010b57600080fd5b60008054600160a060020a031916600160a060020a038316908117825560408051928352602083019190915280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a150600160a060020a03811615156200017a57600080fd5b60038054600160a060020a038316610100810261010060a860020a03199092169190911790915560408051918252517fd5da63a0b864b315bc04128dedbc93888c8529ee6cf47ce664dc204339228c539181900360200190a15060048054600160a060020a038416600160a060020a0319909116811790915560408051918252517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e9181900360200190a1505083516200023c906007906020870190620006c4565b50825162000252906008906020860190620006c4565b5050600955505060068054600160a060020a0319908116600160a060020a0393841617909155601580549091168d831617905560168b905542601755881615159050620003105742600e8190556010549003600f55600095505b87518610156200030a576001601a60008a89815181101515620002cb57fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff191691151591909117905560019590950194620002ac565b620006b1565b86600160a060020a03166378dc70c06040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156200036857600080fd5b505af11580156200037d573d6000803e3d6000fd5b505050506040513d60208110156200039457600080fd5b5051600e55604080517fc9fd83e20000000000000000000000000000000000000000000000000000000081529051600160a060020a0389169163c9fd83e29160048083019260209291908290030181600087803b158015620003f557600080fd5b505af11580156200040a573d6000803e3d6000fd5b505050506040513d60208110156200042157600080fd5b5051600f55604080517f09c1a4b90000000000000000000000000000000000000000000000000000000081529051600160a060020a038916916309c1a4b99160048083019260609291908290030181600087803b1580156200048257600080fd5b505af115801562000497573d6000803e3d6000fd5b505050506040513d6060811015620004ae57600080fd5b5080516020820151604090920151600b829055600c839055600d8190556000985090965090945092505b8751861015620006b1578786815181101515620004f157fe5b6020908102909101810151600160a060020a038082166000818152601a85526040808220805460ff1916600117905580517f6fb8f350000000000000000000000000000000000000000000000000000000008152600481019390935251939650918b1693636fb8f3509360248084019492939192918390030190829087803b1580156200057d57600080fd5b505af115801562000592573d6000803e3d6000fd5b505050506040513d6020811015620005a957600080fd5b50519050801515620005bb57620006a5565b86600160a060020a0316638b3f8088836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082600160a060020a0316600160a060020a03168152602001915050606060405180830381600087803b1580156200063057600080fd5b505af115801562000645573d6000803e3d6000fd5b505050506040513d60608110156200065c57600080fd5b508051602080830151604093840151600160a060020a0387166000908152601b8452858120879055600a9093529390912082815560018101829055600201839055909650945092505b600190950194620004d8565b5050505050505050505050505062000769565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200070757805160ff191683800117855562000737565b8280016001018555821562000737579182015b82811115620007375782518255916020019190600101906200071a565b506200074592915062000749565b5090565b6200076691905b8082111562000745576000815560010162000750565b90565b6136d080620007796000396000f30060806040526004361061033f5763ffffffff60e060020a60003504166304c49f2c8114610344578063054be0b71461035e57806306fdde0314610376578063095ea7b31461040057806309c1a4b9146104385780630b566f331461046b5780631627540c1461049e57806317c70de4146104bf57806318160ddd146104d4578063187cba25146104e957806320714f881461050157806321cf35141461052257806322425fa41461053757806323a4f9461461054c57806323b872dd1461056d57806325192fca1461059757806329f3533c146105b8578063313ce567146105d05780633253ccdf146105fb5780633278c96014610613578063476343ee14610628578063495289be1461063d57806349b9a7af1461066357806353a47bb7146106785780635c8ea7fe146106a957806365688182146106ca5780636fb8f350146106eb5780636fcb01531461070c57806370a082311461072d57806378dc70c01461074e57806379ba5097146107635780637adbf973146107785780637dc0d1d01461079957806380e37b5f146107ae57806382367b2d146107cf578063877b9a67146107ea5780638b3f80881461080b5780638da5cb5b1461082c57806392bdf9ba1461084157806395701be314610862578063959e47481461087757806395d89b411461088c57806397107d6d146108a15780639cb8a26a146108c25780639d8e2177146108d75780639f769807146108ec578063a035b1fe1461090d578063a0edc67114610922578063a461fc821461093a578063a5fdc5de1461094f578063a9059cbb14610970578063b410a03414610994578063b8225dec146109a9578063bc67f832146109be578063bd32aa44146109df578063beccdb77146109f4578063c10c354614610a09578063c2d15d2114610a2a578063c43821aa14610a3f578063c58aaae614610a60578063c939fd5014610a75578063c9fd83e214610a96578063ca77ba3114610aab578063da5341a814610ac0578063db8cfa5a14610ad5578063dd62ed3e14610aed578063dffcf9a714610b14578063e2fdcc1714610b35578063e59160e314610b4a578063e90dd9e214610b5f578063ec55688914610b74578063fe22fcd814610b89578063ffb1a06d14610baa575b600080fd5b34801561035057600080fd5b5061035c600435610bbf565b005b34801561036a57600080fd5b5061035c600435610c3b565b34801561038257600080fd5b5061038b610ca0565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c55781810151838201526020016103ad565b50505050905090810190601f1680156103f25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561040c57600080fd5b50610424600160a060020a0360043516602435610d2e565b604080519115158252519081900360200190f35b34801561044457600080fd5b5061044d610e04565b60408051938452602084019290925282820152519081900360600190f35b34801561047757600080fd5b5061048c600160a060020a0360043516610e10565b60408051918252519081900360200190f35b3480156104aa57600080fd5b5061035c600160a060020a0360043516610e3f565b3480156104cb57600080fd5b5061048c610eaa565b3480156104e057600080fd5b5061048c610eb0565b3480156104f557600080fd5b5061035c600435610eb6565b34801561050d57600080fd5b5061035c600160a060020a036004351661107b565b34801561052e57600080fd5b5061048c611110565b34801561054357600080fd5b5061048c611116565b34801561055857600080fd5b50610424600160a060020a036004351661111c565b34801561057957600080fd5b50610424600160a060020a0360043581169060243516604435611131565b3480156105a357600080fd5b5061048c600160a060020a03600435166111b3565b3480156105c457600080fd5b5061035c6004356111f9565b3480156105dc57600080fd5b506105e5611240565b6040805160ff9092168252519081900360200190f35b34801561060757600080fd5b5061035c600435611245565b34801561061f57600080fd5b5061035c6113d2565b34801561063457600080fd5b5061035c611423565b34801561064957600080fd5b5061035c600160a060020a036004351660243515156116f2565b34801561066f57600080fd5b5061048c611766565b34801561068457600080fd5b5061068d61176c565b60408051600160a060020a039092168252519081900360200190f35b3480156106b557600080fd5b5061035c600160a060020a036004351661177b565b3480156106d657600080fd5b5061048c600160a060020a03600435166117e1565b3480156106f757600080fd5b5061048c600160a060020a0360043516611878565b34801561071857600080fd5b5061048c600160a060020a036004351661188a565b34801561073957600080fd5b5061048c600160a060020a03600435166118a8565b34801561075a57600080fd5b5061048c61192f565b34801561076f57600080fd5b5061035c611935565b34801561078457600080fd5b5061035c600160a060020a03600435166119bf565b3480156107a557600080fd5b5061068d611a25565b3480156107ba57600080fd5b5061048c600160a060020a0360043516611a34565b3480156107db57600080fd5b5061035c600435602435611c30565b3480156107f657600080fd5b50610424600160a060020a0360043516611c82565b34801561081757600080fd5b5061044d600160a060020a0360043516611c97565b34801561083857600080fd5b5061068d611cb8565b34801561084d57600080fd5b5061048c600160a060020a0360043516611cc7565b34801561086e57600080fd5b5061035c611cf2565b34801561088357600080fd5b5061048c611d98565b34801561089857600080fd5b5061038b611d9e565b3480156108ad57600080fd5b5061035c600160a060020a0360043516611df9565b3480156108ce57600080fd5b5061035c611e64565b3480156108e357600080fd5b5061048c611ef7565b3480156108f857600080fd5b5061035c600160a060020a0360043516611f03565b34801561091957600080fd5b5061048c611f69565b34801561092e57600080fd5b5061048c600435611f6f565b34801561094657600080fd5b5061048c611f95565b34801561095b57600080fd5b5061048c600160a060020a0360043516611f9c565b34801561097c57600080fd5b50610424600160a060020a036004351660243561208b565b3480156109a057600080fd5b5061048c612106565b3480156109b557600080fd5b5061042461210c565b3480156109ca57600080fd5b5061035c600160a060020a0360043516612115565b3480156109eb57600080fd5b5061035c61214e565b348015610a0057600080fd5b5061048c6121ae565b348015610a1557600080fd5b5061035c600160a060020a03600435166121b4565b348015610a3657600080fd5b5061048c61221a565b348015610a4b57600080fd5b5061048c600160a060020a0360043516612220565b348015610a6c57600080fd5b5061068d61223b565b348015610a8157600080fd5b5061048c600160a060020a036004351661224f565b348015610aa257600080fd5b5061048c612296565b348015610ab757600080fd5b5061048c61229c565b348015610acc57600080fd5b5061035c6122a2565b348015610ae157600080fd5b5061048c6004356122e5565b348015610af957600080fd5b5061048c600160a060020a0360043581169060243516612305565b348015610b2057600080fd5b5061048c600160a060020a03600435166123ab565b348015610b4157600080fd5b5061068d612411565b348015610b5657600080fd5b5061068d612420565b348015610b6b57600080fd5b5061068d61242f565b348015610b8057600080fd5b5061068d61243e565b348015610b9557600080fd5b5061048c600160a060020a036004351661244d565b348015610bb657600080fd5b5061042461246b565b600454600160a060020a03163314610be45760058054600160a060020a031916331790555b600054600554600160a060020a03908116911614610c0157600080fd5b806201518011158015610c17575062eff1008111155b1515610c2257600080fd5b6010819055610c3081612482565b610c38611cf2565b50565b600454600160a060020a03163314610c605760058054600160a060020a031916331790555b600054600554600160a060020a03908116911614610c7d57600080fd5b670de0b6b3a7640000811115610c9257600080fd5b6019819055610c38816125e2565b6007805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610d265780601f10610cfb57610100808354040283529160200191610d26565b820191906000526020600020905b815481529060010190602001808311610d0957829003601f168201915b505050505081565b6004546000908190600160a060020a03163314610d585760058054600160a060020a031916331790555b50600554600654604080517fda46098c000000000000000000000000000000000000000000000000000000008152600160a060020a0393841660048201819052878516602483015260448201879052915191939092169163da46098c91606480830192600092919082900301818387803b158015610dd557600080fd5b505af1158015610de9573d6000803e3d6000fd5b50505050610df88185856126b6565b600191505b5092915050565b600b54600c54600d5483565b6000806000610e1e84611cc7565b9150610e2984611f9c565b9050610e358183612827565b92505b5050919050565b600054600160a060020a03163314610e5657600080fd5b60018054600160a060020a038316600160a060020a0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b60025481565b60095481565b60045460009081908190600160a060020a03163314610ee25760058054600160a060020a031916331790555b600554600160a060020a03166000818152601a602052604090205460ff161515610f0b57600080fd5b600554600160a060020a03169350610f228461224f565b851115610f2e57600080fd5b601360009054906101000a9004600160a060020a0316600160a060020a03166318160ddd6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f8157600080fd5b505af1158015610f95573d6000803e3d6000fd5b505050506040513d6020811015610fab57600080fd5b5051600160a060020a038086166000818152601b60205260408082205460135482517f867904b40000000000000000000000000000000000000000000000000000000081526004810195909552602485018c9052915195985096509092169263867904b49260448084019391929182900301818387803b15801561102e57600080fd5b505af1158015611042573d6000803e3d6000fd5b50505050611050828661283c565b600160a060020a0385166000908152601b6020526040902055611074848385612852565b5050505050565b600054600160a060020a0316331461109257600080fd5b600160a060020a03811615156110a757600080fd5b60038054600160a060020a038316610100810274ffffffffffffffffffffffffffffffffffffffff00199092169190911790915560408051918252517fd5da63a0b864b315bc04128dedbc93888c8529ee6cf47ce664dc204339228c539181900360200190a150565b60185481565b60105481565b60126020526000908152604090205460ff1681565b6004546000908190600160a060020a0316331461115b5760058054600160a060020a031916331790555b50600554600160a060020a038581166000908152601b60205260409020549116901580611190575061118c856123ab565b8311155b151561119b57600080fd5b6111a78186868661295e565b50600195945050505050565b600160a060020a0381166000908152601b60205260408120548015156111dc57600091506111f3565b6111f06111eb82601954612a91565b611f6f565b91505b50919050565b600454600160a060020a0316331461121e5760058054600160a060020a031916331790555b600054600554600160a060020a0390811691161461123b57600080fd5b601855565b601281565b60045460009081908190600160a060020a031633146112715760058054600160a060020a031916331790555b600554601354604080517f18160ddd0000000000000000000000000000000000000000000000000000000081529051600160a060020a03938416965091909216916318160ddd9160048083019260209291908290030181600087803b1580156112d957600080fd5b505af11580156112ed573d6000803e3d6000fd5b505050506040513d602081101561130357600080fd5b5051600160a060020a038085166000818152601b60205260408082205460135482517f9dc29fac0000000000000000000000000000000000000000000000000000000081526004810195909552602485018b90529151959750955090921692639dc29fac9260448084019391929182900301818387803b15801561138657600080fd5b505af115801561139a573d6000803e3d6000fd5b505050506113a88185612827565b600160a060020a0384166000908152601b60205260409020556113cc838284612852565b50505050565b600054600160a060020a031633146113e957600080fd5b600060028190556003805460ff191690556040517f6adcc7125002935e0aa31697538ebbd65cfddf20431eb6ecdcfc3e238bfd082c9190a1565b60045460009081908190600160a060020a0316331461144f5760058054600160a060020a031916331790555b600554600160a060020a03169250611465611cf2565b601354604080517fd0516650000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301529151919092169163d05166509160248083019260209291908290030181600087803b1580156114cd57600080fd5b505af11580156114e1573d6000803e3d6000fd5b505050506040513d60208110156114f757600080fd5b50511561150357600080fd5b600160a060020a038084166000908152601b602090815260408083205460135482517f18160ddd00000000000000000000000000000000000000000000000000000000815292516115aa968a9693959216936318160ddd9360048083019493928390030190829087803b15801561157957600080fd5b505af115801561158d573d6000803e3d6000fd5b505050506040513d60208110156115a357600080fd5b5051612852565b600160a060020a03831660009081526012602052604090205460ff16156115d057600080fd5b50600c54600081111561161257600160a060020a0383166000908152600a602052604090206001015460115461160f9161160991612aae565b82612a91565b91505b600160a060020a0383166000908152601260205260409020805460ff1916600117905581156116d757601354604080517fad3b1b47000000000000000000000000000000000000000000000000000000008152600160a060020a038681166004830152602482018690529151919092169163ad3b1b479160448083019260209291908290030181600087803b1580156116aa57600080fd5b505af11580156116be573d6000803e3d6000fd5b505050506040513d60208110156116d457600080fd5b50505b6005546116ed90600160a060020a031683612ad4565b505050565b600454600160a060020a031633146117175760058054600160a060020a031916331790555b600054600554600160a060020a0390811691161461173457600080fd5b600160a060020a0382166000908152601a60205260409020805460ff19168215151790556117628282612c1c565b5050565b60175481565b600154600160a060020a031681565b600454600160a060020a031633146117a05760058054600160a060020a031916331790555b600054600554600160a060020a039081169116146117bd57600080fd5b60138054600160a060020a031916600160a060020a038316179055610c3881612d00565b600160a060020a038082166000908152601b602090815260408083205460135482517f18160ddd00000000000000000000000000000000000000000000000000000000815292519495611859958895939492909116926318160ddd926004808201939182900301818a87803b15801561157957600080fd5b50600160a060020a03166000908152600a602052604090206001015490565b601b6020526000908152604090205481565b600160a060020a03166000908152600a602052604090206001015490565b6006546040805160e060020a6370a08231028152600160a060020a038481166004830152915160009392909216916370a082319160248082019260209290919082900301818787803b1580156118fd57600080fd5b505af1158015611911573d6000803e3d6000fd5b505050506040513d602081101561192757600080fd5b505192915050565b600e5481565b600154600160a060020a0316331461194c57600080fd5b60005460015460408051600160a060020a03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a16001805460008054600160a060020a0319908116600160a060020a03841617909155169055565b600454600160a060020a031633146119e45760058054600160a060020a031916331790555b600054600554600160a060020a03908116911614611a0157600080fd5b60158054600160a060020a031916600160a060020a038316179055610c3881612dda565b601554600160a060020a031681565b600080611a3f61246b565b15611a4957600080fd5b600160a060020a0383166000908152601a602052604090205460ff161515611a7457600091506111f3565b601454600160a060020a031615611ba8576006546040805160e060020a6370a08231028152600160a060020a0386811660048301529151611b8b9392909216916370a08231916024808201926020929091908290030181600087803b158015611adc57600080fd5b505af1158015611af0573d6000803e3d6000fd5b505050506040513d6020811015611b0657600080fd5b50516014546040805160e060020a6370a08231028152600160a060020a038881166004830152915191909216916370a082319160248083019260209291908290030181600087803b158015611b5a57600080fd5b505af1158015611b6e573d6000803e3d6000fd5b505050506040513d6020811015611b8457600080fd5b505161283c565b9050611ba1611b99826122e5565b601954612aae565b91506111f3565b6006546040805160e060020a6370a08231028152600160a060020a0386811660048301529151611ba193611b999316916370a082319160248083019260209291908290030181600087803b158015611bff57600080fd5b505af1158015611c13573d6000803e3d6000fd5b505050506040513d6020811015611c2957600080fd5b50516122e5565b601554600160a060020a03163314611c4757600080fd5b80601754108015611c5b5750610258420181105b1515611c6657600080fd5b60168290556017819055611c7a8282612eb4565b611762611cf2565b601a6020526000908152604090205460ff1681565b600a6020526000908152604090208054600182015460029092015490919083565b600054600160a060020a031681565b6000806000611cd5846111b3565b9150611ce084611f9c565b905080821115610dfd57809250610e38565b601054600e54014210611d9657601360009054906101000a9004600160a060020a0316600160a060020a031663ae2e933b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611d5257600080fd5b505af1158015611d66573d6000803e3d6000fd5b505050506040513d6020811015611d7c57600080fd5b5051601155600e8054600f554290819055611d9690612f8f565b565b600d5490565b6008805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610d265780601f10610cfb57610100808354040283529160200191610d26565b600054600160a060020a03163314611e1057600080fd5b60048054600160a060020a038316600160a060020a0319909116811790915560408051918252517ffc80377ca9c49cc11ae6982f390a42db976d5530af7c43889264b13fbbd7c57e9181900360200190a150565b60008054600160a060020a03163314611e7c57600080fd5b60035460ff168015611e945750426224ea0060025401105b1515611e9f57600080fd5b5060035460408051600160a060020a0361010090930492909216808352905190917f8a09e1677ced846cb537dc2b172043bd05a1a81ad7e0033a7ef8ba762df990b7919081900360200190a180600160a060020a0316ff5b670de0b6b3a764000081565b600454600160a060020a03163314611f285760058054600160a060020a031916331790555b600054600554600160a060020a03908116911614611f4557600080fd5b60068054600160a060020a031916600160a060020a038316179055610c3881613063565b60165481565b6000611f7961246b565b15611f8357600080fd5b611f8f82601654612a91565b92915050565b6224ea0081565b6006546040805160e060020a6370a08231028152600160a060020a0384811660048301529151600093849316916370a0823191602480830192602092919082900301818787803b158015611fef57600080fd5b505af1158015612003573d6000803e3d6000fd5b505050506040513d602081101561201957600080fd5b5051601454909150600160a060020a031615611f8f576014546040805160e060020a6370a08231028152600160a060020a038681166004830152915161208493859316916370a082319160248083019260209291908290030181600087803b158015611b5a57600080fd5b9392505050565b6004546000908190600160a060020a031633146120b55760058054600160a060020a031916331790555b50600554600160a060020a03166000818152601b602052604090205415806120e557506120e1816123ab565b8311155b15156120f057600080fd5b6120fb81858561313d565b506001949350505050565b60195481565b60035460ff1681565b600454600160a060020a0316331461212c57600080fd5b60058054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a0316331461216557600080fd5b426002556003805460ff19166001179055604080516224ea00815290517fcbd94ca75b8dc45c9d80c77e851670e78843c0d75180cb81db3e2158228fa9a69181900360200190a1565b60115481565b600454600160a060020a031633146121d95760058054600160a060020a031916331790555b600054600554600160a060020a039081169116146121f657600080fd5b60148054600160a060020a031916600160a060020a038316179055610c3881613152565b600c5490565b600160a060020a03166000908152600a602052604090205490565b6003546101009004600160a060020a031681565b600160a060020a0381166000908152601b60205260408120548161227284611a34565b9050808211156122855760009250610e38565b61228f8183612827565b9250610e38565b600f5481565b600b5490565b600454600160a060020a031633146122c75760058054600160a060020a031916331790555b600554611d96906122e090600160a060020a031661224f565b610eb6565b60006122ef61246b565b156122f957600080fd5b611f8f82601654612aae565b600654604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151600093929092169163dd62ed3e9160448082019260209290919082900301818787803b15801561237857600080fd5b505af115801561238c573d6000803e3d6000fd5b505050506040513d60208110156123a257600080fd5b50519392505050565b6000806000806123ba856111b3565b92506123c585611f9c565b9150818311156123d85760009350612409565b6123e1856118a8565b90506123ed8282612827565b831115612405576123fe8284612827565b9350612409565b8093505b505050919050565b601454600160a060020a031681565b601354600160a060020a031681565b600654600160a060020a031681565b600454600160a060020a031681565b600160a060020a03166000908152600a602052604090206002015490565b60004261247c60175460185461283c565b10905090565b600480546040805160208082018690528251808303820181528284018085527f466565506572696f644475726174696f6e557064617465642875696e7432353690527f29000000000000000000000000000000000000000000000000000000000000006060840152925191829003606101822060e060020a63907dff97028352600160248401819052604484018290526000606485018190526084850181905260a4850181905260c0978501978852855160c48601528551600160a060020a039097169763907dff979792959394919384938493839260e40191908a0190808383885b8381101561257d578181015183820152602001612565565b50505050905090810190601f1680156125aa5780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b1580156125ce57600080fd5b505af1158015611074573d6000803e3d6000fd5b600480546040805160208082018690528251808303820181528284018085527f49737375616e6365526174696f557064617465642875696e74323536290000009052925191829003605d01822060e060020a63907dff97028352600160248401819052604484018290526000606485018190526084850181905260a4850181905260c0978501978852855160c48601528551600160a060020a039097169763907dff979792959394919384938493839260e40191908a0190808383888381101561257d578181015183820152602001612565565b600480546040805160208082018690528251808303820181528284018085527f417070726f76616c28616464726573732c616464726573732c75696e7432353690527f29000000000000000000000000000000000000000000000000000000000000006060840152925191829003606101822060e060020a63907dff9702835260036024840181905260448401829052600160a060020a038a8116606486018190528a821660848701819052600060a4880181905260c09a88019a8b52885160c48901528851939099169963907dff97999497959692959194939092839260e40191908a0190808383885b838110156127b95781810151838201526020016127a1565b50505050905090810190601f1680156127e65780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b15801561280a57600080fd5b505af115801561281e573d6000803e3d6000fd5b50505050505050565b60008282111561283657600080fd5b50900390565b600082820182111561284d57600080fd5b500190565b60408051606081018252600b548152600c546020820152600d549181019190915261287e90829061322c565b8051600b55602080820151600c55604091820151600d55600e54600160a060020a0386166000908152600a9092529190206002015410156128da57600160a060020a0383166000908152601260205260409020805460ff191690555b600160a060020a0383166000908152600a6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915261292490839061322c565b600160a060020a039093166000908152600a6020908152604091829020855181559085015160018201559301516002909301929092555050565b600654604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015287811660248301529151600093929092169163da46098c9187918991612a1291869163dd62ed3e91604480830192602092919082900301818c87803b1580156129e057600080fd5b505af11580156129f4573d6000803e3d6000fd5b505050506040513d6020811015612a0a57600080fd5b505187612827565b6040805160e060020a63ffffffff8716028152600160a060020a03948516600482015292909316602483015260448201529051606480830192600092919082900301818387803b158015612a6557600080fd5b505af1158015612a79573d6000803e3d6000fd5b50505050612a888484846132e4565b95945050505050565b6000612084612aa884670de0b6b3a7640000613539565b83613567565b6000670de0b6b3a7640000612ac38484613539565b811515612acc57fe5b049392505050565b600480546040805160208082018690528251808303820181528284018085527f4665657357697468647261776e28616464726573732c75696e743235362900009052925191829003605e01822060e060020a63907dff9702835260026024840181905260448401829052600160a060020a038981166064860181905260006084870181905260a4870181905260c0998701998a52875160c48801528751929098169863907dff979893969495919484939192839260e490920191908a0190808383885b83811015612baf578181015183820152602001612b97565b50505050905090810190601f168015612bdc5780820380516001836020036101000a031916815260200191505b50975050505050505050600060405180830381600087803b158015612c0057600080fd5b505af1158015612c14573d6000803e3d6000fd5b505050505050565b6004546040805160008152602081018083527f497373756572735570646174656428616464726573732c626f6f6c290000000090529051808203603c019020600160a060020a039283169263907dff979291600391871686612c7f576000612c82565b60015b60405160e060020a63ffffffff881602815260248101859052604481018490526064810183905260ff9190911660848201819052600060a4830181905260c060048401908152875160c48501528751929391929091829160e49091019060208a01908083838883811015612baf578181015183820152602001612b97565b6004805460408051600160a060020a038581166020808401919091528351808403820181528385018086527f4e6f6d696e5570646174656428616464726573732900000000000000000000009052935192839003605501832060e060020a63907dff97028452600160248501819052604485018290526000606486018190526084860181905260a4860181905260c0988601988952865160c48701528651949097169763907dff979791959294919384938493839260e4909201918a0190808383888381101561257d578181015183820152602001612565565b6004805460408051600160a060020a038581166020808401919091528351808403820181528385018086527f4f7261636c6555706461746564286164647265737329000000000000000000009052935192839003605601832060e060020a63907dff97028452600160248501819052604485018290526000606486018190526084860181905260a4860181905260c0988601988952865160c48701528651949097169763907dff979791959294919384938493839260e4909201918a0190808383888381101561257d578181015183820152602001612565565b60048054604080516020808201879052818301869052825180830384018152606083018085527f5072696365557064617465642875696e743235362c75696e74323536290000009052925191829003607d01822060e060020a63907dff97028352600160248401819052604484018290526000606485018190526084850181905260a4850181905260c0978501978852855160c48601528551600160a060020a039097169763907dff979792959394919384938493839260e40191908a01908083838883811015612baf578181015183820152602001612b97565b600480546040805160208082018690528251808303820181528284018085527f466565506572696f64526f6c6c6f7665722875696e74323536290000000000009052925191829003605a01822060e060020a63907dff97028352600160248401819052604484018290526000606485018190526084850181905260a4850181905260c0978501978852855160c48601528551600160a060020a039097169763907dff979792959394919384938493839260e40191908a0190808383888381101561257d578181015183820152602001612565565b6004805460408051600160a060020a038581166020808401919091528351808403820181528385018086527f546f6b656e5374617465557064617465642861646472657373290000000000009052935192839003605a01832060e060020a63907dff97028452600160248501819052604485018290526000606486018190526084860181905260a4860181905260c0988601988952865160c48701528651949097169763907dff979791959294919384938493839260e4909201918a0190808383888381101561257d578181015183820152602001612565565b600061314a8484846132e4565b949350505050565b6004805460408051600160a060020a038581166020808401919091528351808403820181528385018086527f457363726f7755706461746564286164647265737329000000000000000000009052935192839003605601832060e060020a63907dff97028452600160248501819052604485018290526000606486018190526084860181905260a4860181905260c0988601988952865160c48701528651949097169763907dff979791959294919384938493839260e4909201918a0190808383888381101561257d578181015183820152602001612565565b613234613682565b815160208301516040840151600e54600090819081908410156132ac57600f5484101561326357889450613297565b83600e54039250600f54600e54039150613286866132818b86613539565b61283c565b9050818181151561329357fe5b0494505b6132a589600e544203613539565b95506132bf565b6132bc866132818b874203613539565b95505b5050604080516060810182529485526020850193909352505042908201529392505050565b6000600160a060020a03831615156132fb57600080fd5b600160a060020a03831630141561331157600080fd5b600454600160a060020a038481169116141561332c57600080fd5b6006546040805160e060020a6370a08231028152600160a060020a0387811660048301529151919092169163b46310f69187916133be9185916370a082319160248083019260209291908290030181600087803b15801561338c57600080fd5b505af11580156133a0573d6000803e3d6000fd5b505050506040513d60208110156133b657600080fd5b505186612827565b6040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b15801561341057600080fd5b505af1158015613424573d6000803e3d6000fd5b50506006546040805160e060020a6370a08231028152600160a060020a038881166004830152915191909216935063b46310f6925086916134ba9185916370a082319160248083019260209291908290030181600087803b15801561348857600080fd5b505af115801561349c573d6000803e3d6000fd5b505050506040513d60208110156134b257600080fd5b50518661283c565b6040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b15801561350c57600080fd5b505af1158015613520573d6000803e3d6000fd5b5050505061352f848484613580565b5060019392505050565b60008083151561354c5760009150610dfd565b5082820282848281151561355c57fe5b041461208457600080fd5b600081151561357557600080fd5b8183811515612acc57fe5b600480546040805160208082018690528251808303820181528284018085527f5472616e7366657228616464726573732c616464726573732c75696e7432353690527f29000000000000000000000000000000000000000000000000000000000000006060840152925191829003606101822060e060020a63907dff9702835260036024840181905260448401829052600160a060020a038a8116606486018190528a821660848701819052600060a4880181905260c09a88019a8b52885160c48901528851939099169963907dff97999497959692959194939092839260e40191908a019080838388838110156127b95781810151838201526020016127a1565b60606040519081016040528060008152602001600081526020016000815250905600a165627a7a72305820982d1c9fac665f13a60b2b8dcb9780c81c03c36f114710ea70b424844872668a0029000000000000000000000000c011a72400e58ecd99ee497cf89e3775d4bd732f0000000000000000000000005b1b5fea1b99d83ad479df0c222f0492385381dd000000000000000000000000b10c85274d2a58ddec72c1d826e75256ff93dead000000000000000000000000b10c8f6d5a3a99267fa2a34fbb66c94ba913ee0b00000000000000000000000000000000000000000000000004168fdbd694500000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000001da95f253122636d0776017311892835a15d9dd000000000000000000000000000000000000000000000000000000000000003800000000000000000000000043faad107926a2019caf52e3be51cd773d263726000000000000000000000000457a403e1003ce5f0514c1ce5f97284a1759b47400000000000000000000000048ab39a8d817cabcdd4c3176ee14d1c4f7bd81d70000000000000000000000004cb7e58dabbd6ecb38ef0103497b8930b4f0512200000000000000000000000054197c5900ef9c70a3d5a99632b61bebce46859a0000000000000000000000005651973bbe0f75ccd5b9e12ce1e08d47ad3a5090000000000000000000000000680ba9e850944f78ad136a8c6368c53fb47f45cf000000000000000000000000691ce62a208b195accf54c39a98f1112c90046d10000000000000000000000006aff961297ec2248839d6adb5731f79b582fd5d90000000000000000000000006f6e5836941235ef6255b51b05b1c9b767d49c9a0000000000000000000000007113fbdc1c6ef083a72ba152b446b10654e4e05e00000000000000000000000072586eec278d62ea783b9941206bcdcfa12059eb0000000000000000000000007336f733657fe7ffc92e27fb19fd5a6ae4c0e0c200000000000000000000000073b0d2fe3b57456e46d3c17cf6bf5faa71ec6786000000000000000000000000758d10334bc9b3e6f0d41b6e96e64a1663324d8b0000000000000000000000007b201ded890f49445b45e1388d89c2d902038eb00000000000000000000000007bb79ad6f3b42e71be4557b2f205d257c323bdd300000000000000000000000083026eff97f966f40ecb2673c7dd74aae84483e60000000000000000000000008785bc7c6499c6ffcf2f246251c88e222aee6290000000000000000000000000890ae53155a2465d9f9ff603a746cbf04e7fb98e0000000000000000000000008cfe2c93d5734283d7232e1817b63c95f9452a430000000000000000000000008ec3d296801206f4b730be8a06e08bd3c376c0e600000000000000000000000093770f4bf7455237e5e9373d1fb49f8d3e7a20f200000000000000000000000093867b142026e3582fbf2d747987ce7cfcd5cc320000000000000000000000009515bf2f910279ce3a54245b5ea7c67a3a3d4c44000000000000000000000000957a04d49e1fe05d52b49244e4ed32ab451435c20000000000000000000000009c1ca39cb4a88bcaafecf4c2e775630dc65f35850000000000000000000000009cdc5521ef66e57b4a04d3f9a558ffca9d736e97000000000000000000000000a90ff30acc0d7c43b36e6f7871f55d552d06b6ca000000000000000000000000a982bbdaf783eb7c3914d988b7e2a0be865ccb53000000000000000000000000ac0367375ec176d30f38dbc50904209f4dc67cf4000000000000000000000000af13aee10352f7394a30a7aaf0bf6fa6f5b1cfcf000000000000000000000000b74ddbc2480ff182f524e4f308881f3be9123768000000000000000000000000b76ded4b696ac9832a8f97ba8ffd3b87f393ef84000000000000000000000000bc69b868a4cf6fe2fc8deaaa6173ed50379a4ac0000000000000000000000000bc9e297a1d1f97198f1d1f01c835e2516b0b71ea000000000000000000000000bd2b7b9af0c823f0f02c4c875bba619f95539aea000000000000000000000000bed8c03e31f822bdf450335dc35ec85ef6499b80000000000000000000000000bf3f54ab0cd10f5b53bf8adbc275417e780cd965000000000000000000000000bfea67ff131ab6ee3ae33b6f0547d7ce5c87b3e3000000000000000000000000c4b0772b22edb9b1a68a6f51ef6dcb3667f7ce16000000000000000000000000c872dcfe719fbd043fd48aa340f58d0ae5ae1dd1000000000000000000000000ced50221abe135f6085882dbe451cfaa6e8cbc23000000000000000000000000ceed474d02362da11951a17e352b15379132c077000000000000000000000000d85a7a3c5f08e3e709c233e133ce1335fbbf5518000000000000000000000000dddc4a4bf91c51a5ee598ce9c51d83fb80478eba000000000000000000000000dfc9decb79c5a7820ae6cb2681c8ff812069e465000000000000000000000000e1d0fd369af427ce86e883b8866fc6dba0796a68000000000000000000000000e20ff024e00a324d6fd29750ebe92e6b4faa2741000000000000000000000000e8ea41f87bbd365a3ec766e35ac4ac1d6a5e760a000000000000000000000000ea6e2ee9b87b8052ec8e5aa023c249dc74383ed1000000000000000000000000fc1b2ce616d924c413b62f3a9782997b7545898b000000000000000000000000fe592366b2fe07a1a7f3a8f4374fade45a2f13ab000000000000000000000000d1dd1e2492de07c80713695e2a630fbdfe9e26f50000000000000000000000006eec24666b05748357fedcf1634e556845934661000000000000000000000000042ed37d32b88ab6b1c2e7b8a400dcdc728050bc

    Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c011a72400e58ecd99ee497cf89e3775d4bd732f0000000000000000000000005b1b5fea1b99d83ad479df0c222f0492385381dd000000000000000000000000b10c85274d2a58ddec72c1d826e75256ff93dead000000000000000000000000b10c8f6d5a3a99267fa2a34fbb66c94ba913ee0b00000000000000000000000000000000000000000000000004168fdbd694500000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000001da95f253122636d0776017311892835a15d9dd000000000000000000000000000000000000000000000000000000000000003800000000000000000000000043faad107926a2019caf52e3be51cd773d263726000000000000000000000000457a403e1003ce5f0514c1ce5f97284a1759b47400000000000000000000000048ab39a8d817cabcdd4c3176ee14d1c4f7bd81d70000000000000000000000004cb7e58dabbd6ecb38ef0103497b8930b4f0512200000000000000000000000054197c5900ef9c70a3d5a99632b61bebce46859a0000000000000000000000005651973bbe0f75ccd5b9e12ce1e08d47ad3a5090000000000000000000000000680ba9e850944f78ad136a8c6368c53fb47f45cf000000000000000000000000691ce62a208b195accf54c39a98f1112c90046d10000000000000000000000006aff961297ec2248839d6adb5731f79b582fd5d90000000000000000000000006f6e5836941235ef6255b51b05b1c9b767d49c9a0000000000000000000000007113fbdc1c6ef083a72ba152b446b10654e4e05e00000000000000000000000072586eec278d62ea783b9941206bcdcfa12059eb0000000000000000000000007336f733657fe7ffc92e27fb19fd5a6ae4c0e0c200000000000000000000000073b0d2fe3b57456e46d3c17cf6bf5faa71ec6786000000000000000000000000758d10334bc9b3e6f0d41b6e96e64a1663324d8b0000000000000000000000007b201ded890f49445b45e1388d89c2d902038eb00000000000000000000000007bb79ad6f3b42e71be4557b2f205d257c323bdd300000000000000000000000083026eff97f966f40ecb2673c7dd74aae84483e60000000000000000000000008785bc7c6499c6ffcf2f246251c88e222aee6290000000000000000000000000890ae53155a2465d9f9ff603a746cbf04e7fb98e0000000000000000000000008cfe2c93d5734283d7232e1817b63c95f9452a430000000000000000000000008ec3d296801206f4b730be8a06e08bd3c376c0e600000000000000000000000093770f4bf7455237e5e9373d1fb49f8d3e7a20f200000000000000000000000093867b142026e3582fbf2d747987ce7cfcd5cc320000000000000000000000009515bf2f910279ce3a54245b5ea7c67a3a3d4c44000000000000000000000000957a04d49e1fe05d52b49244e4ed32ab451435c20000000000000000000000009c1ca39cb4a88bcaafecf4c2e775630dc65f35850000000000000000000000009cdc5521ef66e57b4a04d3f9a558ffca9d736e97000000000000000000000000a90ff30acc0d7c43b36e6f7871f55d552d06b6ca000000000000000000000000a982bbdaf783eb7c3914d988b7e2a0be865ccb53000000000000000000000000ac0367375ec176d30f38dbc50904209f4dc67cf4000000000000000000000000af13aee10352f7394a30a7aaf0bf6fa6f5b1cfcf000000000000000000000000b74ddbc2480ff182f524e4f308881f3be9123768000000000000000000000000b76ded4b696ac9832a8f97ba8ffd3b87f393ef84000000000000000000000000bc69b868a4cf6fe2fc8deaaa6173ed50379a4ac0000000000000000000000000bc9e297a1d1f97198f1d1f01c835e2516b0b71ea000000000000000000000000bd2b7b9af0c823f0f02c4c875bba619f95539aea000000000000000000000000bed8c03e31f822bdf450335dc35ec85ef6499b80000000000000000000000000bf3f54ab0cd10f5b53bf8adbc275417e780cd965000000000000000000000000bfea67ff131ab6ee3ae33b6f0547d7ce5c87b3e3000000000000000000000000c4b0772b22edb9b1a68a6f51ef6dcb3667f7ce16000000000000000000000000c872dcfe719fbd043fd48aa340f58d0ae5ae1dd1000000000000000000000000ced50221abe135f6085882dbe451cfaa6e8cbc23000000000000000000000000ceed474d02362da11951a17e352b15379132c077000000000000000000000000d85a7a3c5f08e3e709c233e133ce1335fbbf5518000000000000000000000000dddc4a4bf91c51a5ee598ce9c51d83fb80478eba000000000000000000000000dfc9decb79c5a7820ae6cb2681c8ff812069e465000000000000000000000000e1d0fd369af427ce86e883b8866fc6dba0796a68000000000000000000000000e20ff024e00a324d6fd29750ebe92e6b4faa2741000000000000000000000000e8ea41f87bbd365a3ec766e35ac4ac1d6a5e760a000000000000000000000000ea6e2ee9b87b8052ec8e5aa023c249dc74383ed1000000000000000000000000fc1b2ce616d924c413b62f3a9782997b7545898b000000000000000000000000fe592366b2fe07a1a7f3a8f4374fade45a2f13ab000000000000000000000000d1dd1e2492de07c80713695e2a630fbdfe9e26f50000000000000000000000006eec24666b05748357fedcf1634e556845934661000000000000000000000000042ed37d32b88ab6b1c2e7b8a400dcdc728050bc

-----Encoded View---------------
64 Constructor Arguments found :
Arg [0] : 000000000000000000000000c011a72400e58ecd99ee497cf89e3775d4bd732f
Arg [1] : 0000000000000000000000005b1b5fea1b99d83ad479df0c222f0492385381dd
Arg [2] : 000000000000000000000000b10c85274d2a58ddec72c1d826e75256ff93dead
Arg [3] : 000000000000000000000000b10c8f6d5a3a99267fa2a34fbb66c94ba913ee0b
Arg [4] : 00000000000000000000000000000000000000000000000004168fdbd6945000
Arg [5] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [6] : 00000000000000000000000001da95f253122636d0776017311892835a15d9dd
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000038
Arg [8] : 00000000000000000000000043faad107926a2019caf52e3be51cd773d263726
Arg [9] : 000000000000000000000000457a403e1003ce5f0514c1ce5f97284a1759b474
Arg [10] : 00000000000000000000000048ab39a8d817cabcdd4c3176ee14d1c4f7bd81d7
Arg [11] : 0000000000000000000000004cb7e58dabbd6ecb38ef0103497b8930b4f05122
Arg [12] : 00000000000000000000000054197c5900ef9c70a3d5a99632b61bebce46859a
Arg [13] : 0000000000000000000000005651973bbe0f75ccd5b9e12ce1e08d47ad3a5090
Arg [14] : 000000000000000000000000680ba9e850944f78ad136a8c6368c53fb47f45cf
Arg [15] : 000000000000000000000000691ce62a208b195accf54c39a98f1112c90046d1
Arg [16] : 0000000000000000000000006aff961297ec2248839d6adb5731f79b582fd5d9
Arg [17] : 0000000000000000000000006f6e5836941235ef6255b51b05b1c9b767d49c9a
Arg [18] : 0000000000000000000000007113fbdc1c6ef083a72ba152b446b10654e4e05e
Arg [19] : 00000000000000000000000072586eec278d62ea783b9941206bcdcfa12059eb
Arg [20] : 0000000000000000000000007336f733657fe7ffc92e27fb19fd5a6ae4c0e0c2
Arg [21] : 00000000000000000000000073b0d2fe3b57456e46d3c17cf6bf5faa71ec6786
Arg [22] : 000000000000000000000000758d10334bc9b3e6f0d41b6e96e64a1663324d8b
Arg [23] : 0000000000000000000000007b201ded890f49445b45e1388d89c2d902038eb0
Arg [24] : 0000000000000000000000007bb79ad6f3b42e71be4557b2f205d257c323bdd3
Arg [25] : 00000000000000000000000083026eff97f966f40ecb2673c7dd74aae84483e6
Arg [26] : 0000000000000000000000008785bc7c6499c6ffcf2f246251c88e222aee6290
Arg [27] : 000000000000000000000000890ae53155a2465d9f9ff603a746cbf04e7fb98e
Arg [28] : 0000000000000000000000008cfe2c93d5734283d7232e1817b63c95f9452a43
Arg [29] : 0000000000000000000000008ec3d296801206f4b730be8a06e08bd3c376c0e6
Arg [30] : 00000000000000000000000093770f4bf7455237e5e9373d1fb49f8d3e7a20f2
Arg [31] : 00000000000000000000000093867b142026e3582fbf2d747987ce7cfcd5cc32
Arg [32] : 0000000000000000000000009515bf2f910279ce3a54245b5ea7c67a3a3d4c44
Arg [33] : 000000000000000000000000957a04d49e1fe05d52b49244e4ed32ab451435c2
Arg [34] : 0000000000000000000000009c1ca39cb4a88bcaafecf4c2e775630dc65f3585
Arg [35] : 0000000000000000000000009cdc5521ef66e57b4a04d3f9a558ffca9d736e97
Arg [36] : 000000000000000000000000a90ff30acc0d7c43b36e6f7871f55d552d06b6ca
Arg [37] : 000000000000000000000000a982bbdaf783eb7c3914d988b7e2a0be865ccb53
Arg [38] : 000000000000000000000000ac0367375ec176d30f38dbc50904209f4dc67cf4
Arg [39] : 000000000000000000000000af13aee10352f7394a30a7aaf0bf6fa6f5b1cfcf
Arg [40] : 000000000000000000000000b74ddbc2480ff182f524e4f308881f3be9123768
Arg [41] : 000000000000000000000000b76ded4b696ac9832a8f97ba8ffd3b87f393ef84
Arg [42] : 000000000000000000000000bc69b868a4cf6fe2fc8deaaa6173ed50379a4ac0
Arg [43] : 000000000000000000000000bc9e297a1d1f97198f1d1f01c835e2516b0b71ea
Arg [44] : 000000000000000000000000bd2b7b9af0c823f0f02c4c875bba619f95539aea
Arg [45] : 000000000000000000000000bed8c03e31f822bdf450335dc35ec85ef6499b80
Arg [46] : 000000000000000000000000bf3f54ab0cd10f5b53bf8adbc275417e780cd965
Arg [47] : 000000000000000000000000bfea67ff131ab6ee3ae33b6f0547d7ce5c87b3e3
Arg [48] : 000000000000000000000000c4b0772b22edb9b1a68a6f51ef6dcb3667f7ce16
Arg [49] : 000000000000000000000000c872dcfe719fbd043fd48aa340f58d0ae5ae1dd1
Arg [50] : 000000000000000000000000ced50221abe135f6085882dbe451cfaa6e8cbc23
Arg [51] : 000000000000000000000000ceed474d02362da11951a17e352b15379132c077
Arg [52] : 000000000000000000000000d85a7a3c5f08e3e709c233e133ce1335fbbf5518
Arg [53] : 000000000000000000000000dddc4a4bf91c51a5ee598ce9c51d83fb80478eba
Arg [54] : 000000000000000000000000dfc9decb79c5a7820ae6cb2681c8ff812069e465
Arg [55] : 000000000000000000000000e1d0fd369af427ce86e883b8866fc6dba0796a68
Arg [56] : 000000000000000000000000e20ff024e00a324d6fd29750ebe92e6b4faa2741
Arg [57] : 000000000000000000000000e8ea41f87bbd365a3ec766e35ac4ac1d6a5e760a
Arg [58] : 000000000000000000000000ea6e2ee9b87b8052ec8e5aa023c249dc74383ed1
Arg [59] : 000000000000000000000000fc1b2ce616d924c413b62f3a9782997b7545898b
Arg [60] : 000000000000000000000000fe592366b2fe07a1a7f3a8f4374fade45a2f13ab
Arg [61] : 000000000000000000000000d1dd1e2492de07c80713695e2a630fbdfe9e26f5
Arg [62] : 0000000000000000000000006eec24666b05748357fedcf1634e556845934661
Arg [63] : 000000000000000000000000042ed37d32b88ab6b1c2e7b8a400dcdc728050bc


   Swarm Source:
bzzr://982d1c9fac665f13a60b2b8dcb9780c81c03c36f114710ea70b424844872668a

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.