# Exitに関するテスト設計
###### tags: `テスト設計`
## Exit ZKP Proof
```javascript=
describe("Exit ZKP Proof", () => {
// normalとfreezeで使う回路が変わる
describe("normal mode", () => {
// User State Rootと Merkle Proofから
// 自分の持っている資産の量を証明できる
it("should prove user's assets", () => {});
// User State Rootと Merkle Proofから
// 自分の持っている資産の量がUint256のMaxだとしても証明できる
it("should prove user's max balance", () => {});
// User State Rootと Merkle Proofから
// 自分の持っている資産の種類が100種類あったとしても、ある資産の量を証明できる
it("should prove user's multi assets", () => {});
// User State Rootと Merkle Proofから
// 自分の持っている資産以上の量を証明しようとするとProveに失敗する
it("should not prove more than user's assets", () => {});
});
describe("freeze mode", () => {
// User State Rootと Merkle Proofから
// 自分の持っている資産の量を証明できる
it("should prove user's assets", () => {});
// User State Rootと Merkle Proofから
// 自分の持っている資産の量がUint256のMaxだとしても証明できる
it("should prove user's max balance", () => {});
// User State Rootと Merkle Proofから
// 自分の持っている資産の種類が100種類あったとしても、ある資産の量を証明できる
it("should prove user's multi assets", () => {});
// User State Rootと Merkle Proofから
// 自分の持っている資産以上の量を証明しようとするとProveに失敗する
it("should not prove more than user's assets", () => {});
// zkp内でonetime address listの
// SMTを利用してnon inclusion proveできる
it("should prove non iclusion onetime address list", () => {});
// zkp内でonetime address listの
// SMTを利用してnon inclusion proveできる
it("should prove non iclusion onetime address list", () => {});
// zkp内でonetime address listが1兆レコードあったとしても
// SMTを利用してnon inclusion proveできる
it("should prove non iclusion onetime address list", () => {});
// recursive proveでき、どちらかが不正だとこける
it("should fail recursive. OK: balance, NG: onetime address list", () => {});
it("should fail recursive. NG: balance, OK: onetime address list", () => {});
// 両方OKだったら通る
it("should success recursive. OK: balance, OK: onetime address list", () => {});
});
})
```
## Exitコントラクト
```javascript=
describe("L1 Exit contract", () => {
describe("normal mode", () => {
// state diffの解決をしてないとexitできない。
it("should not exit without updating with state diff", () => {});
// state diffの解決をしているのでexitできる。
it("should exit without updating with state diff", () => {});
// 同じProofで同じassetを2度exitできない
it("should not exit with same proofs", () => {});
// 別のProofで同じassetを2度exitできる
it("should not exit with same proofs", () => {});
// normal mode中は自力exitはできない
it("should not exit by self in normal mode", () => {});
// L1産ERC20をexitできる
it("should exit L1 native ERC20", () => {});
// L1産ERC721をexitできる
it("should exit L1 native ERC721", () => {});
// L2産ERC20をexitできる
it("should exit L2 native ERC20", () => {});
// L2産ERC721をexitできる
it("should exit L2 native ERC721", () => {});
});
describe("onetime address list", () => {
// onetime address listをcalldataに載せれる
it("should upload onetime address list to calldata", () => {});
// calldataからonetime address listを復元し、SMTを構築できる
it("should create SMT with calldata", () => {});
});
describe("freeze mode", () => {
// 最後のコミットからN時間が経過したので、freeze modeに入れれる
it("should change mode to freeze", () => {});
// recursive proofのverifyが通ってexitできる
it("should exit with recursive proof", () => {});
// SMT: OK, balance: NGの時にexitできない
it("should not exit with invalid balance proof", () => {});
// SMT: NG, balance: OKの時にexitできない
it("should not exit with invalid SMT proof", () => {});
// 適当なProofでexitができない
it("should not exit with random proof", () => {});
// 同じProofでexitできない
it("should not exit with same proof", () => {});
// 1回exitしても、また別のProofを作ればexitできる
it("should exit with other proof after exiting", () => {});
// L1産ERC20をexitできる
it("should exit L1 native ERC20", () => {});
// L1産ERC721をexitできる
it("should exit L1 native ERC721", () => {});
// L2産ERC20をexitできる
it("should exit L2 native ERC20", () => {});
// L2産ERC721をexitできる
it("should exit L2 native ERC721", () => {});
});
});
```