# Testing

Testing work load can be unlimited if we don't think carefully about that. This is why we create this testing documentation, so we can communicate through different teams. People from different backgrounds can review and give us feed back. It also give the users the confidence about our code quality.

The document list the high level of testing ideas, sometime written in form of pseudo code. It is structured by components in our smartcontracts. Each item is numbered so we can easily indentify the case when we communicate. Each paragraph's title will match exactly the test name in our source code.

## 1. MathLibrary

Math library implement all math operations, from fundamental as simple division or multiplication to the sophisticated fee calculations, discount factor calculation ..etc. We implement all calculations in this library so all other smart contracts are not exposed to math security issues, they just used the formulas, functions implemented in this library.

#### 1.1. multiply

multiply implement a simple arithmetic math operation $A*B$

###### 1.1.1. multiply overflow

We find a max number MM, and we test

• $MM*1$ = $1*MM$
• $(MM+1)*1$ and $1*(MM+1)$ should overflow
• test $[\sqrt{MM}-1]*[\sqrt{MM}-1]$ should not overflow and give exact result
• find two numbers $A$, $B$ so that $A*B == B*A == MM$. Then $(A+1)*B$ and $A*(B+1)$ should overflow. Hint $A$ and $B$ should be close to $[\sqrt{MM}-1]$
###### 1.1.2. multiply zero

For a random number, multiply with zero should return zero

###### 1.1.3. multiply commutativity

Generate two random numbers $A$,$B \leq (\sqrt{MM}-1)$, and test $A*B==B*A$, and should return exact result

#### 1.2. divide

divide implement a simple arithmetic math operation $A/B$

###### 1.2.1. divide zero

Divide by zero should throw error

###### 1.2.2. max divisor

We find a max number MD, and we test

• $1/MD$ return decent result
• $1/(MD+1)$ should throw an error

If $MD=MAXUINT256-1$, then it's perfect

###### 1.2.3. divide very small number

We find a max number MD, and we test

• $\frac{1}{\frac{1}{MD}}$ return result ok
• $\frac{1}{\frac{1}{MD+1}}$ should throw error or overflow
###### 1.2.4. perfect division

For the normal cases, with numbers are all in bound with previous test, generate random numbers $A$, $B$ and $C=A*B$

• test $C/A=B$ and $C/B=A$
###### 1.2.5. divide precision lost

As we expect our math operations are good for all numbers within the range uint128. Given $A=MAXUINT128-1$

• calculate $R=A*(1/A)$ and compare relative error, i.e $abs(R-A)/A$. Hard code some epsilon and make sure the relative error is less then this value
• do the same thing for MAXUINT96, MAXUINT64, MAXUINT32, to get the idea how the error behaves
###### 1.2.6. divide precision lost (randomized)

Again this test is similar to the previous one, but randomized. Test for all configurations MAXUINT128, MAXUINT96, MAXUINT64, MAXUINT32

Example for a single case MAXUINT128 :

• Generate two random numbers $A$, $B$, within the range $[1,MAXUINT128-1]$
• calculate $R=B*(A/B)$ and compare relative error, i.e $abs(R-A)/A$. The relative error should be lower or equal to the hardcoded error found previously when we consider divide 1

Note : we don't need to do many random iteration, just one time randomized is enough. But make sure to print out the inputs and result, reason test failed, when there are errors, so we can reproduce and debug. Think about what informations we need to reproduce the failed test.

#### 1.3. portion

###### 1.3.1. portion is invalid

We test if portion is invalid in case of portion result greater than or equal 1.

###### 1.3.2. portion is valid

We test if portion is valid in case of portion result less than 1.

###### 1.3.3. portion and total amoun are very large numbers

We test if there are overflow in case of multiplication large number.

#### 1.4. earlyFeeRate

###### 1.4.1. day is invalid

We test if day of fee rate is invalid in case day greater than or equal 42.

###### 1.4.2. day is valid

We test if day of fee rate is invalid.

###### 1.4.3. day equal 42

We test if there are abnormal cases in case of day equal 42.

#### 1.5. discountValueIncludingFeeDelta

\textbf{delta} = \frac{s_i}{\textbf{P}_{t_i}}
###### 1.5.1. s is very large number and P is very small number

We test if there are overflow in case of s divide P.

###### 1.5.2. s is very small number and P is very large number

We test if there are overflow in case of s divide P.

###### 1.5.3. P is zero

We test if there are cases of P is zero, should catch error Division by zero.

#### 1.6. discountValueExcludingFeeDelta

###### 1.6.1. amount, productOfInterestRate, feeRate are very large numbers

We test if there are overflow in case of amount, productOfInterestRate, feeRate are very large numbers.

## 2. AuctionManager

#### 2.1. constructor

We test if Auction Manager deployed, then deployed Cash Token address is registered to Auction Manager.

We test if Auction Manager deployed, then deployed Token420 address is registered to Auction Manager.

We test if Auction Manager deployed, then deployed Treasury Manager address is registered to Auction Manager.

###### 2.1.4. Register Auction Manager in Treasury

We test if Auction Manager deployed, then Auction Manager address has registered to Treasury.

#### 2.2. registerDaoManager

###### 2.2.1. DAO Manager has been registered

We test if DAO Manager has been registered, then throw error DaoManager has been registered.

###### 2.2.2. DAO Manager has not registered yet

We test if DAO Manager still be ZERO address, then can register.

#### 2.3. deposit

###### 2.3.1. deposit CASH move from user account to Auction Manager

We test if user deposit CASH, then cash transfer from user account to Auction Manager.

###### 2.3.2. deposit amount zero causes revert

We test if user deposit 0, then the transaction will be reverted.

#### 2.4. withdraw

###### 2.4.1. single user withdraw maximum token emission when deposit of previous auction is equal to softFloorDeposit

We test if user deposit of previous auction is equal to softFloorDeposit, then user can withdraw maximum token emission.

###### 2.4.2. single user withdraw maximum token emission when deposit of previous auction is more than softFloorDeposit

We test if user deposit of previous auction is more than softFloorDeposit, then user can withdraw maximum token emission.

###### 2.4.3. single user withdraw less than maximum token emission when deposit of previous auction is less than softFloorDeposit

We test if user deposit of previous auction is less than softFloorDeposit, then user can withdraw less than maximum token emission.

###### 2.4.4. single user withdraw in extreme case when they deposit 1 (10^(-18))

We test if user deposit of previous auction is equal to 1 (10^{-18)}), then user can withdraw token.

###### 2.4.5. Should throw error No token to withdraw when user did not deposit

We test if user did not deposit of previous auction, then throw the error when user withdraw token.

#### 2.5. withdrawableTokenAmountOf

###### 2.5.1. correct withdrawable token amount after auction inflation

We test if the withdrawable token amount is updated correctly after daily inflation of auction.

###### 2.5.2. correct withdrawable token amount after deposit

We test if the withdrawable token amount is updated correctly after the user deposits.

###### 2.5.3. correct withdrawable token amount after token withdrawal

We test if the withdrawable token amount is updated correctly after the user withdraws.

###### 2.5.4. correct withdrawable token amount after deposit and withdrawal in a same auction

We test if the withdrawable token amount is updated correctly after the user deposits and withdraws in a same auction.

#### 2.6. initializeSoftFloorPrice

###### 2.6.1. Only Dao Manager can be called

We test if caller is not Dao Manager, then throw error Permission: Unauthorized.

###### 2.6.2. Init soft floor price successfully

We test if caller is Dao Manager can call initializeSoftFloorPrice successfully

## 3. DaoManager

#### 3.1. construction

We test if DaoManager deployed, then deployed Token420 address is registered to Dao Manager.

We test if DaoManager deployed, then deployed Auction Manager address is registered to Dao Manager.

We test if DaoManager deployed, then deployed Mirror Pool address is registered to Dao Manager.

We test if DaoManager deployed, then deployed Staking Pool address is registered to Dao Manager.

We test if DaoManager deployed, then deployed Treasury Manager address is registered to Dao Manager.

###### 3.1.6. register Dao Manager address

We test if DaoManager deployed, then DAO register DAO Manager address to Token420, Auction Manager, Mirror Pool, Staking Pool and Treasury Manager successfully.

###### 3.1.7. Initial migration status

We test if DaoManager deployed, the DAO's status of isGoingToMigrate, isBlockedForMigration and emissionTerminated are false.

###### 3.1.8. Initial auction day

We test if DaoManager deployed, the DAO's first day count should be 1.

###### 3.1.9. Admin is deployer account

We test if DaoManager deployed, the DAO's admin is the one who deploy.

###### 3.1.10. Initial auction information

We test if DaoManager deployed, AuctionManager is updated with correct softFloorPrice and maximumEmission.

We test if DaoManager deployed: - Whitelist address is ZERO address. - lastTriggerNextAuction is equal deployed timestamp.

We test if DaoManager deployed: - Whitelist address is NOT ZERO address. - lastTriggerNextAuction is equal Whitelist expiration D2 timestamp.

#### 3.2. burn

###### 3.2.1. Caller is not Treasury Manager

We test if caller is not Treasury Manager, then throw error.

###### 3.2.2. Treasury Manager burn exceed amount

We test if Treasury Manager burn exceed amount, then throw error.

###### 3.2.3. Treasury Manager can burn

We test if Treasury Manager burn with valid amount, then these token will be destroyed.

