ETH Price: $2,255.83 (-1.74%)

Transaction Decoder

Block:
2220197 at Sep-08-2016 07:16:33 AM +UTC
Transaction Fee:
0.01354238 ETH $30.55
Gas Used:
677,119 Gas / 20 Gwei

Account State Difference:

  Address   Before After State Difference Code
0x32B724f0...F6fE42950
54.06023645 Eth
Nonce: 0
54.04669407 Eth
Nonce: 1
0.01354238
0x687a2414...0B74C8b3C
0 Eth
Nonce: 0
0 Eth
Nonce: 0
From: 0 To: 1633108772271623098874219524435465586224541586050329016388519085835291436823185351049455027004604888240155027204217054100134003445413313798495541433404237342611954342434286516018833457529749998038856561035577300474705935984857715134428671466934282447039942882438811839579903897330964267611464903610988022996322133820017101863952486840430970566871397624048675476938367931239831653632344826845057030582522113313809250041598339807822412763727428574348942487426285148872291118441813745784940760485817505180992628274321054652617850370117107053659296751590168387502035130634868274070785694804028609730492882288580541278815322776278885774079010864685406556280509562420023806918908036642965555502616576491878123109996242638803056924179009323698475815198220633825001060304364498951208719060487809423716920329185298465238873084789336777190398191676450293150510096943372021632649367539385751525555963826870476722088321818979126289638547393326861467746632747691872791469560935523654514608034474490489065872276966339846557408990385448308917343487349561448681589364559218345369486389058628227708829199120922302759693862545848114298338329993962490755259877904985346851791074244518250298512970491006160495222092044099085213990882550522111678697673949169183044643219062910800489333775301289578988772738120375298593676305019128105327592415027554939400861283342760885553176299294479680987201041280541702295071126267031903520733639532547301339618541213017360347142482026585299606365221922921740594754831015307961997622702338946995044015897501570470138539960180219706954783430799235361564673632658180870803693680778873593652077370296266880794794326516737394218184847400963708252917367949815316503539454129576607276452093090982261241369635281061111838693965837518157500416849506784230567529167200513173103552821394546147658127601417843352328836806459005660291369789729667829791696401244815913604749218869267451389855756182545088045136072525153995500618915817239759677739068344431299390863303170501340449575224774509879935524626331837998943226676015896166823394849207899372916163823789019401893178259980288520991750603683835807447351571082053096016257738802058848141772616214770771832604663045269310083422713492443950666401636115770675168327512873571127456488008161756598348486315706430292667614964446009591291734134631994156853635478011072717829994261016598416567750519805173040577141968511396264392979413566651831771222017112690673246708944436367418420830395442248985308935466799884744902693698672879680659499339482614697277499282034277852308249609811754477613009769100552866436549200841355359340269812713620271232247043261835619386326116452501413300575619450119536659127927568439194446131760537039652935735686776373918147366145513080769662645323218726233132814199779298161144309934876843216731820874720468537938798274156721246967708842998608072002879756311644449436660437695022045114613049693556660153390870501463832567700544551382708588809067175922126903148518321943737222235542215152371328292509307582843417104435497358341769889550104842752083589556450470064596968181780930831780263518097588254611366918198382554175003567274205373075740233664842004648920213354166911434967123006221966873195645791339465037566127633464144103514074877848742482551575258176327473764077881157204360804099038011753760696023326598812358085640054607681255248505758244887081820906358414422632955173867269210917648637396652162230348157323138328623757751688630835899196531598294559721857078666597019916098903775860085183639375138174207968923347801546658339875133726138202047460489197214667211865863708875140877368297228271116437535861173160310995001264369808158855304383213647039259158260806806218982845991758405959013442680330860677022744154115299024528869476357740951345019559519354476235145184663236561087246878567725564376485614623709697540209182264836901251510759312720940541459244951075089121046064681104728469202206388729127668411097445738160252388874344073296130814159739302277589489511121636908546679881742056217800499725953787923812853805408424260284742938785870570407759606248146444388175085152048418246294943430405157845162994407485193786467876986687357235598383590102492781626504467105461968567341321357001540458898309536657314947502476044194439249142627990468434597898457179820374638852629168540785905582914842348158644463731472510015842596597067015791804991025024765647668322626573173079556425200286512528419203767376763547802799455843630825466375284569818513416180161893697866439026610981777302865337792384192505093909845294642640516451534967328164004945467231960452892429819146205362284970454735055157898584663548437407178208958587501820253784455685910181224130314249213756484580669351962568364937134668451055631227252788913744599750510662850587120776537954381778466298840413603074823003083271972895771245729870549147546069635422995530013972739482973012459326917301388384855297992037633920024643292492688115475023792344105883481904180803291263981529515935938055689282837360982318515719228138450424510134059591638376473286628731539191635395982594896539442850254002438518208239983090834912881805448041068468986028642152527278175897108462730196695426398386404907964491760110748596507249348220160572493137838593805619641403438340952035222086422738281252454277472921099006768434600822586934097921709200726
402.907281783591402698 Eth402.920824163591402698 Eth0.01354238

