LP shares can be minted against an old mark for a loaned asset the vault no longer holds
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 15/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Área
- backend
Línea de trabajo
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.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Shell
- Estrellas
- 19
- Forks
- 7
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de dfinity/public-multidex
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 35/100
dfinity/public-multidex#96 ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
dfinity/public-multidex#95 ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
dfinity/public-multidex#94 ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 15/100
dfinity/public-multidex#93 ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 20/100
dfinity/public-multidex#92 ·
Todos los issues de dfinity/public-multidex
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 1 día
-
S3: friction & debt
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
MedakaLang/medaka#5010 ·
Los mantenedores suelen responder en 1 día
-
[BUG] apply-crs.sh reads wrong config.ini key ('namespace' instead of 'PH_NAMESPACE') and uses non-portable mktemp suffixPosiblemente ocupada @muskan-creates352 la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
openMF/mifos-gazelle#214 ·
-
status: ready
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
melodic-software/claude-code-plugins#14389 ·
Los mantenedores suelen responder en 1 día
-
area:ci good first issue priority:p2 type:test
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día