#### 3.3. nextAuction

###### 3.3.1. Caller nextAuction success

We test if caller is not Dao Admin, then - Auction ID will be added 1.

###### 3.3.2. auction current total deposit greater than 0

We test if auction current total deposit greater than 0, then

• Token balance of Auction Manager and Mirror Pool will be added 100,000 token.
• Auction ID will be added 1.
###### 3.3.3. auction current total deposit equal 0

We test if auction current total deposit equal 0, then

• Token balance of Auction Manager and Mirror Pool will not added 100,000 token.
• Auction ID will be added 1.
###### 3.3.4. staking pool is empty

We test if staking pool is empty, then productOfInterestRate of Staking Pool will be reset to 1.

###### 3.3.5. staking pool is not empty and token total supply is not less than current auctionEmission

We test if staking pool is not empty and token total supply is not less than current auctionEmission, then token balance of Staking Pool will added 220,000 token reward.

###### 3.3.6. Staking pool is not empty and token total supply is less than current auctionEmission

We test if staking pool is not empty and token total supply is less than current auctionEmission, then token balance of Staking Pool will be added exactly token reward amount equal current token total supply.

###### 3.3.7. next day is less than or equal staking fee convergent day

We test if next day is less than or equal staking fee convergent day, then Staking fee rate will be updated incrementally.

###### 3.3.8. next day is greater than staking fee convergent day

We test if next day is greater than staking fee convergent day, then Staking fee rate will be set to base fee rate.

###### 3.3.9. Invalid trigger nextAuction without whitelist on test net

We test after deploying DAO Manager to test net with Auction duration is 1 hour = 3600 second. We test:

• Dao Manager trigger nextAuction well.
• Skip EVM timestamp with minimum skip time = 3599 second, Dao Manager trigger nextAuction well.
• Skip EVM timestamp with skip time = minimum skip time - 1 = 3598 second, Dao Manager trigger nextAuction failed.
###### 3.3.10. Invalid trigger nextAuction without whitelist on main net

We test after deploying DAO Manager to main net with Auction duration is 23 hour 50 minutes = 85800 second. We test:

• Dao Manager trigger nextAuction well.
• Skip EVM timestamp with minimum skip time = 85799 second, Dao Manager trigger nextAuction well.
• Skip EVM timestamp with skip time = minimum skip time - 1 = 85798 second, Dao Manager trigger nextAuction failed.
###### 3.3.11. Invalid trigger nextAuction with whitelist before whitelist finish

We test after deploying DAO Manager to main net with Auction duration is 23 hour 50 minutes = 85800 second. We test: - Dao Manager trigger nextAuction failed after deploying. - Skip EVM timestamp to Whitelist expiration timestamp - 1, Dao Manager trigger nextAuction failed. - Then, Dao Manager trigger nextAuction well.

#### 3.4. prepareForMigration

###### 3.4.1. migration and emissionTerminated status

After calling prepareForMigration, the system should be at the prepare-to-migrate state. When a nextAuction is called, then the system is totally freezed

###### 3.5.1. Caller is not DAO admin

We test if caller is not Admin then throw error Unauthorized.

We test if calls transferAdministration with account that equal zero-address or current admin address then throw error Invalid admin address.

We test if caller transferAdministration with account that is different from zero-address or current admin address, admin will be assigned correctly.

## 4. CashTestToken

#### 4.1. construction

###### 4.1.1. total supply 200M stable cash coin

We test if Cash Token deployed, total supply of stable Cash coin is 200M.

###### 4.1.2. balance 100M for each test account

We test if Cash token admin pregenerate tokens and distributes to testing accounts at construct time, then cash balance of each account equal 100,000,000.

###### 4.1.3. Cash decimals

We test if Cash token admin pregenerate tokens and distributes to testing accounts at construct time, then cash decimals is 6.

#### 4.2. deployment

###### 4.2.1. Treasury Manager hold Cash Token

We test if TreasuryManager deployed, then deployed Cash Token address is registered to Treasury Manager.

###### 4.2.2. Auction Manager hold Cash Token

We test if Auction Manager deployed, then deployed Cash Token address is registered to Auction Manager.

## 5. MirrorPool

#### 5.1. construction

We test if Mirror Pool deployed, then deployed Token420 address is registered to Mirror Pool.

#### 5.2. registerDaoManager

###### 5.2.1. DAO Manager has been registered

We test if DAO Manager has been registered, then throw error DaoManager has been registered.

###### 5.2.2. DAO Manager has not registered yet

We test if DAO Manager still be ZERO address, then can register.

#### 5.3. fetchToken

###### 5.3.1. Caller is not DAO Manager

We test if caller is not DAO Manager then throw error.

###### 5.3.2. Dao Manager can fetch token and split the token pie

We test if Dao Manager can fetch token that minted by DAO manager and the fetched token amount accordingly to the defined percentages

#### 5.4. assignDevMktShareOwner

###### 5.4.1. owner is deployer before any assignment

We test if the devMktShareOwner is zero-address before any assignDevMktShareOwner transaction is executed.

###### 5.4.2. assign successfully an ordinary address

We test if dao calls assignDevMktShareOwner the first time with an address different from zero-address, devMktShareOwner will be assigned correctly.

###### 5.4.3. re-assign successfully an ordinary address

We test if dao calls assignDevMktShareOwner with an address different from zero-address when the owner has already been assigned, devMktShareOwner will be assigned correctly.

We test if dao calls assignDevMktShareOwner with zero-address will cause revert.

###### 5.4.5. assign unsuccessfully from sender different from admin

We test if an address different from admin calls assignDevMktShareOwner will cause revert

#### 5.5. withdrawDevMktShare

###### 5.5.1. withdraw unsuccessfully from sender different from the owner

We test if an address different from devMktShareOwner calls withdrawDevMktShare will cause revert.

###### 5.5.2. withdraw unsuccessfully amount exceeding the share

We test if devMktShareOwner calls withdrawDevMktShare with the amount exceeding devMktShare will cause revert.

###### 5.5.3. withdraw successfully

We test if devMktShareOwner calls withdrawDevMktShare with a valid amount, devMktShare will decrease correctly and cash balance of devMktShareOwner will increase correctly.

#### 5.6. refundDevMktShare

###### 5.6.1. refund unsuccessfully from sender different from the owner

We test if an address different from devMktShareOwner calls refundDevMktShare will cause revert.

###### 5.6.2. refund successfully

We test if devMktShareOwner calls refundDevMktShare, devMktShare will increase correctly and cash balance of devMktShareOwner will increase correctly.

#### 5.7. assignEarlySupShareOwner

###### 5.7.1. owner is deployer before any assignment

We test if the earlySupShareOwner is zero-address before any assignEarlySupShareOwner transaction is executed.

###### 5.7.2. assign successfully an ordinary address

We test if dao calls assignEarlySupShareOwner the first time with an address different from zero-address, earlySupShareOwner will be assigned correctly.

###### 5.7.3. re-assign successfully an ordinary address

We test if dao calls assignEarlySupShareOwner with an address different from zero-address when the owner has already been assigned, earlySupShareOwner will be assigned correctly.

We test if dao calls assignEarlySupShareOwner with zero-address will cause revert.

###### 5.7.5. assign unsuccessfully from sender different from admin

We test if an address different from admin calls assignEarlySupShareOwner will cause revert

#### 5.8. withdrawEarlySupShare

###### 5.8.1. withdraw unsuccessfully from sender different from the owner

We test if an address different from earlySupShareOwner calls withdrawEarlySupShare will cause revert.

###### 5.8.2. withdraw unsuccessfully amount exceeding the share

We test if earlySupShareOwner calls withdrawEarlySupShare with the amount exceeding earlySupShare will cause revert.

###### 5.8.3. withdraw successfully

We test if earlySupShareOwner calls withdrawEarlySupShare with a valid amount, earlySupShare will decrease correctly and cash balance of earlySupShareOwner will increase correctly.

#### 5.9. refundEarlySupShare

###### 5.9.1. refund unsuccessfully from sender different from the owner

We test if an address different from earlySupShareOwner calls refundEarlySupShare will cause revert.

###### 5.9.2. refund successfully

We test if earlySupShareOwner calls refundEarlySupShare, earlySupShare will increase correctly and cash balance of earlySupShareOwner will increase correctly.

#### 5.10. assignRsvShareOwner

###### 5.10.1. owner is deployer before any assignment

We test if the rsvShareOwner is zero-address before any assignRsvShareOwner transaction is executed.

###### 5.10.2. assign successfully an ordinary address

We test if dao calls assignRsvShareOwner the first time with an address different from zero-address, rsvShareOwner will be assigned correctly.

###### 5.10.3. re-assign successfully an ordinary address

We test if dao calls assignRsvShareOwner with an address different from zero-address when the owner has already been assigned, rsvShareOwner will be assigned correctly.

We test if dao calls assignRsvShareOwner with zero-address will cause revert.

###### 5.10.5. assign unsuccessfully from sender different from admin

We test if an address different from admin calls assignRsvShareOwner will cause revert

#### 5.11. withdrawRsvShare

###### 5.11.1. withdraw unsuccessfully from sender different from the owner

We test if an address different from rsvShareOwner calls withdrawRsvShare will cause revert.

###### 5.11.2. withdraw unsuccessfully amount exceeding the share

