LP shares can be minted against an old mark for a loaned asset the vault no longer holds
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 15/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 領域
- backend
調査の方向性
Start in src/backend/main.mo by comparing vaultLentOutUsd, which values outstanding base-token loans, with vaultHeldLegMarkIssue and stagedLpMarkets, which only check assets whose vault balance is positive. Also read vaultAssetBalance, the wait-list test. Done means an LP deposit or staged release holds for a fresh mark on any loan token that contributes to vault value, even when the physical balance is zero. Reproducing the zero-ETH loan state needs the signed replay in the issue, so this is not a quick first change.
索引モデルが issue の本文から書いたものです。
説明
An LP deposit can settle during a pending price jump for an asset that is still owed to the vault but absent from its wallet. The loan's price contributes to vault net asset value, yet the deposit's mark gate and wait list check only assets the vault physically holds. The new LP can receive too many shares before the loan's mark updates.
At commit a225a74, vaultLentOutUsd marks every outstanding base-token loan into vault value. vaultHeldLegMarkIssue checks pending and stale marks only when the vault balance for that asset is positive (main.mo:19992-20038). stagedLpMarkets uses the same held-balance test when it decides which fresh quotes a deposit must wait for (main.mo:21739-21781).
The vault values a loan with the token's mark:
if (owed > 0) { sum += Fixed.mul(owed, poolRefPrice(marketId), false) };
The staged request's wait list uses physical holdings instead:
if (vaultAssetBalance(vv, asset) > 0) { List.add(out, market) };
Reproduce on an isolated development canister
Use signed accounts for LPs, a margin trader, a maker, and a swapper. Controller hooks seed simulated balances, set test oracle marks, and pause timers. Trading, LP, and loan repayment calls are signed. The important starting state is zero ETH in the vault with an outstanding ETH loan; the following signed sequence reaches it without editing the vault balance.
- An LP deposits 10 BTC, 50 ETH, and 1,200,000 ICPUSD. Set BTC at $50,000 and ETH at $3,000. A maker rests a bid for 11.56249999 ETH at $2,995. A margin pool funded with 100,000 ICPUSD stages a short of that amount. Another user stages a 125,000 ICPUSD-to-ETH swap.
- Refresh ETH at $3,000 and requote. The short borrows and sells 11.56249999 ETH to the maker. The swap takes the remaining 38.43750001 ETH from the AMM asks posted before that borrow. The vault now holds 0 ETH and still owns the 11.56249999 ETH loan.
- From that state, stage an LP deposit of 2,000 SOL at $100 while a move from $3,000 to $6,000 ETH is pending confirmation. Refresh the markets in the request's wait list, BTC and SOL. The deposit settles before ETH confirms. Then confirm ETH at $6,000, repay the ETH loan, and redeem the new LP's shares.
- For the control, restore the same zero-ETH state. Confirm ETH at $6,000 before the 2,000 SOL deposit, then repay the loan and redeem the shares in the same way.
| Result | Deposit before ETH confirmation | Deposit after ETH confirmation |
|---|---|---|
| LP shares minted | 199,844.83416425 | 196,169.50670037 |
| Claim after ETH confirmation, before loan close | $203,381.77849274 | $200,000.00187202 |
| Final wallet after loan repayment and LP exit | $402,573.30459796 | $399,204.97071741 |
The depositor began each branch with assets worth $400,000 at the final marks. The early-deposit branch produced $2,573.30459796 net gain after the 40 bp LP exit fee, fees, and interest. The control lost $795.02928259. The initial share-pricing error gave the depositor about $3,381.78 in extra claim after ETH confirmation. The $3,368.33388055 final wallet difference also includes small timing and trade-path differences. At 5% and 10% ETH moves, the share over-allocation was smaller than the immediate exit fee; the demonstrated profitable full exit used the 100% move.
Please include every outstanding loan token whose mark contributes to vault value in the LP deposit, withdrawal, and staged-release mark checks. A pending or stale loan mark should hold settlement until a fresh mark arrives, even if the vault's physical balance of that token is zero. Rechecking the AMM inventory floor after borrowing would block this zero-balance route, but the LP mark gate also needs the loan dependency.
This replay used a local #dev build with simulated balances. It did not send a transaction to a public deployment. The public canisters checked on 2026-11-03 reported #play mode and a module hash different from the local build. The replay establishes the checked source path, not live real-asset exposure.
- 主要言語
- Shell
- スター
- 19
- フォーク
- 7
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
dfinity/public-multidex のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 35/100
dfinity/public-multidex#96 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 45/100
dfinity/public-multidex#95 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 35/100
dfinity/public-multidex#94 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 15/100
dfinity/public-multidex#93 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 20/100
dfinity/public-multidex#92 ·
dfinity/public-multidex の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
S3: friction & debt
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
MedakaLang/medaka#5010 ·
メンテナーはふだん 1 日以内に返信
-
[BUG] apply-crs.sh reads wrong config.ini key ('namespace' instead of 'PH_NAMESPACE') and uses non-portable mktemp suffix対応中かも @muskan-creates352 が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
openMF/mifos-gazelle#214 ·
-
status: ready
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
melodic-software/claude-code-plugins#14389 ·
メンテナーはふだん 1 日以内に返信
-
area:ci good first issue priority:p2 type:test
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信