Robinhood Chain · 4663

Know how much
of your history
it actually read.

One trade here emits 5.2 Transfer logs on average. Every leg is netted before anything is classified.

One transaction in five moves ETH that logs nothing; its amount is read from the transaction itself.

Whatever it cannot price stays unpriced, and the export says INCOMPLETE until you answer.

The problem

Most of the work is deciding what happened.

The arithmetic of cost basis is easy. Knowing which transfers were a purchase, which were you moving your own coins, and which were a swap that nothing on chain priced — that is the whole problem. Get the classification wrong and every figure downstream is confidently wrong.

The solution

Decide what the chain proves. Ask about the rest.

Vrismcost adds up every leg of a transaction, per asset, across the wallets you register, and classifies the result by rules you can read in its source. Each decision keeps the transactions behind it. What the chain cannot settle is queued with its reason rather than filled in, and the report reads COMPLETE only once nothing is left open.

Was it a purchase?
USDG out and something else in, inside one transaction: a purchase, priced to the cent by the USDG leg. Paid in ETH, it takes the ETH rate read from the chain.
Were you moving your own coins?
When every leg nets to zero across wallets you registered, nothing was sold: the lot keeps its basis and its acquisition date. From a wallet you did not register, you are asked.
Did anything on chain price it?
USDG is its own price. ETH is priced from the chain’s WETH/USDG swaps, and only where they agree within 3%. A trade with neither stays unpriced, queued with the reason.