We test if rsvShareOwner calls withdrawRsvShare with the amount exceeding rsvShare will cause revert.

###### 5.11.3. withdraw successfully

We test if rsvShareOwner calls withdrawRsvShare with a valid amount, rsvShare will decrease correctly and cash balance of rsvShareOwner will increase correctly.

#### 5.12. refundRsvShare

###### 5.12.1. refund unsuccessfully from sender different from the owner

We test if an address different from rsvShareOwner calls refundRsvShare will cause revert.

###### 5.12.2. refund successfully

We test if rsvShareOwner calls refundRsvShare, rsvShare will increase correctly and cash balance of rsvShareOwner will increase correctly.

#### 5.13. stakeFromRsvShare

###### 5.13.1. stake unsuccessfully from sender different from owner

We test if an address different from rsvShareOwner calls stakeFromRsvShare will cause revert.

###### 5.13.2. stake unsuccessfully amount exceeding the share

We test if rsvShareOwner calls stakeFromRsvShare with the amount exceeding rsvShare will cause revert.

###### 5.13.3. stake successfully

We test if rsvShareOwner calls stakeFromRsvShare with a valid amount, rsvShare and tokenS420 balance of MirrorPool will change correctly.

#### 5.14. unstakeToRsvShare

###### 5.14.1. unstake unsuccessfully from sender different from owner

We test if an address different from rsvShareOwner calls stakeToRsvShare will cause revert.

###### 5.14.2. unstake unsuccessfully amount exceeding s420 balance

We test if rsvShareOwner calls stakeToRsvShare with the amount exceeding tokenS420 balance of MirrorPool will cause revert.

###### 5.14.3. unstake successfully

We test if rsvShareOwner calls stakeToRsvShare with a valid amount, rsvShare and tokenS420 balance of MirrorPool will change correctly.

#### 5.15. withdrawRsvShareStake

###### 5.15.1. withdraw unsuccessfully from sender different from owner

We test if an address different from rsvShareOwner calls withdrawRsvShareStake will cause revert.

###### 5.15.2. withdraw unsuccessfully amount exceeding s420 balance

We test if rsvShareOwner calls withdrawRsvShareStake with the amount exceeding tokenS420 balance of MirrorPool will cause revert.

###### 5.15.3. withdraw successfully

We test if rsvShareOwner calls withdrawRsvShareStake with a valid amount, tokenS420 balances of MirrorPool and rsvShareOwner will change correctly.

## 6. StakingPool

#### 6.1. construction

###### 6.1.1. Token420 and TokenS420 address

We test if StakingPool deployed, then deployed Token420 address and TokenS420 address are registered to StakingPool.

#### 6.2. registerDaoManager

###### 6.2.1. DAO Manager has been registered

We test if DAO Manager has been registered, then throw error DaoManager has been registered.

###### 6.2.2. DAO Manager has not registered yet

We test if DAO Manager still be ZERO address, then can register.

#### 6.3. resetproductOfInterestRate

###### 6.3.1. Caller is not Dao Manager

We test if DAO Manager has been registered, then throw error Only DaoManager can trigger resetproductOfInterestRate.

###### 6.3.2. Reset productOfInterestRate when staking amount is empty

We test if staking amount is empty, then productOfInterestRate reset to be 1..

###### 6.4.1. Caller is not Dao Manager

We test if DAO Manager has been registered, then throw error Transaction reverted without a reason string.

###### 6.4.2. Converges early and stays stable lately

We test if

• We test if converges early, then staking fee rate will be updated incrementally.
• We test if converges stays stable lately, then staking fee rate will be reset to be base fee rate.

#### 6.5. stake

###### 6.5.1. Invalid stake amount

We test if user stakes amount is 0, then throw error Invalid stake amount.

###### 6.5.2. User stakes 100,000

We test if user stakes 100,000, check

• totalCapital
• discountValueIncludingFee
• discountValueExcludingFee
• penalizedCapital
• capitalExcludingFee
• productOfInterestRate
###### 6.5.3. User stakes 2 times, 100,000 for each time

We test if user stakes 2 times with 100,000 each time, check

• totalCapital
• discountValueIncludingFee
• discountValueExcludingFee
• penalizedCapital
• capitalExcludingFee
• productOfInterestRate
###### 6.5.4. TODO: Multiple user stakes multiple times

We test if there are multiple user stakes multiple times.

#### 6.6. unstake

###### 6.6.1. Invalid unstake amount

We test if user unstakes exceed staked token amount, then throw error Invalid unstake amount.

###### 6.6.2. User only unstakes part of the tokens

We test if user only unstakes part of the tokens, then check

• totalCapital
• discountValueIncludingFee
• discountValueExcludingFee
• penalizedCapital
• capitalExcludingFee
• productOfInterestRate
###### 6.6.3. User unstakes all

We test if user unstakes all unstakes part of the tokens, then check

• totalCapital
• discountValueIncludingFee
• discountValueExcludingFee
• penalizedCapital
• capitalExcludingFee
• productOfInterestRate reset to be 1
###### 6.6.4. TODO: Multiple user unstakes part of the tokens

We test if there are multiple user unstakes part of the tokens.

###### 6.6.5. TODO: Multiple user unstakes all staked tokens

We test if there are multiple user unstakes all staked tokens.

#### 6.7. totalStake

##### 6.7.1. totalStake remains the same after tokens transferred to the Staking Pool without staking

We test if when some tokens are transferred to the Staking Pool not through stake method, the totalStake should remain the same.

## 7. Token420

#### 7.1. construction

###### 7.1.1. Token name

We test if Token420 deployed, then deployed token name is Token420.

###### 7.1.2. Token symbol

We test if Token420 deployed, then deployed token symbol is 420D.

#### 7.2. registerDaoManager

###### 7.2.1. DAO Manager has been registered

We test if DAO Manager has been registered, then throw error DAO Manager has been registered.

###### 7.2.2. DAO Manager has not registered yet

We test if DAO Manager still be ZERO address, then can register.

#### 7.3. mint

###### 7.3.1. DAO Manager can mint token

We test if DAO Manager can mint token with given amount.

###### 7.3.2. Caller is not DAO Manager

We test if Caller is not DAO Manager, then then throw error.

#### 7.4. burn

###### 7.4.1. DAO Manager can burn token

We test if DAO Manager can burn token with given amount.

###### 7.4.2. Caller is not DAO Manager

We test if Caller is not DAO Manager, then then throw error.

###### 7.4.3. Burn amount exceeds balance

We test if burn amount exceeds balance, then throw error ERC20: burn amount exceeds balance.

## 8. TreasuryManager

#### 8.1. construction

We test if Treasury Manager deployed, then deployed Cash Token address is registered to Treasury Manager.

We test if Treasury Manager deployed, then deployed Token420 address is registered to Treasury Manager.

###### 8.1.3. lock until

We test if Treasury Manager deployed, then lock until is 0.

#### 8.2. registerDaoManager

###### 8.2.1. DAO Manager has been registered

We test if DAO Manager has been registered, then throw error DAO Manager has been registered.

###### 8.2.2. DAO Manager has not registered yet

We test if DAO Manager still be ZERO address, then can register.

#### 8.3. registerAuctionManager

###### 8.3.1. Auction Manager has been registered

We test if Auction Manager has been registered, then throw error AuctionManager has been registered.

###### 8.3.2. Auction Manager has not registered yet

We test if Auction Manager still be ZERO address, then can register.

#### 8.4. fetchCash

###### 8.4.1. Caller is not Auction Manager

We test if Caller is not Auction Manager, then then throw error.

###### 8.4.2. Auction Manager can fetch and split the cash pie

We test if Auction Manager can fetch and split the cash pie for

• Asset Fund (60%).
• Insurance Fund (30%).
• Operation Fund (10%).

#### 8.5. Claim cash back

###### 8.5.1. Claim is locked

We test if current auction day less than or equal claim lock until, then TreasuryManager throw error Claim is locked

###### 8.5.2. Claim back success

