@@ -127,15 +127,21 @@ mod premium_redeem_tests {
127127 CoreVaultData :: force_to (
128128 & vault_id,
129129 CoreVaultData {
130- issued : vault_id. wrapped ( 450_000 ) ,
131- to_be_issued : vault_id. wrapped ( 250_000 ) ,
132- to_be_redeemed : vault_id. wrapped ( 50_000 ) ,
133- backing_collateral : vault_id. collateral ( 2_000_000 ) ,
130+ issued : vault_id. wrapped ( 450_000_000 ) ,
131+ to_be_issued : vault_id. wrapped ( 250_000_000 ) ,
132+ to_be_redeemed : vault_id. wrapped ( 50_000_000 ) ,
133+ backing_collateral : vault_id. collateral ( 2_000_000_000 ) ,
134134 to_be_replaced : vault_id. wrapped ( 0 ) ,
135135 replace_collateral : griefing ( 0 ) ,
136136 ..default_vault_state ( & vault_id)
137137 } ,
138138 ) ;
139+
140+ // make sure user has enough tokens to redeem
141+ let mut user_state = UserData :: get ( USER ) ;
142+ ( * user_state. balances . get_mut ( & vault_id. wrapped_currency ( ) ) . unwrap ( ) ) . free =
143+ ( * user_state. balances . get_mut ( & vault_id. wrapped_currency ( ) ) . unwrap ( ) ) . free * 1000 ;
144+ UserData :: force_to ( USER , user_state) ;
139145 }
140146
141147 #[ test]
@@ -144,46 +150,53 @@ mod premium_redeem_tests {
144150 setup_vault_below_premium_threshold ( vault_id. clone ( ) ) ;
145151
146152 assert ! ( !VaultRegistryPallet :: is_vault_below_secure_threshold( & vault_id) . unwrap( ) ) ;
147- assert ! ( VaultRegistryPallet :: is_vault_below_premium_threshold ( & vault_id) . unwrap( ) ) ;
153+ assert ! ( VaultRegistryPallet :: will_be_below_premium_threshold ( & vault_id) . unwrap( ) ) ;
148154
149- let redeem_id = setup_redeem ( vault_id. wrapped ( 400_000 ) , USER , & vault_id) ;
155+ let compute_collateral = VaultRegistryPallet :: compute_collateral ( & vault_id) . unwrap ( ) . amount ( ) ;
156+ assert_eq ! ( compute_collateral, 2_000_000_000 ) ;
150157
151- assert ! ( !VaultRegistryPallet :: is_vault_below_secure_threshold( & vault_id) . unwrap( ) ) ;
152- assert ! ( !VaultRegistryPallet :: is_vault_below_premium_threshold( & vault_id) . unwrap( ) ) ;
158+ let initial_state = ParachainState :: get ( & vault_id) ;
153159
160+ let redeem_id = setup_redeem ( vault_id. wrapped ( 400_000_000 ) , USER , & vault_id) ;
154161 let redeem = RedeemPallet :: get_open_redeem_request_from_id ( & redeem_id) . unwrap ( ) ;
155- // we should get rewarded only for 150_000 + 3840 tokens (that's when we reach nearer to secure threshold)
156- let expected_premium = FeePallet :: get_premium_redeem_fee (
157- & vault_id
158- . wrapped ( 150_000 + 3840 ) // need to add 0.384 = 153.84
159- . convert_to ( vault_id. collateral_currency ( ) )
160- . unwrap ( ) ,
161- )
162- . unwrap ( ) ;
163- assert_eq ! ( vault_id. collateral( redeem. premium) , expected_premium) ;
164162
165- // Execute redeem
166- execute_redeem ( redeem_id ) ;
163+ assert ! ( ! VaultRegistryPallet :: is_vault_below_secure_threshold ( & vault_id ) . unwrap ( ) ) ;
164+ assert ! ( ! VaultRegistryPallet :: will_be_below_premium_threshold ( & vault_id ) . unwrap ( ) ) ;
167165
168- let compute_collateral = VaultRegistryPallet :: compute_collateral ( & vault_id) . unwrap ( ) . amount ( ) ;
169- assert_eq ! ( compute_collateral, 2000000 - 15384 ) ; //15.384 COL tokens lost as premium fees
166+ dry_run ( || {
167+ // further redeems will have no rewards, even though the premium redeem
168+ // has not executed yet
169+ let redeem_id = setup_redeem ( vault_id. wrapped ( 2_000_000 ) , USER , & vault_id) ;
170+ let redeem = RedeemPallet :: get_open_redeem_request_from_id ( & redeem_id) . unwrap ( ) ;
171+ assert_eq ! ( redeem. premium, 0 ) ;
172+ } ) ;
170173
171- // Setup another redeem request
172- let redeem_id = setup_redeem ( vault_id. wrapped ( 2_000 ) , USER , & vault_id) ;
174+ execute_redeem ( redeem_id) ;
173175
174- let redeem = RedeemPallet :: get_open_redeem_request_from_id ( & redeem_id) . unwrap ( ) ;
176+ assert_eq ! (
177+ ParachainState :: get( & vault_id) ,
178+ initial_state. with_changes( |user, vault, _, fee_pool| {
179+ // premium transferred to user
180+ // we should get rewarded only for 15.3846153846 *10^6 tokens (that's when we reach nearer to secure
181+ // threshold)
182+ let expected_premium = vault_id. collateral( 15_384_615 ) ;
183+ vault. backing_collateral -= expected_premium;
184+ ( * user. balances. get_mut( & vault_id. collateral_currency( ) ) . unwrap( ) ) . free += expected_premium;
185+
186+ // bitcoin balance update as usual
187+ ( * user. balances. get_mut( & vault_id. wrapped_currency( ) ) . unwrap( ) ) . free -=
188+ redeem. amount_btc( ) + redeem. fee( ) + redeem. transfer_fee_btc( ) ;
189+ vault. issued -= redeem. amount_btc( ) + redeem. transfer_fee_btc( ) ;
190+ * fee_pool. rewards_for( & vault_id) += redeem. fee( ) ;
191+ } )
192+ ) ;
175193
176- // No premium should be given for this request
194+ // We already checked that redeems have no more rewards after requesting the
195+ // premium redeem. Here we do a sanity check that it's still the case after
196+ // execution
197+ let redeem_id = setup_redeem ( vault_id. wrapped ( 2_000_000 ) , USER , & vault_id) ;
198+ let redeem = RedeemPallet :: get_open_redeem_request_from_id ( & redeem_id) . unwrap ( ) ;
177199 assert_eq ! ( redeem. premium, 0 ) ;
178-
179- // Execute redeem
180- execute_redeem ( redeem_id) ;
181-
182- // initially 400 tokens, 1st redeem consumed 398 tokens , 2nd redeem consumed 1.99 tokens, remaining 0.01
183- let get_free_redeemable_tokens = VaultRegistryPallet :: get_free_redeemable_tokens ( & vault_id)
184- . unwrap ( )
185- . amount ( ) ;
186- assert_eq ! ( get_free_redeemable_tokens, 10 ) ;
187200 } ) ;
188201 }
189202
@@ -195,13 +208,14 @@ mod premium_redeem_tests {
195208 let global_secure = VaultRegistryPallet :: get_global_secure_threshold ( & vault_id. currencies ) . unwrap ( ) ; // 200%
196209
197210 // secure > premium > liquidation threshold
198- // at start vault should be below premium threshold, while above global secure & secure threshold
211+ // at start the vault is above the custom&global secure threshold, but due to the to_be_issued
212+ // tokens it is already eligible for premium redeem
199213 assert ! ( !VaultRegistryPallet :: is_vault_below_secure_threshold( & vault_id) . unwrap( ) ) ;
200- assert ! ( VaultRegistryPallet :: is_vault_below_premium_threshold( & vault_id) . unwrap( ) ) ;
201214 assert ! ( !VaultRegistryPallet :: is_vault_below_certain_threshold( & vault_id, global_secure) . unwrap( ) ) ;
215+ assert ! ( VaultRegistryPallet :: will_be_below_premium_threshold( & vault_id) . unwrap( ) ) ;
202216
203217 // Change vault secure threshold,
204- // now secure > global secure > premium > liquidation threshold
218+ // now custom secure > global secure > premium > liquidation threshold
205219 let vault_custom_secure_threshold = UnsignedFixedPoint :: checked_from_rational ( 300 , 100 ) ;
206220 assert_ok ! (
207221 RuntimeCall :: VaultRegistry ( VaultRegistryCall :: set_custom_secure_threshold {
@@ -213,23 +227,24 @@ mod premium_redeem_tests {
213227
214228 // vault should be below premium & secure threshold, while above global secure threshold
215229 assert ! ( VaultRegistryPallet :: is_vault_below_secure_threshold( & vault_id) . unwrap( ) ) ;
216- assert ! ( VaultRegistryPallet :: is_vault_below_premium_threshold( & vault_id) . unwrap( ) ) ;
217230 assert ! ( !VaultRegistryPallet :: is_vault_below_certain_threshold( & vault_id, global_secure) . unwrap( ) ) ;
231+ assert ! ( VaultRegistryPallet :: will_be_below_premium_threshold( & vault_id) . unwrap( ) ) ;
218232
219233 let max_premium_for_vault = VaultRegistryPallet :: get_vault_max_premium_redeem ( & vault_id) . unwrap ( ) ;
220234 // get premium redeem vaults
221- let premium_redeem_vaults = RedeemPallet :: get_premium_redeem_vaults ( )
222- . unwrap ( )
223- . get ( 0 )
224- . unwrap ( )
225- . clone ( ) ;
235+ let premium_redeem_vaults = RedeemPallet :: get_premium_redeem_vaults ( ) . unwrap ( ) [ 0 ] . clone ( ) ;
236+ // non-zero amount of tokens that are elible for premium redeem
237+ assert ! ( !premium_redeem_vaults. 1 . is_zero( ) ) ;
226238
227239 // request redeem tokens given by RPC
228240 let redeem_id_1 = setup_redeem ( premium_redeem_vaults. 1 , USER , & vault_id) ;
229241
230242 let redeem_1 = RedeemPallet :: get_open_redeem_request_from_id ( & redeem_id_1) . unwrap ( ) ;
231- // recv premium should be equal to max premium
232- assert_eq ! ( redeem_1. premium, max_premium_for_vault. amount( ) ) ;
243+ // premium should be equal to max premium, but allow rounding error in this check.
244+ assert ! (
245+ redeem_1. premium >= max_premium_for_vault. amount( ) - 1
246+ && redeem_1. premium <= max_premium_for_vault. amount( ) + 1
247+ ) ;
233248 assert ! ( !redeem_1. premium. is_zero( ) ) ;
234249
235250 // max premium for vault should be zero
@@ -239,9 +254,21 @@ mod premium_redeem_tests {
239254 // redeeming the max premium amount put backs vault above premium threshold
240255 // vault should be below secure threshold, while above global secure & premium threshold
241256 assert ! ( VaultRegistryPallet :: is_vault_below_secure_threshold( & vault_id) . unwrap( ) ) ;
242- assert ! ( !VaultRegistryPallet :: is_vault_below_premium_threshold ( & vault_id) . unwrap( ) ) ;
257+ assert ! ( !VaultRegistryPallet :: will_be_below_premium_threshold ( & vault_id) . unwrap( ) ) ;
243258 assert ! ( !VaultRegistryPallet :: is_vault_below_certain_threshold( & vault_id, global_secure) . unwrap( ) ) ;
244259
260+ execute_redeem ( redeem_id_1) ;
261+ // We should be almost exactly at the secure threshold (there should only be minor
262+ // rounding errors)
263+ let vault = CoreVaultData :: vault ( vault_id. clone ( ) ) ;
264+ let future_tokens = vault. to_be_issued + vault. issued - vault. to_be_redeemed ;
265+ let collateral = vault. backing_collateral ;
266+ let future_ratio = collateral
267+ . ratio ( & future_tokens. convert_to ( vault_id. collateral_currency ( ) ) . unwrap ( ) )
268+ . unwrap ( ) ;
269+ // actual collateralization rate: 2.000004822104648639. Allow small rounding changes
270+ assert ! ( future_ratio - global_secure < FixedU128 :: from_float( 0.00001 ) ) ;
271+
245272 let redeem_id_2 = setup_redeem ( vault_id. wrapped ( 800_00 ) , USER , & vault_id) ;
246273 let redeem_2 = RedeemPallet :: get_open_redeem_request_from_id ( & redeem_id_2) . unwrap ( ) ;
247274 // no premium is given out for new redeems
@@ -254,12 +281,12 @@ mod premium_redeem_tests {
254281 setup_vault_below_premium_threshold ( vault_id. clone ( ) ) ;
255282
256283 assert ! ( !VaultRegistryPallet :: is_vault_below_secure_threshold( & vault_id) . unwrap( ) ) ;
257- assert ! ( VaultRegistryPallet :: is_vault_below_premium_threshold ( & vault_id) . unwrap( ) ) ;
284+ assert ! ( VaultRegistryPallet :: will_be_below_premium_threshold ( & vault_id) . unwrap( ) ) ;
258285
259- let redeem_id = setup_redeem ( vault_id. wrapped ( 100_000 ) , USER , & vault_id) ;
286+ let redeem_id = setup_redeem ( vault_id. wrapped ( 100_000_000 ) , USER , & vault_id) ;
260287
261288 assert ! ( !VaultRegistryPallet :: is_vault_below_secure_threshold( & vault_id) . unwrap( ) ) ;
262- assert ! ( !VaultRegistryPallet :: is_vault_below_premium_threshold ( & vault_id) . unwrap( ) ) ;
289+ assert ! ( !VaultRegistryPallet :: will_be_below_premium_threshold ( & vault_id) . unwrap( ) ) ;
263290
264291 let redeem = RedeemPallet :: get_open_redeem_request_from_id ( & redeem_id) . unwrap ( ) ;
265292
@@ -272,11 +299,6 @@ mod premium_redeem_tests {
272299 )
273300 . unwrap ( ) ;
274301 assert_eq ! ( vault_id. collateral( redeem. premium) , expected_premium) ;
275-
276- let get_free_redeemable_tokens = VaultRegistryPallet :: get_free_redeemable_tokens ( & vault_id)
277- . unwrap ( )
278- . amount ( ) ;
279- assert_eq ! ( get_free_redeemable_tokens, 300500 ) ;
280302 } ) ;
281303 }
282304}
0 commit comments