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