Execution Trace

DepositHolder.60606040( )
pragma solidity ^0.3.5;

contract DepositHolder {
    uint constant GUARANTEE_PERIOD = 365 days;
    
    event Claim(address addr, uint amount);
    
    struct Entry {
        bytes16 next;
        uint64 deposit;
        uint64 expires;
    }

    address owner;
    address auditor;
    
    mapping(bytes16=>Entry) entries;
    bytes16 oldestHash;
    bytes16 newestHash;
    
    uint public paidOut;
    uint public totalPaidOut;
    uint public depositCount;
    
    function DepositHolder() {
        owner = msg.sender;
        auditor = owner;
    }
    
    modifier owner_only {
        if(msg.sender != owner) throw;
        _;
    }
    
    modifier auditor_only {
        if(msg.sender != auditor) throw;
        _;
    }

    /**
     * @dev Lodge deposits for a set of address hashes. Automatically uses
     *      expired deposits to pay for new ones.
     * @param values A list of hashes of addresses to place deposits for.
     *        Each value is the first 16 bytes of the keccak-256 hash of the
     *        address the deposit is for.
     * @param deposit The amount of the deposit on each address.
     */
    function deposit(bytes16[] values, uint64 deposit) owner_only {
        uint required = values.length * deposit;
        if(msg.value < required) {
            throw;
        } else if(msg.value > required) {
            if(!msg.sender.send(msg.value - required))
                throw;
        }

        extend(values, uint64(deposit));
    }

    function extend(bytes16[] values, uint64 deposit) private {
        uint64 expires = uint64(now + GUARANTEE_PERIOD);

        if(oldestHash == 0) {
            oldestHash = values[0];
            newestHash = values[0];
        } else {
            entries[newestHash].next = values[0];
        }
        
        for(uint i = 0; i < values.length - 1; i++) {
            if(entries[values[i]].expires != 0)
                throw;
            entries[values[i]] = Entry(values[i + 1], deposit, expires);
        }
        
        newestHash = values[values.length - 1];
        if(entries[newestHash].expires != 0)
            throw;
        entries[newestHash] = Entry(0, deposit, expires);
        
        depositCount += values.length;
    }

    /**
     * @dev Withdraw funds held for expired deposits.
     * @param max Maximum number of deposits to claim.
     */
    function withdraw(uint max) owner_only {
        uint recovered = recover(max);
        if(!msg.sender.send(recovered))
            throw;
    }

    function recover(uint max) private returns(uint recovered) {
        // Iterate through entries deleting them, until we find one
        // that's new enough, or hit the limit.
        bytes16 ptr = oldestHash;
        uint count;
        for(uint i = 0; i < max && ptr != 0 && entries[ptr].expires < now; i++) {
            recovered += entries[ptr].deposit;
            ptr = entries[ptr].next;
            count += 1;
        }

        oldestHash = ptr;
        if(oldestHash == 0)
            newestHash = 0;
        
        // Deduct any outstanding payouts from the recovered funds
        if(paidOut > 0) {
            if(recovered > paidOut) {
                recovered -= paidOut;
                paidOut = 0;
            } else {
                paidOut -= recovered;
                recovered = 0;
            }
        }
        
        depositCount -= count;
    }

    /**
     * @dev Fetches information on a future withdrawal event
     * @param hash The point at which to start scanning; 0 for the first event.
     * @return when Unix timestamp at which a withdrawal can next happen.
     * @return count Number of addresses expiring at this time
     * @return value Total amount withdrawable at this time
     * @return next Hash of the start of the next withdrawal event, if any.
     */
    function nextWithdrawal(bytes16 hash) constant returns(uint when, uint count, uint value, bytes16 next) {
        if(hash == 0) {
            hash = oldestHash;
        }
        next = hash;
        when = entries[hash].expires;
        while(next != 0 && entries[next].expires == when) {
            count += 1;
            value += entries[next].deposit;
            next = entries[next].next;
        }
    }

    /**
     * @dev Checks if a deposit is held for the provided address.
     * @param addr The address to check.
     * @return expires The unix timestamp at which the deposit on this address
     *         expires, or 0 if there is no deposit.
     * @return deposit The amount deposited against this address.
     */
    function check(address addr) constant returns (uint expires, uint deposit) {
        Entry storage entry = entries[bytes16(sha3(addr))];
        expires = entry.expires;
        deposit = entry.deposit;
    }
    
    /**
     * @dev Pays out a claim.
     * @param addr The address to pay.
     * @param amount The amount to send.
     */
    function disburse(address addr, uint amount) auditor_only {
        paidOut += amount;
        totalPaidOut += amount;
        Claim(addr, amount);
        if(!addr.send(amount))
            throw;
    }
    
    /**
     * @dev Deletes the contract, if no deposits are held.
     */
    function destroy() owner_only {
        if(depositCount > 0)
            throw;
        selfdestruct(msg.sender);
    }
}