@tradelayerprotocol/tradelayer 1.9.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/.claude/settings.local.json +13 -0
- package/.claude/skills/tl-algo/SKILL.md +255 -0
- package/.gitattributes +2 -0
- package/.github/workflows/publish.yaml +26 -0
- package/4mm.js +163 -0
- package/LICENSE +21 -0
- package/NPMSwapRefactor.zip +0 -0
- package/README.md +217 -0
- package/address.sh +26 -0
- package/algoAPI.js +581 -0
- package/analyzepsbt.js +92 -0
- package/apiEx.js +99 -0
- package/bb_hyperscalper.js +290 -0
- package/bbo_demo.js +111 -0
- package/buyer.js +622 -0
- package/client.js +50 -0
- package/createTxTest.js +26 -0
- package/createWallet.js +75 -0
- package/daytrader.js +531 -0
- package/decodeTest.js +69 -0
- package/fundingManager.js +144 -0
- package/index.js +4 -0
- package/listener.js +27 -0
- package/litecoreTxBuilder.js +1128 -0
- package/mmEx.js +356 -0
- package/networks.js +51 -0
- package/orderbook.js +200 -0
- package/package.json +34 -0
- package/perTradeQueue.js +36 -0
- package/projectsTLNPMTLNPM/package-lock.json +162 -0
- package/projectsTLNPMTLNPM/package.json +5 -0
- package/quick.js +32 -0
- package/quickFut.js +37 -0
- package/quickSell.js +37 -0
- package/relayerClient.js +117 -0
- package/run4mm.js +80 -0
- package/run_bbo_tracker.js +241 -0
- package/seller.js +443 -0
- package/session.js +45 -0
- package/setup-lin-ltc.sh +139 -0
- package/setup-lin.sh +203 -0
- package/setup-win-ltc.bat +108 -0
- package/setup-win.bat +167 -0
- package/spam_screamer_futures.js +222 -0
- package/tradelayer.js/.gitattributes +2 -0
- package/tradelayer.js/README.md +2 -0
- package/tradelayer.js/oldTests/activationTest.js +6 -0
- package/tradelayer.js/oldTests/base58.test.js +23 -0
- package/tradelayer.js/oldTests/base64Decode.test.js +16 -0
- package/tradelayer.js/oldTests/blocksRefactor.js +140 -0
- package/tradelayer.js/oldTests/checkVestBalance.js +25 -0
- package/tradelayer.js/oldTests/consensusHashProto.js +151 -0
- package/tradelayer.js/oldTests/contractOrderbook.js +243 -0
- package/tradelayer.js/oldTests/createPayload.js +0 -0
- package/tradelayer.js/oldTests/createTestnetAddr.js +43 -0
- package/tradelayer.js/oldTests/decode.js +205 -0
- package/tradelayer.js/oldTests/decodeTest.js +50 -0
- package/tradelayer.js/oldTests/displayTallyMap.js +19 -0
- package/tradelayer.js/oldTests/encodeDecode.js +340 -0
- package/tradelayer.js/oldTests/expressTest.js +29 -0
- package/tradelayer.js/oldTests/extractBlocksVanilla.js +214 -0
- package/tradelayer.js/oldTests/extractBlocksVanillaa.js +179 -0
- package/tradelayer.js/oldTests/extractPubkeyTest.js +60 -0
- package/tradelayer.js/oldTests/fillInputCacheProto.js +111 -0
- package/tradelayer.js/oldTests/getRawTxTest.js +22 -0
- package/tradelayer.js/oldTests/indexTest.js +26 -0
- package/tradelayer.js/oldTests/initTokensTest.js +32 -0
- package/tradelayer.js/oldTests/interfaceChild.js +129 -0
- package/tradelayer.js/oldTests/listenerChild.js +112 -0
- package/tradelayer.js/oldTests/opdecode.js +26 -0
- package/tradelayer.js/oldTests/options.js +79 -0
- package/tradelayer.js/oldTests/optxtest.js +116 -0
- package/tradelayer.js/oldTests/optxtest1.js +64 -0
- package/tradelayer.js/oldTests/oracle.test.js +32 -0
- package/tradelayer.js/oldTests/orderbook.test.js +36 -0
- package/tradelayer.js/oldTests/parsing.js +93 -0
- package/tradelayer.js/oldTests/payload.js +13 -0
- package/tradelayer.js/oldTests/persistenceUnitTest.js +23 -0
- package/tradelayer.js/oldTests/property.test.js +53 -0
- package/tradelayer.js/oldTests/propertyLevel.js +75 -0
- package/tradelayer.js/oldTests/propertyTest.js +32 -0
- package/tradelayer.js/oldTests/queryAddressTest.js +17 -0
- package/tradelayer.js/oldTests/salter.js +14 -0
- package/tradelayer.js/oldTests/tally.js +81 -0
- package/tradelayer.js/oldTests/tally.test.js +48 -0
- package/tradelayer.js/oldTests/tally2.js +124 -0
- package/tradelayer.js/oldTests/tally3.js +142 -0
- package/tradelayer.js/oldTests/tallyDiag.js +38 -0
- package/tradelayer.js/oldTests/testGetRaw.js +40 -0
- package/tradelayer.js/oldTests/testHexConvert.js +47 -0
- package/tradelayer.js/oldTests/testNewEncoding.js +96 -0
- package/tradelayer.js/oldTests/testNewEncoding2.js +113 -0
- package/tradelayer.js/oldTests/testNewEncoding3 +112 -0
- package/tradelayer.js/oldTests/testNewEncoding3.js +168 -0
- package/tradelayer.js/oldTests/testOPReturn.js +102 -0
- package/tradelayer.js/oldTests/testPayload.js +23 -0
- package/tradelayer.js/oldTests/testRaw.js +50 -0
- package/tradelayer.js/oldTests/testSendTooMuch.js +20 -0
- package/tradelayer.js/oldTests/testTxBuild +28 -0
- package/tradelayer.js/oldTests/testTxBuild.js +42 -0
- package/tradelayer.js/oldTests/tokenOrderbook.js +243 -0
- package/tradelayer.js/oldTests/txUtilsA.js +515 -0
- package/tradelayer.js/oldTests/validityUnitTest.js +53 -0
- package/tradelayer.js/oldTests/vaults.js +72 -0
- package/tradelayer.js/oldTests/volumeIndex.js +117 -0
- package/tradelayer.js/oldTests/volumeIndex2.js +88 -0
- package/tradelayer.js/output_base64.txt +1 -0
- package/tradelayer.js/package-lock.json +9967 -0
- package/tradelayer.js/package.json +61 -0
- package/tradelayer.js/server/index.js +88 -0
- package/tradelayer.js/server/litecoind.exe +0 -0
- package/tradelayer.js/src/activation.js +303 -0
- package/tradelayer.js/src/adjuster.js +77 -0
- package/tradelayer.js/src/amm.js +400 -0
- package/tradelayer.js/src/base256.js +55 -0
- package/tradelayer.js/src/base94.js +79 -0
- package/tradelayer.js/src/channels.js +1163 -0
- package/tradelayer.js/src/clearing.js +3109 -0
- package/tradelayer.js/src/clearlist.js +364 -0
- package/tradelayer.js/src/client.js +295 -0
- package/tradelayer.js/src/consensus.js +613 -0
- package/tradelayer.js/src/contractRegistry.js +964 -0
- package/tradelayer.js/src/db.js +89 -0
- package/tradelayer.js/src/init.js +24 -0
- package/tradelayer.js/src/insurance.js +347 -0
- package/tradelayer.js/src/interface.js +218 -0
- package/tradelayer.js/src/interfaceExpress.js +178 -0
- package/tradelayer.js/src/iou.js +509 -0
- package/tradelayer.js/src/listener.js +226 -0
- package/tradelayer.js/src/logic.js +1702 -0
- package/tradelayer.js/src/main.js +927 -0
- package/tradelayer.js/src/marginMap.js +2165 -0
- package/tradelayer.js/src/options.js +126 -0
- package/tradelayer.js/src/oracle.js +394 -0
- package/tradelayer.js/src/orderbook.js +4123 -0
- package/tradelayer.js/src/persistence.js +554 -0
- package/tradelayer.js/src/property.js +411 -0
- package/tradelayer.js/src/reOrg.js +41 -0
- package/tradelayer.js/src/scaling.js +145 -0
- package/tradelayer.js/src/tally.js +1275 -0
- package/tradelayer.js/src/tradeHistoryManager.js +552 -0
- package/tradelayer.js/src/txDecoder.js +584 -0
- package/tradelayer.js/src/txEncoder.js +610 -0
- package/tradelayer.js/src/txIndex.js +502 -0
- package/tradelayer.js/src/txUtils.js +1392 -0
- package/tradelayer.js/src/types.js +429 -0
- package/tradelayer.js/src/validity.js +3077 -0
- package/tradelayer.js/src/vaults.js +430 -0
- package/tradelayer.js/src/vesting.js +491 -0
- package/tradelayer.js/src/volumeIndex.js +618 -0
- package/tradelayer.js/src/walletInterface.js +220 -0
- package/tradelayer.js/src/walletListener.js +665 -0
- package/tradelayer.js/tests/256decode.js +82 -0
- package/tradelayer.js/tests/UTXOracle.js +205 -0
- package/tradelayer.js/tests/base94test.js +23 -0
- package/tradelayer.js/tests/cancelTxTest.js +62 -0
- package/tradelayer.js/tests/contractInterfaceTest.js +48 -0
- package/tradelayer.js/tests/decimalTest.js +65 -0
- package/tradelayer.js/tests/decoderTest.js +100 -0
- package/tradelayer.js/tests/deltaCount.js +47 -0
- package/tradelayer.js/tests/deltaCount2.js +60 -0
- package/tradelayer.js/tests/interfaceTest.js +37 -0
- package/tradelayer.js/tests/mainTest.js +53 -0
- package/tradelayer.js/tests/makeActivationTest.js +24 -0
- package/tradelayer.js/tests/maxHeightTest.js +49 -0
- package/tradelayer.js/tests/reverseHash.js +72 -0
- package/tradelayer.js/tests/sensitiveConsoleOutput.txt +267 -0
- package/tradelayer.js/tests/tallyTest.js +40 -0
- package/tradelayer.js/tests/testBuybacks.js +46 -0
- package/tradelayer.js/tests/testCodeHash.js +49 -0
- package/tradelayer.js/tests/testConsensusHash.js +91 -0
- package/tradelayer.js/tests/testDecode.js +30 -0
- package/tradelayer.js/tests/testEncodingLengths.js +129 -0
- package/tradelayer.js/tests/testGetTx +32 -0
- package/tradelayer.js/tests/testGetTx.js +32 -0
- package/tradelayer.js/tests/testHexHash.js +32 -0
- package/tradelayer.js/tests/testIndexHash.js +35 -0
- package/tradelayer.js/tests/testInitContracts.js +38 -0
- package/tradelayer.js/tests/testMaxConsensus.js +12 -0
- package/tradelayer.js/tests/testMaxSynth.js +44 -0
- package/tradelayer.js/tests/testMint.js +21 -0
- package/tradelayer.js/tests/testNetwork.js +33 -0
- package/tradelayer.js/tests/testOrderbookLoad.js +62 -0
- package/tradelayer.js/tests/testRebates.js +32 -0
- package/tradelayer.js/tests/testRedeem.js +22 -0
- package/tradelayer.js/tests/testTokenTrade.js +39 -0
- package/tradelayer.js/tests/testTxBuild.js +42 -0
- package/tradelayer.js/tests/testUTXOTrade.js +27 -0
- package/tradelayer.js/tests/tokenTradeHistory.js +27 -0
- package/tradelayer.js/tests/tradeFutures.js +40 -0
- package/tradelayer.js/tests/tradeHistoryExample.js +35 -0
- package/tradelayer.js/tests/tradeHistoryLoad.js +15 -0
- package/tradelayer.js/tests/txScanTest.js +134 -0
- package/tradelayer.js/tests/validateTest.js +136 -0
- package/tradelayer.js/tests/vestingTest.js +37 -0
- package/tradelayer.js/utils/activateMainnet.js +59 -0
- package/tradelayer.js/utils/activateMainnetDoge.js +63 -0
- package/tradelayer.js/utils/autocompactdb.js +23 -0
- package/tradelayer.js/utils/base64toHex.js +32 -0
- package/tradelayer.js/utils/broadcastDoge.js +38 -0
- package/tradelayer.js/utils/calcRedeem.js +19 -0
- package/tradelayer.js/utils/checkNetwork.js +27 -0
- package/tradelayer.js/utils/createAddress.js +48 -0
- package/tradelayer.js/utils/createAttestation.js +133 -0
- package/tradelayer.js/utils/createContract.js +118 -0
- package/tradelayer.js/utils/createOracle.js +94 -0
- package/tradelayer.js/utils/createwallet.js +20 -0
- package/tradelayer.js/utils/crossFuturesTrades.js +57 -0
- package/tradelayer.js/utils/crossTokenTrades.js +62 -0
- package/tradelayer.js/utils/dumpPriv.js +29 -0
- package/tradelayer.js/utils/generateChannel.js +34 -0
- package/tradelayer.js/utils/getInfo.js +21 -0
- package/tradelayer.js/utils/hardWipe.js +20 -0
- package/tradelayer.js/utils/hexTo64.js +16 -0
- package/tradelayer.js/utils/importAddress.js +28 -0
- package/tradelayer.js/utils/importpriv.js +20 -0
- package/tradelayer.js/utils/issueOracleContract.js +67 -0
- package/tradelayer.js/utils/issueTokens.js +41 -0
- package/tradelayer.js/utils/listunspent.js +66 -0
- package/tradelayer.js/utils/litecoinClient.js +30 -0
- package/tradelayer.js/utils/loadwallet.js +20 -0
- package/tradelayer.js/utils/publishOracle.js +113 -0
- package/tradelayer.js/utils/sendActivation.js +21 -0
- package/tradelayer.js/utils/sendChannelContractTrade.js +34 -0
- package/tradelayer.js/utils/sendChannelTokenTrade.js +34 -0
- package/tradelayer.js/utils/sendCommit.js +24 -0
- package/tradelayer.js/utils/sendDoge.js +62 -0
- package/tradelayer.js/utils/sendDogeMain.js +67 -0
- package/tradelayer.js/utils/sendDogeTx.js +46 -0
- package/tradelayer.js/utils/sendLTC.js +63 -0
- package/tradelayer.js/utils/sendMainnet.js +62 -0
- package/tradelayer.js/utils/sendTransfer.js +19 -0
- package/tradelayer.js/utils/sendVestTest.js +88 -0
- package/tradelayer.js/utils/sendWithdrawal.js +26 -0
- package/tradelayer.js/utils/simpleStart.js +8 -0
- package/tradelayer.js/utils/startStop.js +27 -0
- package/tradelayer.js/utils/structuredTrades.js +136 -0
- package/tradelayer.js/utils/verifySignature.js +90 -0
- package/tradelayer.js/utils/verifyWitnessAndScriptPubkey.js +41 -0
- package/tradelayer.js/utils/walletCache.js +172 -0
- package/tradelayer.js/utils/walletContractInterface.js +48 -0
- package/tradelayer.js/utils/walletFetchTxs.js +66 -0
- package/tradelayer.js/utils/walletUtils.js +97 -0
- package/tradelayer.js/utils/wipeDB.js +55 -0
- package/tradelayer.js/utils/wipeDBNotTx.js +50 -0
- package/txEncoder.js +529 -0
- package/utility.js +28 -0
- package/verifymessage.js +38 -0
- package/ws-transport.js +311 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
const ContractRegistry = require('./contractRegistry.js')
|
|
2
|
+
const Orderbook = require('./orderbook.js')
|
|
3
|
+
const Clearing = require('./clearing.js')
|
|
4
|
+
const db = require('./db.js');
|
|
5
|
+
|
|
6
|
+
class AMMPool {
|
|
7
|
+
constructor(initialPosition, maxPosition, maxQuoteSize, contractType) {
|
|
8
|
+
this.position = initialPosition;
|
|
9
|
+
this.maxPosition = maxPosition;
|
|
10
|
+
this.maxQuoteSize = maxQuoteSize;
|
|
11
|
+
this.contractType = contractType;
|
|
12
|
+
this.lpAddresses = {}; // Object to store LP addresses and their positions
|
|
13
|
+
this.ammOrders = []; // Array to store AMM orders
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Create a new AMM and insert into ammRegistry
|
|
17
|
+
async createAMM(payload) {
|
|
18
|
+
const registryDB = db.getDatabase('ammRegistry');
|
|
19
|
+
const stateDB = db.getDatabase('ammState');
|
|
20
|
+
|
|
21
|
+
// Find current max ID
|
|
22
|
+
const last = await registryDB.findAsync({}).sort({ ammId: -1 }).limit(1);
|
|
23
|
+
const nextId = last.length > 0 ? last[0].ammId + 1 : 1;
|
|
24
|
+
|
|
25
|
+
const newAMM = {
|
|
26
|
+
ammId: nextId,
|
|
27
|
+
contractId: payload.contractId,
|
|
28
|
+
propertyId: payload.propertyId,
|
|
29
|
+
optionsMaker: payload.optionsMaker || null,
|
|
30
|
+
optionsTaker: payload.optionsTaker || null,
|
|
31
|
+
strategyBlob: payload.strategyBlob || null,
|
|
32
|
+
createdAt: Date.now()
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
await registryDB.insertAsync(newAMM);
|
|
36
|
+
|
|
37
|
+
// initialize state
|
|
38
|
+
const state = {
|
|
39
|
+
ammId: nextId,
|
|
40
|
+
lpShares: {},
|
|
41
|
+
position: 0,
|
|
42
|
+
orders: [],
|
|
43
|
+
pnl: 0,
|
|
44
|
+
updatedAt: Date.now()
|
|
45
|
+
};
|
|
46
|
+
await stateDB.insertAsync(state);
|
|
47
|
+
|
|
48
|
+
return newAMM;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Save mutable state of an AMM
|
|
52
|
+
async saveAMMState(ammId, stateUpdate) {
|
|
53
|
+
const stateDB = db.getDatabase('ammState');
|
|
54
|
+
stateUpdate.updatedAt = Date.now();
|
|
55
|
+
await stateDB.updateAsync(
|
|
56
|
+
{ ammId },
|
|
57
|
+
{ $set: stateUpdate },
|
|
58
|
+
{ upsert: true }
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Load state of an AMM
|
|
63
|
+
async loadAMMState(ammId) {
|
|
64
|
+
const stateDB = db.getDatabase('ammState');
|
|
65
|
+
return await stateDB.findOneAsync({ ammId });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Load immutable AMM info
|
|
69
|
+
async loadAMMRegistry(ammId) {
|
|
70
|
+
const registryDB = db.getDatabase('ammRegistry');
|
|
71
|
+
return await registryDB.findOneAsync({ ammId });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ---------------- Order Update ----------------
|
|
75
|
+
static async updateOrdersForAllContractAMMs(block) {
|
|
76
|
+
const volIndex = await VolumeIndex.calculateVolIndex();
|
|
77
|
+
const contractIds = await ContractRegistry.loadContractSeries();
|
|
78
|
+
if (!contractIds || contractIds.size === 0) return;
|
|
79
|
+
|
|
80
|
+
for (const contractId of contractIds) {
|
|
81
|
+
let id = contractId[1].id;
|
|
82
|
+
let change = await Clearing.isPriceUpdatedForBlockHeight(id, block);
|
|
83
|
+
if (!change) continue;
|
|
84
|
+
|
|
85
|
+
let blob = await Clearing.getPriceChange(block, id);
|
|
86
|
+
let lastPrice = blob.lastPrice;
|
|
87
|
+
const ammInstance = await ContractRegistry.getAMM(id);
|
|
88
|
+
if (!ammInstance) continue;
|
|
89
|
+
|
|
90
|
+
let orderBookKey = contractId;
|
|
91
|
+
let orderbook = Orderbook.getOrderbookInstance(orderBookKey);
|
|
92
|
+
orderbook.cancelOrdersByCriteria('amm', orderBookKey, {}, false, true);
|
|
93
|
+
|
|
94
|
+
const coreOrders = await ammInstance.generateOrders(lastPrice, 0.2, 10, contractId, null, false, false);
|
|
95
|
+
const optionOrders = await ammInstance.runOptionStrategy(lastPrice, volIndex, block);
|
|
96
|
+
const allOrders = [...coreOrders, ...optionOrders];
|
|
97
|
+
|
|
98
|
+
for (const order of allOrders) {
|
|
99
|
+
const isBuyOrder = order.side === 'buy';
|
|
100
|
+
const isLiq = order.isLiq || false;
|
|
101
|
+
await orderbook.insertOrder(order, orderBookKey, isBuyOrder, isLiq);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ---------------- Core LP Capital Logic ----------------
|
|
107
|
+
static async insertCapital(address, id, capital, isContract, id2, amount2, block) {
|
|
108
|
+
if (this.position + capital > this.maxPosition) {
|
|
109
|
+
throw new Error('Pool has reached its maximum position');
|
|
110
|
+
}
|
|
111
|
+
this.position += capital;
|
|
112
|
+
this.lpShares[address] = (this.lpShares[address] || 0) + capital;
|
|
113
|
+
|
|
114
|
+
let LPPropertyId, LPPropertyId2;
|
|
115
|
+
if (isContract) {
|
|
116
|
+
LPPropertyId = `${id}-LP`;
|
|
117
|
+
await TallyMap.updateBalance(address, id, -capital, 0, 0, 0, 'AMMPledge', block);
|
|
118
|
+
await TallyMap.updateBalance(address, LPPropertyId, capital, 0, 0, 0, 'LPIssue', block);
|
|
119
|
+
} else {
|
|
120
|
+
LPPropertyId = `${id}-${id2}-LP`;
|
|
121
|
+
LPPropertyId2 = `${id2}-${id}-LP`;
|
|
122
|
+
await TallyMap.updateBalance(address, id, -capital, 0, 0, 0, 'AMMPledge', block);
|
|
123
|
+
await TallyMap.updateBalance(address, LPPropertyId, capital, 0, 0, 0, 'LPIssue', block);
|
|
124
|
+
await TallyMap.updateBalance(address, id2, -amount2, 0, 0, 0, 'AMMPledge', block);
|
|
125
|
+
await TallyMap.updateBalance(address, LPPropertyId2, amount2, 0, 0, 0, 'LPIssue', block);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static async redeemCapital(address, id, capital, isContract, id2, amount2, block) {
|
|
130
|
+
if (!this.lpShares[address] || this.lpShares[address] < capital) {
|
|
131
|
+
throw new Error('Insufficient LP shares to redeem');
|
|
132
|
+
}
|
|
133
|
+
this.position -= capital;
|
|
134
|
+
this.lpShares[address] -= capital;
|
|
135
|
+
if (this.lpShares[address] === 0) delete this.lpShares[address];
|
|
136
|
+
|
|
137
|
+
let LPPropertyId, LPPropertyId2;
|
|
138
|
+
if (isContract) {
|
|
139
|
+
LPPropertyId = `${id}-LP`;
|
|
140
|
+
await TallyMap.updateBalance(address, LPPropertyId, -capital, 0, 0, 0, 'LPBurn', block);
|
|
141
|
+
await TallyMap.updateBalance(address, id, capital, 0, 0, 0, 'AMMRedeem', block);
|
|
142
|
+
} else {
|
|
143
|
+
LPPropertyId = `${id}-${id2}-LP`;
|
|
144
|
+
LPPropertyId2 = `${id2}-${id}-LP`;
|
|
145
|
+
await TallyMap.updateBalance(address, LPPropertyId, -capital, 0, 0, 0, 'LPBurn', block);
|
|
146
|
+
await TallyMap.updateBalance(address, id, capital, 0, 0, 0, 'AMMRedeem', block);
|
|
147
|
+
await TallyMap.updateBalance(address, LPPropertyId2, -amount2, 0, 0, 0, 'LPBurn', block);
|
|
148
|
+
await TallyMap.updateBalance(address, id2, amount2, 0, 0, 0, 'AMMRedeem', block);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ---------------- Maker/Taker Relationships ----------------
|
|
153
|
+
static async requestLiquidity(order) {
|
|
154
|
+
if (this.position + order.size > this.maxPosition) return null;
|
|
155
|
+
this.position += order.size * (order.side === 'buy' ? 1 : -1);
|
|
156
|
+
this.ammOrders.push(order);
|
|
157
|
+
return order;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// ---------------- Option Strategy Runner ----------------
|
|
161
|
+
static async runOptionStrategy(lastPrice, volIndex, block) {
|
|
162
|
+
if (!this.strategyBlob) return [];
|
|
163
|
+
let strategy;
|
|
164
|
+
try {
|
|
165
|
+
strategy = JSON.parse(this.strategyBlob);
|
|
166
|
+
} catch (err) {
|
|
167
|
+
console.error("Invalid strategy blob:", err);
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
switch (strategy.type) {
|
|
171
|
+
case 'straddle': return this.buildStraddle(lastPrice, block);
|
|
172
|
+
case 'ironFly': return this.buildIronFly(lastPrice, block);
|
|
173
|
+
case 'calendar': return this.buildCalendar(lastPrice, block);
|
|
174
|
+
default: return [];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
static buildStraddle(lastPrice, block) {
|
|
179
|
+
return [
|
|
180
|
+
{ side: 'buy', type: 'call', strike: lastPrice, expiry: block+1, size: this.maxQuoteSize },
|
|
181
|
+
{ side: 'buy', type: 'put', strike: lastPrice, expiry: block+1, size: this.maxQuoteSize }
|
|
182
|
+
];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
static buildIronFly(lastPrice, block) {
|
|
186
|
+
let up = lastPrice * 1.02, down = lastPrice * 0.98;
|
|
187
|
+
return [
|
|
188
|
+
{ side: 'sell', type: 'call', strike: lastPrice, expiry: block+1, size: this.maxQuoteSize },
|
|
189
|
+
{ side: 'sell', type: 'put', strike: lastPrice, expiry: block+1, size: this.maxQuoteSize },
|
|
190
|
+
{ side: 'buy', type: 'call', strike: up, expiry: block+1, size: this.maxQuoteSize },
|
|
191
|
+
{ side: 'buy', type: 'put', strike: down, expiry: block+1, size: this.maxQuoteSize }
|
|
192
|
+
];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
static buildCalendar(lastPrice, block) {
|
|
196
|
+
return [
|
|
197
|
+
{ side: 'sell', type: 'call', strike: lastPrice, expiry: block+1, size: this.maxQuoteSize },
|
|
198
|
+
{ side: 'buy', type: 'call', strike: lastPrice, expiry: block+10, size: this.maxQuoteSize }
|
|
199
|
+
];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static calculateRedemptionValue(amount, isContract, poolData, lastPrice) {
|
|
203
|
+
if (isContract) {
|
|
204
|
+
// If the AMM is for a contract
|
|
205
|
+
// Calculate the pro-rated value based on the total value of collateralId tokens in the pool
|
|
206
|
+
const totalCollateralValue = poolData.collateralId * poolData.price;
|
|
207
|
+
const poolValue = poolData.tokens + totalCollateralValue;
|
|
208
|
+
const redemptionValue = (amount / poolData.tokens) * poolValue;
|
|
209
|
+
return redemptionValue;
|
|
210
|
+
} else {
|
|
211
|
+
// If the AMM is for tokens
|
|
212
|
+
// Calculate the redemption value based on the last price
|
|
213
|
+
const redemptionValue = amount * lastPrice;
|
|
214
|
+
return redemptionValue;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
// Function to calculate the total position of an address in the pool
|
|
220
|
+
static calculateTotalPosition(address = null) {
|
|
221
|
+
if (address === null) {
|
|
222
|
+
// Calculate the total position of all LPs in the pool
|
|
223
|
+
const totalShares = Object.values(this.lpShares).reduce((total, shares) => total + shares, 0);
|
|
224
|
+
return (totalShares / this.maxPosition) * 100; // Calculate percentage
|
|
225
|
+
} else {
|
|
226
|
+
// Calculate the pro-rata position of the given address
|
|
227
|
+
if (this.lpShares[address]) {
|
|
228
|
+
return (this.lpShares[address] / this.maxPosition) * 100; // Calculate percentage
|
|
229
|
+
} else {
|
|
230
|
+
return 0; // If the address is not found in the LP shares, return 0
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Function to look up which addresses are LPs for a given contractid's AMM
|
|
236
|
+
static getLPAddresses() {
|
|
237
|
+
return Object.keys(this.lpAddresses);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Function to get AMM orders and positions
|
|
241
|
+
static getAMMOrdersAndPositions() {
|
|
242
|
+
// You can return any relevant data here, such as orders and positions
|
|
243
|
+
return {
|
|
244
|
+
orders: this.ammOrders,
|
|
245
|
+
position: this.position,
|
|
246
|
+
maxPosition: this.maxPosition,
|
|
247
|
+
lpAddresses: this.lpAddresses
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
static calculateOrderSize(distanceFromOracle, priceDistance, totalOrders) {
|
|
252
|
+
// Calculate order size based on the given distance from the oracle
|
|
253
|
+
const totalDistance = 0.2 * priceDistance; // Total distance from bottom tick to top of the book
|
|
254
|
+
const distanceRatio = distanceFromOracle / totalDistance;
|
|
255
|
+
let orderSize;
|
|
256
|
+
|
|
257
|
+
if (distanceRatio <= 0.05) {
|
|
258
|
+
// Bottom quarter of the book
|
|
259
|
+
orderSize = totalOrders * 0.35;
|
|
260
|
+
} else if (distanceRatio <= 0.1) {
|
|
261
|
+
// Second to bottom quarter of the book
|
|
262
|
+
orderSize = totalOrders * 0.25;
|
|
263
|
+
} else if (distanceRatio <= 0.15) {
|
|
264
|
+
// Third to bottom quarter of the book
|
|
265
|
+
orderSize = totalOrders * 0.15;
|
|
266
|
+
} else {
|
|
267
|
+
// Top quarter of the book
|
|
268
|
+
orderSize = totalOrders * 0.05;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return orderSize;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
static generateOrdersForInverse(oraclePrice, priceDistance, totalOrders) {
|
|
275
|
+
// Calculate distance from oracle to bottom tick
|
|
276
|
+
const distanceFromOracle = 0.001; // Assuming bottom tick is 0.01 away from oracle
|
|
277
|
+
|
|
278
|
+
// Calculate order size based on distance from oracle
|
|
279
|
+
const orderSize = this.calculateOrderSize(distanceFromOracle, priceDistance, totalOrders);
|
|
280
|
+
|
|
281
|
+
// Adjust quote size based on position and max quote size
|
|
282
|
+
let quoteSize = Math.min(this.position, this.maxQuoteSize);
|
|
283
|
+
|
|
284
|
+
// Adjust order size based on available quote size
|
|
285
|
+
const maxOrderSize = Math.min(orderSize, quoteSize);
|
|
286
|
+
|
|
287
|
+
// Update position and quote size
|
|
288
|
+
this.position += maxOrderSize;
|
|
289
|
+
quoteSize -= maxOrderSize;
|
|
290
|
+
|
|
291
|
+
// Generate order object
|
|
292
|
+
const order = {
|
|
293
|
+
price: oraclePrice + distanceFromOracle, // Assume bottom tick is above oracle price
|
|
294
|
+
size: maxOrderSize,
|
|
295
|
+
side: 'sell' // Assuming it's a sell order for inverse quoted contracts
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
return order;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
static generateOrdersForLinear(oraclePrice, priceDistance, totalOrders) {
|
|
302
|
+
// Calculate distance from oracle to bottom tick
|
|
303
|
+
const distanceFromOracle = 0.01; // Assuming bottom tick is 0.01 away from oracle
|
|
304
|
+
|
|
305
|
+
// Calculate order size based on distance from oracle
|
|
306
|
+
const orderSize = this.calculateOrderSize(distanceFromOracle, priceDistance, totalOrders);
|
|
307
|
+
|
|
308
|
+
// Adjust quote size based on position and max quote size
|
|
309
|
+
let quoteSize = Math.min(this.position, this.maxQuoteSize);
|
|
310
|
+
|
|
311
|
+
// Adjust order size based on available quote size
|
|
312
|
+
const maxOrderSize = Math.min(orderSize, quoteSize);
|
|
313
|
+
|
|
314
|
+
// Update position and quote size
|
|
315
|
+
this.position += maxOrderSize;
|
|
316
|
+
quoteSize -= maxOrderSize;
|
|
317
|
+
|
|
318
|
+
// Generate order object
|
|
319
|
+
const order = {
|
|
320
|
+
price: oraclePrice + distanceFromOracle, // Assume bottom tick is above oracle price
|
|
321
|
+
size: maxOrderSize,
|
|
322
|
+
side: this.position > 0 ? 'buy' : 'sell' // Buy if long, sell if short for linear contracts
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
return order;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
static async generateTokenOrders(tokenXId, tokenYId, totalLiquidity, totalOrders, lastPrice, blockHeight) {
|
|
329
|
+
const pairKey = `${tokenXId}-${tokenYId}`;
|
|
330
|
+
const orderbook = await Orderbook.getOrderbookInstance(pairKey);
|
|
331
|
+
|
|
332
|
+
const curveDistance = 0.30 * lastPrice; // Distance from the last price
|
|
333
|
+
const orderIncrement = curveDistance / totalOrders; // Increment for each order
|
|
334
|
+
|
|
335
|
+
// Calculate the initial supply ratio
|
|
336
|
+
const initialXSupply = Math.sqrt(totalLiquidity * (1 - curveDistance / (2 * lastPrice)));
|
|
337
|
+
const initialYSupply = Math.sqrt(totalLiquidity * (1 + curveDistance / (2 * lastPrice)));
|
|
338
|
+
|
|
339
|
+
// Generate orders for token X and token Y
|
|
340
|
+
for (let i = 1; i <= totalOrders; i++) {
|
|
341
|
+
const priceX = lastPrice - (i * orderIncrement);
|
|
342
|
+
const priceY = lastPrice + (i * orderIncrement);
|
|
343
|
+
|
|
344
|
+
// Calculate the supply at this price level
|
|
345
|
+
const xSupply = initialXSupply * (lastPrice / priceX);
|
|
346
|
+
const ySupply = totalLiquidity / xSupply;
|
|
347
|
+
|
|
348
|
+
const orderX = {
|
|
349
|
+
offeredPropertyId: tokenXId,
|
|
350
|
+
desiredPropertyId: tokenYId,
|
|
351
|
+
amountOffered: xSupply - initialXSupply,
|
|
352
|
+
amountExpected: ySupply - initialYSupply,
|
|
353
|
+
price: priceX,
|
|
354
|
+
sender: "pool",
|
|
355
|
+
txid: "amm"
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
const orderY = {
|
|
359
|
+
offeredPropertyId: tokenYId,
|
|
360
|
+
desiredPropertyId: tokenXId,
|
|
361
|
+
amountOffered: ySupply - initialYSupply,
|
|
362
|
+
amountExpected: xSupply - initialXSupply,
|
|
363
|
+
price: priceY,
|
|
364
|
+
sender: "pool",
|
|
365
|
+
txid: "amm"
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
try {
|
|
369
|
+
await Promise.all([
|
|
370
|
+
orderbook.addTokenOrder(orderX, blockHeight, txid),
|
|
371
|
+
orderbook.addTokenOrder(orderY, blockHeight, txid)
|
|
372
|
+
]);
|
|
373
|
+
} catch (error) {
|
|
374
|
+
console.error(`Error placing orders for pair ${pairKey}: ${error.message}`);
|
|
375
|
+
// Handle the error as needed
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
console.log(`Token orders placed for pair ${pairKey}`);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
static generateOrders(lastPrice, priceDistance, totalOrders, id1, id2, inverse, token) {
|
|
383
|
+
|
|
384
|
+
if(token==true){
|
|
385
|
+
let totalLiquidity = this.calculateTotalLiquidityForToken(id1,id2,totalLiquidity,lastPrice,block);
|
|
386
|
+
return this.generateTokenOrders()
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (this.contractType === 'inverse') {
|
|
390
|
+
return this.generateOrdersForInverse(lastPrice, priceDistance, totalOrders);
|
|
391
|
+
} else if (this.contractType === 'linear') {
|
|
392
|
+
return this.generateOrdersForLinear(lastPrice, priceDistance, totalOrders);
|
|
393
|
+
} else {
|
|
394
|
+
throw new Error('Invalid contract type');
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
module.exports = AMMPool
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const baseConverter = require('bigint-base-converter');
|
|
2
|
+
|
|
3
|
+
// Define the Custom Base 256 Character Set
|
|
4
|
+
const allCharacters = [...Array(65536).keys()].map(i => String.fromCharCode(i));
|
|
5
|
+
const customBase256Chars = allCharacters.filter(
|
|
6
|
+
char => !/[\s\u0000-\u001F\u007F-\u00A0\u00AD\u2028\u2029]/.test(char)
|
|
7
|
+
).slice(0, 256);
|
|
8
|
+
|
|
9
|
+
// Ensure we have exactly 256 characters
|
|
10
|
+
if (customBase256Chars.length !== 256) {
|
|
11
|
+
throw new Error("Character set must contain exactly 256 unique, usable characters."); // <-- use throw, not return
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const ALPH = customBase256Chars.join('');
|
|
15
|
+
|
|
16
|
+
const Base256Converter = {
|
|
17
|
+
// Convert decimal (string/BigInt/number) to custom Base 256
|
|
18
|
+
toBase256(decimalInput) {
|
|
19
|
+
const decStr = String(decimalInput).replace(/[,\s]/g, '');
|
|
20
|
+
return baseConverter(decStr, 10, ALPH);
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
// Convert custom Base 256 back to decimal (string)
|
|
24
|
+
fromBase256(base256String) {
|
|
25
|
+
const out = baseConverter(base256String, ALPH, 10);
|
|
26
|
+
// bigint-base-converter returns an array of digits when toBase is numeric
|
|
27
|
+
return Array.isArray(out) ? out.join('') : String(out);
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
// Hex <-> Decimal helpers
|
|
31
|
+
hexToDecimal(hex) {
|
|
32
|
+
// normalize & allow odd-length hex
|
|
33
|
+
const h = hex.length % 2 ? '0' + hex : hex;
|
|
34
|
+
return BigInt('0x' + h).toString(10);
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
decimalToHex(decimalString) {
|
|
38
|
+
const clean = String(decimalString).replace(/[,\s]/g, '');
|
|
39
|
+
let hex = BigInt(clean).toString(16);
|
|
40
|
+
if (hex.length % 2) hex = '0' + hex; // even-length hex
|
|
41
|
+
return hex;
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
// Hex <-> Base256
|
|
45
|
+
hexToBase256(hex) {
|
|
46
|
+
return this.toBase256(this.hexToDecimal(hex));
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
base256ToHex(base256String) {
|
|
50
|
+
const dec = this.fromBase256(base256String);
|
|
51
|
+
return this.decimalToHex(dec);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
module.exports = Base256Converter;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const baseConverter = require('bigint-base-converter');
|
|
2
|
+
|
|
3
|
+
// Define the Base 94 character set
|
|
4
|
+
const base94Chars = Array.from({ length: 94 }, (_, i) => String.fromCharCode(i + 33));
|
|
5
|
+
//console.log(base94Chars); // Should print valid ASCII printable characters
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
// Create the conversion functions within an object
|
|
9
|
+
const Base94Converter = {
|
|
10
|
+
// Convert decimal to base 94
|
|
11
|
+
toBase94(decimalString) {
|
|
12
|
+
return baseConverter(decimalString, 10, base94Chars.join(''));
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
// Convert hex to decimal
|
|
16
|
+
hexToDecimal(hex) {
|
|
17
|
+
return BigInt('0x' + hex).toString();
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
// Convert decimal to hex
|
|
21
|
+
decimalToHex(decimalString) {
|
|
22
|
+
return BigInt(decimalString).toString(16);
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// Convert hex to Base 94
|
|
26
|
+
hexToBase94(hex) {
|
|
27
|
+
const decimalString = this.hexToDecimal(hex);
|
|
28
|
+
return this.toBase94(decimalString);
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
// Convert Base 94 back to hex
|
|
32
|
+
base94ToHex(base94String) {
|
|
33
|
+
const decimalString = this.fromBase94(base94String);
|
|
34
|
+
return this.decimalToHex(decimalString);
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
validateBase94Input(input) {
|
|
38
|
+
for (const char of input) {
|
|
39
|
+
if (!base94Chars.includes(char)) {
|
|
40
|
+
throw new Error(`Invalid Base94 character detected: ${char}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
decimalToBase94(decimal) {
|
|
46
|
+
if (!decimal) return null; // Validate input
|
|
47
|
+
|
|
48
|
+
const [integerPart, fractionalPart] = decimal.toString().split('.');
|
|
49
|
+
console.log('integer part '+integerPart)
|
|
50
|
+
const integerEncoded = this.toBase94(integerPart);
|
|
51
|
+
|
|
52
|
+
let fractionalEncoded = '';
|
|
53
|
+
if (fractionalPart) {
|
|
54
|
+
const scale = Math.pow(10, fractionalPart.length);
|
|
55
|
+
const scaledFraction = BigInt(fractionalPart) * BigInt(scale) / BigInt('1' + '0'.repeat(fractionalPart.length));
|
|
56
|
+
fractionalEncoded = this.toBase94(scaledFraction.toString());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return fractionalPart ? `${integerEncoded}|${fractionalEncoded}` : integerEncoded;
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
fromBase94(base94String) {
|
|
63
|
+
if (!base94String) return null; // Validate input
|
|
64
|
+
|
|
65
|
+
const [integerEncoded, fractionalEncoded] = base94String.split('|');
|
|
66
|
+
const integerDecoded = this.fromBase94(integerEncoded);
|
|
67
|
+
let fractionalDecoded = '0';
|
|
68
|
+
|
|
69
|
+
if (fractionalEncoded) {
|
|
70
|
+
fractionalDecoded = BigInt(this.fromBase94(fractionalEncoded)).toString();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return `${integerDecoded}.${fractionalDecoded}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Export the object for use in other modules
|
|
79
|
+
module.exports = Base94Converter;
|