Repository navigation
Lending example with Oracle challenge window - #22
Draft
stringhandler wants to merge 9 commits into
Draft
stringhandler wants to merge 9 commits into
stringhandler wants to merge 9 commits into
Conversation
The node rejects a program that may cost more than its witness's size buys, with "Program's execution cost could exceed budget". run still built, signed and even exported such a transaction. Finalizing a covenant input on Elements now checks the budget, and says how many bytes short the witness is. Liquid doesn't relay the annex that would pad it (bad-witness-nonstandard), so the error says to pad with a witness the program reads.
An explicit wallet UTXO, such as a payout a covenant made with confidential: false, reaches the builder as a covenant input, and the builder counted only the L-BTC of covenant inputs toward balance and change. Spending explicit tUSDT therefore built a transaction with no tUSDT change and no error, which the node refused: bad-txns-in-ne-out. Every input's amount now counts toward its asset's balance, so the surplus becomes change where the manifest permits it and an error where it doesn't.
An action's lock_time, {"height": <expr>} or {"time": <expr>}, sets the
transaction's nLockTime, which the check_lock_height and check_lock_time jets
read. Until now it was always zero, so a covenant could only demand a lock
time the wallet could never set.
A height must be below 500,000,000 and a time at least that, since consensus
tells them apart by size. A lock time is ignored when every input is final, so
each input that asks for no sequence gets 0xfffffffe, on both chains.
An example can ship a second manifest in a subdirectory, since run writes its state files beside each manifest. The parse, validate, schema, UI-coverage and CLI checks now cover those too.
Burns testnet L-BTC for a new tUSDT asset at the price in a signed oracle statement. Simplicity can't tell whether a statement is current, so a mint takes two steps: a request opens a 5-block window in which anyone holding a newer statement whose price differs by more than 0.5% can cancel it, and after which anyone can finalize it. Statements use Mycelia Signal's canonical format and ECDSA scheme, signed by a local test key (fake_oracle.py), and the covenant verifies and parses them itself. issue_usdt/ issues the asset. Both paths ran on Liquid testnet; the README lists the transactions.
The service no longer fixes an oracle key. It fixes a cold key, which signs BIP340 certificates saying an oracle key may sign statements timestamped within a range; each statement is presented with its key's certificate, and the covenant checks both signatures and the range. A new or rotated oracle needs a new certificate rather than a redeploy, and the cold key can be a MuSig2 or FROST committee without changing the program. fake_oracle.py gains cold-keygen, certify and verify-cert, with a BIP340 signer after the BIP's reference code, and the tests check its certificates against the program's own BIP340 check. Every address changes, so the README's testnet run is gone until the next one.
A certificate's range alone doesn't stop a leaked oracle key: it could date a request at the end of the range, weeks ahead, where no honest statement is newer and nothing can challenge it before it finalizes. A request now sets a lock time of timestamp - MAX_FUTURE_SECONDS, which the covenant checks with check_lock_time. Consensus only mines it once the chain's median time is past that, so a statement can be dated at most MAX_FUTURE_SECONDS (default 300) ahead of the chain. On Liquid, whose median time lags about 5 minutes, an honest request is usable within a minute. Ran on Liquid testnet: an honest mint, a stale price challenged, a second oracle certified after deployment challenging the first's request, and a statement dated an hour ahead refused by the node as non-final.
lending_v3 liquidates only on expiry. Before then, the lender can now start a liquidation with a certified oracle statement at which the debt is more than LIQUIDATION_LTV_BPS (default 80%) of the collateral's value. The loan moves to a pending state recording the claim. Anyone with a newer statement at which it isn't liquidatable can cancel it back to active; after WINDOW_BLOCKS the lender burns the lender NFT and takes the collateral. The borrower can repay in full while it is pending. The new paths sit behind a separate LIQUIDATION witness, so lending_v3's PATH values and the offer and active addresses' derivation are unchanged. The statement, certificate and lock-time checks are oracle_demo's. Ran on Liquid testnet: a liquidation started at 60000.00 and cancelled at 84231.50, then one started at 59000.00 and finished after the window.
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.
No description provided.