---
# System prepended metadata

title: コントラクトに預けていた資産のexit

---

# コントラクトに預けていた資産のexit

## 前提
1. 何とかして債券トークンの残高をuserStateに入れておく
2. なるべく汎用性の高い仕組みにしたいので、システム独自の機能にしない
3. なるべくシンプルに
4. 1コントラクト１債券 => 債券を持っている人でそのコントラクトに入ってる資産を山分け

## 提案手法の概要
- コントラクトに資産を預けるときは必ず債券を発行する
- 債券を持っていればフリーズモード時にコントラクトに入っていた資産を債券の持ち分に応じて山分けしExitする
- 債券も資産とみなし、コントラクトに債券を持っていた場合は再帰的にExitする


## 処理フロー

```mermaid

sequenceDiagram

actor U as User
actor A as Asset Manager
participant CA as L2 Vault ContractA
participant CB as L2 Vault ContractB
participant L1 as L1 Exit Contract

autonumber
U ->> CA : deposit assets
CA ->> U : transfer bond1
A ->> CA : request investment
CA ->> CB : deposit assets
CB ->> CA : transfer bond2
Note right of CA: freeze mode
U ->> L1 : claim assets with ZkProof
L1 ->> U : transfer assets
```

## 具体的な処理

$$ zkProve((exitAssetAddress, merkleRoot, amount), (assetProofs, )) \to zkProof_{verifyRecursiveAssets}$$


**回路インタフェース**
| name             | type    | visibility | remarks                                      |
| ---------------- | ------- | ---------- | -------------------------------------------- |
| exitAssetAddress | address | public     | exitしたいL1のERC20のアドレス                |
| merkleRoot       | bytes32 | public     | freezeしたタイミングで最新のverifyされたroot |
| amount           | uint256 | public     | exitする資産の量                             |
| assetProofs                 |   assetProof[]      |  private          | exitしたい資産までの債券の証拠                                             |

**assetProofインタフェース**

| name            | type    | visibility | remarks                        |
| --------------- | ------- | ---------- | ------------------------------ |
| assetAddress | address | private    | L2のERC20のアドレス            |
| bondAddress      | address | private    | このコントラクトにある債券のアドレス                       |
| assetAmount      | uint256 | private    | 返却されるべき資産の量                       |
| bondAmount      | uint256 | private    | このコントラクトにある債券の量                       |
| totalBondSupply                | uint256        | private            | その債券の全部の量                               |
| assetMerkleProof     | bytes   | private    | そのコントラクトの資産量を証明するMerkle Proof |
| bondMerkleProof     | bytes   | private    | そのコントラクトの債券の量を証明するMerkle Proof |



## セキュリティ

exit対象の資産が $exitableBalance = contractBalance * userBondBalance / totalBondSupply$ になっていれば、資産が盗まれることはない。

## 利点
- かなりシンプル

## 課題など

- コントラクトが複数の債券を発行したり、複数の債券を持ったりしていると厳しい
  - ValutコントラクトにDAIとETHを預けれるとする
  - 運用中にDAIとETHで別のトークン($DOGE)をValutコントラクトが買った
  - その時にフリーズになってしまった
  - 債券を持ってる人で$DOGEを分けたいけど、債券2つの価値がわからない


