@velocity-exchange/sdk 0.4.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/lib/browser/adminClient.d.ts +52 -0
- package/lib/browser/adminClient.js +97 -0
- package/lib/browser/config.js +6 -7
- package/lib/browser/constants/numericConstants.d.ts +1 -1
- package/lib/browser/constants/numericConstants.js +1 -1
- package/lib/browser/decode/user.js +5 -1
- package/lib/browser/idl/velocity.d.ts +191 -15
- package/lib/browser/idl/velocity.json +192 -16
- package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +1 -0
- package/lib/browser/orderSubscriber/OrderSubscriber.js +10 -4
- package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
- package/lib/browser/types.d.ts +6 -0
- package/lib/browser/user.d.ts +20 -3
- package/lib/browser/user.js +52 -4
- package/lib/browser/velocityClient.d.ts +46 -10
- package/lib/browser/velocityClient.js +107 -35
- package/lib/node/adminClient.d.ts +52 -0
- package/lib/node/adminClient.d.ts.map +1 -1
- package/lib/node/adminClient.js +97 -0
- package/lib/node/config.d.ts.map +1 -1
- package/lib/node/config.js +6 -7
- package/lib/node/constants/numericConstants.d.ts +1 -1
- package/lib/node/constants/numericConstants.d.ts.map +1 -1
- package/lib/node/constants/numericConstants.js +1 -1
- package/lib/node/decode/user.d.ts.map +1 -1
- package/lib/node/decode/user.js +5 -1
- package/lib/node/idl/velocity.d.ts +191 -15
- package/lib/node/idl/velocity.d.ts.map +1 -1
- package/lib/node/idl/velocity.json +192 -16
- package/lib/node/orderSubscriber/OrderSubscriber.d.ts +1 -0
- package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
- package/lib/node/orderSubscriber/OrderSubscriber.js +10 -4
- package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
- package/lib/node/pyth/pythLazerSubscriber.js +37 -27
- package/lib/node/types.d.ts +6 -0
- package/lib/node/types.d.ts.map +1 -1
- package/lib/node/user.d.ts +20 -3
- package/lib/node/user.d.ts.map +1 -1
- package/lib/node/user.js +52 -4
- package/lib/node/velocityClient.d.ts +46 -10
- package/lib/node/velocityClient.d.ts.map +1 -1
- package/lib/node/velocityClient.js +107 -35
- package/package.json +7 -3
- package/.prettierignore +0 -1
- package/CHANGELOG.md +0 -132
- package/build-browser.js +0 -58
- package/bunfig.toml +0 -3
- package/esbuild-shims.js +0 -12
- package/scripts/deposit-isolated-positions.ts +0 -110
- package/scripts/find-flagged-users.ts +0 -213
- package/scripts/grpc-client-test-comparison.ts +0 -372
- package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
- package/scripts/postbuild.js +0 -95
- package/scripts/single-grpc-client-test.ts +0 -284
- package/scripts/withdraw-isolated-positions.ts +0 -174
- package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
- package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
- package/src/accounts/basicUserAccountSubscriber.ts +0 -79
- package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
- package/src/accounts/bulkAccountLoader.ts +0 -358
- package/src/accounts/bulkUserStatsSubscription.ts +0 -40
- package/src/accounts/bulkUserSubscription.ts +0 -39
- package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
- package/src/accounts/fetch.ts +0 -200
- package/src/accounts/grpcAccountSubscriber.ts +0 -225
- package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
- package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
- package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
- package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
- package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
- package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
- package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
- package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
- package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
- package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
- package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
- package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
- package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
- package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
- package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
- package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
- package/src/accounts/testBulkAccountLoader.ts +0 -59
- package/src/accounts/types.ts +0 -428
- package/src/accounts/utils.ts +0 -90
- package/src/accounts/webSocketAccountSubscriber.ts +0 -304
- package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
- package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
- package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
- package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
- package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
- package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
- package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
- package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
- package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
- package/src/addresses/marketAddresses.ts +0 -28
- package/src/addresses/pda.ts +0 -620
- package/src/adminClient.ts +0 -8136
- package/src/assert/assert.ts +0 -5
- package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
- package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
- package/src/auctionSubscriber/index.ts +0 -9
- package/src/auctionSubscriber/types.ts +0 -30
- package/src/bankrun/bankrunConnection.ts +0 -630
- package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
- package/src/blockhashSubscriber/index.ts +0 -6
- package/src/blockhashSubscriber/types.ts +0 -13
- package/src/clock/clockSubscriber.ts +0 -146
- package/src/config.ts +0 -312
- package/src/constants/index.ts +0 -9
- package/src/constants/numericConstants.ts +0 -194
- package/src/constants/perpMarkets.ts +0 -127
- package/src/constants/spotMarkets.ts +0 -104
- package/src/constants/txConstants.ts +0 -2
- package/src/constituentMap/constituentMap.ts +0 -305
- package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
- package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
- package/src/core/VelocityCore.ts +0 -606
- package/src/core/index.ts +0 -12
- package/src/core/instructions/deposit.ts +0 -64
- package/src/core/instructions/fill.ts +0 -51
- package/src/core/instructions/funding.ts +0 -33
- package/src/core/instructions/liquidation.ts +0 -55
- package/src/core/instructions/orders.ts +0 -84
- package/src/core/instructions/perpOrders.ts +0 -312
- package/src/core/instructions/settlement.ts +0 -40
- package/src/core/instructions/trigger.ts +0 -41
- package/src/core/instructions/withdraw.ts +0 -65
- package/src/core/remainingAccounts.ts +0 -320
- package/src/core/signedMsg.ts +0 -109
- package/src/decode/customCoder.ts +0 -148
- package/src/decode/user.ts +0 -401
- package/src/dlob/DLOB.ts +0 -2793
- package/src/dlob/DLOBNode.ts +0 -305
- package/src/dlob/DLOBSubscriber.ts +0 -269
- package/src/dlob/NodeList.ts +0 -244
- package/src/dlob/orderBookLevels.ts +0 -695
- package/src/dlob/types.ts +0 -37
- package/src/events/eventList.ts +0 -114
- package/src/events/eventSubscriber.ts +0 -521
- package/src/events/eventsServerLogProvider.ts +0 -189
- package/src/events/fetchLogs.ts +0 -219
- package/src/events/parse.ts +0 -271
- package/src/events/pollingLogProvider.ts +0 -113
- package/src/events/sort.ts +0 -51
- package/src/events/txEventCache.ts +0 -92
- package/src/events/types.ts +0 -337
- package/src/events/webSocketLogProvider.ts +0 -152
- package/src/factory/bigNum.ts +0 -709
- package/src/factory/oracleClient.ts +0 -73
- package/src/idl/pyth.json +0 -142
- package/src/idl/pyth.ts +0 -97
- package/src/idl/pyth_solana_receiver.json +0 -628
- package/src/idl/token_faucet.json +0 -229
- package/src/idl/token_faucet.ts +0 -197
- package/src/idl/velocity.json +0 -23974
- package/src/idl/velocity.ts +0 -23980
- package/src/index.ts +0 -150
- package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
- package/src/isomorphic/README.md +0 -19
- package/src/isomorphic/anchor.browser.ts +0 -44
- package/src/isomorphic/anchor.node.ts +0 -1
- package/src/isomorphic/anchor.ts +0 -1
- package/src/isomorphic/anchor29.browser.ts +0 -24
- package/src/isomorphic/anchor29.node.ts +0 -1
- package/src/isomorphic/anchor29.ts +0 -1
- package/src/isomorphic/grpc.browser.ts +0 -4
- package/src/isomorphic/grpc.node.ts +0 -130
- package/src/isomorphic/grpc.ts +0 -1
- package/src/jupiter/jupiterClient.ts +0 -502
- package/src/keypair.ts +0 -32
- package/src/margin/README.md +0 -138
- package/src/marginCalculation.ts +0 -407
- package/src/marinade/idl/idl.json +0 -1962
- package/src/marinade/index.ts +0 -73
- package/src/marinade/types.ts +0 -3925
- package/src/math/amm.ts +0 -1758
- package/src/math/auction.ts +0 -480
- package/src/math/bankruptcy.ts +0 -138
- package/src/math/builder.ts +0 -130
- package/src/math/conversion.ts +0 -45
- package/src/math/exchangeStatus.ts +0 -261
- package/src/math/funding.ts +0 -498
- package/src/math/insurance.ts +0 -171
- package/src/math/liquidation.ts +0 -433
- package/src/math/margin.ts +0 -327
- package/src/math/market.ts +0 -487
- package/src/math/oracles.ts +0 -477
- package/src/math/orders.ts +0 -500
- package/src/math/position.ts +0 -381
- package/src/math/repeg.ts +0 -223
- package/src/math/spotBalance.ts +0 -996
- package/src/math/spotMarket.ts +0 -115
- package/src/math/spotPosition.ts +0 -263
- package/src/math/state.ts +0 -71
- package/src/math/superStake.ts +0 -602
- package/src/math/tiers.ts +0 -73
- package/src/math/trade.ts +0 -879
- package/src/math/utils.ts +0 -183
- package/src/memcmp.ts +0 -279
- package/src/oracles/oracleClientCache.ts +0 -41
- package/src/oracles/oracleId.ts +0 -99
- package/src/oracles/prelaunchOracleClient.ts +0 -63
- package/src/oracles/pythClient.ts +0 -125
- package/src/oracles/pythLazerClient.ts +0 -141
- package/src/oracles/quoteAssetOracleClient.ts +0 -43
- package/src/oracles/strictOraclePrice.ts +0 -40
- package/src/oracles/types.ts +0 -82
- package/src/oracles/utils.ts +0 -45
- package/src/orderParams.ts +0 -117
- package/src/orderSubscriber/OrderSubscriber.ts +0 -378
- package/src/orderSubscriber/PollingSubscription.ts +0 -50
- package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
- package/src/orderSubscriber/grpcSubscription.ts +0 -155
- package/src/orderSubscriber/index.ts +0 -7
- package/src/orderSubscriber/types.ts +0 -64
- package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
- package/src/priorityFee/averageStrategy.ts +0 -13
- package/src/priorityFee/ewmaStrategy.ts +0 -51
- package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
- package/src/priorityFee/index.ts +0 -16
- package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
- package/src/priorityFee/maxStrategy.ts +0 -8
- package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
- package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
- package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
- package/src/priorityFee/types.ts +0 -82
- package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
- package/src/pyth/constants.ts +0 -9
- package/src/pyth/index.ts +0 -15
- package/src/pyth/pythLazerSubscriber.ts +0 -365
- package/src/pyth/types.ts +0 -4451
- package/src/pyth/utils.ts +0 -13
- package/src/slot/SlotSubscriber.ts +0 -126
- package/src/slot/SlothashSubscriber.ts +0 -163
- package/src/swap/UnifiedSwapClient.ts +0 -315
- package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
- package/src/swift/index.ts +0 -10
- package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
- package/src/swift/swiftOrderSubscriber.ts +0 -351
- package/src/testClient.ts +0 -42
- package/src/titan/titanClient.ts +0 -438
- package/src/token/index.ts +0 -13
- package/src/tokenFaucet.ts +0 -296
- package/src/tx/baseTxSender.ts +0 -651
- package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
- package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
- package/src/tx/blockhashFetcher/types.ts +0 -9
- package/src/tx/fastSingleTxSender.ts +0 -200
- package/src/tx/forwardOnlyTxSender.ts +0 -193
- package/src/tx/priorityFeeCalculator.ts +0 -117
- package/src/tx/reportTransactionError.ts +0 -176
- package/src/tx/retryTxSender.ts +0 -177
- package/src/tx/txHandler.ts +0 -1009
- package/src/tx/txParamProcessor.ts +0 -225
- package/src/tx/types.ts +0 -117
- package/src/tx/utils.ts +0 -133
- package/src/tx/whileValidTxSender.ts +0 -377
- package/src/types.ts +0 -2575
- package/src/user.ts +0 -5316
- package/src/userConfig.ts +0 -38
- package/src/userMap/PollingSubscription.ts +0 -61
- package/src/userMap/WebsocketSubscription.ts +0 -93
- package/src/userMap/grpcSubscription.ts +0 -93
- package/src/userMap/referrerMap.ts +0 -360
- package/src/userMap/revenueShareEscrowMap.ts +0 -342
- package/src/userMap/userMap.ts +0 -784
- package/src/userMap/userMapConfig.ts +0 -82
- package/src/userMap/userStatsMap.ts +0 -393
- package/src/userName.ts +0 -37
- package/src/userStats.ts +0 -159
- package/src/userStatsConfig.ts +0 -35
- package/src/util/TransactionConfirmationManager.ts +0 -333
- package/src/util/chainClock.ts +0 -65
- package/src/util/computeUnits.ts +0 -101
- package/src/util/digest.ts +0 -33
- package/src/util/ed25519Utils.ts +0 -95
- package/src/util/promiseTimeout.ts +0 -23
- package/src/velocityClient.ts +0 -14802
- package/src/velocityClientConfig.ts +0 -119
- package/src/wallet.ts +0 -91
- package/tests/VelocityCore/builder_escrow.test.ts +0 -121
- package/tests/VelocityCore/decode.test.ts +0 -16
- package/tests/VelocityCore/fill_trigger.test.ts +0 -73
- package/tests/VelocityCore/instructions.test.ts +0 -46
- package/tests/VelocityCore/pdas.test.ts +0 -30
- package/tests/VelocityCore/perp_orders.test.ts +0 -205
- package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
- package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
- package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
- package/tests/amm/test.ts +0 -2402
- package/tests/auctions/test.ts +0 -81
- package/tests/bn/test.ts +0 -355
- package/tests/builder/builderFee.test.ts +0 -42
- package/tests/ci/verifyConstants.ts +0 -393
- package/tests/decode/test.ts +0 -262
- package/tests/decode/userAccountBufferStrings.ts +0 -102
- package/tests/dlob/helpers.ts +0 -748
- package/tests/dlob/test.ts +0 -6969
- package/tests/dlob/tickSizeStandardization.ts +0 -545
- package/tests/events/parseLogsForCuUsage.ts +0 -139
- package/tests/exchangeStatus/test.ts +0 -45
- package/tests/insurance/test.ts +0 -40
- package/tests/liquidation/test.ts +0 -125
- package/tests/oracles/mmOracleGate.test.ts +0 -379
- package/tests/oracles/pythPegSnap.test.ts +0 -76
- package/tests/sdkParity/enumParity.test.ts +0 -84
- package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
- package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
- package/tests/spot/test.ts +0 -281
- package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
- package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
- package/tests/tx/priorityFeeCalculator.ts +0 -77
- package/tests/tx/priorityFeeStrategy.ts +0 -95
- package/tests/user/bankruptcy.ts +0 -165
- package/tests/user/feeAndWithdrawLimits.ts +0 -284
- package/tests/user/getMarginCalculation.ts +0 -586
- package/tests/user/helpers.ts +0 -184
- package/tests/user/liquidations.ts +0 -129
- package/tests/user/marginCalculations.test.ts +0 -321
- package/tests/user/test.ts +0 -833
- package/tsconfig.browser.json +0 -18
- package/tsconfig.json +0 -36
package/tests/user/bankruptcy.ts
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import { assert } from 'chai';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { PositionFlag } from '../../src/types';
|
|
4
|
-
import {
|
|
5
|
-
BASE_PRECISION,
|
|
6
|
-
QUOTE_PRECISION,
|
|
7
|
-
} from '../../src/constants/numericConstants';
|
|
8
|
-
import { BN } from '../../src';
|
|
9
|
-
import { mockPerpMarkets, mockSpotMarkets } from '../dlob/helpers';
|
|
10
|
-
import {
|
|
11
|
-
mockUserAccount as baseMockUserAccount,
|
|
12
|
-
makeMockUser,
|
|
13
|
-
} from './helpers';
|
|
14
|
-
import {
|
|
15
|
-
isUserBankrupt,
|
|
16
|
-
isIsolatedPositionBankrupt,
|
|
17
|
-
hasIsolatedMarginBankrupt,
|
|
18
|
-
} from '../../src/math/bankruptcy';
|
|
19
|
-
|
|
20
|
-
async function makeUserWithAccount(account) {
|
|
21
|
-
const user = await makeMockUser(
|
|
22
|
-
_.cloneDeep(mockPerpMarkets),
|
|
23
|
-
_.cloneDeep(mockSpotMarkets),
|
|
24
|
-
account,
|
|
25
|
-
[1, 1, 1, 1, 1, 1, 1, 1],
|
|
26
|
-
[1, 1, 1, 1, 1, 1, 1, 1]
|
|
27
|
-
);
|
|
28
|
-
return user;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
describe('isUserBankrupt', () => {
|
|
32
|
-
it('cross-bankrupt user is still bankrupt when an open isolated position is present', async () => {
|
|
33
|
-
const account = _.cloneDeep(baseMockUserAccount);
|
|
34
|
-
|
|
35
|
-
// cross position: no base, negative quote (liability), no open orders -> cross-bankrupt shape
|
|
36
|
-
account.perpPositions[0].marketIndex = 0;
|
|
37
|
-
account.perpPositions[0].baseAssetAmount = new BN(0);
|
|
38
|
-
account.perpPositions[0].quoteAssetAmount = new BN(-100).mul(
|
|
39
|
-
QUOTE_PRECISION
|
|
40
|
-
);
|
|
41
|
-
account.perpPositions[0].positionFlag = 0;
|
|
42
|
-
|
|
43
|
-
// isolated position: still open (nonzero base) - would have tripped the old
|
|
44
|
-
// unconditional loop into reporting "not bankrupt"
|
|
45
|
-
account.perpPositions[1].marketIndex = 1;
|
|
46
|
-
account.perpPositions[1].baseAssetAmount = new BN(5).mul(BASE_PRECISION);
|
|
47
|
-
account.perpPositions[1].quoteAssetAmount = new BN(0);
|
|
48
|
-
account.perpPositions[1].positionFlag = PositionFlag.IsolatedPosition;
|
|
49
|
-
|
|
50
|
-
const user = await makeUserWithAccount(account);
|
|
51
|
-
|
|
52
|
-
assert.equal(isUserBankrupt(user), true);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('user with no liability is not bankrupt', async () => {
|
|
56
|
-
const account = _.cloneDeep(baseMockUserAccount);
|
|
57
|
-
const user = await makeUserWithAccount(account);
|
|
58
|
-
assert.equal(isUserBankrupt(user), false);
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
describe('isIsolatedPositionBankrupt', () => {
|
|
63
|
-
it('isolated position with no deposit, no base, and a quote liability is bankrupt', async () => {
|
|
64
|
-
const account = _.cloneDeep(baseMockUserAccount);
|
|
65
|
-
|
|
66
|
-
account.perpPositions[0].marketIndex = 0;
|
|
67
|
-
account.perpPositions[0].baseAssetAmount = new BN(0);
|
|
68
|
-
account.perpPositions[0].quoteAssetAmount = new BN(-50).mul(
|
|
69
|
-
QUOTE_PRECISION
|
|
70
|
-
);
|
|
71
|
-
account.perpPositions[0].positionFlag = PositionFlag.IsolatedPosition;
|
|
72
|
-
account.perpPositions[0].isolatedPositionScaledBalance = new BN(0);
|
|
73
|
-
|
|
74
|
-
const user = await makeUserWithAccount(account);
|
|
75
|
-
|
|
76
|
-
assert.equal(isIsolatedPositionBankrupt(user, 0), true);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('isolated position with a remaining deposit is not bankrupt', async () => {
|
|
80
|
-
const account = _.cloneDeep(baseMockUserAccount);
|
|
81
|
-
|
|
82
|
-
account.perpPositions[0].marketIndex = 0;
|
|
83
|
-
account.perpPositions[0].baseAssetAmount = new BN(0);
|
|
84
|
-
account.perpPositions[0].quoteAssetAmount = new BN(-50).mul(
|
|
85
|
-
QUOTE_PRECISION
|
|
86
|
-
);
|
|
87
|
-
account.perpPositions[0].positionFlag = PositionFlag.IsolatedPosition;
|
|
88
|
-
account.perpPositions[0].isolatedPositionScaledBalance = new BN(1000);
|
|
89
|
-
|
|
90
|
-
const user = await makeUserWithAccount(account);
|
|
91
|
-
|
|
92
|
-
assert.equal(isIsolatedPositionBankrupt(user, 0), false);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('throws (InvalidPerpPosition) on a non-isolated position', async () => {
|
|
96
|
-
const account = _.cloneDeep(baseMockUserAccount);
|
|
97
|
-
|
|
98
|
-
account.perpPositions[0].marketIndex = 0;
|
|
99
|
-
account.perpPositions[0].baseAssetAmount = new BN(0);
|
|
100
|
-
account.perpPositions[0].quoteAssetAmount = new BN(-50).mul(
|
|
101
|
-
QUOTE_PRECISION
|
|
102
|
-
);
|
|
103
|
-
account.perpPositions[0].positionFlag = 0; // not isolated
|
|
104
|
-
account.perpPositions[0].isolatedPositionScaledBalance = new BN(0);
|
|
105
|
-
|
|
106
|
-
const user = await makeUserWithAccount(account);
|
|
107
|
-
|
|
108
|
-
assert.throws(() => isIsolatedPositionBankrupt(user, 0), /not an isolated/);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('hasIsolatedMarginBankrupt', () => {
|
|
113
|
-
it('detects an economically-bankrupt isolated position (flag not yet set on-chain)', async () => {
|
|
114
|
-
const account = _.cloneDeep(baseMockUserAccount);
|
|
115
|
-
|
|
116
|
-
// isolated: drained deposit, flat base, quote liability, no open orders,
|
|
117
|
-
// but the on-chain Bankrupt status flag has NOT been set yet.
|
|
118
|
-
account.perpPositions[0].marketIndex = 1;
|
|
119
|
-
account.perpPositions[0].baseAssetAmount = new BN(0);
|
|
120
|
-
account.perpPositions[0].quoteAssetAmount = new BN(-25).mul(
|
|
121
|
-
QUOTE_PRECISION
|
|
122
|
-
);
|
|
123
|
-
account.perpPositions[0].positionFlag = PositionFlag.IsolatedPosition;
|
|
124
|
-
account.perpPositions[0].isolatedPositionScaledBalance = new BN(0);
|
|
125
|
-
|
|
126
|
-
const user = await makeUserWithAccount(account);
|
|
127
|
-
|
|
128
|
-
// isUserBankrupt (cross) deliberately skips isolated positions, and
|
|
129
|
-
// user.isBankrupt() only reads UserStatus.BANKRUPT -> both miss this.
|
|
130
|
-
assert.equal(isUserBankrupt(user), false);
|
|
131
|
-
assert.equal(user.isBankrupt(), false);
|
|
132
|
-
assert.equal(hasIsolatedMarginBankrupt(user), true);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('detects an isolated position already flagged Bankrupt on-chain', async () => {
|
|
136
|
-
const account = _.cloneDeep(baseMockUserAccount);
|
|
137
|
-
|
|
138
|
-
// still has collateral / non-flat, so not economically bankrupt by shape,
|
|
139
|
-
// but the program already set the Bankrupt position flag.
|
|
140
|
-
account.perpPositions[0].marketIndex = 1;
|
|
141
|
-
account.perpPositions[0].baseAssetAmount = new BN(3).mul(BASE_PRECISION);
|
|
142
|
-
account.perpPositions[0].quoteAssetAmount = new BN(0);
|
|
143
|
-
account.perpPositions[0].isolatedPositionScaledBalance = new BN(1000);
|
|
144
|
-
account.perpPositions[0].positionFlag =
|
|
145
|
-
PositionFlag.IsolatedPosition | PositionFlag.Bankruptcy;
|
|
146
|
-
|
|
147
|
-
const user = await makeUserWithAccount(account);
|
|
148
|
-
|
|
149
|
-
assert.equal(hasIsolatedMarginBankrupt(user), true);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it('returns false for a healthy isolated position', async () => {
|
|
153
|
-
const account = _.cloneDeep(baseMockUserAccount);
|
|
154
|
-
|
|
155
|
-
account.perpPositions[0].marketIndex = 1;
|
|
156
|
-
account.perpPositions[0].baseAssetAmount = new BN(3).mul(BASE_PRECISION);
|
|
157
|
-
account.perpPositions[0].quoteAssetAmount = new BN(0);
|
|
158
|
-
account.perpPositions[0].positionFlag = PositionFlag.IsolatedPosition;
|
|
159
|
-
account.perpPositions[0].isolatedPositionScaledBalance = new BN(1000);
|
|
160
|
-
|
|
161
|
-
const user = await makeUserWithAccount(account);
|
|
162
|
-
|
|
163
|
-
assert.equal(hasIsolatedMarginBankrupt(user), false);
|
|
164
|
-
});
|
|
165
|
-
});
|
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BN,
|
|
3
|
-
ZERO,
|
|
4
|
-
User,
|
|
5
|
-
MarketType,
|
|
6
|
-
SpotBalanceType,
|
|
7
|
-
ReferrerStatus,
|
|
8
|
-
UserStatsAccount,
|
|
9
|
-
SPOT_MARKET_BALANCE_PRECISION,
|
|
10
|
-
} from '../../src';
|
|
11
|
-
import { assert } from '../../src/assert/assert';
|
|
12
|
-
import { mockPerpMarkets, mockSpotMarkets } from '../dlob/helpers';
|
|
13
|
-
import {
|
|
14
|
-
mockUserAccount as baseMockUserAccount,
|
|
15
|
-
makeMockUser,
|
|
16
|
-
} from './helpers';
|
|
17
|
-
import * as _ from 'lodash';
|
|
18
|
-
|
|
19
|
-
const mockFeeTier = {
|
|
20
|
-
feeNumerator: 1,
|
|
21
|
-
feeDenominator: 1000,
|
|
22
|
-
makerRebateNumerator: 0,
|
|
23
|
-
makerRebateDenominator: 1000,
|
|
24
|
-
referrerRewardNumerator: 0,
|
|
25
|
-
referrerRewardDenominator: 100,
|
|
26
|
-
refereeFeeNumerator: 25,
|
|
27
|
-
refereeFeeDenominator: 100,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const mockFeeStructure = {
|
|
31
|
-
feeTiers: Array.from({ length: 6 }, () => ({ ...mockFeeTier })),
|
|
32
|
-
fillerRewardStructure: {
|
|
33
|
-
rewardNumerator: 0,
|
|
34
|
-
rewardDenominator: 1,
|
|
35
|
-
timeBasedRewardLowerBound: ZERO,
|
|
36
|
-
},
|
|
37
|
-
flatFillerFee: ZERO,
|
|
38
|
-
ammFeeNumerator: 0,
|
|
39
|
-
ifFeeNumerator: 0,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const mockUserStatsAccount: UserStatsAccount = {
|
|
43
|
-
numberOfSubAccounts: 1,
|
|
44
|
-
numberOfSubAccountsCreated: 1,
|
|
45
|
-
makerVolume30D: ZERO,
|
|
46
|
-
takerVolume30D: ZERO,
|
|
47
|
-
fillerVolume30D: ZERO,
|
|
48
|
-
lastMakerVolume30DTs: ZERO,
|
|
49
|
-
lastTakerVolume30DTs: ZERO,
|
|
50
|
-
lastFillerVolume30DTs: ZERO,
|
|
51
|
-
fees: {
|
|
52
|
-
totalFeePaid: ZERO,
|
|
53
|
-
totalFeeRebate: ZERO,
|
|
54
|
-
totalTokenDiscount: ZERO,
|
|
55
|
-
totalRefereeDiscount: ZERO,
|
|
56
|
-
},
|
|
57
|
-
referrer: undefined as any,
|
|
58
|
-
referrerStatus: 0,
|
|
59
|
-
disableUpdatePerpBidAskTwap: 0,
|
|
60
|
-
pausedOperations: 0,
|
|
61
|
-
authority: undefined as any,
|
|
62
|
-
ifStakedQuoteAssetAmount: ZERO,
|
|
63
|
-
delegatePermissions: 0,
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
async function makeFeeMockUser(referrerStatus: number): Promise<User> {
|
|
67
|
-
const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
|
|
68
|
-
const myMockSpotMarkets = _.cloneDeep(mockSpotMarkets);
|
|
69
|
-
const myMockUserAccount = _.cloneDeep(baseMockUserAccount);
|
|
70
|
-
|
|
71
|
-
const user = await makeMockUser(
|
|
72
|
-
myMockPerpMarkets,
|
|
73
|
-
myMockSpotMarkets,
|
|
74
|
-
myMockUserAccount,
|
|
75
|
-
[1, 1, 1, 1, 1, 1, 1, 1],
|
|
76
|
-
[1, 1, 1, 1, 1, 1, 1, 1]
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
user.velocityClient.getStateAccount = () =>
|
|
80
|
-
({
|
|
81
|
-
perpFeeStructure: mockFeeStructure,
|
|
82
|
-
spotFeeStructure: mockFeeStructure,
|
|
83
|
-
}) as any;
|
|
84
|
-
|
|
85
|
-
const userStatsAccount = {
|
|
86
|
-
..._.cloneDeep(mockUserStatsAccount),
|
|
87
|
-
referrerStatus,
|
|
88
|
-
};
|
|
89
|
-
user.velocityClient.getUserStatsOrThrow = () =>
|
|
90
|
-
({
|
|
91
|
-
getAccountOrThrow: () => userStatsAccount,
|
|
92
|
-
}) as any;
|
|
93
|
-
// getMarketFees reads referee status via getUserStats()?.getAccount()
|
|
94
|
-
user.velocityClient.getUserStats = () =>
|
|
95
|
-
({
|
|
96
|
-
getAccount: () => userStatsAccount,
|
|
97
|
-
}) as any;
|
|
98
|
-
// getMarketFees(marketIndex) reads the market's feeAdjustment
|
|
99
|
-
user.velocityClient.getPerpMarketAccountOrThrow = () =>
|
|
100
|
-
({
|
|
101
|
-
marketIndex: 0,
|
|
102
|
-
feeAdjustment: 0,
|
|
103
|
-
}) as any;
|
|
104
|
-
|
|
105
|
-
return user;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
describe('User fee calculation', () => {
|
|
109
|
-
it('taker fee for a non-market-index quote amount rounds up (ceil)', async () => {
|
|
110
|
-
const user = await makeFeeMockUser(0);
|
|
111
|
-
|
|
112
|
-
// 1_000_007 * 1 / 1000 = 1000.007 -> ceil = 1001, floor would be 1000
|
|
113
|
-
const fee = user.calculatePerpTakerFee(new BN(1_000_007));
|
|
114
|
-
assert(
|
|
115
|
-
fee.eq(new BN(1001)),
|
|
116
|
-
`expected ceil-rounded fee of 1001, got ${fee.toString()}`
|
|
117
|
-
);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('referee discount is not applied for a non-referred user', async () => {
|
|
121
|
-
const user = await makeFeeMockUser(0);
|
|
122
|
-
|
|
123
|
-
const fee = user.calculatePerpTakerFee(new BN(1_000_000));
|
|
124
|
-
// 1_000_000 * 1 / 1000 = 1000, no referee discount
|
|
125
|
-
assert(
|
|
126
|
-
fee.eq(new BN(1000)),
|
|
127
|
-
`expected undiscounted fee, got ${fee.toString()}`
|
|
128
|
-
);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it('referee discount is applied when the user stats account marks them as referred', async () => {
|
|
132
|
-
const user = await makeFeeMockUser(ReferrerStatus.IsReferred);
|
|
133
|
-
|
|
134
|
-
const fee = user.calculatePerpTakerFee(new BN(1_000_000));
|
|
135
|
-
// base fee = 1000, referee discount = 25% of 1000 = 250 -> fee = 750
|
|
136
|
-
assert(
|
|
137
|
-
fee.eq(new BN(750)),
|
|
138
|
-
`expected 25% referee discount applied, got ${fee.toString()}`
|
|
139
|
-
);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('an explicit isReferee override applies the discount regardless of user stats', async () => {
|
|
143
|
-
const user = await makeFeeMockUser(0);
|
|
144
|
-
|
|
145
|
-
const fee = user.calculatePerpTakerFee(new BN(1_000_000), undefined, true);
|
|
146
|
-
assert(
|
|
147
|
-
fee.eq(new BN(750)),
|
|
148
|
-
`expected 25% referee discount applied via override, got ${fee.toString()}`
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// M11: getMarketFees (the primary fee-prediction entry point) must apply the
|
|
153
|
-
// referee discount, not just calculatePerpTakerFee's volume-tier branch.
|
|
154
|
-
it('getMarketFees applies the referee discount to the taker fee for a referred user', async () => {
|
|
155
|
-
const referred = await makeFeeMockUser(ReferrerStatus.IsReferred);
|
|
156
|
-
const notReferred = await makeFeeMockUser(0);
|
|
157
|
-
|
|
158
|
-
const { takerFee: referredTakerFee } =
|
|
159
|
-
referred.velocityClient.getMarketFees(MarketType.PERP, 0, referred);
|
|
160
|
-
const { takerFee: baseTakerFee } = notReferred.velocityClient.getMarketFees(
|
|
161
|
-
MarketType.PERP,
|
|
162
|
-
0,
|
|
163
|
-
notReferred
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
// base taker fee = 1/1000 = 0.001; referee discount = 25% -> 0.00075
|
|
167
|
-
assert(
|
|
168
|
-
Math.abs(baseTakerFee - 0.001) < 1e-12,
|
|
169
|
-
`expected base taker fee 0.001, got ${baseTakerFee}`
|
|
170
|
-
);
|
|
171
|
-
assert(
|
|
172
|
-
Math.abs(referredTakerFee - 0.00075) < 1e-12,
|
|
173
|
-
`expected discounted taker fee 0.00075, got ${referredTakerFee}`
|
|
174
|
-
);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
// M11: the calculatePerpTakerFee marketIndex path (which delegates to
|
|
178
|
-
// getMarketFees) must now also reflect the referee discount.
|
|
179
|
-
it('calculatePerpTakerFee marketIndex path applies the referee discount', async () => {
|
|
180
|
-
const user = await makeFeeMockUser(ReferrerStatus.IsReferred);
|
|
181
|
-
|
|
182
|
-
const fee = user.calculatePerpTakerFee(new BN(1_000_000), 0);
|
|
183
|
-
// 1_000_000 * 0.00075 = 750
|
|
184
|
-
assert(
|
|
185
|
-
fee.eq(new BN(750)),
|
|
186
|
-
`expected discounted market-index fee 750, got ${fee.toString()}`
|
|
187
|
-
);
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
// M12: builder fee must be added by getMarketFees when orderParams carry a builder code.
|
|
191
|
-
it('getMarketFees adds the builder fee fraction to the taker fee', async () => {
|
|
192
|
-
const user = await makeFeeMockUser(0);
|
|
193
|
-
|
|
194
|
-
const { takerFee } = user.velocityClient.getMarketFees(
|
|
195
|
-
MarketType.PERP,
|
|
196
|
-
0,
|
|
197
|
-
user,
|
|
198
|
-
{ builderIdx: 0, builderFeeTenthBps: 10 }
|
|
199
|
-
);
|
|
200
|
-
// base 0.001 + builder 10/100_000 = 0.0001 -> 0.0011
|
|
201
|
-
assert(
|
|
202
|
-
Math.abs(takerFee - 0.0011) < 1e-12,
|
|
203
|
-
`expected taker fee incl. builder 0.0011, got ${takerFee}`
|
|
204
|
-
);
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
// M12: builder fee must also be applied by calculatePerpTakerFee on both
|
|
208
|
-
// the volume-tier branch and the marketIndex branch.
|
|
209
|
-
it('calculatePerpTakerFee adds the builder fee on the volume-tier branch', async () => {
|
|
210
|
-
const user = await makeFeeMockUser(0);
|
|
211
|
-
|
|
212
|
-
const fee = user.calculatePerpTakerFee(
|
|
213
|
-
new BN(1_000_000),
|
|
214
|
-
undefined,
|
|
215
|
-
false,
|
|
216
|
-
{ builderIdx: 0, builderFeeTenthBps: 10 }
|
|
217
|
-
);
|
|
218
|
-
// base 1000 + builderFee(1_000_000, 10) = 1_000_000*10/100_000 = 100 -> 1100
|
|
219
|
-
assert(
|
|
220
|
-
fee.eq(new BN(1100)),
|
|
221
|
-
`expected fee incl. builder 1100, got ${fee.toString()}`
|
|
222
|
-
);
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it('calculatePerpTakerFee adds the builder fee on the marketIndex branch', async () => {
|
|
226
|
-
const user = await makeFeeMockUser(0);
|
|
227
|
-
|
|
228
|
-
const fee = user.calculatePerpTakerFee(new BN(1_000_000), 0, false, {
|
|
229
|
-
builderIdx: 0,
|
|
230
|
-
builderFeeTenthBps: 10,
|
|
231
|
-
});
|
|
232
|
-
// 1_000_000 * (0.001 + 0.0001) = 1100
|
|
233
|
-
assert(
|
|
234
|
-
fee.eq(new BN(1100)),
|
|
235
|
-
`expected market-index fee incl. builder 1100, got ${fee.toString()}`
|
|
236
|
-
);
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
describe('User canBypassWithdrawLimits', () => {
|
|
241
|
-
async function makeWithdrawMockUser(cumulativeDeposits: BN): Promise<User> {
|
|
242
|
-
const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
|
|
243
|
-
const myMockSpotMarkets = _.cloneDeep(mockSpotMarkets);
|
|
244
|
-
const myMockUserAccount = _.cloneDeep(baseMockUserAccount);
|
|
245
|
-
|
|
246
|
-
// generous withdraw guard threshold so canBypass isn't gated on deposit size
|
|
247
|
-
myMockSpotMarkets[0].withdrawGuardThreshold = new BN(100_000).mul(
|
|
248
|
-
SPOT_MARKET_BALANCE_PRECISION
|
|
249
|
-
);
|
|
250
|
-
|
|
251
|
-
myMockUserAccount.totalDeposits = new BN(1000).mul(
|
|
252
|
-
SPOT_MARKET_BALANCE_PRECISION
|
|
253
|
-
);
|
|
254
|
-
myMockUserAccount.totalWithdraws = ZERO;
|
|
255
|
-
myMockUserAccount.spotPositions[0].balanceType = SpotBalanceType.DEPOSIT;
|
|
256
|
-
myMockUserAccount.spotPositions[0].scaledBalance = new BN(100).mul(
|
|
257
|
-
SPOT_MARKET_BALANCE_PRECISION
|
|
258
|
-
);
|
|
259
|
-
myMockUserAccount.spotPositions[0].cumulativeDeposits = cumulativeDeposits;
|
|
260
|
-
|
|
261
|
-
return makeMockUser(
|
|
262
|
-
myMockPerpMarkets,
|
|
263
|
-
myMockSpotMarkets,
|
|
264
|
-
myMockUserAccount,
|
|
265
|
-
[1, 1, 1, 1, 1, 1, 1, 1],
|
|
266
|
-
[1, 1, 1, 1, 1, 1, 1, 1]
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
it('can bypass when net deposits and cumulative deposits are both non-negative', async () => {
|
|
271
|
-
const user = await makeWithdrawMockUser(new BN(100));
|
|
272
|
-
const { canBypass } = user.canBypassWithdrawLimits(0);
|
|
273
|
-
assert(canBypass, 'expected canBypass to be true');
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
it('cannot bypass when cumulative deposits on the position are negative', async () => {
|
|
277
|
-
const user = await makeWithdrawMockUser(new BN(-1));
|
|
278
|
-
const { canBypass } = user.canBypassWithdrawLimits(0);
|
|
279
|
-
assert(
|
|
280
|
-
!canBypass,
|
|
281
|
-
'expected canBypass to be false with negative cumulativeDeposits'
|
|
282
|
-
);
|
|
283
|
-
});
|
|
284
|
-
});
|