@@ -11,12 +11,13 @@ import {
1111 GovernanceCurrency ,
1212 AssetRegistryAPI ,
1313 DefaultAssetRegistryAPI ,
14+ DefaultTransactionAPI ,
1415} from "../../../../../src/index" ;
1516
1617import { createSubstrateAPI } from "../../../../../src/factory" ;
17- import { VAULT_1_URI , VAULT_2_URI , PARACHAIN_ENDPOINT , VAULT_3_URI , ESPLORA_BASE_PATH } from "../../../../config" ;
18+ import { VAULT_1_URI , VAULT_2_URI , PARACHAIN_ENDPOINT , VAULT_3_URI , ESPLORA_BASE_PATH , SUDO_URI } from "../../../../config" ;
1819import { newAccountId , WrappedCurrency , newVaultId } from "../../../../../src" ;
19- import { getSS58Prefix , newMonetaryAmount } from "../../../../../src/utils" ;
20+ import { getSS58Prefix , newCurrencyId , newMonetaryAmount } from "../../../../../src/utils" ;
2021import {
2122 getAUSDForeignAsset ,
2223 getCorrespondingCollateralCurrenciesForTests ,
@@ -27,6 +28,7 @@ import {
2728
2829export const vaultsTests = ( ) => {
2930 describe ( "vaultsAPI" , ( ) => {
31+ let sudoAccount : KeyringPair ;
3032 let vault_1 : KeyringPair ;
3133 let vault_1_ids : Array < InterbtcPrimitivesVaultId > ;
3234 let vault_2 : KeyringPair ;
@@ -56,7 +58,8 @@ export const vaultsTests = () => {
5658 // also add aUSD collateral vaults if they exist (ie. the foreign asset exists)
5759 collateralCurrencies . push ( aUSD ) ;
5860 }
59-
61+
62+ sudoAccount = keyring . addFromUri ( SUDO_URI ) ;
6063 vault_1 = keyring . addFromUri ( VAULT_1_URI ) ;
6164 vault_1_ids = collateralCurrencies . map ( ( collateralCurrency ) =>
6265 newVaultId ( api , vault_1 . address , collateralCurrency , wrappedCurrency )
@@ -142,6 +145,61 @@ export const vaultsTests = () => {
142145 expect ( collateralizationBeforeDeposit . toString ( ) ) . toEqual ( collateralizationAfterWithdrawal . toString ( ) ) ;
143146 }
144147 } ) ;
148+
149+ it ( "should be able to withdraw all collateral" , async ( ) => {
150+ const vaults = await interBtcAPI . vaults . list ( ) ;
151+ // find vault with issued tokens, but zero to-be-issued tokens
152+ const vaultExt = vaults . find ( ( vault ) => vault . toBeIssuedTokens . isZero ( ) && vault . issuedTokens . toBig ( ) . gt ( 0 ) ) ;
153+
154+ if ( vaultExt === undefined ) {
155+ throw Error ( "Precondition failure: Unable to find test vault to attempt withdraw all collateral" ) ;
156+ }
157+
158+ const vaultAccountId = newAccountId ( api , vaultExt . id . accountId . toHuman ( ) ) ;
159+ const collateralCurrency = await currencyIdToMonetaryCurrency ( api , vaultExt . id . currencies . collateral ) ;
160+
161+ // give enough wrapped tokens to vault to be able to self redeem all
162+ const amountIssued = vaultExt . getBackedTokens ( ) ;
163+ // .toBig(0) returns amount in atomic units
164+ const amountIssuedAtomic = amountIssued . toBig ( 0 ) . toNumber ( ) ;
165+ const issuedCurrencyId = newCurrencyId ( api , amountIssued . currency ) ;
166+
167+ const vaultIssuedBalance = await interBtcAPI . tokens . balance ( amountIssued . currency , vaultAccountId ) ;
168+ if ( ! vaultIssuedBalance . free . gt ( amountIssued ) ) {
169+ // set balance and wait for event
170+ const result = await DefaultTransactionAPI . sendLogged (
171+ api ,
172+ sudoAccount ,
173+ api . tx . sudo . sudo ( api . tx . tokens . setBalance ( vaultAccountId , issuedCurrencyId , amountIssuedAtomic * 2 , 0 ) ) ,
174+ api . events . tokens . BalanceSet
175+ ) ;
176+ expect ( result . isCompleted ) . toBe ( true ) ;
177+ }
178+
179+ // find matching keyring
180+ const vaultKR = ( vault_1 . address === vaultAccountId . toHuman ( ) )
181+ ? vault_1
182+ : ( vault_2 . address === vaultAccountId . toHuman ( ) )
183+ ? vault_2
184+ : vault_3 ;
185+
186+ // self redeem so vault has no more issued tokens
187+ const result2 = await DefaultTransactionAPI . sendLogged (
188+ api ,
189+ vaultKR ,
190+ api . tx . redeem . selfRedeem ( vaultExt . id . currencies , amountIssuedAtomic ) ,
191+ api . events . redeem . ExecuteRedeem
192+ ) ;
193+ expect ( result2 . isCompleted ) . toBe ( true ) ;
194+
195+ const vaultInterBtcApi = new DefaultInterBtcApi ( api , "regtest" , vaultKR , ESPLORA_BASE_PATH ) ;
196+
197+ // finally, withdraw all collateral
198+ await submitExtrinsic ( vaultInterBtcApi , await vaultInterBtcApi . vaults . withdrawAllCollateral ( collateralCurrency ) ) ;
199+
200+ const collateralAfter = await vaultInterBtcApi . vaults . getCollateral ( vaultAccountId , collateralCurrency ) ;
201+ expect ( collateralAfter . toBig ( ) . toNumber ( ) ) . toEqual ( 0 ) ;
202+ } ) ;
145203
146204 it ( "should getLiquidationCollateralThreshold" , async ( ) => {
147205 for ( const collateralCurrency of collateralCurrencies ) {
0 commit comments