@@ -1663,7 +1663,7 @@ mod tests {
1663
1663
}
1664
1664
1665
1665
#[ test]
1666
- fn test_unlocking_schedule_with_termination ( ) {
1666
+ fn test_unlocking_schedule_with_termination_and_vesting_started_before_phase2 ( ) {
1667
1667
// https://wiki.near.org/getting-started/near-token/lockups#termination-of-vesting
1668
1668
// This test checks that termination of vesting
1669
1669
// fixes the amount of tokens that finally should become liquid (*),
@@ -1973,6 +1973,196 @@ mod tests {
1973
1973
) ;
1974
1974
}
1975
1975
1976
+ #[ test]
1977
+ fn test_unlocking_schedule_with_termination_and_vesting_started_after_phase2 ( ) {
1978
+ // https://wiki.near.org/getting-started/near-token/lockups#termination-of-vesting
1979
+ // This test checks that termination of vesting
1980
+ // fixes the amount of tokens that finally should become liquid (*),
1981
+ // but does not change the schedule of unlocking the tokens.
1982
+ // The contract should act as there was no termination at all,
1983
+ // until we do not reach the amount (*).
1984
+ // After we reach this amount, the unlocking process should stop.
1985
+
1986
+ // Taking bigger lockup amount because we compare the balances further
1987
+ // and there is a comparison delta.
1988
+ // We want to be sure that this delta does not grow on bigger numbers
1989
+ let lockup_amount = to_yocto ( LOCKUP_NEAR * 1000 ) ;
1990
+ let mut context = basic_context ( ) ;
1991
+ context. account_balance = lockup_amount;
1992
+ testing_env ! ( context. clone( ) ) ;
1993
+
1994
+ let vesting_cliff_offset = YEAR + 300 ;
1995
+ let vesting_schedule = new_vesting_schedule ( vesting_cliff_offset) ;
1996
+ let mut contract = new_contract (
1997
+ true ,
1998
+ Some ( vesting_schedule. clone ( ) ) ,
1999
+ Some ( to_nanos ( YEAR * 4 ) . into ( ) ) ,
2000
+ true ,
2001
+ ) ;
2002
+
2003
+ // Vesting starts at day 800: 300 days after transfers enabled
2004
+ let ts_vesting_started = to_ts ( GENESIS_TIME_IN_DAYS - YEAR + vesting_cliff_offset) ;
2005
+ assert_eq ! ( vesting_schedule. start_timestamp. 0 , ts_vesting_started) ;
2006
+
2007
+ // We don't use lockup_timestamp,
2008
+ // it means that lockup starts from the transfers enabled moment
2009
+ assert_eq ! ( contract. lockup_information. lockup_timestamp, None ) ;
2010
+
2011
+ // Transfers are enabled at day 500, lockup also starts here
2012
+ if let TransfersInformation :: TransfersEnabled {
2013
+ transfers_timestamp,
2014
+ } = & contract. lockup_information . transfers_information
2015
+ {
2016
+ assert_eq ! ( transfers_timestamp. 0 , to_ts( GENESIS_TIME_IN_DAYS ) ) ;
2017
+ } else {
2018
+ assert ! ( false , "Transfers should be enabled" ) ;
2019
+ }
2020
+
2021
+ // Vesting cliff ends at day 1165
2022
+ assert_eq ! (
2023
+ vesting_schedule. cliff_timestamp. 0 ,
2024
+ to_ts( GENESIS_TIME_IN_DAYS + vesting_cliff_offset)
2025
+ ) ;
2026
+
2027
+ // Lockup cliff ends at day 865
2028
+ assert_eq ! ( contract. lockup_information. lockup_duration, to_nanos( YEAR ) ) ;
2029
+
2030
+ // Everything is locked and unvested in the beginning
2031
+ assert_eq ! (
2032
+ contract. get_vesting_information( ) ,
2033
+ VestingInformation :: VestingHash (
2034
+ VestingScheduleWithSalt {
2035
+ vesting_schedule: vesting_schedule. clone( ) ,
2036
+ salt: SALT . to_vec( ) . into( ) ,
2037
+ }
2038
+ . hash( )
2039
+ . into( )
2040
+ )
2041
+ ) ;
2042
+ assert_eq ! ( contract. get_owners_balance( ) . 0 , 0 ) ;
2043
+ assert_eq ! ( contract. get_liquid_owners_balance( ) . 0 , 0 ) ;
2044
+ assert_eq ! ( contract. get_locked_amount( ) . 0 , lockup_amount) ;
2045
+ assert_eq ! (
2046
+ contract. get_unvested_amount( vesting_schedule. clone( ) ) . 0 ,
2047
+ lockup_amount
2048
+ ) ;
2049
+ assert_eq ! (
2050
+ contract
2051
+ . get_locked_vested_amount( vesting_schedule. clone( ) )
2052
+ . 0 ,
2053
+ 0
2054
+ ) ;
2055
+
2056
+ // *** day 1164: day before vesting cliff is passed ***
2057
+ let ts_1_day_before_vesting_cliff = to_ts ( GENESIS_TIME_IN_DAYS + vesting_cliff_offset - 1 ) ;
2058
+ assert_eq ! (
2059
+ ts_1_day_before_vesting_cliff,
2060
+ vesting_schedule. cliff_timestamp. 0 - to_nanos( 1 )
2061
+ ) ;
2062
+ context. block_timestamp = ts_1_day_before_vesting_cliff;
2063
+ testing_env ! ( context. clone( ) ) ;
2064
+
2065
+ // Tokens are fully unvested
2066
+ assert_eq ! (
2067
+ contract. get_unvested_amount( vesting_schedule. clone( ) ) . 0 ,
2068
+ lockup_amount
2069
+ ) ;
2070
+ // But some of tokens have already unlocked
2071
+ assert_almost_eq_with_max_delta (
2072
+ to_yocto ( 545205 ) ,
2073
+ contract. get_locked_amount ( ) . 0 ,
2074
+ to_yocto ( 1 ) ,
2075
+ ) ;
2076
+
2077
+ // *** day 1165: day of vesting cliff ***
2078
+ let ts_day_of_vesting_cliff = to_ts ( GENESIS_TIME_IN_DAYS + vesting_cliff_offset) ;
2079
+ assert_eq ! ( ts_day_of_vesting_cliff, vesting_schedule. cliff_timestamp. 0 ) ;
2080
+ context. block_timestamp = ts_day_of_vesting_cliff;
2081
+ testing_env ! ( context. clone( ) ) ;
2082
+
2083
+ // 25% is vested
2084
+ let vesting_nanos_passed = ( ts_day_of_vesting_cliff - ts_vesting_started) as u128 ;
2085
+ let vesting_nanos_total =
2086
+ ( vesting_schedule. end_timestamp . 0 - vesting_schedule. start_timestamp . 0 ) as u128 ;
2087
+
2088
+ let expected_unvested_amount_at_cliff_day =
2089
+ lockup_amount - lockup_amount / vesting_nanos_total * vesting_nanos_passed;
2090
+ let unvested_amount_at_cliff_day = contract. get_unvested_amount ( vesting_schedule. clone ( ) ) . 0 ;
2091
+ assert_almost_eq_with_max_delta (
2092
+ expected_unvested_amount_at_cliff_day,
2093
+ unvested_amount_at_cliff_day,
2094
+ to_yocto ( 1 ) ,
2095
+ ) ;
2096
+ assert_eq ! ( to_yocto( 750000 ) , unvested_amount_at_cliff_day) ;
2097
+
2098
+ // *** day 1230: day of termination ***
2099
+ let ts_termination_day = to_ts ( GENESIS_TIME_IN_DAYS + YEAR * 2 ) ;
2100
+ context. block_timestamp = ts_termination_day;
2101
+ testing_env ! ( context. clone( ) ) ;
2102
+
2103
+ assert_eq ! (
2104
+ contract. get_vesting_information( ) ,
2105
+ VestingInformation :: VestingHash (
2106
+ VestingScheduleWithSalt {
2107
+ vesting_schedule: vesting_schedule. clone( ) ,
2108
+ salt: SALT . to_vec( ) . into( ) ,
2109
+ }
2110
+ . hash( )
2111
+ . into( )
2112
+ )
2113
+ ) ;
2114
+
2115
+ // Some tokens are vested
2116
+ let vesting_nanos_passed = ( ts_termination_day - ts_vesting_started) as u128 ;
2117
+ let expected_unvested_amount_at_termination_day =
2118
+ lockup_amount - lockup_amount / vesting_nanos_total * vesting_nanos_passed;
2119
+ let unvested_amount_at_termination_day =
2120
+ contract. get_unvested_amount ( vesting_schedule. clone ( ) ) . 0 ;
2121
+ assert_almost_eq_with_max_delta (
2122
+ expected_unvested_amount_at_termination_day,
2123
+ unvested_amount_at_termination_day,
2124
+ to_yocto ( 1 ) ,
2125
+ ) ;
2126
+ assert_almost_eq_with_max_delta (
2127
+ to_yocto ( 705479 ) ,
2128
+ unvested_amount_at_termination_day,
2129
+ to_yocto ( 1 ) ,
2130
+ ) ;
2131
+
2132
+ // Terminate the vesting
2133
+ context. predecessor_account_id = account_foundation ( ) ;
2134
+ context. signer_account_pk = public_key ( 3 ) . into ( ) ;
2135
+ context. is_view = false ;
2136
+ testing_env ! ( context. clone( ) ) ;
2137
+ contract. terminate_vesting ( Some ( VestingScheduleWithSalt {
2138
+ vesting_schedule : vesting_schedule. clone ( ) ,
2139
+ salt : SALT . to_vec ( ) . into ( ) ,
2140
+ } ) ) ;
2141
+
2142
+ context. is_view = true ;
2143
+ testing_env ! ( context. clone( ) ) ;
2144
+ assert_eq ! (
2145
+ contract. get_vesting_information( ) ,
2146
+ VestingInformation :: Terminating ( TerminationInformation {
2147
+ unvested_amount: unvested_amount_at_termination_day. into( ) ,
2148
+ status: TerminationStatus :: ReadyToWithdraw ,
2149
+ } )
2150
+ ) ;
2151
+
2152
+ // *** day 1231: 1 day after termination ***
2153
+ let ts_1_day_after_termination = to_ts ( GENESIS_TIME_IN_DAYS + YEAR * 2 + 1 ) ;
2154
+ context. block_timestamp = ts_1_day_after_termination;
2155
+ testing_env ! ( context. clone( ) ) ;
2156
+
2157
+ // Nothing new is vested since termination
2158
+ let unvested_amount_1_day_after_termination =
2159
+ contract. get_unvested_amount ( vesting_schedule. clone ( ) ) . 0 ;
2160
+ assert_eq ! (
2161
+ unvested_amount_1_day_after_termination,
2162
+ unvested_amount_at_termination_day
2163
+ ) ;
2164
+ }
2165
+
1976
2166
#[ test]
1977
2167
fn test_termination_with_staking ( ) {
1978
2168
let lockup_amount = to_yocto ( 1000 ) ;
0 commit comments