We test if user can claim cash back in simple auction case (TreasuryManager only hold one user's cash), then TreasuryManager burn their token.

#### 8.6. lockUpTo

###### 8.6.1. Only admin can lockUpTo

We test if caller is not Dao Manager admin, then throw error Only admin can lockUpTo.

###### 8.6.2. new lockTerm equal current auction day

We test if $newLockUntil <= currentAuctionDay$, then throw error Invalid lock until auction day.

###### 8.6.3. new lockTerm less and equal old lockTerm

We test if $newLockUntil <= oldLockUntil$, then throw error Invalid lock until auction day.

###### 8.6.4. lockUpTo success

We test if $newLockUntil$:

• $newLockUntil > currentAuctionDay$
• $newLockUntil != oldLockUntil$

Then lockUpTo should lock success.

#### 8.7. assignAssetFundOwner

###### 8.7.1. owner is deployer before any assignment

We test if the assetFundOwner is zero-address before any assignAssetFundOwner transaction is executed.

###### 8.7.2. assign successfully an ordinary address

We test if dao calls assignAssetFundOwner the first time with an address different from zero-address, assetFundOwner will be assigned correctly.

###### 8.7.3. re-assign successfully an ordinary address

We test if dao calls assignAssetFundOwner with an address different from zero-address when the owner has already been assigned, assetFundOwner will be assigned correctly.

We test if dao calls assignAssetFundOwner with zero-address will cause revert.

###### 8.7.5. assign unsuccessfully from sender different from admin

We test if an address different from admin calls assignAssetFundOwner will cause revert

#### 8.8. withdrawAssetFund

###### 8.8.1. withdraw unsuccessfully from sender different from the owner

We test if an address different from assetFundOwner calls withdrawAssetFund will cause revert.

###### 8.8.2. withdraw unsuccessfully amount exceeding the fund

We test if assetFundOwner calls withdrawAssetFund with the amount exceeding assetFund will cause revert.

###### 8.8.3. withdraw successfully

We test if assetFundOwner calls withdrawAssetFund with a valid amount, assetFund will decrease correctly and cash balance of assetFundOwner will increase correctly.

#### 8.9. refundAssetFund

###### 8.9.1. refund unsuccessfully from sender different from the owner

We test if an address different from assetFundOwner calls refundAssetFund will cause revert.

###### 8.9.2. refund successfully

We test if assetFundOwner calls refundAssetFund, assetFund will increase correctly and cash balance of assetFundOwner will increase correctly.

#### 8.10. assignInsuranceFundOwner

###### 8.10.1. owner is deployer before any assignment

We test if the insuranceFundOwner is zero-address before any assignInsuranceFundOwner transaction is executed.

###### 8.10.2. assign successfully an ordinary address

We test if dao calls assignInsuranceFundOwner the first time with an address different from zero-address, insuranceFundOwner will be assigned correctly.

###### 8.10.3. re-assign successfully an ordinary address

We test if dao calls assignInsuranceFundOwner with an address different from zero-address when the owner has already been assigned, insuranceFundOwner will be assigned correctly.

We test if dao calls assignInsuranceFundOwner with zero-address will cause revert.

###### 8.10.5. assign unsuccessfully from sender different from admin

We test if an address different from admin calls assignInsuranceFundOwner will cause revert

#### 8.11. withdrawInsuranceFund

###### 8.11.1. withdraw unsuccessfully from sender different from the owner

We test if an address different from insuranceFundOwner calls withdrawInsuranceFund will cause revert.

###### 8.11.2. withdraw unsuccessfully amount exceeding the fund

We test if insuranceFundOwner calls withdrawInsuranceFund with the amount exceeding insuranceFund will cause revert.

###### 8.11.3. withdraw successfully

We test if insuranceFundOwner calls withdrawInsuranceFund with a valid amount, insuranceFund will decrease correctly and cash balance of insuranceFundOwner will increase correctly.

#### 8.12. refundInsuranceFund

###### 8.12.1. refund unsuccessfully from sender different from the owner

We test if an address different from insuranceFundOwner calls refundInsuranceFund will cause revert.

###### 8.12.2. refund successfully

We test if insuranceFundOwner calls refundInsuranceFund, insuranceFund will increase correctly and cash balance of insuranceFundOwner will increase correctly.

#### 8.13. assignOperationFundOwner

###### 8.13.1. owner is deployer before any assignment

We test if the operationFundOwner is zero-address before any assignOperationFundOwner transaction is executed.

###### 8.13.2. assign successfully an ordinary address

We test if dao calls assignOperationFundOwner the first time with an address different from zero-address, operationFundOwner will be assigned correctly.

###### 8.13.3. re-assign successfully an ordinary address

We test if dao calls assignOperationFundOwner with an address different from zero-address when the owner has already been assigned, operationFundOwner will be assigned correctly.

We test if dao calls assignOperationFundOwner with zero-address will cause revert.

###### 8.13.5. assign unsuccessfully from sender different from admin

We test if an address different from admin calls assignOperationFundOwner will cause revert

#### 8.14. withdrawOperationFund

###### 8.14.1. withdraw unsuccessfully from sender different from the owner

We test if an address different from operationFundOwner calls withdrawOperationFund will cause revert.

###### 8.14.2. withdraw unsuccessfully amount exceeding the fund

We test if operationFundOwner calls withdrawOperationFund with the amount exceeding operationFund will cause revert.

###### 8.14.3. withdraw successfully

We test if operationFundOwner calls withdrawOperationFund with a valid amount, operationFund will decrease correctly and cash balance of operationFundOwner will increase correctly.

#### 8.15. refundOperationFund

###### 8.15.1. refund unsuccessfully from sender different from the owner

We test if an address different from operationFundOwner calls refundOperationFund will cause revert.

###### 8.15.2. refund successfully

We test if operationFundOwner calls refundOperationFund, operationFund will increase correctly and cash balance of operationFundOwner will increase correctly.

## 9. Fixed

#### 9.1. one

###### 9.1.1. scaling factor Q=2^128

We test return value of one is equal $2^{128}$, we call return value is Q.

Q = 0x100000000000000000000000000000000
= 340282366920938463463374607431768211456

###### 9.1.2. fixedToInt(one()) = 1

We convert fixedToInt from Fixed(1), it should return 1.

###### 9.1.3. intToFixed(1) = one()

We convert intToFixed from 1, the result should equal Fixed.one().

###### 9.1.4. one() * one() = one()

We test $Fixed.one() * Fixed.one() = Fixed.one()$

###### 9.1.5. Fixed one multiplication invariant

Generate a random big uint $A < 2^{64}$, convert it to Fixed to get a random Fixed.

#### 9.2. Fixed conversion

###### 9.2.1. intToFixed(0)=0

For $Fixed(A) = 0$, converting $Fixed(A)$ to uint number should return 0.

###### 9.2.2. intToFixed(1)=2^128

For $Fixed(A) = 2^{128}$, converting $Fixed(A)$ to uint number should return $1$ and vice versa.

###### 9.2.3. uint256(intToFixed(A)) should divide 2^128

For uint256 random number, it should divide $2^{128}$ success.

###### 9.2.4. intToFixed(2^128) overflow

For $A = Q$, converting $A$ to Fixed number should overflow.

###### 9.2.5. fixedToInt(intToFixed(random)) conversion

Generate a random bigInt $A < 2^{128-1}$, convert it to Fixed, then convert it back to int, should get the back the initial generated bigInt

###### 9.2.6. fixedToInt(0)

For a Fixed number with value is 0, convert it from Fixed to int should return 0.

###### 9.2.7. fixedToInt([2^128-1])=0

For a Fixed number with value is $2^{128-1}$, convert it from Fixed to int should return 0.

###### 9.2.8. fixedToInt([2^128])=1

For a Fixed number with value is $2^{128}$, convert it from Fixed to int should return 1.

###### 9.3.1. add( Fixed([2^256-1]), Fixed([1]) ) should overflow

For two Fixed number $[A] = 2^{256-1}$ and $[B] = 1$, then $[A] + [B]$ should throw overflow.

For two random Fixed number $[A]$ and $[B]$, then we test:

$$[A] + [B] = [B] + [A]$$.

For random Fixed number $[A]$, then we test:

$$[A] + [0] = [A]$$.

###### 9.3.4. add([A],[B]) overflow if A+B>=2^256

For random Fixed number $[A] < 10^{32}$ and $[B] = 2^{256} - [A]$, we test $[A] + [B]$ and $[B] + [A]$ should throw overflow.

#### 9.4. subtract(Fixed, Fixed)

###### 9.4.1. subtract([A], [0]) = [A]

For a random Fixed number $[A] < 10^{32}$, we test:

[A] - [0] = [A]
###### 9.4.2. subtract([A], [A]) = [0]

For a random Fixed number $[A] < 10^{32}$, we test:

[A] - [A] = [0]
###### 9.4.3. subtract([A], [A+1]) should revert

For a random Fixed number $[A] < 10^{32}$, we test:

[A] - [(A + 1)]

should throw error oveflow.

#### 9.5. multiply(Fixed, Fixed)

###### 9.5.1. multiply([A],[0]) = [0]

For two Fixed numbers $[A] = 10^{32} (random)$, $[B]= 0$, we test:

[A] * [B] = [0].
###### 9.5.2. multiply([A],one) = [A]

For two Fixed numbers $[A] = 10^{32} (random)$, $[B] = 2^{128}$, we test:

[A] * [B] = [A].
###### 9.5.3. multiply([A],[B]) = multiply([B],[A])

For random two Fixed numbers $[A] = 10^{12}$, $[B] = 10^{12}$, we test:

[A] * [B] = [B] * [A].
###### 9.5.4. multiply(intToFixed(2^128-1),one) should pass
• For random uint $A = 2^{128} - 1$ and Fixed number $[B] = 2^{128}$, we test $IntToFixed(A) * [B]$ should return exact result.
###### 9.5.5. multiply(intToFixed(2^64),intToFixed(2^64)) should overflow

For random two uint numbers $A = 2^{64}$, $B = 2^{64}$, we test:

• $IntToFixed(A) * IntToFixed(B)$ should overflow.
###### 9.5.6. multiply(Fixed([2^128+1]),Fixed([2^256-1])) should overflow

For two Fixed numbers $[A] = 2^{128} + 1$, $[B] = 2^{256} -1$, we test:

• $[A] * [B]$ should overflow.
###### 9.5.7. multiply(intToFixed(AA),intToFixed(BB)) = intToFixed(AA*BB)

For random two uint numbers $AA = 2$, $BB = 2$, we test

$IntToFixed(AA) * IntToFixed(BB) = IntToFixed(AA*BB)$

###### 9.5.8. Should multiply success in basic case

For two uint numbers $A = 2$, $B = 5$, we test:

A * B = 10.
###### 9.5.9. Should multiply success in edge case
• For an uint numbers $MM = Q - 1 = 2^{128} - 1$, we test $MM * 1 = 1 * MM$ should return exact result.

• For two uint numbers $A = 2^{64} - 1$, $B = 2^{64} + 1$, we test $A * B$ should return exact result.

###### 9.5.10. Should throw overflow

For two uint numbers $A = 2^{64} - 1$, $B = 2^{64} + 1$, we test:

• $(A + 1) * B$ should overflow.
• $A * (B + 1)$ should overflow.

#### 9.6. multiply(Fixed, uint)

###### 9.6.1. multiply([A],0) = [0]

For random Fixed numbers $[A] = 10^{32}$, uint number $B = 0$, we test:

[A] * B = [0].
###### 9.6.2. multiply([A],1) = [A]

For random Fixed number $[A] = 10^{32}$, uint number $B = 1$, we test:

[A] * B = [A].
###### 9.6.3. multiply([A],B) = multiply([B],A)

For random two uint numbers $A = 10^{12}$, $B = 10^{12}$, we test:

[A] * B = [B] * A.
###### 9.6.4. multiply(intToFixed(2^128-1),one) should pass
• For two uint numbers $A = 2^{128} - 1$, $B = 1$, we test $IntToFixed(A) * B$ should return exact result.
###### 9.6.5. multiply(intToFixed(2^64),2^64) should overflow

For two uint numbers $A = 2^{64}$, $B = 2^{64}$, we test:

• $IntToFixed(A) * B$ should overflow.
• $IntToFixed(A - 1) * (B + 2)$ should overflow.
###### 9.6.6. multiply(Fixed([2^256]),1)) should overflow

For Fixed number $[A] = 2^{256}$ and uint number $B = 1$, we test:

• $[A] * B$ should overflow.
• $[(A - 1)] * (B + 1)$ should overflow.

#### 9.7. multiplyTruncating(Fixed, uint)

###### 9.7.1. multiplyTruncating([A],0) = 0

For random Fixed number $[A] = 10^{32}$ and uint number $B = 0$, we test:

[A] * B = 0.
###### 9.7.2. multiplyTruncating([A],1) = A

For random Fixed number $[A] = 10^{32}$ and uint number $B = 1$, we test:

[A] * B = A.
###### 9.7.3. multiplyTruncating([A],B) = multiplyTruncating([B],A)

For random two uint numbers $A = 10^{12}$, $B = 10^{12}$, we test:

[A] * B = [B] * A.
###### 9.7.4. multiplyTruncating(intToFixed(2^128-1),one) should pass
• For two uint numbers $A = 2^{128} - 1$, $B = 1$, we test $IntToFixed(A) * B$ should return exact result.
###### 9.7.5. multiplyTruncating(Fixed([2^128]),2^256)) should overflow

For Fixed number $[A] = 2^{128}$ and uint number $B = 2^{256}$, we test:

• $[A] * B$ should overflow.
• $[(A - 1)] * B$ should overflow.
###### 9.7.6. multiplyTruncating(Fixed([2^256]),1)) should overflow

For Fixed number $[A] = 2^{256}$ and uint number $B = 1$, we test:

• $[A] * B$ should overflow.
• $[(A - 1)] * (B + 1)$ should overflow.

#### 9.8. divide(Fixed, Fixed)

###### 9.8.1. divide([A],[0]) should throw error Division by zero

For two Fixed numbers $[A] = 10^{32} (random)$, $[B] = 0$, we test:

• $[A] / [B]$ should throw error Division by zero.
###### 9.8.2. divide([A],one) = [A]

For two Fixed numbers $[A] = 10^{32} (random)$, $[B] = 2^128$, we test:

[A] / [B] = [A].
###### 9.8.3. divide([A],[B]) should pass

For random two Fixed numbers $[A] = 2$, $[B] = 2$, we test $[A] / [B]$ should return exact result.

###### 9.8.4. divide(intToFixed(2^128-1),one) should pass
• For uint numbers $A = 2^{128} - 1$ and Fixed $[B] = 2^{128}$, we test $IntToFixed(A) / [B]$ should return exact result.
###### 9.8.5. divide(Fixed([2^256-1]),one) should pass

For random two uint numbers $[A] = 2^{256} -1$, $[B] = 2^{128}$, we test $[A] / [B]$ should return exact result.

###### 9.8.6. divide(intToFixed(2^64),intToFixed(1 / 2^64)) should overflow

For random two uint numbers $A = 2^{64}$, $B = 1 / 2^{64}$, we test:

• $IntToFixed(A) / IntToFixed(B)$ should overflow.
###### 9.8.7. Should throw error Division by zero

For two uint numbers $A < 2^{128} - 1$, $B = 0$, we test $A / B$ should throw error Division by zero.

###### 9.8.8. Should perfect division

For three uint numbers $A = 5$, $B = 2$ and $C = 10$, we test:

C/A = B
C/B = A
###### 9.8.9. Should division success in edge case

For two uint number $A = 2^128 - 1$, $B = 1$. We test $A / B$ should return exact result.

#### 9.9. divide(uint, uint)

###### 9.9.1. divide(A,0) should throw error Division by zero

For two uint numbers $A = 2 (random)$, $B = 0$, we test:

• $A / B$ should throw error Division by zero.
###### 9.9.2. divide(A,1) = [A]

For two uint numbers $A = 2 (random)$, $B = 1$, we test:

A / B = [A].
###### 9.9.3. divide(A,B) should pass

For random two uint numbers $A = 2$, $B = 2$, We test $A / B$ should return exact result.

###### 9.9.4. divide(2^128-1,one) should pass
• For random two uint numbers $A = 2^{128} - 1$, $B = 1$, we test $A / B$ should return exact result.
###### 9.9.5. Should throw error Division by zero

For two uint numbers $A < 2^{128} - 1$, $B = 0$, we test $A / B$ should throw error Division by zero.

###### 9.9.6. Should perfect division

For three uint numbers $A = 5$, $B = 2$ and $C = 10$, we test:

C/A = B
C/B = A
###### 9.9.7. Should throw overflow

For two uint numbers $A = 2^{128}$, $B = 1$, we test $A / B$ should throw error overflow.

#### 9.10. divide(Fixed, uint)

###### 9.10.1. divide([A],0) should throw error Division by zero

For random Fixed number $[A] = 10^{12} (random)$, uint number $B = 0$, we test:

• $[A] / B$ should throw error Division by zero.
###### 9.10.2. divide([A],1) = [A]

For random Fixed number $[A] = 10^{12} (random)$, uint number $B = 1$, we test:

[A] / B = [A].
###### 9.10.3. divide([A],B) should pass

For random Fixed number $[A] = 10^{12}$, uint number $B = 2$, We test $[A] / B$ should return exact result.

###### 9.10.4. divide(intToFixed(2^128-1),1) should pass
• For random two uint numbers $A = 2^{128} - 1$, $B = 1$, we test $IntToFixed(A) / B$ should return exact result.
###### 9.10.5. divide(Fixed([2^256-1]),1) should pass

For random Fixed numbers $[A] = 2^{256} - 1$, uint number $B = 1$, we test $[A] / B$ should return exact result.

###### 9.10.6. Should divide success

For three uint numbers $A = 5$, $B = 2$ and $C = 10$, we test:

C/A = B
C/B = A
###### 9.10.7. Should throw error division by zero

For two uint numbers $A < 2^{128} - 1$, $B = 0$, we test $A / B$ should throw error Division by zero.

###### 9.10.8. Should division success in edge case

For two uint numbers $A < 2^{128} - 1$, $B = 1$, we test $A / B$ should give exact result.

## 10.TokenS420

#### 10.1. construction

###### 10.1.1. Token name

We test if TokenS420 deployed, then deployed token name is TokenS420.

###### 10.1.2. Token symbol

We test if TokenS420 deployed, then deployed token symbol is TokenS420.

#### 10.2. registerStakingPool

###### 10.2.1. Staking Pool has been registered

We test if Staking Pool has been registered, then throw error Staking Pool has been registered.

###### 10.2.2. Staking Pool has not registered yet

We test if Staking Pool has been registered, then check Staking Pool address.

#### 10.3. totalSupply

###### 10.3.1. Calculate totalSupply correctly

We test total supply of the tokens.

#### 10.4. balanceOf

###### 10.4.1. Calculate balance correctly

We test balance of the tokens.

#### 10.5. mint discount factor

###### 10.5.1. Fail for not Staking Pool

We test if caller is not Staking Pool then throw error.

###### 10.5.2. Mint exactly

We test if Staking Pool can mint token with given amount.

#### 10.6. burn

###### 10.6.1. Fail for not Staking Pool

We test if caller is not Staking Pool then throw error.

###### 10.6.2. Burn exactly

We test if Staking Pool can burn token with given amount.

###### 10.6.3. Burn more than balance

We test if Staking Pool can burn token amount more than balance.

#### 10.7. transfer

###### 10.7.1. Transfer successfully

We test if can transfer token with given amount.

## 11. Auction Manager Case

#### 11.1. Day 1 total deposit is greater than soft floor deposit then user withdraws

We test if user deposit more than softFloorDeposit, then user calls withdraw to collect tokens of day 1.

#### 11.2. Day 2 total deposit is less than soft floor deposit then user withdraws

We test if user deposit less than softFloorDeposit, then user calls withdraw to collect tokens of day 2.

#### 11.3. Day 3 total deposit is greater than soft floor deposit but user does not withdraw

We test if user deposit more than softFloorDeposit, then user doesn't collect tokens of day 3.

#### 11.4. Day 4 total deposit is equal to soft floor deposit then user withdraws

We test if user deposit equal to softFloorDeposit, then user calls withdraw to collect tokens of day 3 and 4.

#### 11.5. Day 5 total deposit is less than soft floor deposit but user does not withdraw

We test if user deposit less than softFloorDeposit, then user doesn't collect tokens of day 5.

#### 11.6. Day 6 total deposit is less than soft floor deposit then user withdraws

We test if user deposit less than softFloorDeposit, then user calls withdraw to collect tokens of day 5 and 6.

#### 11.7. Day 7 total deposit is greater than soft floor deposit but user does not withdraw

We test if user deposit more than softFloorDeposit, then user doesn't collect tokens of day 7.

#### 11.8. Day 8 total deposit is less than soft floor deposit but user does not withdraw

We test if user deposit less than softFloorDeposit, then user doesn't collect tokens of day 8.

#### 11.9. Day 9 total deposit is equal to soft floor deposit then user withdraws

We test if user deposit equal to softFloorDeposit, then user calls withdraw to collect tokens of day 7, 8, and 9.

## 12. Staking Case

#### 12.1. Day 2 stake token success

We test if user stake 1 token, we check:

• productOfInterestRate
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.2. Day 3 unstake part 1 of token

We test if user unstake 1 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.3. Day 3 unstake part 2 of token

We test if user unstake 2 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.4. Day 3 unstake part 3 of token

We test if user unstake 3 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.5. Day 4 stake token success

We test if user stake 1 token, we check:

• productOfInterestRate
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.6. Day 5 unstake part 1 of token

We test if user unstake 1 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.7. Day 5 unstake part 2 of token

We test if user unstake 2 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.8. Day 5 unstake part 3 of token

We test if user unstake 3 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.9. Day 6 check total supply and balance token

We test if user do nothing, we check:

• productOfInterestRate
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.10. Day 7 check total supply and balance token

We test if user do nothing, we check:

• productOfInterestRate
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.11. Day 8 check total supply and balance token

We test if user do nothing, we check:

• productOfInterestRate
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.12. Day 9 check total supply and balance token

We test if user do nothing, we check:

• productOfInterestRate
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 12.13. Day 10 unstake all token

We test if user unstake all token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

## 13. Treasury Case

#### 13.1. Day 1 auction total deposit is greater than 0 then user do NOT claim token

We test if user deposit and auction total deposit is greater than 0, then user can withdraw token but do NOT claim token, we check:

• cash_balance_treasury_before
• cash_balance_treasury_after

#### 13.2. Day 2 auction total deposit is equal 0 and treasury do NOT receive cash

We test if user deposit and auction total deposit is equal 0 and treasury do NOT receive cash, we check:

• cash_balance_treasury_before
• cash_balance_treasury_after

#### 13.3. Day 3 auction total deposit is greater than 0 then user 1 do NOT withdraw token but buy back

We test if user deposit and auction total deposit is greater than 0, then user do NOT withdraw token but user claim token, we check:

• token_total
• cash_balance_treasury_before
• cash_balance_treasury_after
• cash_IFund
• cash_AFund
• token_ubalance
• cash_move_to_user
• cash_move_from_treasury

#### 13.4. Day 4 auction total deposit is greater than 0 then withdraw and claim all token for user 1,3,5,7,9

We test if user deposit and auction total deposit is greater than 0 then user withdraw token and claim token, we check:

• token_total
• cash_balance_treasury_before
• cash_balance_treasury_after
• cash_IFund
• cash_AFund
• token_ubalance
• cash_move_to_user
• cash_move_from_treasury

#### 13.5. Day 5 auction total deposit is equal 0 then user 2 claim token

We test if user deposit and auction total deposit is equal 0 then user 2 claim token, we check:

• token_total
• cash_balance_treasury_before
• cash_balance_treasury_after
• cash_IFund
• cash_AFund
• token_ubalance
• cash_move_to_user
• cash_move_from_treasury

#### 13.6. Day 6 auction total deposit is greater than 0 but user 2 do NOT withdraw token

We test if user deposit and total deposit is greater than 0 then user 2 claim token, throw exception Unable to calculate withdrawal parts.

#### 13.7. Day 7 auction total deposit is equal 0 and treasury do NOT receive cash and user do NOT claim

We test if user deposit and auction total deposit is equal 0 and treasury do NOT receive cash, we check:

• cash_balance_treasury_before
• cash_balance_treasury_after

#### 13.8. Day 8 auction total deposit is greater than 0 then withdraw token and claim token for user 1..9

We test if user deposit and auction total deposit is greater than 0 then user withdraw token and claim token, we check:

• token_total
• cash_balance_treasury_before
• cash_balance_treasury_after
• cash_IFund
• cash_AFund
• token_ubalance
• cash_move_to_user
• cash_move_from_treasury

## 14. Migration

#### 14.1. Update and Migration permission

We test how the entire system migration process.

• Admin first call DaoManager prepareForMigration. At this time, users still can bid to auction and stake, unstake and all other normal activities
• Admin then call DaoManager for nextAuction. At this time :

• No one can bid to auction or stake/unstake
• Users still can do other operations : claim past auctions, buyBack
• We clone all the contract V1 to the new one V2 (copy all its state and move all its funds)

• Admin call to replace DaoManagerV2 and StakingPoolV2. At this time

• Existing users should see their 420 tokens unchanged
• Their might be changes in their s420 tokens, but it shouldn't be empty
• Users having s420 can unstake
• User start to bid to auction, stake, unstake as normal again

This test doesn't check the number precisions. It just check that the migration process is well migrated to the new one. It also check at certain step, the corresponding functionalities are blocked as expected

## 15. Complex Staking Case

#### 15.1. Day 2 user 3-6 stakes

We test if multiple user only stakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 15.2. Day 3 user 3-5 stakes

We test if multiple user only stakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 15.3. Day 4 user 3-6 stakes

We test if multiple user only stakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 15.4. Day 5 user do not stakes

We test if multiple user do not stakes stakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 15.5. Day 6 user 3-6 stakes

We test if multiple user stakes stakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 15.6. Day 7 user 3-6 unstakes part of the tokens

We test if multiple user only unstakes part of the tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 15.7. Day 8 user 3,4,5 unstakes all

We test if multiple user 3,4,5 unstakes all tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 15.8. Day 9 user 6 do not unstakes

We test if user 6 do not unstakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 15.9. Day 10 user 6 unstakes all

We test if multiple user 6 unstakes all tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

## 16. Auction Manager Case V2

#### 16.1. Day 1 total deposit is greater than soft floor deposit then user withdraws

We test if user deposit more than softFloorDeposit, then user calls withdraw to collect tokens of day 1.

#### 16.2. Day 2 total deposit is less than soft floor deposit then user withdraws

We test if user deposit less than softFloorDeposit, then user calls withdraw to collect tokens of day 2.

#### 16.3. Day 3 total deposit is greater than soft floor deposit but user does not withdraw

We test if user deposit more than softFloorDeposit, then user doesn't collect tokens of day 3.

#### 16.4. Day 4 total deposit is equal to soft floor deposit then user withdraws

We test if user deposit equal to softFloorDeposit, then user calls withdraw to collect tokens of day 3 and 4.

#### 16.5. Day 5 total deposit is less than soft floor deposit but user does not withdraw

We test if user deposit less than softFloorDeposit, then user doesn't collect tokens of day 5.

#### 16.6. Day 6 migration V2

We migrate DAO from V1 to V2.

#### 16.7. Day 6 total deposit is less than soft floor deposit then user withdraws

We test if user deposit less than softFloorDeposit, then user calls withdraw to collect tokens of day 5 and 6.

#### 16.8. Day 7 total deposit is greater than soft floor deposit but user does not withdraw

We test if user deposit more than softFloorDeposit, then user doesn't collect tokens of day 7.

#### 16.9. Day 8 total deposit is less than soft floor deposit but user does not withdraw

We test if user deposit less than softFloorDeposit, then user doesn't collect tokens of day 8.

#### 16.10. Day 9 total deposit is equal to soft floor deposit then user withdraws

We test if user deposit equal to softFloorDeposit, then user calls withdraw to collect tokens of day 7, 8, and 9.

## 17. Staking Case V2

#### 17.1. Day 2 stake token success

We test if user stake 1 token, we check:

• productOfInterestRate
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.2. Day 3 unstake part 1 of token

We test if user unstake 1 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.3. Day 3 unstake part 2 of token

We test if user unstake 2 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.4. Day 3 unstake part 3 of token

We test if user unstake 3 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.5. Day 4 stake token success

We test if user stake 1 token, we check:

• productOfInterestRate
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.6. Day 5 migration V2

We migrate DAO from V1 to V2.

#### 17.7. Day 5 unstake part 1 of token

We test if user unstake 1 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.8. Day 5 unstake part 2 of token

We test if user unstake 2 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.9. Day 5 unstake part 3 of token

We test if user unstake 3 token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.10. Day 6 check total supply and balance token

We test if user do nothing, we check:

• productOfInterestRate
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.11. Day 7 check total supply and balance token

We test if user do nothing, we check:

• productOfInterestRate
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.12. Day 8 check total supply and balance token

We test if user do nothing, we check:

• productOfInterestRate
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.13. Day 9 check total supply and balance token

We test if user do nothing, we check:

• productOfInterestRate
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

#### 17.14. Day 10 unstake all token

We test if user unstake all token, we check:

• chargedFee
• balance420D
• totalSupply
• poolBalance
• convertedCapital
• balanceS420D

## 18. Treasury Case V2

#### 18.1. Day 1 auction total deposit is greater than 0 then user do NOT claim token

We test if user deposit and auction total deposit is greater than 0, then user can withdraw token but do NOT claim token, we check:

• cash_balance_treasury_before
• cash_balance_treasury_after

#### 18.2. Day 2 auction total deposit is equal 0 and treasury do NOT receive cash

We test if user deposit and auction total deposit is equal 0 and treasury do NOT receive cash, we check:

• cash_balance_treasury_before
• cash_balance_treasury_after

#### 18.3. Day 3 auction total deposit is greater than 0 then user 1 do NOT withdraw token but claim token

We test if user deposit and auction total deposit is greater than 0, then user do NOT withdraw token but user claim token, we check:

• token_total
• cash_balance_treasury_before
• cash_balance_treasury_after
• cash_IFund
• cash_AFund
• token_ubalance
• cash_move_to_user
• cash_move_from_treasury

#### 18.4. Day 4 auction total deposit is greater than 0 then migration V2 and withdraw token

We test if user deposit and auction total deposit is greater than 0 then migrate DAO V1 to V2.

#### 18.5. Day 5 claim all token for user 1,3,5,7,9

We test if user deposit and auction total deposit is greater than 0 then user withdraw token and claim token, we check:

• token_total
• cash_balance_treasury_before
• cash_balance_treasury_after
• cash_IFund
• cash_AFund
• token_ubalance
• cash_move_to_user
• cash_move_from_treasury

#### 18.6. Day 6 auction total deposit is equal 0 then user 2 claim token

We test if user deposit and auction total deposit is equal 0 then user 2 claim token, we check:

• token_total
• cash_balance_treasury_before
• cash_balance_treasury_after
• cash_IFund
• cash_AFund
• token_ubalance
• cash_move_to_user
• cash_move_from_treasury

#### 18.7. Day 7 auction total deposit is greater than 0 then user 2 do NOT withdraw token

We test if user deposit and auction total deposit is equal 0 then user 2 claim token, throw exception Unable to calculate withdrawal parts.

#### 18.8. Day 8 auction total deposit is equal 0 and treasury do NOT receive cash and user do NOT claim

We test if user deposit and auction total deposit is equal 0 and treasury do NOT receive cash, we check:

• cash_balance_treasury_before
• cash_balance_treasury_after

#### 18.9. Day 9 auction total deposit is greater than 0 then withdraw token and claim token for user 1..9

We test if user deposit and auction total deposit is greater than 0 then user withdraw token and claim token, we check:

• token_total
• cash_balance_treasury_before
• cash_balance_treasury_after
• cash_IFund
• cash_AFund
• token_ubalance
• cash_move_to_user
• cash_move_from_treasury

## 19. Complex Staking Case V2

#### 19.1. Day 2 user 3-6 stakes

We test if multiple user only stakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 19.2. Day 3 user 3-5 stakes

We test if multiple user only stakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 19.3. Day 4 user 3-6 stakes

We test if multiple user only stakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 19.4. Day 5 migration V2

We migrate DAO from V1 to V2.

#### 19.5. Day 5 user do not stakes

We test if multiple user do not stakes stakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 19.6. Day 6 user 3-6 stakes

We test if multiple user stakes stakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 19.7. Day 7 user 3-6 unstakes part of the tokens

We test if multiple user only unstakes part of the tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 19.8. Day 8 user 3,4,5 unstakes all

We test if multiple user 3,4,5 unstakes all tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 19.9. Day 9 user 6 do not unstakes

We test if user 6 do not unstakes tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

#### 19.10. Day 10 user 6 unstakes all

We test if multiple user 6 unstakes all tokens, then check

• totalSupply
• balance420D
• poolBalance
• convertedCapital
• balanceS420D
• productOfInterestRate

## 21. WhiteList

#### 21.1. constructor

We test when WhiteList is deployed, whether admin is the address of the deployer.

###### 21.1.2. correct cash

We test when WhiteList is deployed, whether cash is the correct ERC-20 token we use.

###### 21.1.3. correct token

We test when WhiteList is deployed, whether token is contract Token420.

###### 21.1.4. correct expirationD2

We test when WhiteList is deployed, whether expirationD2 is equal to the deploying timestamp plus the durationD1 and the durationD2 we have deployed.

We test when WhiteList is deployed, whether dao is the address of the deployer.

###### 21.1.6. correct balance token

We test when WhiteList is deployed, whether balance token of the deployer.

###### 21.1.7. correct tokenPrice

We test when WhiteList is deployed, whether tokenPrice is the correct value we have deployed.

#### 21.2. registerUsers

###### 21.2.1. registerUsers successfully

We test if admin calls registerUsers before expirationD2 with a valid list of addresses, those addresses should be registered.

###### 21.2.2. registerUsers failed from sender different from admin

We test if an address different from admin calls registerUsers will cause revert.

###### 21.2.3. registerUsers failed when list user empty

We test if admin calls registerUsers with list of addresses is empty will cause revert.

###### 21.2.4. registerUsers failed when user is zero address

We test if admin calls registerUsers with a list of addresses that has a user is zero address will cause revert.

###### 21.2.5. registerUsers failed when add duplicated user

We test if admin calls registerUsers with a list of addresses that has a user duplicated within the list or with registered user will cause revert.

#### 21.3. removeUsers

###### 21.3.1. removeUsers successfully

We test if admin calls removeUsers before expirationD2 with a valid list of addresses, those addresses should be registered.

###### 21.3.2. removeUsers failed from sender different from admin

We test if an address different from admin calls removeUsers will cause revert.

###### 21.3.3. removeUsers failed when list user empty

We test if admin calls removeUsers with list of addresses is empty will cause revert.

###### 21.3.4. removeUsers failed when user is deposit

We test if admin calls removeUsers after expirationD2 will cause revert.

We test if a member calls buy successfully before deadline with amounts that don't exceed depositLimit in total.

###### 21.4.2. throw error when user not in whitelist before expiration date 1

We test if a member calls buy when user is not in whitelist and timestamp less than expirationD1 will cause revert.

###### 21.4.3. throw error when buy more than whitelist max amount

We test if a member calls buy when amount is greater than WHITELIST_MAX_USD will cause revert.

###### 21.4.4. throw error when buy amount is 0

We test if a member calls buy when amount is 0 will cause revert.

###### 21.4.5. throw error when buy more than whitelist max token amount

We test if a member calls buy after timestamp expirationD1 when token is greater than WHITELIST_TOKEN_AMOUNT will cause revert.

###### 21.4.6. throw error after expirationD2

We test if a member calls buy after expirationD2 will cause revert.

#### 21.5. withdrawCash

###### 21.5.1. withdrawCash successfully

We test if admin calls withdrawCash successfully.

###### 21.5.2. withdrawCash unsuccessfully from sender different from admin

We test if an address different from admin calls withdrawCash will cause revert.

###### 21.5.3. withdrawCash unsuccessfully when there is no cash to withdraw

We test if members cannot call withdrawCash when there is no cash to withdraw.

#### 21.6. closeAndTransferToTreasury

###### 21.6.1. closeAndTransferToTreasury successfully

We test if admin calls closeAndTransferToTreasury successfully.

###### 21.6.2. closeAndTransferToTreasury unsuccessfully from sender different from admin

We test if an address different from admin calls closeAndTransferToTreasury will cause revert.

###### 21.6.3. closeAndTransferToTreasury unsuccessfully when after expirationD2

We test if admin calls closeAndTransferToTreasury with expirationD2 greater than curent time will cause revert.

###### 21.6.4. closeAndTransferToTreasury unsuccessfully when there is no cash to withdraw

We test if members cannot call closeAndTransferToTreasury when there is no cash to withdraw.

#### 21.7. closeAndTransferToAccount

###### 21.7.1. closeAndTransferToAccount successfully

We test if admin calls closeAndTransferToAccount successfully.

###### 21.7.2. closeAndTransferToAccount unsuccessfully from sender different from admin

We test if an address different from admin calls closeAndTransferToAccount will cause revert.

###### 21.7.3. closeAndTransferToAccount unsuccessfully when after expirationD2

We test if admin calls closeAndTransferToAccount with expirationD2 less than curent time will cause revert.

###### 21.7.4. closeAndTransferToAccount unsuccessfully when there is no cash to withdraw

We test if members cannot call closeAndTransferToAccount when there is no cash to withdraw.

## 22. WhiteList Staking

#### 22.1. stake

###### 22.1.1. User white list stakes in day 0

We test when WhiteList is deployed, we check token reward of user in day 1.

## 23. WhiteList AuctionManager

#### 23.1. withdraw

###### 23.1.1. single user withdraw maximum token emission when deposit of previous auction is equal to init softFloorDeposit

We test if user deposit of previous auction is equal to softFloorDeposit, then user can withdraw maximum token emission.

###### 23.1.2. single user withdraw maximum token emission when deposit of previous auction is more than init softFloorDeposit

We test if user deposit of previous auction is more than softFloorDeposit, then user can withdraw maximum token emission.

###### 23.1.3. single user withdraw less than maximum token emission when deposit of previous auction is less than init softFloorDeposit

We test if user deposit of previous auction is less than softFloorDeposit, then user can withdraw less than maximum token emission.

###### 23.1.4. single user withdraw in extreme case when they deposit 1 (10^(-18))

We test if user deposit of previous auction is equal to 1 (10^{-18)}), then user can withdraw token.