How Vrismcost works

    01 — Reconstruction

    Net the legs, then read the shape

    Router hops, fee sinks and mint-burn legs sit around the two that matter — 70.9% of transactions here emit more than two. Vrismcost nets every leg per asset across your wallets, adds the native ETH from tx.value, and classifies what is left. Some history still has to come from you; Vrismcost says which.

    02 — Pricing

    Your trades already contain their prices

    No price oracle, no historical feed. When one leg of a trade is USDG, that leg is the price — exactly, to the cent. Most real trades here settle in ETH instead, so the ETH rate is read back off the chain: WETH and USDG legs matched across a shared pool, outliers dropped, and the median kept only where those swaps agree within 3%. A trade with nothing behind it is queued for you, not guessed.

    03 — Wallet moves

    Moving your own coins is not a sale

    A transfer where both sides are addresses you registered is a move. The lot survives it, keeps its original acquisition date, and the holding clock does not restart. Treat it as a disposal and your taxable gain inflates for no reason.

    04 — Gas

    Every transaction costs something

    Gas is read from each receipt — gasUsed × effectiveGasPrice — on every buy and sale one of your wallets sent, and folded in: added to the basis of what it bought, subtracted from the proceeds of what it sold. A transaction someone else sent, like an issuer’s split, was paid for by them and adds nothing.

    05 — Holding periods

    Days held are reported, not labelled

    Every matched leg carries the days it was held, from acquisition to disposal. Whether that counts as short or long term is a rule of where you file, so Vrismcost reports the days and leaves the label to you. It will not quote a rate or a threshold it cannot verify.

    Your positions

    The ledger.

    Worked example · not a live account

    The NVDA disposals, in full

    Watch a sale consume its lots.

    What the command line prints for the worked example: both NVDA disposals under all four methods, including the one nobody has priced yet. The round trips in the other stocks print the same way and are left out of this excerpt. Figures are carried unrounded and rounded only for display, so a line can differ from a total by a cent.

    python vrismcost.py · excerpt
    
                

    Honest limits

    The correction queue.

    Some figures genuinely are not recoverable from the chain. A tool that fills them in with a plausible guess produces a report you cannot defend. Vrismcost queues them with the reason and the answers that would close them, and marks the export INCOMPLETE until you decide. Try it below — the numbers move as you answer.

    Known blind spots

      Method comparison

      The same sale. Four answers.

      Computed from the worked example above · Method eligibility depends on your jurisdiction

      Measured, not assumed

      We tested your chain before we designed for it.

      Tokenized stock only

      Your position changed. You did not sell.

      When you are done

      One file. Every leg. Gas included.

      Four sheets, because an accountant works in a spreadsheet: the disposal schedule with one row per matched leg, distributions kept apart from the lot inventory, the positions still open, and a summary whose first line says whether any of it is complete. Every row carries both transaction hashes and a provenance column, and unresolved rows are exported as UNPRICED rather than dropped.

      2026-disposals.csv
      
                  

      Take it

      Nine files. One dependency.

      The command line, the chain reader, the engine, the vault, the export and the test suite. Python 3.10 or newer. Nothing to sign up for, and nothing that runs unless you run it.

      Every file is served as plain text at its own address, so you can read the whole thing in a browser before deciding whether to take it.

      Python 3.10+ 1 dependency 95 tests, offline No account

      SHA-256

      231c740a4ff5328f75641858d8ebcf9c527f7d7bea81aa16ac7e898e76609040

      Or take the files one by one

      curl --remote-name-all "https://your-site/src/{vrismcost.py,fetcher.py,engine.py,price.py,report.py,vault.py,test_vrismcost.py,README.md,requirements.txt,SHA256SUMS}" sha256sum -c SHA256SUMS

      Nine files and their manifest, in the format sha256sum -c reads. On macOS, shasum -a 256 -c SHA256SUMS.

      Confirm the archive

      shasum -a 256 vrismcost-0.2.6.zip certutil -hashfile vrismcost-0.2.6.zip SHA256

      Then

      unzip vrismcost-0.2.6.zip && cd vrismcost-0.2.6 pip install -r requirements.txt python test_vrismcost.py

      If the suite is not green, do not trust the numbers. That is what it is for.

      Verify, don't trust

      What leaves this machine.

      One address, and it is the chain. You do not have to take that on faith — this is plain Python you can read, so every claim below comes with the command that settles it. Run them before you run anything else.

      One address is contacted, and it is the chain

      The public RPC, and nothing else. No account, no key, no analytics, no server of ours.

      Check it yourself

      grep -rn "https://" *.py

      Nothing is ever uploaded

      Lists every RPC method this calls. All six are reads — there is no code path that writes to the chain or sends your holdings anywhere.

      Check it yourself

      grep -rhoE '(call|batched)\("eth_[a-zA-Z]+"' *.py | sort -u

      Your keys are never asked for

      It reads public data. A seed phrase would not even have anywhere to go.

      Check it yourself

      grep -rniE "private_?key|mnemonic|seed" *.py

      The vault is unreadable on disk

      A test opens a saved vault and searches the raw file for your own data.

      Check it yourself

      python test_vrismcost.py -k nothing_readable

      Every published hash matches its file

      The build refuses to publish when a served file, its hash, the archive or this page disagree. The archive check is one you can repeat from here, against the hash shown above.

      Check it yourself

      curl -s "https://your-site/vrismcost-0.2.6.zip" | shasum -a 256

      The arithmetic is pinned

      Every test runs offline, in seconds. Break the lot matching and the suite fails.

      Check it yourself

      python test_vrismcost.py

      If a hash ever disagrees

      It would mean one of two things, and from the outside you cannot tell which: the build got it wrong, or the file was changed after it was published. That ambiguity is why the build refuses to produce a release at all unless every published hash matches the file it names — and any one check failing stops it.

      A version that is out never changes. If the code needs fixing the version number moves with it; the bytes behind 0.2.6 stay the bytes behind 0.2.6, permanently. Every release is recorded in RELEASES, which is only ever appended to.

      Found one anyway?

      Keep the file you downloaded — do not re-download it, that is the evidence. Then tell @vrismcost on X which file, which hash you got, and when. A report like that is worth more than any assurance on this page.

      Check it against the record

      curl -s "https://your-site/RELEASES" | grep -F "vrismcost-0.2.6.zip "

      Stays on your machine

      • Your cost basis, lots and matched disposals
      • Every answer you give the correction queue
      • Wallet labels, notes and the exported schedule
      • The vault key — held in memory, dropped on lock

      The node can still see

      • Which addresses you asked about
      • Your IP address, like any web request
      • Roughly when you asked

      Private is not the same as anonymous. Use a VPN, or point it at your own node with --rpc=URL.

      Straight answers

      Before you run it.

      Do I need an API key, or an account?

      No, and there is nowhere to enter one. Robinhood Chain's public RPC answers everything this needs, free. That is also why there is no sign-up: there is no server on our side to sign up to.

      Does it ever want my private key or seed phrase?

      Never. It only reads public chain data, so a key would have no use here. Anything that asks you for a seed phrase to compute a tax figure is not computing a tax figure.

      Why is my coverage not 100%?

      Because some of your history genuinely is not on the chain. A transfer in with nothing paid could be income, a gift, or your own unregistered wallet — and only you know which. Those land in the correction queue with the reason. Answering one keeps it answered.

      Where does the ETH rate come from?

      Out of the chain. WETH and USDG legs are matched across a shared pool — one contract taking one token and paying the other inside a single transaction — and the median of the matched swaps becomes the rate. Inside a five-second window they agree to 0.03% at the median, and within 0.1% nine times in ten. Where they disagree by more than 3%, those legs stay unpriced.

      Which cost-basis method should I use?

      That is your accountant's call and your jurisdiction's rule, not ours. What this shows is the consequence: on the worked example, the same sale produces a gain 970.76 USDG apart depending on the method. Eligibility varies by country and we will not quote a rule we cannot verify.

      How long does a full history take?

      About two minutes: 134 seconds, measured on a wallet with 45 transactions across its whole history. The longest stage is reading an ETH rate off the pools for each stretch of blocks the wallet traded in. Bound it with --recent=N to scan only the last N blocks, but a sale of anything bought before that window has no lot: it is marked UNMATCHED and holds the report open.

      What if my wallet is very active?

      There is a hard wall. The node refuses any query matching more than 10,000 logs, and below a 500-block window there is nowhere left to narrow to. Vrismcost stops and says which range defeated it — it does not truncate and hand you a shorter history that looks complete.

      What happens if I lose the passphrase?

      The recovery code opens the vault and rotates itself. Lose both and the contents are gone. That is the same property that means nobody else can read the file either — write the recovery code on paper.

      Is this tax advice?

      No. It computes figures from public chain data and records you supply. Rates, eligibility and treatment are yours to confirm against current regulation where you live, with someone qualified.

      Not tax, legal or financial advice · Figures are computed from public chain data and records you supply · Confirm treatment where you live