2021-05-04 14:47:21 +00:00
package keeper_test
import (
2021-06-10 13:35:44 +00:00
"testing"
2021-05-04 14:47:21 +00:00
"time"
2024-02-06 22:54:10 +00:00
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
2021-05-04 14:47:21 +00:00
sdk "github.com/cosmos/cosmos-sdk/types"
2022-01-08 00:39:27 +00:00
proposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
2021-06-10 13:35:44 +00:00
"github.com/stretchr/testify/suite"
2021-05-04 14:47:21 +00:00
2024-08-03 09:51:56 +00:00
"github.com/0glabs/0g-chain/app"
cdpkeeper "github.com/0glabs/0g-chain/x/cdp/keeper"
cdptypes "github.com/0glabs/0g-chain/x/cdp/types"
"github.com/0glabs/0g-chain/x/incentive/keeper"
"github.com/0glabs/0g-chain/x/incentive/testutil"
"github.com/0glabs/0g-chain/x/incentive/types"
kavadisttypes "github.com/0glabs/0g-chain/x/kavadist/types"
2021-05-04 14:47:21 +00:00
)
2021-07-26 19:07:24 +00:00
type USDXIntegrationTests struct {
testutil . IntegrationTester
genesisTime time . Time
addrs [ ] sdk . AccAddress
}
func TestUSDXIntegration ( t * testing . T ) {
suite . Run ( t , new ( USDXIntegrationTests ) )
}
// SetupTest is run automatically before each suite test
func ( suite * USDXIntegrationTests ) SetupTest ( ) {
_ , suite . addrs = app . GeneratePrivKeyAddressPairs ( 5 )
suite . genesisTime = time . Date ( 2020 , 12 , 15 , 14 , 0 , 0 , 0 , time . UTC )
}
func ( suite * USDXIntegrationTests ) ProposeAndVoteOnNewRewardPeriods ( committeeID uint64 , voter sdk . AccAddress , newPeriods types . RewardPeriods ) {
suite . ProposeAndVoteOnNewParams (
voter ,
committeeID ,
2022-01-08 00:39:27 +00:00
[ ] proposaltypes . ParamChange { {
Subspace : types . ModuleName ,
Key : string ( types . KeyUSDXMintingRewardPeriods ) ,
Value : string ( types . ModuleCdc . LegacyAmino . MustMarshalJSON ( newPeriods ) ) ,
2021-07-26 19:07:24 +00:00
} } )
}
func ( suite * USDXIntegrationTests ) TestSingleUserAccumulatesRewardsAfterSyncing ( ) {
userA := suite . addrs [ 0 ]
2022-01-08 00:39:27 +00:00
authBulder := app . NewAuthBankGenesisBuilder ( ) .
WithSimpleModuleAccount ( kavadisttypes . ModuleName , cs ( c ( types . USDXMintingRewardDenom , 1e18 ) ) ) . // Fill kavadist with enough coins to pay out any reward
WithSimpleAccount ( userA , cs ( c ( "bnb" , 1e12 ) ) ) // give the user some coins
2021-07-26 19:07:24 +00:00
incentBuilder := testutil . NewIncentiveGenesisBuilder ( ) .
WithGenesisTime ( suite . genesisTime ) .
2022-01-08 00:39:27 +00:00
WithMultipliers ( types . MultipliersPerDenoms { {
2021-08-04 18:02:59 +00:00
Denom : types . USDXMintingRewardDenom ,
2022-01-08 00:39:27 +00:00
Multipliers : types . Multipliers { types . NewMultiplier ( "large" , 12 , d ( "1.0" ) ) } , // keep payout at 1.0 to make maths easier
2021-08-04 18:02:59 +00:00
} } ) .
2021-07-26 19:07:24 +00:00
WithSimpleUSDXRewardPeriod ( "bnb-a" , c ( types . USDXMintingRewardDenom , 1e6 ) )
2022-01-08 00:39:27 +00:00
suite . SetApp ( )
2022-10-19 23:13:37 +00:00
suite . WithGenesisTime ( suite . genesisTime )
2021-07-26 19:07:24 +00:00
suite . StartChain (
2022-01-08 00:39:27 +00:00
NewPricefeedGenStateMultiFromTime ( suite . App . AppCodec ( ) , suite . genesisTime ) ,
NewCDPGenStateMulti ( suite . App . AppCodec ( ) ) ,
authBulder . BuildMarshalled ( suite . App . AppCodec ( ) ) ,
incentBuilder . BuildMarshalled ( suite . App . AppCodec ( ) ) ,
2021-07-26 19:07:24 +00:00
)
// User creates a CDP to begin earning rewards.
suite . NoError (
suite . DeliverMsgCreateCDP ( userA , c ( "bnb" , 1e10 ) , c ( cdptypes . DefaultStableDenom , 1e9 ) , "bnb-a" ) ,
)
// Let time pass to accumulate interest on the deposit
// Use one long block instead of many to reduce any rounding errors, and speed up tests.
suite . NextBlockAfter ( 1e6 * time . Second ) // about 12 days
// User repays and borrows just to sync their CDP
suite . NoError (
suite . DeliverCDPMsgRepay ( userA , "bnb-a" , c ( cdptypes . DefaultStableDenom , 1 ) ) ,
)
suite . NoError (
suite . DeliverCDPMsgBorrow ( userA , "bnb-a" , c ( cdptypes . DefaultStableDenom , 1 ) ) ,
)
// Accumulate more rewards.
// The user still has the same percentage of all CDP debt (100%) so their rewards should be the same as in the previous block.
suite . NextBlockAfter ( 1e6 * time . Second ) // about 12 days
// User claims all their rewards
2022-01-08 00:39:27 +00:00
msg := types . NewMsgClaimUSDXMintingReward ( userA . String ( ) , "large" )
2023-10-20 16:18:37 +00:00
suite . Require ( ) . NoError ( suite . DeliverIncentiveMsg ( & msg ) )
2021-07-26 19:07:24 +00:00
// The users has always had 100% of cdp debt, so they should receive all rewards for the previous two blocks.
// Total rewards for each block is block duration * rewards per second
accuracy := 1e-18 // using a very high accuracy to flag future small calculation changes
suite . BalanceInEpsilon ( userA , cs ( c ( "bnb" , 1e12 - 1e10 ) , c ( cdptypes . DefaultStableDenom , 1e9 ) , c ( types . USDXMintingRewardDenom , 2 * 1e6 * 1e6 ) ) , accuracy )
}
func ( suite * USDXIntegrationTests ) TestSingleUserAccumulatesRewardsWithoutSyncing ( ) {
user := suite . addrs [ 0 ]
initialCollateral := c ( "bnb" , 1e9 )
2022-01-08 00:39:27 +00:00
authBuilder := app . NewAuthBankGenesisBuilder ( ) .
WithSimpleModuleAccount ( kavadisttypes . ModuleName , cs ( c ( types . USDXMintingRewardDenom , 1e18 ) ) ) . // Fill kavadist with enough coins to pay out any reward
2021-07-26 19:07:24 +00:00
WithSimpleAccount ( user , cs ( initialCollateral ) )
collateralType := "bnb-a"
incentBuilder := testutil . NewIncentiveGenesisBuilder ( ) .
WithGenesisTime ( suite . genesisTime ) .
2022-01-08 00:39:27 +00:00
WithMultipliers ( types . MultipliersPerDenoms { {
2021-08-04 18:02:59 +00:00
Denom : types . USDXMintingRewardDenom ,
2022-01-08 00:39:27 +00:00
Multipliers : types . Multipliers { types . NewMultiplier ( "large" , 12 , d ( "1.0" ) ) } , // keep payout at 1.0 to make maths easier
2021-08-04 18:02:59 +00:00
} } ) .
2021-07-26 19:07:24 +00:00
WithSimpleUSDXRewardPeriod ( collateralType , c ( types . USDXMintingRewardDenom , 1e6 ) )
2022-01-08 00:39:27 +00:00
suite . SetApp ( )
2022-10-19 23:13:37 +00:00
suite . WithGenesisTime ( suite . genesisTime )
2021-07-26 19:07:24 +00:00
suite . StartChain (
2022-01-08 00:39:27 +00:00
authBuilder . BuildMarshalled ( suite . App . AppCodec ( ) ) ,
NewPricefeedGenStateMultiFromTime ( suite . App . AppCodec ( ) , suite . genesisTime ) ,
NewCDPGenStateMulti ( suite . App . AppCodec ( ) ) ,
incentBuilder . BuildMarshalled ( suite . App . AppCodec ( ) ) ,
2021-07-26 19:07:24 +00:00
)
// Setup cdp state containing one CDP
suite . NoError (
suite . DeliverMsgCreateCDP ( user , initialCollateral , c ( "usdx" , 1e8 ) , collateralType ) ,
)
// Skip ahead a few blocks blocks to accumulate both interest and usdx reward for the cdp
// Don't sync the CDP between the blocks
suite . NextBlockAfter ( 1e6 * time . Second ) // about 12 days
suite . NextBlockAfter ( 1e6 * time . Second )
suite . NextBlockAfter ( 1e6 * time . Second )
2022-01-08 00:39:27 +00:00
msg := types . NewMsgClaimUSDXMintingReward ( user . String ( ) , "large" )
2023-10-20 16:18:37 +00:00
suite . Require ( ) . NoError ( suite . DeliverIncentiveMsg ( & msg ) )
2021-07-26 19:07:24 +00:00
// The users has always had 100% of cdp debt, so they should receive all rewards for the previous two blocks.
// Total rewards for each block is block duration * rewards per second
accuracy := 1e-18 // using a very high accuracy to flag future small calculation changes
suite . BalanceInEpsilon ( user , cs ( c ( cdptypes . DefaultStableDenom , 1e8 ) , c ( types . USDXMintingRewardDenom , 3 * 1e6 * 1e6 ) ) , accuracy )
}
func ( suite * USDXIntegrationTests ) TestReinstatingRewardParamsDoesNotTriggerOverPayments ( ) {
userA := suite . addrs [ 0 ]
userB := suite . addrs [ 1 ]
2022-01-08 00:39:27 +00:00
authBuilder := app . NewAuthBankGenesisBuilder ( ) .
WithSimpleModuleAccount ( kavadisttypes . ModuleName , cs ( c ( types . USDXMintingRewardDenom , 1e18 ) ) ) . // Fill kavadist with enough coins to pay out any reward
2021-07-26 19:07:24 +00:00
WithSimpleAccount ( userA , cs ( c ( "bnb" , 1e10 ) ) ) .
WithSimpleAccount ( userB , cs ( c ( "bnb" , 1e10 ) ) )
incentBuilder := testutil . NewIncentiveGenesisBuilder ( ) .
WithGenesisTime ( suite . genesisTime ) .
2022-01-08 00:39:27 +00:00
WithMultipliers ( types . MultipliersPerDenoms { {
2021-08-04 18:02:59 +00:00
Denom : types . USDXMintingRewardDenom ,
2022-01-08 00:39:27 +00:00
Multipliers : types . Multipliers { types . NewMultiplier ( "large" , 12 , d ( "1.0" ) ) } , // keep payout at 1.0 to make maths easier
2021-08-04 18:02:59 +00:00
} } ) .
2021-07-26 19:07:24 +00:00
WithSimpleUSDXRewardPeriod ( "bnb-a" , c ( types . USDXMintingRewardDenom , 1e6 ) )
2022-01-08 00:39:27 +00:00
suite . SetApp ( )
2022-10-19 23:13:37 +00:00
suite . WithGenesisTime ( suite . genesisTime )
2021-07-26 19:07:24 +00:00
suite . StartChain (
2022-01-08 00:39:27 +00:00
authBuilder . BuildMarshalled ( suite . App . AppCodec ( ) ) ,
NewPricefeedGenStateMultiFromTime ( suite . App . AppCodec ( ) , suite . genesisTime ) ,
NewCDPGenStateMulti ( suite . App . AppCodec ( ) ) ,
incentBuilder . BuildMarshalled ( suite . App . AppCodec ( ) ) ,
NewCommitteeGenesisState ( suite . App . AppCodec ( ) , 0 , userA ) , // create a committtee to change params
2021-07-26 19:07:24 +00:00
)
// Accumulate some CDP rewards, requires creating a cdp so the total borrowed isn't 0.
suite . NoError (
suite . DeliverMsgCreateCDP ( userA , c ( "bnb" , 1e10 ) , c ( "usdx" , 1e9 ) , "bnb-a" ) ,
)
suite . NextBlockAfter ( 1e6 * time . Second )
// Remove the USDX reward period
suite . ProposeAndVoteOnNewRewardPeriods ( 0 , userA , types . RewardPeriods { } )
// next block so proposal is enacted
suite . NextBlockAfter ( 1 * time . Second )
// Create a CDP when there is no reward periods. In a previous version the claim object would not be created, leading to the bug.
// Withdraw the same amount of usdx as the first cdp currently has. This make the reward maths easier, as rewards will be split 50:50 between each cdp.
firstCDP , f := suite . App . GetCDPKeeper ( ) . GetCdpByOwnerAndCollateralType ( suite . Ctx , userA , "bnb-a" )
suite . True ( f )
firstCDPTotalPrincipal := firstCDP . GetTotalPrincipal ( )
suite . NoError (
suite . DeliverMsgCreateCDP ( userB , c ( "bnb" , 1e10 ) , firstCDPTotalPrincipal , "bnb-a" ) ,
)
// Add back the reward period
suite . ProposeAndVoteOnNewRewardPeriods ( 0 , userA ,
types . RewardPeriods { types . NewRewardPeriod (
true ,
"bnb-a" ,
suite . Ctx . BlockTime ( ) , // start accumulating again from this block
suite . genesisTime . Add ( 365 * 24 * time . Hour ) ,
c ( types . USDXMintingRewardDenom , 1e6 ) ,
) } ,
)
// next block so proposal is enacted
suite . NextBlockAfter ( 1 * time . Second )
// Sync the cdp and claim by borrowing a bit
// In a previous version this would create the cdp with incorrect indexes, leading to overpayment.
suite . NoError (
suite . DeliverCDPMsgBorrow ( userB , "bnb-a" , c ( cdptypes . DefaultStableDenom , 1 ) ) ,
)
// Claim rewards
2022-01-08 00:39:27 +00:00
msg := types . NewMsgClaimUSDXMintingReward ( userB . String ( ) , "large" )
2023-10-20 16:18:37 +00:00
suite . Require ( ) . NoError ( suite . DeliverIncentiveMsg ( & msg ) )
2021-07-26 19:07:24 +00:00
// The cdp had half the total borrows for a 1s block. So should earn half the rewards for that block
suite . BalanceInEpsilon (
userB ,
cs ( firstCDPTotalPrincipal . Add ( c ( cdptypes . DefaultStableDenom , 1 ) ) , c ( types . USDXMintingRewardDenom , 0.5 * 1e6 ) ) ,
1e-18 , // using very high accuracy to catch small changes to the calculations
)
}
2021-06-10 13:35:44 +00:00
// Test suite used for all keeper tests
type USDXRewardsTestSuite struct {
suite . Suite
keeper keeper . Keeper
cdpKeeper cdpkeeper . Keeper
app app . TestApp
ctx sdk . Context
genesisTime time . Time
addrs [ ] sdk . AccAddress
}
// SetupTest is run automatically before each suite test
func ( suite * USDXRewardsTestSuite ) SetupTest ( ) {
config := sdk . GetConfig ( )
app . SetBech32AddressPrefixes ( config )
_ , suite . addrs = app . GeneratePrivKeyAddressPairs ( 5 )
suite . genesisTime = time . Date ( 2020 , 12 , 15 , 14 , 0 , 0 , 0 , time . UTC )
}
func ( suite * USDXRewardsTestSuite ) SetupApp ( ) {
suite . app = app . NewTestApp ( )
suite . keeper = suite . app . GetIncentiveKeeper ( )
suite . cdpKeeper = suite . app . GetCDPKeeper ( )
2022-01-08 00:39:27 +00:00
suite . ctx = suite . app . NewContext ( true , tmproto . Header { Height : 1 , Time : suite . genesisTime } )
2021-06-10 13:35:44 +00:00
}
2022-01-08 00:39:27 +00:00
func ( suite * USDXRewardsTestSuite ) SetupWithGenState ( authBuilder * app . AuthBankGenesisBuilder , incentBuilder testutil . IncentiveGenesisBuilder ) {
2021-06-10 13:35:44 +00:00
suite . SetupApp ( )
suite . app . InitializeFromGenesisStatesWithTime (
suite . genesisTime ,
2022-01-08 00:39:27 +00:00
authBuilder . BuildMarshalled ( suite . app . AppCodec ( ) ) ,
NewPricefeedGenStateMultiFromTime ( suite . app . AppCodec ( ) , suite . genesisTime ) ,
NewCDPGenStateMulti ( suite . app . AppCodec ( ) ) ,
incentBuilder . BuildMarshalled ( suite . app . AppCodec ( ) ) ,
2021-06-10 13:35:44 +00:00
)
}
2021-05-04 14:47:21 +00:00
2021-06-10 13:35:44 +00:00
func ( suite * USDXRewardsTestSuite ) TestAccumulateUSDXMintingRewards ( ) {
2021-05-04 14:47:21 +00:00
type args struct {
ctype string
rewardsPerSecond sdk . Coin
initialTotalPrincipal sdk . Coin
timeElapsed int
expectedRewardFactor sdk . Dec
}
type test struct {
name string
args args
}
testCases := [ ] test {
{
"7 seconds" ,
args {
ctype : "bnb-a" ,
rewardsPerSecond : c ( "ukava" , 122354 ) ,
initialTotalPrincipal : c ( "usdx" , 1000000000000 ) ,
timeElapsed : 7 ,
expectedRewardFactor : d ( "0.000000856478000000" ) ,
} ,
} ,
{
"1 day" ,
args {
ctype : "bnb-a" ,
rewardsPerSecond : c ( "ukava" , 122354 ) ,
initialTotalPrincipal : c ( "usdx" , 1000000000000 ) ,
timeElapsed : 86400 ,
expectedRewardFactor : d ( "0.0105713856" ) ,
} ,
} ,
{
"0 seconds" ,
args {
ctype : "bnb-a" ,
rewardsPerSecond : c ( "ukava" , 122354 ) ,
initialTotalPrincipal : c ( "usdx" , 1000000000000 ) ,
timeElapsed : 0 ,
expectedRewardFactor : d ( "0.0" ) ,
} ,
} ,
}
for _ , tc := range testCases {
suite . Run ( tc . name , func ( ) {
2021-07-15 14:05:54 +00:00
incentBuilder := testutil . NewIncentiveGenesisBuilder ( ) . WithGenesisTime ( suite . genesisTime ) . WithSimpleUSDXRewardPeriod ( tc . args . ctype , tc . args . rewardsPerSecond )
2021-06-10 13:35:44 +00:00
2022-01-08 00:39:27 +00:00
suite . SetupWithGenState ( app . NewAuthBankGenesisBuilder ( ) , incentBuilder )
2021-05-04 14:47:21 +00:00
// setup cdp state
2021-06-10 13:35:44 +00:00
suite . cdpKeeper . SetTotalPrincipal ( suite . ctx , tc . args . ctype , cdptypes . DefaultStableDenom , tc . args . initialTotalPrincipal . Amount )
2021-05-04 14:47:21 +00:00
updatedBlockTime := suite . ctx . BlockTime ( ) . Add ( time . Duration ( int ( time . Second ) * tc . args . timeElapsed ) )
suite . ctx = suite . ctx . WithBlockTime ( updatedBlockTime )
rewardPeriod , found := suite . keeper . GetUSDXMintingRewardPeriod ( suite . ctx , tc . args . ctype )
suite . Require ( ) . True ( found )
2021-07-22 12:53:18 +00:00
suite . keeper . AccumulateUSDXMintingRewards ( suite . ctx , rewardPeriod )
2021-05-04 14:47:21 +00:00
2021-06-10 13:35:44 +00:00
rewardFactor , _ := suite . keeper . GetUSDXMintingRewardFactor ( suite . ctx , tc . args . ctype )
2021-05-04 14:47:21 +00:00
suite . Require ( ) . Equal ( tc . args . expectedRewardFactor , rewardFactor )
} )
}
}
2021-06-10 13:35:44 +00:00
func ( suite * USDXRewardsTestSuite ) TestSynchronizeUSDXMintingReward ( ) {
2021-05-04 14:47:21 +00:00
type args struct {
ctype string
rewardsPerSecond sdk . Coin
initialCollateral sdk . Coin
initialPrincipal sdk . Coin
blockTimes [ ] int
expectedRewardFactor sdk . Dec
expectedRewards sdk . Coin
}
type test struct {
name string
args args
}
testCases := [ ] test {
{
"10 blocks" ,
args {
ctype : "bnb-a" ,
rewardsPerSecond : c ( "ukava" , 122354 ) ,
initialCollateral : c ( "bnb" , 1000000000000 ) ,
initialPrincipal : c ( "usdx" , 10000000000 ) ,
blockTimes : [ ] int { 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 } ,
expectedRewardFactor : d ( "0.001223540000000000" ) ,
expectedRewards : c ( "ukava" , 12235400 ) ,
} ,
} ,
{
"10 blocks - long block time" ,
args {
ctype : "bnb-a" ,
rewardsPerSecond : c ( "ukava" , 122354 ) ,
initialCollateral : c ( "bnb" , 1000000000000 ) ,
initialPrincipal : c ( "usdx" , 10000000000 ) ,
blockTimes : [ ] int { 86400 , 86400 , 86400 , 86400 , 86400 , 86400 , 86400 , 86400 , 86400 , 86400 } ,
expectedRewardFactor : d ( "10.57138560000000000" ) ,
expectedRewards : c ( "ukava" , 105713856000 ) ,
} ,
} ,
}
for _ , tc := range testCases {
suite . Run ( tc . name , func ( ) {
2022-01-08 00:39:27 +00:00
authBuilder := app . NewAuthBankGenesisBuilder ( ) . WithSimpleAccount ( suite . addrs [ 0 ] , cs ( tc . args . initialCollateral ) )
2021-07-15 14:05:54 +00:00
incentBuilder := testutil . NewIncentiveGenesisBuilder ( ) . WithGenesisTime ( suite . genesisTime ) . WithSimpleUSDXRewardPeriod ( tc . args . ctype , tc . args . rewardsPerSecond )
2021-06-10 13:35:44 +00:00
suite . SetupWithGenState ( authBuilder , incentBuilder )
2021-05-04 14:47:21 +00:00
// setup cdp state
2021-06-10 13:35:44 +00:00
err := suite . cdpKeeper . AddCdp ( suite . ctx , suite . addrs [ 0 ] , tc . args . initialCollateral , tc . args . initialPrincipal , tc . args . ctype )
2021-05-04 14:47:21 +00:00
suite . Require ( ) . NoError ( err )
claim , found := suite . keeper . GetUSDXMintingClaim ( suite . ctx , suite . addrs [ 0 ] )
suite . Require ( ) . True ( found )
suite . Require ( ) . Equal ( sdk . ZeroDec ( ) , claim . RewardIndexes [ 0 ] . RewardFactor )
var timeElapsed int
previousBlockTime := suite . ctx . BlockTime ( )
for _ , t := range tc . args . blockTimes {
timeElapsed += t
updatedBlockTime := previousBlockTime . Add ( time . Duration ( int ( time . Second ) * t ) )
previousBlockTime = updatedBlockTime
blockCtx := suite . ctx . WithBlockTime ( updatedBlockTime )
rewardPeriod , found := suite . keeper . GetUSDXMintingRewardPeriod ( blockCtx , tc . args . ctype )
suite . Require ( ) . True ( found )
2021-07-22 12:53:18 +00:00
suite . keeper . AccumulateUSDXMintingRewards ( blockCtx , rewardPeriod )
2021-05-04 14:47:21 +00:00
}
updatedBlockTime := suite . ctx . BlockTime ( ) . Add ( time . Duration ( int ( time . Second ) * timeElapsed ) )
suite . ctx = suite . ctx . WithBlockTime ( updatedBlockTime )
2021-06-10 13:35:44 +00:00
cdp , found := suite . cdpKeeper . GetCdpByOwnerAndCollateralType ( suite . ctx , suite . addrs [ 0 ] , tc . args . ctype )
2021-05-04 14:47:21 +00:00
suite . Require ( ) . True ( found )
suite . Require ( ) . NotPanics ( func ( ) {
suite . keeper . SynchronizeUSDXMintingReward ( suite . ctx , cdp )
} )
2021-06-10 13:35:44 +00:00
rewardFactor , _ := suite . keeper . GetUSDXMintingRewardFactor ( suite . ctx , tc . args . ctype )
2021-05-04 14:47:21 +00:00
suite . Require ( ) . Equal ( tc . args . expectedRewardFactor , rewardFactor )
claim , found = suite . keeper . GetUSDXMintingClaim ( suite . ctx , suite . addrs [ 0 ] )
suite . Require ( ) . True ( found )
suite . Require ( ) . Equal ( tc . args . expectedRewardFactor , claim . RewardIndexes [ 0 ] . RewardFactor )
suite . Require ( ) . Equal ( tc . args . expectedRewards , claim . Reward )
} )
}
}
2021-06-10 13:35:44 +00:00
func ( suite * USDXRewardsTestSuite ) TestSimulateUSDXMintingRewardSynchronization ( ) {
2021-05-04 14:47:21 +00:00
type args struct {
ctype string
2021-06-10 13:35:44 +00:00
rewardsPerSecond sdk . Coin
2021-05-04 14:47:21 +00:00
initialCollateral sdk . Coin
initialPrincipal sdk . Coin
blockTimes [ ] int
expectedRewardFactor sdk . Dec
expectedRewards sdk . Coin
}
type test struct {
name string
args args
}
testCases := [ ] test {
{
"10 blocks" ,
args {
ctype : "bnb-a" ,
2021-06-10 13:35:44 +00:00
rewardsPerSecond : c ( "ukava" , 122354 ) ,
2021-05-04 14:47:21 +00:00
initialCollateral : c ( "bnb" , 1000000000000 ) ,
initialPrincipal : c ( "usdx" , 10000000000 ) ,
blockTimes : [ ] int { 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 } ,
expectedRewardFactor : d ( "0.001223540000000000" ) ,
expectedRewards : c ( "ukava" , 12235400 ) ,
} ,
} ,
{
"10 blocks - long block time" ,
args {
ctype : "bnb-a" ,
2021-06-10 13:35:44 +00:00
rewardsPerSecond : c ( "ukava" , 122354 ) ,
2021-05-04 14:47:21 +00:00
initialCollateral : c ( "bnb" , 1000000000000 ) ,
initialPrincipal : c ( "usdx" , 10000000000 ) ,
blockTimes : [ ] int { 86400 , 86400 , 86400 , 86400 , 86400 , 86400 , 86400 , 86400 , 86400 , 86400 } ,
expectedRewardFactor : d ( "10.57138560000000000" ) ,
expectedRewards : c ( "ukava" , 105713856000 ) ,
} ,
} ,
}
for _ , tc := range testCases {
suite . Run ( tc . name , func ( ) {
2022-01-08 00:39:27 +00:00
authBuilder := app . NewAuthBankGenesisBuilder ( ) . WithSimpleAccount ( suite . addrs [ 0 ] , cs ( tc . args . initialCollateral ) )
2021-07-15 14:05:54 +00:00
incentBuilder := testutil . NewIncentiveGenesisBuilder ( ) . WithGenesisTime ( suite . genesisTime ) . WithSimpleUSDXRewardPeriod ( tc . args . ctype , tc . args . rewardsPerSecond )
2021-06-10 13:35:44 +00:00
suite . SetupWithGenState ( authBuilder , incentBuilder )
2021-05-04 14:47:21 +00:00
// setup cdp state
2021-06-10 13:35:44 +00:00
err := suite . cdpKeeper . AddCdp ( suite . ctx , suite . addrs [ 0 ] , tc . args . initialCollateral , tc . args . initialPrincipal , tc . args . ctype )
2021-05-04 14:47:21 +00:00
suite . Require ( ) . NoError ( err )
claim , found := suite . keeper . GetUSDXMintingClaim ( suite . ctx , suite . addrs [ 0 ] )
suite . Require ( ) . True ( found )
suite . Require ( ) . Equal ( sdk . ZeroDec ( ) , claim . RewardIndexes [ 0 ] . RewardFactor )
var timeElapsed int
previousBlockTime := suite . ctx . BlockTime ( )
for _ , t := range tc . args . blockTimes {
timeElapsed += t
updatedBlockTime := previousBlockTime . Add ( time . Duration ( int ( time . Second ) * t ) )
previousBlockTime = updatedBlockTime
blockCtx := suite . ctx . WithBlockTime ( updatedBlockTime )
rewardPeriod , found := suite . keeper . GetUSDXMintingRewardPeriod ( blockCtx , tc . args . ctype )
suite . Require ( ) . True ( found )
2021-07-22 12:53:18 +00:00
suite . keeper . AccumulateUSDXMintingRewards ( blockCtx , rewardPeriod )
2021-05-04 14:47:21 +00:00
}
updatedBlockTime := suite . ctx . BlockTime ( ) . Add ( time . Duration ( int ( time . Second ) * timeElapsed ) )
suite . ctx = suite . ctx . WithBlockTime ( updatedBlockTime )
claim , found = suite . keeper . GetUSDXMintingClaim ( suite . ctx , suite . addrs [ 0 ] )
suite . Require ( ) . True ( found )
suite . Require ( ) . Equal ( claim . RewardIndexes [ 0 ] . RewardFactor , sdk . ZeroDec ( ) )
suite . Require ( ) . Equal ( claim . Reward , sdk . NewCoin ( "ukava" , sdk . ZeroInt ( ) ) )
updatedClaim := suite . keeper . SimulateUSDXMintingSynchronization ( suite . ctx , claim )
suite . Require ( ) . Equal ( tc . args . expectedRewardFactor , updatedClaim . RewardIndexes [ 0 ] . RewardFactor )
suite . Require ( ) . Equal ( tc . args . expectedRewards , updatedClaim . Reward )
} )
}
}
2021-06-10 13:35:44 +00:00
func TestUSDXRewardsTestSuite ( t * testing . T ) {
suite . Run ( t , new ( USDXRewardsTestSuite ) )
}