#### 23.2. withdrawableTokenAmountOf

###### 23.2.1. correct withdrawable token amount after auction inflation

We test if the withdrawable token amount is updated correctly after daily inflation of auction.

###### 23.2.2. correct withdrawable token amount after deposit

We test if the withdrawable token amount is updated correctly after the user deposits.

###### 23.2.3. correct withdrawable token amount after token withdrawal

We test if the withdrawable token amount is updated correctly after the user withdraws.

###### 23.2.4. correct withdrawable token amount after deposit and withdrawal in a same auction

We test if the withdrawable token amount is updated correctly after the user deposits and withdraws in a same auction.

## 24. EarlySupporterPool

#### 24.1. construction

We test if EarlySupporterPool deployed, then deployed Token address is registered to Early Supporter Pool.

We test if EarlySupporterPool deployed, then deployed Mirror address is registered to Early Supporter Pool.

###### 24.2.1. Should catch error Permission: Unauthorized

We test if an address different from admin calls updateAdmin will cause revert.

We test if the address admin is updated correctly after calls updateAdmin.

#### 24.3. fetch

###### 24.3.1. fetch token successfully

We test if totalFetched is updated correctly after after calls fetch.

#### 24.4. register

###### 24.4.1. Should catch error Permission: Unauthorized

We test if an address different from admin calls register will cause revert.

###### 24.4.2. Should catch error Empty argument prohibited

We check if the address list is empty will cause revert.

###### 24.4.3. Should catch error Inconsistent lengths

We check if the number of elements in the address list is different from the number of elements in the weight list will cause revert.

###### 24.4.4. Should catch error Weights has been initialized

We check if total weights has been initialized will cause revert..

###### 24.4.5. Should catch error Excessive weights

We check if the weight exceeds 100 will cause revert.

###### 24.4.6. Should catch error Invalid investor address

We check if the investor address is Zero address or Admin address will cause revert.

###### 24.4.7. Should catch error Weight must be greater than 0

We check if the weight is equal 0 will cause revert.

###### 24.4.8. register successfully

We test if the weight of address is updated correctly after calls register.

#### 24.5. moveOwnership

###### 24.5.1. Should catch error Weight must be greater than 0

We check if transfer weight equal 0, will cause revert.

###### 24.5.2. Should catch error Excessive tranferable weight

We test if the address transfer exceeds their weight will cause revert.

###### 24.5.3. Move successfully with empty Mirror Pool

We test if mirror pool is empty, the weight of address is transfered correctly after calls moveOwnership.

###### 24.5.4. Move successfully with none empty Mirror Pool

We test if mirror pool is not empty, the weight of address is transfered correctly after calls moveOwnership.

#### 24.6. claim

###### 24.6.1. claim successfully simple case

We test if the token amount is updated correctly after calls claim.

###### 24.6.2. claim successfully complex case

We check if the token amount over several days are updated correctly after calling claim.

## 25. MultiSend

#### 25.1. deployment

###### 25.1.1. correct owner

We test when MultiSend is deployed, owner is deployer address

###### 25.1.2. correct 420 token

We test when MultiSend is deployed, 420 token address set exactly

###### 25.1.3. correct s420 token

We test when MultiSend is deployed, s420 token address set exactly

###### 25.1.4. correct minFeeFree

We test when MultiSend is deployed, minFeeFree is equal to 0

###### 25.1.5. correct feePercent

We test when MultiSend is deployed, feePercent is equal to 0

#### 25.2. multisendTokenERC20

###### 25.2.1. The receiver list is empty

We test if receiver list is empty, then throw error MultiSend: The receiver list is empty.

###### 25.2.2. Inconsistent lengths

We test if the length of receiver list and balances list is not matched, then throw error MultiSend: Inconsistent lengths.

###### 25.2.3. Send token 420 or s420 successfully without fee

We test if sender send token 420 or s420 tokens, then contract will NOT received any token fee.

###### 25.2.4. Send other token successfully without fee

We test if sender send tokens that different from 420 and s420 token, then contract will NOT received any token fee in 3 following cases:

