Repository navigation
Conversation
The treasury reports what a round did in external-out messages, and they carry what its messages do not: loan_result, take_borrower_fee and take_profit carry only a query id, so how a loan was repaid and split exists only in log::repayment. emit_log puts the topic in the destination, a 256-bit external address, and starts the body at round_since with no op-code, so abi read round_since as an op-code and reported a different one every round. ConvertMessage now decodes them by topic, and only when the treasury wrote them, so the trace view shows hipo_finance_log_repayment and its fields. Two of the logs changed layout with Hipo's 2026-09-05 release. The layout is chosen by when the log was written, because an old body can fit the new layout exactly: 8 of 542 real logs do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge started the new bubble's accounts and transactions from the head and then added the head again with the rest of the mapping, so they doubled each time a straw extended an action it had built before. A straw that folds one child per pass into an action doubled them once per child, and ran out of memory on a round that burns sixteen bills. They now start empty and the head is added once, after its builder, so an account a builder credits still lands. Accounts are only ever searched and transactions are sorted and compacted before use, so no action changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hipo's staking reads well since tonkeeper#939 and tonkeeper#971, but the loans it makes to validators, and the rounds they run in, showed as raw contract calls, and the three external messages that drive a round as nothing at all. This adds four generic action types, each with an implementation like DepositStake, so any lending pool could emit them: - LoanRequest: a validator asks the pool for a loan. - LoanIssue: the pool lends, and the loan contract stakes it. - LoanRepayment: the loan comes back and its reward is split between the stakers, the operator, the burner and the borrower; loan_result, take_borrower_fee and take_profit fold into it. - PoolRoundTransition: election, began, validated, ended, settled. vset_changed arrives twice, for the round that began and for the one before it, whose stakes are now held. The figures come from the treasury's logs. A loan's log is written one logical time after its proxy_new_stake, so BubbleTx now keeps its incoming message's lt and its sender's external-out messages. Each action is anchored on the treasury's own transaction or its own logs, because these ops are public and the actions name a borrower. The elector legs stay ElectionsDepositStake and ElectionsRecoverStake, and the staker-facing actions are unchanged: over 1,327 real traces the value flows match master, and traces without a loan or round action are identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
send_unstake_all, or the text comment "w" that wallets without custom payloads send, asks the treasury to unstake a whole balance. It showed as a bare transfer followed by proxy_unstake_all and unstake_all as contract calls. It is now a WithdrawStakeRequest with no amount, which the API already shows as ALL; the burn and the payout below it stay their own actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The burner that receives the borrower fee (take_borrower_fee) logs each step the same way, with topics of its own: what it received, staked, swapped and burned. Its logs appear in every round-end trace and showed as op-code 0x00000000. They are decoded only when the burner wrote them. A log whose body starts with 32 zero bits is kept as text in Message.Body, so the logs are decoded from the body cell. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- loan and round actions record the transfers they fold in, so extra no longer reports a repayment's stake, fees and profit or a round's recover/burn/mint legs as unexplained - a refused loan request counts its bounced refund - parse the repayment log in the check, so an unfit log does not match instead of reporting an error to sentry - skip loans and repayments whose log names no borrower - name a settled round by the last repayment log when last_bill_burned is missing, and leave a round of unknown start undescribed - reuse the log ConvertMessage decoded, and only serialize ext-out bodies of the treasury and the burner - add en/ru translations for the loan and round actions - drop function-level comments and order declarations Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hipo's staking now reads well on tonviewer (#939, #971). Its other half, the loans it makes to validators and the validation rounds they run in, still shows as raw contract calls, and the three external messages that drive a round show as "Something happened but we don't understand what". A round-end trace is up to a hundred transactions, most of them
SmartContractExecrows.This adds four generic action types, each with
implementation: PoolImplementationTypelikeDepositStake, so any lending pool could emit them:LoanRequestmin_payment, GRAM attachedLoanIssuemin_paymentLoanRepaymentPoolRoundTransitionelection,began,validated,ended,settledsettledalso has the round's total staked and recoveredWhat stays as it was: the elector legs stay
ElectionsDepositStakeandElectionsRecoverStake, and every staker-facing action (DepositStake,WithdrawStake,WithdrawStakeRequest,JettonMint,JettonBurn) is unchanged. The new straws only fold in the loan and round legs around them. One staking addition: an unstake-all request (send_unstake_all, or the commentw) is now aWithdrawStakeRequestwith no amount, rather than a bare transfer and two contract calls.Where the figures come from. The treasury's messages do not carry them:
loan_result,take_borrower_feeandtake_profitcarry only a query id. They are in external-out logs, whose topic is the 256-bit external destination and whose body has no op-code, soabireads the round number as an op-code (a different one every round).pkg/core/hipo_logs.goreads them by topic, andConvertMessagenow decodes them, only when the treasury wrote them, so the trace view showshipo_finance_log_repaymentand its fields instead of a bogus op-code. The burner that receives the borrower fee logs the same way and is decoded too. Two treasury logs changed layout on 2026-09-05; the layout is chosen by when the log was written, since some old bodies also fit the new layout exactly. A logloanis paired with itsproxy_new_stakeby logical time, since it is written right after it; for that,BubbleTxnow keeps its incoming message's lt and its sender's external-out messages.Anchoring. Each new action names a borrower and amounts, so each is anchored on something only the treasury produces: a log is read only from the treasury's own transaction, a loan only from a message the treasury sent, and a round only from the treasury's own transactions.
TestHipoLoanStrawsRejectForgeriescovers the shapes an impostor could build.One generic fix.
Straw.Mergeadded the head bubble's accounts and transactions twice, so a straw that folds one child per pass into an action it built before doubled them each pass, and ran out of memory on a round that burns sixteen bills. They are now added once; accounts are only searched and transactions are compacted before use, so no other output changes.Checked against mainnet. 1,327 real traces (every loan and round trace on the treasury since June, and the earlier staking corpus) were replayed through
bathon this branch and on master and diffed: value flows are identical in every trace, the 421 traces without a new action are byte-identical, and the staker-facing action counts are unchanged. What changed is that the loan and round contract calls and transfers became the actions above. Every treasury and burner log in them (1,206) decodes. New goldens:hipo-loan-request,hipo-round-election,hipo-round-began,hipo-round-validated,hipo-round-end.The message flows and the anchoring rules are documented at https://github.com/HipoFinance/contract/blob/main/docs/integration.md#explorer-actions. Happy to rename the types or narrow them if you would rather shape them differently.
🤖 Generated with Claude Code