Skip to content

Release: develop -> main - #4458

Merged
TaprootFreak merged 1 commit into
mainfrom
develop
Jul 29, 2026
Merged

Release: develop -> main#4458
TaprootFreak merged 1 commit into
mainfrom
develop

Conversation

@github-actions

Copy link
Copy Markdown

Automatic Release PR

This PR was automatically created after changes were pushed to develop.

Commits: 1 new commit(s)

Checklist

  • Review all changes
  • Verify CI passes
  • Approve and merge when ready for production

…hrough the value history (#4451)

* fix(custody): carry the saving position and its interest through the value history

The Safe's value history dropped any holding whose asset had no asset_price row
for a given day, and left accrued interest out of both the history and the
balance total.

Ethereum/sZCHF was created long after the deposits it represents, so it has no
price series before its creation date. The daily valuation iterated over the
prices and looked up a balance for each, which meant a holding without a row
that day contributed nothing and vanished from the series without a trace. In
production a position booked in January only appeared in the chart six months
later, on the day its first price was written, as a vertical jump.

Valuation is now driven by the holdings instead, and an asset without a row of
its own is priced from an asset sharing its price rule -- identical by
definition, not an estimate. A holding that cannot be priced at all is reported
once per request rather than silently skipped.

Accrued interest is now part of both figures. It was previously excluded from
totalValue to keep it equal to the history, which had no notion of interest;
the history accrues it per day now, so both sides agree and the customer sees
what the position is actually worth.

* style: apply prettier formatting

* fix(custody): stop reporting interest for a closed saving position

Tranches accrue with their own sign, so a fully paid out position leaves a
frozen remainder -- the interest it earned while it was held. That figure is
never booked and never paid out. Carrying it into totalValue and the value
history, as this branch newly does, left a Safe holding nothing showing a
residue forever.

Interest is now only reported while the position is actually open, in both the
balance total and the history. Partial payouts are unaffected: the remaining
principal keeps accruing, which the existing negative-tranche test pins down.

Also replaces the exact zero-balance comparison in the daily valuation with a
tolerance. Balances are plain floating point sums, so a closed position rarely
lands on exact zero, and the dust left behind would be reported as an unpriced
holding on any day without a price.

* refactor(custody): hold the dust bound in one place

The closed-position guards compared against exact zero while the daily
valuation used a tolerance, so floating point residue could pass one and not
the other -- and reviving the interest of a position that is in fact closed is
exactly what the guard exists to prevent. All three now share one documented
bound.
@TaprootFreak
TaprootFreak merged commit ba4a78a into main Jul 29, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant