@@ -1425,3 +1425,118 @@ async fn success_withdraw_all_fee_tokens() {
1425
1425
. await ;
1426
1426
assert_eq ! ( fee_tokens, 0 ) ;
1427
1427
}
1428
+
1429
+ #[ tokio:: test]
1430
+ async fn success_empty_out_stake_with_fee ( ) {
1431
+ let (
1432
+ mut banks_client,
1433
+ payer,
1434
+ recent_blockhash,
1435
+ stake_pool_accounts,
1436
+ _,
1437
+ deposit_info,
1438
+ user_transfer_authority,
1439
+ user_stake_recipient,
1440
+ tokens_to_withdraw,
1441
+ ) = setup ( ) . await ;
1442
+
1443
+ // add another validator and deposit into it
1444
+ let other_validator_stake_account = simple_add_validator_to_pool (
1445
+ & mut banks_client,
1446
+ & payer,
1447
+ & recent_blockhash,
1448
+ & stake_pool_accounts,
1449
+ )
1450
+ . await ;
1451
+
1452
+ let other_deposit_info = simple_deposit_stake (
1453
+ & mut banks_client,
1454
+ & payer,
1455
+ & recent_blockhash,
1456
+ & stake_pool_accounts,
1457
+ & other_validator_stake_account,
1458
+ TEST_STAKE_AMOUNT ,
1459
+ )
1460
+ . await
1461
+ . unwrap ( ) ;
1462
+
1463
+ // move tokens to new account
1464
+ transfer_spl_tokens (
1465
+ & mut banks_client,
1466
+ & payer,
1467
+ & recent_blockhash,
1468
+ & deposit_info. pool_account . pubkey ( ) ,
1469
+ & other_deposit_info. pool_account . pubkey ( ) ,
1470
+ & user_transfer_authority,
1471
+ tokens_to_withdraw,
1472
+ )
1473
+ . await ;
1474
+
1475
+ let user_tokens =
1476
+ get_token_balance ( & mut banks_client, & other_deposit_info. pool_account . pubkey ( ) ) . await ;
1477
+
1478
+ let user_transfer_authority = Keypair :: new ( ) ;
1479
+ delegate_tokens (
1480
+ & mut banks_client,
1481
+ & payer,
1482
+ & recent_blockhash,
1483
+ & other_deposit_info. pool_account . pubkey ( ) ,
1484
+ & other_deposit_info. authority ,
1485
+ & user_transfer_authority. pubkey ( ) ,
1486
+ user_tokens,
1487
+ )
1488
+ . await ;
1489
+
1490
+ // calculate exactly how much to withdraw, given the fee, to get the account
1491
+ // down to 0, using an inverse fee calculation
1492
+ let validator_stake_account = get_account (
1493
+ & mut banks_client,
1494
+ & other_validator_stake_account. stake_account ,
1495
+ )
1496
+ . await ;
1497
+ let stake_state =
1498
+ deserialize :: < stake:: state:: StakeState > ( & validator_stake_account. data ) . unwrap ( ) ;
1499
+ let meta = stake_state. meta ( ) . unwrap ( ) ;
1500
+ let lamports_to_withdraw = validator_stake_account. lamports - minimum_stake_lamports ( & meta) ;
1501
+ let stake_pool_account =
1502
+ get_account ( & mut banks_client, & stake_pool_accounts. stake_pool . pubkey ( ) ) . await ;
1503
+ let stake_pool =
1504
+ try_from_slice_unchecked :: < state:: StakePool > ( stake_pool_account. data . as_slice ( ) ) . unwrap ( ) ;
1505
+ let fee = stake_pool. stake_withdrawal_fee ;
1506
+ let inverse_fee = state:: Fee {
1507
+ numerator : fee. denominator - fee. numerator ,
1508
+ denominator : fee. denominator ,
1509
+ } ;
1510
+ let pool_tokens_to_withdraw =
1511
+ lamports_to_withdraw * inverse_fee. denominator / inverse_fee. numerator ;
1512
+
1513
+ let new_authority = Pubkey :: new_unique ( ) ;
1514
+ let error = stake_pool_accounts
1515
+ . withdraw_stake (
1516
+ & mut banks_client,
1517
+ & payer,
1518
+ & recent_blockhash,
1519
+ & user_stake_recipient. pubkey ( ) ,
1520
+ & user_transfer_authority,
1521
+ & other_deposit_info. pool_account . pubkey ( ) ,
1522
+ & other_validator_stake_account. stake_account ,
1523
+ & new_authority,
1524
+ pool_tokens_to_withdraw,
1525
+ )
1526
+ . await ;
1527
+ assert ! ( error. is_none( ) ) ;
1528
+
1529
+ // Check balance of validator stake account is MINIMUM + rent-exemption
1530
+ let validator_stake_account = get_account (
1531
+ & mut banks_client,
1532
+ & other_validator_stake_account. stake_account ,
1533
+ )
1534
+ . await ;
1535
+ let stake_state =
1536
+ deserialize :: < stake:: state:: StakeState > ( & validator_stake_account. data ) . unwrap ( ) ;
1537
+ let meta = stake_state. meta ( ) . unwrap ( ) ;
1538
+ assert_eq ! (
1539
+ validator_stake_account. lamports,
1540
+ minimum_stake_lamports( & meta)
1541
+ ) ;
1542
+ }
0 commit comments