• Do not set min fee free and fee percent yet.
• Total 420 + s420 balance of sender greater than min fee free and fee percent is 10%
• Total 420 + s420 balance of sender less than min fee free but fee percent is 0%
###### 25.2.5. Send other token successfully with fee

We test if sender send tokens that different from 420 and s420 token, then contract will received 5% token fee when min fee free greater than total 420 + s420 balance and fee percent is 5%

#### 25.3. multisendNative

###### 25.3.1. The receiver list is empty

We test if receiver list is empty, then throw error MultiSend: The receiver list is empty.

###### 25.3.2. Inconsistent lengths

We test if the length of receiver list and balances list is not matched, then throw error MultiSend: Inconsistent lengths.

###### 25.3.3. Send successfully without fee

We test if sender send native token without fee in 3 following cases:

• Do not set min fee free and fee percent yet.
• Total 420 + s420 balance of sender greater than min fee free and fee percent is 10%
• Total 420 + s420 balance of sender less than min fee free but fee percent is 0%
###### 25.3.4. Send successfully with fee

We test if sender send native tokens, then contract will received 5% fee when min fee free greater than total 420 + s420 balance of sender and fee percent is 5%

###### 25.3.5. Insufficient funds

We test if sender send native tokens, require native token is less than total send and fee, will throw error MultiSend: Insufficient funds.

#### 25.4. claimFeeTokenERC20

###### 25.4.1. Claim token successfully

We test if there are tokens exist in contract, owner can withdraw it.

#### 25.5. claimNative

###### 25.5.1. Claim token successfully

We test if there are ETH exist in contract, owner can withdraw it.

#### 25.6. setMinFeeFree

###### 25.6.1. caller is not the owner

We test if not the owner set minFeeFree, then throw error Ownable: caller is not the owner.

###### 25.6.2. Set successfully

We test if the owner set minFeeFree, then set minFeeFree will successfully.

#### 25.7. setFeePercent

###### 25.7.1. caller is not the owner

We test if not the owner set feePercent, then throw error Ownable: caller is not the owner.

###### 25.7.2. Invalid fee percentage

We test if the owner set feePercent with value greater than 100%, then throw error MultiSend: Invalid fee percentage.

###### 25.7.3. Set successfully

We test if the owner set feePercent, then set feePercent will successfully.

## 26. OpPusher

#### 26.1. construction

We test when OpPusher is deployed, admin is deployer address

We test when OpPusher is deployed, Mirror Pool contract address is exactly

We test when OpPusher is deployed, Treasury contract address is exactly

We test when OpPusher is deployed, token cold wallet and cash cold wallet are Zero address

###### 26.2.1. Should catch error Permission: Unauthorized

We test if an address different from admin calls updateAdmin will cause revert.

We test if the parameters address is Zero address or current admin address will cause revert.

We test if the address admin is updated correctly after calls updateAdmin.

#### 26.3. setTokenColdWallet

###### 26.3.1. Should catch error Permission: Unauthorized

We test if an address different from admin calls setTokenColdWallet will cause revert.

###### 26.3.2. Should catch error Invalid address

We test if new wallet address is Zero address or current wallet address will cause revert.

###### 26.3.3. Set successfully

We test if new wallet address is not Zero address or current wallet address will success

#### 26.4. setCashColdWallet

###### 26.4.1. Should catch error Permission: Unauthorized

We test if an address different from admin calls setCashColdWallet will cause revert.

###### 26.4.2. Should catch error Invalid address

We test if new wallet address is Zero address or current wallet address will cause revert.

###### 26.4.3. Set successfully

We test if new wallet address is not Zero address or current wallet address will success

#### 26.5. push

###### 26.5.1. No tokens and cashes were pushed when cold wallets is not set yet

We test if cold wallets is not set yet, no tokens and cashes were pushed. In other words, token or cash balance of cold wallets is 0

###### 26.5.2. tokens and cashes were pushed when cold wallets were set

We test if cold wallets is set well, tokens and cashes were pushed to cold wallets. In other words, token or cash balance of cold wallets is greater than 0

#### 26.6. pushTest

###### 26.6.1. No tokens and cashes were pushed when cold wallets is not set yet

We test if cold wallets is not set yet, no tokens and cashes were pushed. In other words, token or cash balance of cold wallets is 0

###### 26.6.2. tokens and cashes were pushed when cold wallets were set

We test if cold wallets is set well, tokens and cashes were pushed to cold wallets. In other words, token or cash balance of cold wallets is greater than 0

###### 26.6.3. tokens and cashes were pushed a little bit when cold wallets were set

We test if cold wallets is set well, tokens and cashes were pushed a little bit to cold wallets. In other words, token or cash balance of cold wallets is greater than 0