@gala-chain/launchpad 1.0.0
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/.dev-env +7 -0
- package/.dockerignore +9 -0
- package/.eslintignore +4 -0
- package/.eslintrc.json +37 -0
- package/.github/workflows/publish-on-tag.yml +72 -0
- package/.github/workflows/test-on-push.yml +32 -0
- package/.nvmrc +1 -0
- package/.prettierignore +4 -0
- package/.prettierrc +12 -0
- package/Dockerfile +31 -0
- package/LICENSE +201 -0
- package/README.md +2 -0
- package/api-config.json +16 -0
- package/e2e/__snapshots__/api.spec.ts.snap +2482 -0
- package/e2e/api-config.json +17 -0
- package/e2e/api.spec.ts +48 -0
- package/e2e/jest.config.js +42 -0
- package/e2e/tsconfig.json +10 -0
- package/jest.config.ts +27 -0
- package/lib/jest.config.d.ts +13 -0
- package/lib/jest.config.d.ts.map +1 -0
- package/lib/jest.config.js +28 -0
- package/lib/jest.config.js.map +1 -0
- package/lib/package.json +54 -0
- package/lib/src/api/index.d.ts +4 -0
- package/lib/src/api/index.d.ts.map +1 -0
- package/lib/src/api/index.js +21 -0
- package/lib/src/api/index.js.map +1 -0
- package/lib/src/api/types/LaunchpadDtos.d.ts +102 -0
- package/lib/src/api/types/LaunchpadDtos.d.ts.map +1 -0
- package/lib/src/api/types/LaunchpadDtos.js +410 -0
- package/lib/src/api/types/LaunchpadDtos.js.map +1 -0
- package/lib/src/api/types/LaunchpadFeeConfig.d.ts +9 -0
- package/lib/src/api/types/LaunchpadFeeConfig.d.ts.map +1 -0
- package/lib/src/api/types/LaunchpadFeeConfig.js +56 -0
- package/lib/src/api/types/LaunchpadFeeConfig.js.map +1 -0
- package/lib/src/api/types/LaunchpadFinalizeAllocation.d.ts +10 -0
- package/lib/src/api/types/LaunchpadFinalizeAllocation.d.ts.map +1 -0
- package/lib/src/api/types/LaunchpadFinalizeAllocation.js +70 -0
- package/lib/src/api/types/LaunchpadFinalizeAllocation.js.map +1 -0
- package/lib/src/api/types/LaunchpadSale.d.ts +35 -0
- package/lib/src/api/types/LaunchpadSale.d.ts.map +1 -0
- package/lib/src/api/types/LaunchpadSale.js +195 -0
- package/lib/src/api/types/LaunchpadSale.js.map +1 -0
- package/lib/src/api/types/index.d.ts +5 -0
- package/lib/src/api/types/index.d.ts.map +1 -0
- package/lib/src/api/types/index.js +22 -0
- package/lib/src/api/types/index.js.map +1 -0
- package/lib/src/api/utils/error.d.ts +20 -0
- package/lib/src/api/utils/error.d.ts.map +1 -0
- package/lib/src/api/utils/error.js +35 -0
- package/lib/src/api/utils/error.js.map +1 -0
- package/lib/src/api/utils/index.d.ts +2 -0
- package/lib/src/api/utils/index.d.ts.map +1 -0
- package/lib/src/api/utils/index.js +19 -0
- package/lib/src/api/utils/index.js.map +1 -0
- package/lib/src/api/validators/decorators.d.ts +19 -0
- package/lib/src/api/validators/decorators.d.ts.map +1 -0
- package/lib/src/api/validators/decorators.js +391 -0
- package/lib/src/api/validators/decorators.js.map +1 -0
- package/lib/src/api/validators/index.d.ts +2 -0
- package/lib/src/api/validators/index.d.ts.map +1 -0
- package/lib/src/api/validators/index.js +19 -0
- package/lib/src/api/validators/index.js.map +1 -0
- package/lib/src/chaincode/LaunchpadContract.d.ts +20 -0
- package/lib/src/chaincode/LaunchpadContract.d.ts.map +1 -0
- package/lib/src/chaincode/LaunchpadContract.js +217 -0
- package/lib/src/chaincode/LaunchpadContract.js.map +1 -0
- package/lib/src/chaincode/dexLaunchpadFeeGate.d.ts +14 -0
- package/lib/src/chaincode/dexLaunchpadFeeGate.d.ts.map +1 -0
- package/lib/src/chaincode/dexLaunchpadFeeGate.js +47 -0
- package/lib/src/chaincode/dexLaunchpadFeeGate.js.map +1 -0
- package/lib/src/chaincode/index.d.ts +2 -0
- package/lib/src/chaincode/index.d.ts.map +1 -0
- package/lib/src/chaincode/index.js +19 -0
- package/lib/src/chaincode/index.js.map +1 -0
- package/lib/src/chaincode/launchpad/buyExactToken.d.ts +20 -0
- package/lib/src/chaincode/launchpad/buyExactToken.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/buyExactToken.js +113 -0
- package/lib/src/chaincode/launchpad/buyExactToken.js.map +1 -0
- package/lib/src/chaincode/launchpad/buyWithNative.d.ts +22 -0
- package/lib/src/chaincode/launchpad/buyWithNative.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/buyWithNative.js +106 -0
- package/lib/src/chaincode/launchpad/buyWithNative.js.map +1 -0
- package/lib/src/chaincode/launchpad/callMemeTokenIn.d.ts +27 -0
- package/lib/src/chaincode/launchpad/callMemeTokenIn.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/callMemeTokenIn.js +76 -0
- package/lib/src/chaincode/launchpad/callMemeTokenIn.js.map +1 -0
- package/lib/src/chaincode/launchpad/callMemeTokenOut.d.ts +25 -0
- package/lib/src/chaincode/launchpad/callMemeTokenOut.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/callMemeTokenOut.js +56 -0
- package/lib/src/chaincode/launchpad/callMemeTokenOut.js.map +1 -0
- package/lib/src/chaincode/launchpad/callNativeTokenIn.d.ts +25 -0
- package/lib/src/chaincode/launchpad/callNativeTokenIn.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/callNativeTokenIn.js +51 -0
- package/lib/src/chaincode/launchpad/callNativeTokenIn.js.map +1 -0
- package/lib/src/chaincode/launchpad/callNativeTokenOut.d.ts +26 -0
- package/lib/src/chaincode/launchpad/callNativeTokenOut.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/callNativeTokenOut.js +60 -0
- package/lib/src/chaincode/launchpad/callNativeTokenOut.js.map +1 -0
- package/lib/src/chaincode/launchpad/configureLaunchpadFeeConfig.d.ts +4 -0
- package/lib/src/chaincode/launchpad/configureLaunchpadFeeConfig.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/configureLaunchpadFeeConfig.js +58 -0
- package/lib/src/chaincode/launchpad/configureLaunchpadFeeConfig.js.map +1 -0
- package/lib/src/chaincode/launchpad/createSale.d.ts +26 -0
- package/lib/src/chaincode/launchpad/createSale.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/createSale.js +129 -0
- package/lib/src/chaincode/launchpad/createSale.js.map +1 -0
- package/lib/src/chaincode/launchpad/fees.d.ts +6 -0
- package/lib/src/chaincode/launchpad/fees.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/fees.js +85 -0
- package/lib/src/chaincode/launchpad/fees.js.map +1 -0
- package/lib/src/chaincode/launchpad/fetchLaunchpadAdressConfig.d.ts +4 -0
- package/lib/src/chaincode/launchpad/fetchLaunchpadAdressConfig.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/fetchLaunchpadAdressConfig.js +36 -0
- package/lib/src/chaincode/launchpad/fetchLaunchpadAdressConfig.js.map +1 -0
- package/lib/src/chaincode/launchpad/fetchSaleDetails.d.ts +19 -0
- package/lib/src/chaincode/launchpad/fetchSaleDetails.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/fetchSaleDetails.js +49 -0
- package/lib/src/chaincode/launchpad/fetchSaleDetails.js.map +1 -0
- package/lib/src/chaincode/launchpad/finaliseSale.d.ts +4 -0
- package/lib/src/chaincode/launchpad/finaliseSale.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/finaliseSale.js +144 -0
- package/lib/src/chaincode/launchpad/finaliseSale.js.map +1 -0
- package/lib/src/chaincode/launchpad/finalizeTokenAllocation.d.ts +4 -0
- package/lib/src/chaincode/launchpad/finalizeTokenAllocation.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/finalizeTokenAllocation.js +43 -0
- package/lib/src/chaincode/launchpad/finalizeTokenAllocation.js.map +1 -0
- package/lib/src/chaincode/launchpad/index.d.ts +15 -0
- package/lib/src/chaincode/launchpad/index.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/index.js +32 -0
- package/lib/src/chaincode/launchpad/index.js.map +1 -0
- package/lib/src/chaincode/launchpad/preMintCalculation.d.ts +17 -0
- package/lib/src/chaincode/launchpad/preMintCalculation.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/preMintCalculation.js +56 -0
- package/lib/src/chaincode/launchpad/preMintCalculation.js.map +1 -0
- package/lib/src/chaincode/launchpad/sellExactToken.d.ts +22 -0
- package/lib/src/chaincode/launchpad/sellExactToken.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/sellExactToken.js +102 -0
- package/lib/src/chaincode/launchpad/sellExactToken.js.map +1 -0
- package/lib/src/chaincode/launchpad/sellWithNative.d.ts +23 -0
- package/lib/src/chaincode/launchpad/sellWithNative.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/sellWithNative.js +97 -0
- package/lib/src/chaincode/launchpad/sellWithNative.js.map +1 -0
- package/lib/src/chaincode/utils/index.d.ts +2 -0
- package/lib/src/chaincode/utils/index.d.ts.map +1 -0
- package/lib/src/chaincode/utils/index.js +19 -0
- package/lib/src/chaincode/utils/index.js.map +1 -0
- package/lib/src/chaincode/utils/launchpadSaleUtils.d.ts +11 -0
- package/lib/src/chaincode/utils/launchpadSaleUtils.d.ts.map +1 -0
- package/lib/src/chaincode/utils/launchpadSaleUtils.js +65 -0
- package/lib/src/chaincode/utils/launchpadSaleUtils.js.map +1 -0
- package/lib/src/cli.d.ts +3 -0
- package/lib/src/cli.d.ts.map +1 -0
- package/lib/src/cli.js +41 -0
- package/lib/src/cli.js.map +1 -0
- package/lib/src/index.d.ts +14 -0
- package/lib/src/index.d.ts.map +1 -0
- package/lib/src/index.js +32 -0
- package/lib/src/index.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +54 -0
- package/src/api/index.ts +18 -0
- package/src/api/types/LaunchpadDtos.ts +362 -0
- package/src/api/types/LaunchpadFeeConfig.ts +45 -0
- package/src/api/types/LaunchpadFinalizeAllocation.ts +65 -0
- package/src/api/types/LaunchpadSale.ts +200 -0
- package/src/api/types/index.ts +19 -0
- package/src/api/utils/error.ts +32 -0
- package/src/api/utils/index.ts +16 -0
- package/src/api/validators/decorators.spec.ts +277 -0
- package/src/api/validators/decorators.ts +401 -0
- package/src/api/validators/index.ts +16 -0
- package/src/chaincode/LaunchpadContract.ts +211 -0
- package/src/chaincode/dexLaunchpadFeeGate.ts +43 -0
- package/src/chaincode/index.ts +16 -0
- package/src/chaincode/launchpad/buyExactToken.ts +128 -0
- package/src/chaincode/launchpad/buyWithNative.ts +120 -0
- package/src/chaincode/launchpad/callMemeTokenIn.ts +82 -0
- package/src/chaincode/launchpad/callMemeTokenOut.ts +80 -0
- package/src/chaincode/launchpad/callNativeTokenIn.ts +71 -0
- package/src/chaincode/launchpad/callNativeTokenOut.ts +81 -0
- package/src/chaincode/launchpad/configureLaunchpadFeeConfig.ts +69 -0
- package/src/chaincode/launchpad/createSale.ts +157 -0
- package/src/chaincode/launchpad/fees.ts +105 -0
- package/src/chaincode/launchpad/fetchLaunchpadAdressConfig.ts +38 -0
- package/src/chaincode/launchpad/fetchSaleDetails.ts +53 -0
- package/src/chaincode/launchpad/finaliseSale.ts +217 -0
- package/src/chaincode/launchpad/finalizeTokenAllocation.ts +47 -0
- package/src/chaincode/launchpad/index.ts +28 -0
- package/src/chaincode/launchpad/preMintCalculation.ts +61 -0
- package/src/chaincode/launchpad/sellExactToken.ts +122 -0
- package/src/chaincode/launchpad/sellWithNative.ts +112 -0
- package/src/chaincode/utils/index.ts +15 -0
- package/src/chaincode/utils/launchpadSaleUtils.ts +68 -0
- package/src/cli.ts +63 -0
- package/src/index.ts +32 -0
- package/tsconfig.base.json +29 -0
- package/tsconfig.json +19 -0
- package/tsconfig.spec.json +11 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
import { ConflictError, TokenInstanceKey, asValidUserAlias } from "@gala-chain/api";
|
|
16
|
+
import {
|
|
17
|
+
GalaChainContext,
|
|
18
|
+
createTokenClass,
|
|
19
|
+
getObjectByKey,
|
|
20
|
+
mintTokenWithAllowance,
|
|
21
|
+
putChainObject,
|
|
22
|
+
updateTokenClass
|
|
23
|
+
} from "@gala-chain/chaincode";
|
|
24
|
+
import { BigNumber } from "bignumber.js";
|
|
25
|
+
|
|
26
|
+
import { CreateSaleResDto, CreateTokenSaleDTO, LaunchpadSale, NativeTokenQuantityDto } from "../../api/types";
|
|
27
|
+
import { PreConditionFailedError } from "../../api/utils/error";
|
|
28
|
+
import { buyWithNative } from "./buyWithNative";
|
|
29
|
+
|
|
30
|
+
BigNumber.config({
|
|
31
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Creates a new token sale (Launchpad) in the GalaChain environment.
|
|
36
|
+
*
|
|
37
|
+
* This function validates input parameters, creates a token class, mints an initial supply
|
|
38
|
+
* of tokens, and initializes the Launchpad sale object. If a pre-buy amount is specified,
|
|
39
|
+
* it simulates a token purchase using native tokens.
|
|
40
|
+
*
|
|
41
|
+
* @param ctx - The context object providing access to the GalaChain environment.
|
|
42
|
+
* @param launchpadDetails - An object containing details for the token sale, including:
|
|
43
|
+
* - `tokenName`: The name of the token being created.
|
|
44
|
+
* - `tokenSymbol`: The symbol for the token.
|
|
45
|
+
* - `tokenDescription`: A description of the token.
|
|
46
|
+
* - `tokenImage`: An optional image URL for the token.
|
|
47
|
+
* - `preBuyAmount`: The amount of native tokens to use for a pre-buy (optional).
|
|
48
|
+
*
|
|
49
|
+
* @returns A promise that resolves to a `CreateSaleResDto` object containing details about
|
|
50
|
+
* the created sale, including the vault address and token collection name.
|
|
51
|
+
*
|
|
52
|
+
* @throws DefaultError if:
|
|
53
|
+
* - Required fields (`tokenName`, `tokenSymbol`, `tokenDescription`) are missing or empty.
|
|
54
|
+
* - The token class creation fails (no response key returned).
|
|
55
|
+
*/
|
|
56
|
+
export async function createSale(
|
|
57
|
+
ctx: GalaChainContext,
|
|
58
|
+
launchpadDetails: CreateTokenSaleDTO
|
|
59
|
+
): Promise<CreateSaleResDto> {
|
|
60
|
+
let isSaleFinalized = false;
|
|
61
|
+
// Validate input parameters
|
|
62
|
+
|
|
63
|
+
if (!launchpadDetails.websiteUrl && !launchpadDetails.telegramUrl && !launchpadDetails.twitterUrl) {
|
|
64
|
+
throw new PreConditionFailedError("Token sale creation requires atleast one social link.");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
launchpadDetails.tokenSymbol = launchpadDetails.tokenSymbol.toUpperCase();
|
|
68
|
+
|
|
69
|
+
// Define the token class key
|
|
70
|
+
const tokenInstanceKey = new TokenInstanceKey();
|
|
71
|
+
tokenInstanceKey.collection = `${launchpadDetails.tokenCollection}`;
|
|
72
|
+
tokenInstanceKey.category = `${launchpadDetails.tokenCategory}`;
|
|
73
|
+
tokenInstanceKey.type = `${launchpadDetails.tokenSymbol}`;
|
|
74
|
+
tokenInstanceKey.additionalKey = `${ctx.callingUser.replace(/\|/, ":")}`;
|
|
75
|
+
tokenInstanceKey.instance = new BigNumber(0);
|
|
76
|
+
|
|
77
|
+
// Validate uniqueness of sale and token
|
|
78
|
+
const vaultAddress = asValidUserAlias(
|
|
79
|
+
`service|${tokenInstanceKey.getTokenClassKey().toStringKey()}$launchpad`
|
|
80
|
+
);
|
|
81
|
+
const key = ctx.stub.createCompositeKey(LaunchpadSale.INDEX_KEY, [vaultAddress]);
|
|
82
|
+
const sale = await getObjectByKey(ctx, LaunchpadSale, key).catch(() => undefined);
|
|
83
|
+
if (sale) {
|
|
84
|
+
throw new ConflictError("This token and a sale associated with it already exists");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Call createTokenClass
|
|
88
|
+
await createTokenClass(ctx, {
|
|
89
|
+
network: "GC",
|
|
90
|
+
tokenClass: tokenInstanceKey.getTokenClassKey(),
|
|
91
|
+
isNonFungible: false,
|
|
92
|
+
decimals: 18,
|
|
93
|
+
name: launchpadDetails.tokenName,
|
|
94
|
+
symbol: launchpadDetails.tokenSymbol,
|
|
95
|
+
description: launchpadDetails.tokenDescription,
|
|
96
|
+
image: launchpadDetails.tokenImage,
|
|
97
|
+
maxSupply: new BigNumber("2e+7"),
|
|
98
|
+
maxCapacity: new BigNumber("2e+7"),
|
|
99
|
+
totalMintAllowance: new BigNumber(0),
|
|
100
|
+
totalSupply: new BigNumber(0),
|
|
101
|
+
totalBurned: new BigNumber(0),
|
|
102
|
+
authorities: [vaultAddress, ctx.callingUser]
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Mint tokens using the calling user's allowance
|
|
106
|
+
await mintTokenWithAllowance(ctx, {
|
|
107
|
+
tokenClassKey: tokenInstanceKey.getTokenClassKey(),
|
|
108
|
+
tokenInstance: new BigNumber(0),
|
|
109
|
+
owner: vaultAddress,
|
|
110
|
+
quantity: new BigNumber("2e+7")
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
//Update token class to remove the calling user as an authority in the token class
|
|
114
|
+
await updateTokenClass(ctx, {
|
|
115
|
+
tokenClass: tokenInstanceKey.getTokenClassKey(),
|
|
116
|
+
authorities: [vaultAddress]
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Create the LaunchpadSale object
|
|
120
|
+
const launchpad = new LaunchpadSale(
|
|
121
|
+
vaultAddress,
|
|
122
|
+
tokenInstanceKey,
|
|
123
|
+
launchpadDetails.reverseBondingCurveConfiguration?.toChainObject(),
|
|
124
|
+
ctx.callingUser
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
await putChainObject(ctx, launchpad);
|
|
128
|
+
|
|
129
|
+
if (launchpadDetails.preBuyQuantity.isGreaterThan(0)) {
|
|
130
|
+
const nativeTokenDto = new NativeTokenQuantityDto(
|
|
131
|
+
asValidUserAlias(launchpad.vaultAddress),
|
|
132
|
+
launchpadDetails.preBuyQuantity
|
|
133
|
+
);
|
|
134
|
+
const tradeStatus = await buyWithNative(ctx, nativeTokenDto);
|
|
135
|
+
isSaleFinalized = tradeStatus.isFinalized;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Return the response object
|
|
139
|
+
return {
|
|
140
|
+
image: launchpadDetails.tokenImage,
|
|
141
|
+
tokenName: launchpadDetails.tokenName,
|
|
142
|
+
symbol: launchpadDetails.tokenSymbol,
|
|
143
|
+
description: launchpadDetails.tokenDescription,
|
|
144
|
+
websiteUrl: launchpadDetails.websiteUrl ? launchpadDetails.websiteUrl : "",
|
|
145
|
+
telegramUrl: launchpadDetails.telegramUrl ? launchpadDetails.telegramUrl : "",
|
|
146
|
+
twitterUrl: launchpadDetails.twitterUrl ? launchpadDetails.twitterUrl : "",
|
|
147
|
+
initialBuyQuantity: launchpadDetails.preBuyQuantity.toFixed(),
|
|
148
|
+
vaultAddress: vaultAddress,
|
|
149
|
+
creatorAddress: ctx.callingUser,
|
|
150
|
+
collection: launchpadDetails.tokenCollection,
|
|
151
|
+
category: launchpadDetails.tokenCategory,
|
|
152
|
+
functionName: "CreateSale",
|
|
153
|
+
isFinalized: isSaleFinalized,
|
|
154
|
+
tokenStringKey: tokenInstanceKey.getTokenClassKey().toStringKey(),
|
|
155
|
+
reverseBondingCurveConfiguration: launchpadDetails.reverseBondingCurveConfiguration
|
|
156
|
+
} satisfies CreateSaleResDto;
|
|
157
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
import { FeeReceiptStatus } from "@gala-chain/api";
|
|
16
|
+
import {
|
|
17
|
+
GalaChainContext,
|
|
18
|
+
getObjectByKey,
|
|
19
|
+
transferToken,
|
|
20
|
+
txUnixTimeToDateIndexKeys,
|
|
21
|
+
writeChannelPaymentReceipt,
|
|
22
|
+
writeUserPaymentReceipt
|
|
23
|
+
} from "@gala-chain/chaincode";
|
|
24
|
+
import BigNumber from "bignumber.js";
|
|
25
|
+
|
|
26
|
+
import { LaunchpadFeeConfig, LaunchpadSale } from "../../api/types";
|
|
27
|
+
import { SlippageToleranceExceededError } from "../../api/utils/error";
|
|
28
|
+
|
|
29
|
+
const REVERSE_BONDING_CURVE_FEE_CODE = "LaunchpadReverseBondingCurveFee";
|
|
30
|
+
const NATIVE_TOKEN_DECIMALS = 8;
|
|
31
|
+
|
|
32
|
+
export function calculateReverseBondingCurveFee(sale: LaunchpadSale, nativeTokensToReceive: BigNumber) {
|
|
33
|
+
if (
|
|
34
|
+
!sale.reverseBondingCurveConfiguration ||
|
|
35
|
+
sale.reverseBondingCurveConfiguration.maxFeePortion.isZero()
|
|
36
|
+
) {
|
|
37
|
+
return BigNumber(0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const circulatingSupplyProportional = sale.fetchCirculatingSupplyProportional();
|
|
41
|
+
const { minFeePortion, maxFeePortion } = sale.reverseBondingCurveConfiguration;
|
|
42
|
+
const feePortionDiff = maxFeePortion.minus(minFeePortion);
|
|
43
|
+
const portionAboveBaseline = circulatingSupplyProportional.multipliedBy(feePortionDiff);
|
|
44
|
+
const feePortion = minFeePortion.plus(portionAboveBaseline);
|
|
45
|
+
|
|
46
|
+
const feeAmount = nativeTokensToReceive
|
|
47
|
+
.multipliedBy(feePortion)
|
|
48
|
+
.decimalPlaces(NATIVE_TOKEN_DECIMALS, BigNumber.ROUND_UP);
|
|
49
|
+
|
|
50
|
+
return feeAmount;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function payReverseBondingCurveFee(
|
|
54
|
+
ctx: GalaChainContext,
|
|
55
|
+
sale: LaunchpadSale,
|
|
56
|
+
nativeTokensToReceive: BigNumber,
|
|
57
|
+
maxAcceptableFee?: BigNumber
|
|
58
|
+
) {
|
|
59
|
+
const feeAmount = await calculateReverseBondingCurveFee(sale, nativeTokensToReceive);
|
|
60
|
+
|
|
61
|
+
if (feeAmount.isZero()) {
|
|
62
|
+
return; // No fee
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (maxAcceptableFee && feeAmount.isGreaterThan(maxAcceptableFee)) {
|
|
66
|
+
throw new SlippageToleranceExceededError("Fee exceeds maximum acceptable amount");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const launchpadConfigKey = ctx.stub.createCompositeKey(LaunchpadFeeConfig.INDEX_KEY, []);
|
|
70
|
+
const launchpadConfig = await getObjectByKey(ctx, LaunchpadFeeConfig, launchpadConfigKey);
|
|
71
|
+
const nativeToken = sale.fetchNativeTokenInstanceKey();
|
|
72
|
+
const { year, month, day } = txUnixTimeToDateIndexKeys(ctx.txUnixTime);
|
|
73
|
+
const txId = ctx.stub.getTxID();
|
|
74
|
+
|
|
75
|
+
await writeChannelPaymentReceipt(ctx, {
|
|
76
|
+
year,
|
|
77
|
+
month,
|
|
78
|
+
day,
|
|
79
|
+
feeCode: REVERSE_BONDING_CURVE_FEE_CODE,
|
|
80
|
+
paidByUser: ctx.callingUser,
|
|
81
|
+
txId,
|
|
82
|
+
quantity: feeAmount,
|
|
83
|
+
status: FeeReceiptStatus.Settled
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await writeUserPaymentReceipt(ctx, {
|
|
87
|
+
paidByUser: ctx.callingUser,
|
|
88
|
+
year,
|
|
89
|
+
month,
|
|
90
|
+
day,
|
|
91
|
+
feeCode: REVERSE_BONDING_CURVE_FEE_CODE,
|
|
92
|
+
txId,
|
|
93
|
+
quantity: feeAmount,
|
|
94
|
+
status: FeeReceiptStatus.Settled
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
await transferToken(ctx, {
|
|
98
|
+
to: launchpadConfig.feeAddress,
|
|
99
|
+
from: ctx.callingUser,
|
|
100
|
+
tokenInstanceKey: nativeToken,
|
|
101
|
+
quantity: feeAmount,
|
|
102
|
+
allowancesToUse: [],
|
|
103
|
+
authorizedOnBehalf: undefined
|
|
104
|
+
});
|
|
105
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
import { NotFoundError, UnauthorizedError } from "@gala-chain/api";
|
|
16
|
+
import { GalaChainContext } from "@gala-chain/chaincode";
|
|
17
|
+
|
|
18
|
+
import { LaunchpadFeeConfig } from "../../api/types";
|
|
19
|
+
import { fetchLaunchpadFeeAddress } from "../utils";
|
|
20
|
+
|
|
21
|
+
export async function fetchLaunchpadFeeConfig(ctx: GalaChainContext): Promise<LaunchpadFeeConfig> {
|
|
22
|
+
const curatorOrgMsp = process.env.CURATOR_ORG_MSP ?? "CuratorOrg";
|
|
23
|
+
|
|
24
|
+
const platformFeeAddress = await fetchLaunchpadFeeAddress(ctx);
|
|
25
|
+
|
|
26
|
+
if (ctx.clientIdentity.getMSPID() !== curatorOrgMsp) {
|
|
27
|
+
throw new UnauthorizedError(`CallingUser ${ctx.callingUser} is not authorized to create or update`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!platformFeeAddress) {
|
|
31
|
+
throw new NotFoundError(
|
|
32
|
+
"Platform fee configuration has yet to be defined. Platform fee configuration is not defined."
|
|
33
|
+
);
|
|
34
|
+
} else if (!platformFeeAddress.authorities.includes(ctx.callingUser)) {
|
|
35
|
+
throw new UnauthorizedError(`CallingUser ${ctx.callingUser} is not authorized to create or update`);
|
|
36
|
+
}
|
|
37
|
+
return platformFeeAddress;
|
|
38
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
import { NotFoundError } from "@gala-chain/api";
|
|
16
|
+
import { GalaChainContext, getObjectByKey } from "@gala-chain/chaincode";
|
|
17
|
+
import { BigNumber } from "bignumber.js";
|
|
18
|
+
|
|
19
|
+
import { FetchSaleDto, LaunchpadSale } from "../../api/types";
|
|
20
|
+
|
|
21
|
+
BigNumber.config({
|
|
22
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Fetches the details of a specific token sale (LaunchpadSale) using its sale address.
|
|
27
|
+
*
|
|
28
|
+
* This function retrieves the sale object from the chain using a composite key derived
|
|
29
|
+
* from the sale address. If the sale record is not found, an error is thrown.
|
|
30
|
+
*
|
|
31
|
+
* @param ctx - The context object providing access to the GalaChain environment.
|
|
32
|
+
* @param fetchSaleDTO - An object containing the sale address:
|
|
33
|
+
* - `vaultAddress`: The address of the sale to be fetched.
|
|
34
|
+
*
|
|
35
|
+
* @returns A promise that resolves to a `LaunchpadSale` object containing details about
|
|
36
|
+
* the specified token sale.
|
|
37
|
+
*
|
|
38
|
+
* @throws NotFoundError if no sale record is found for the provided sale address.
|
|
39
|
+
*/
|
|
40
|
+
export async function fetchSaleDetails(
|
|
41
|
+
ctx: GalaChainContext,
|
|
42
|
+
fetchSaleDTO: FetchSaleDto
|
|
43
|
+
): Promise<LaunchpadSale> {
|
|
44
|
+
const key = ctx.stub.createCompositeKey(LaunchpadSale.INDEX_KEY, [fetchSaleDTO.vaultAddress]);
|
|
45
|
+
|
|
46
|
+
const sale = await getObjectByKey(ctx, LaunchpadSale, key);
|
|
47
|
+
|
|
48
|
+
if (sale === undefined) {
|
|
49
|
+
throw new NotFoundError("Sale record not found.");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return sale;
|
|
53
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
// TODO: dependencies on DEX
|
|
16
|
+
import { BurnTokenQuantity } from "@gala-chain/api";
|
|
17
|
+
import {
|
|
18
|
+
GalaChainContext,
|
|
19
|
+
burnTokens,
|
|
20
|
+
fetchOrCreateBalance,
|
|
21
|
+
getObjectByKey,
|
|
22
|
+
putChainObject,
|
|
23
|
+
resolveUserAlias,
|
|
24
|
+
transferToken
|
|
25
|
+
} from "@gala-chain/chaincode";
|
|
26
|
+
import {
|
|
27
|
+
AddLiquidityDTO,
|
|
28
|
+
CreatePoolDto,
|
|
29
|
+
GetAddLiquidityEstimationDto,
|
|
30
|
+
addLiquidity,
|
|
31
|
+
createPool,
|
|
32
|
+
generateKeyFromClassKey,
|
|
33
|
+
getAddLiquidityEstimation,
|
|
34
|
+
getPoolData,
|
|
35
|
+
getSlot0,
|
|
36
|
+
sortString
|
|
37
|
+
} from "@gala-chain/dex";
|
|
38
|
+
import BigNumber from "bignumber.js";
|
|
39
|
+
import Decimal from "decimal.js";
|
|
40
|
+
|
|
41
|
+
import { LaunchpadFinalizeFeeAllocation, LaunchpadSale } from "../../api/types";
|
|
42
|
+
import { PreConditionFailedError } from "../../api/utils/error";
|
|
43
|
+
import { fetchLaunchpadFeeAddress, getBondingConstants } from "../utils";
|
|
44
|
+
|
|
45
|
+
export async function finalizeSale(ctx: GalaChainContext, sale: LaunchpadSale): Promise<void> {
|
|
46
|
+
const key = ctx.stub.createCompositeKey(LaunchpadFinalizeFeeAllocation.INDEX_KEY, []);
|
|
47
|
+
const feeAllocation = await getObjectByKey(ctx, LaunchpadFinalizeFeeAllocation, key).catch(() => undefined);
|
|
48
|
+
|
|
49
|
+
const platformFeeAddressConfiguration = await fetchLaunchpadFeeAddress(ctx);
|
|
50
|
+
if (!platformFeeAddressConfiguration) {
|
|
51
|
+
throw new PreConditionFailedError("Platform fee configuration is yet to be defined.");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const platformFeePercentage = feeAllocation ? feeAllocation.platformFeePercentage : 0.1;
|
|
55
|
+
const ownerAllocationPercentage = feeAllocation ? feeAllocation.ownerAllocationPercentage : 0.6;
|
|
56
|
+
const liquidityAllocationPercentage = feeAllocation ? feeAllocation.liquidityAllocationPercentage : 0.3;
|
|
57
|
+
|
|
58
|
+
const nativeToken = sale.fetchNativeTokenInstanceKey();
|
|
59
|
+
const memeToken = sale.fetchSellingTokenInstanceKey();
|
|
60
|
+
const vaultAddressAlias = await resolveUserAlias(ctx, sale.vaultAddress);
|
|
61
|
+
|
|
62
|
+
await transferToken(ctx, {
|
|
63
|
+
from: vaultAddressAlias,
|
|
64
|
+
to: sale.saleOwner,
|
|
65
|
+
tokenInstanceKey: nativeToken,
|
|
66
|
+
quantity: new BigNumber(sale.nativeTokenQuantity)
|
|
67
|
+
.times(ownerAllocationPercentage)
|
|
68
|
+
.decimalPlaces(8, BigNumber.ROUND_DOWN),
|
|
69
|
+
allowancesToUse: [],
|
|
70
|
+
authorizedOnBehalf: {
|
|
71
|
+
callingOnBehalf: vaultAddressAlias,
|
|
72
|
+
callingUser: ctx.callingUser
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await transferToken(ctx, {
|
|
77
|
+
from: vaultAddressAlias,
|
|
78
|
+
to: platformFeeAddressConfiguration.feeAddress,
|
|
79
|
+
tokenInstanceKey: nativeToken,
|
|
80
|
+
quantity: new BigNumber(sale.nativeTokenQuantity)
|
|
81
|
+
.times(platformFeePercentage)
|
|
82
|
+
.decimalPlaces(8, BigNumber.ROUND_DOWN),
|
|
83
|
+
allowancesToUse: [],
|
|
84
|
+
authorizedOnBehalf: {
|
|
85
|
+
callingOnBehalf: vaultAddressAlias,
|
|
86
|
+
callingUser: ctx.callingUser
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const sellingTokenClassKey = sale.fetchSellingTokenInstanceKey().getTokenClassKey();
|
|
91
|
+
const nativeTokenClassKey = sale.fetchNativeTokenInstanceKey().getTokenClassKey();
|
|
92
|
+
|
|
93
|
+
const { isChanged: areTokensSorted } = sortString(
|
|
94
|
+
[sellingTokenClassKey, nativeTokenClassKey].map(generateKeyFromClassKey)
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const { sqrtPrice, finalPrice } = calculateFinalLaunchpadPrice(sale, areTokensSorted);
|
|
98
|
+
const poolDTO = new CreatePoolDto(
|
|
99
|
+
areTokensSorted ? nativeTokenClassKey : sellingTokenClassKey,
|
|
100
|
+
areTokensSorted ? sellingTokenClassKey : nativeTokenClassKey,
|
|
101
|
+
3000,
|
|
102
|
+
sqrtPrice
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// Check if a pool for this token already exists
|
|
106
|
+
const pool = await getPoolData(ctx, poolDTO);
|
|
107
|
+
if (!pool) {
|
|
108
|
+
await createPool(ctx, poolDTO);
|
|
109
|
+
}
|
|
110
|
+
const poolInfo = await getSlot0(ctx, poolDTO);
|
|
111
|
+
|
|
112
|
+
// Proceed normally if price in the pool is within an acceptable range
|
|
113
|
+
const priceCloseEnough = sqrtPrice.minus(poolInfo.sqrtPrice).abs().lte(sqrtPrice.multipliedBy(0.05));
|
|
114
|
+
const expectedNativeTokenRequired = new BigNumber(sale.nativeTokenQuantity).times(
|
|
115
|
+
liquidityAllocationPercentage
|
|
116
|
+
);
|
|
117
|
+
const isPriceGreaterThanExpected = poolInfo.sqrtPrice.isGreaterThan(sqrtPrice);
|
|
118
|
+
const expectedSaleTokenRequired = expectedNativeTokenRequired.times(finalPrice);
|
|
119
|
+
|
|
120
|
+
// Determine token amounts and token ordering
|
|
121
|
+
const token0 = areTokensSorted ? nativeTokenClassKey : sellingTokenClassKey;
|
|
122
|
+
const token1 = areTokensSorted ? sellingTokenClassKey : nativeTokenClassKey;
|
|
123
|
+
|
|
124
|
+
const liquidityAmount = priceCloseEnough
|
|
125
|
+
? expectedNativeTokenRequired
|
|
126
|
+
: isPriceGreaterThanExpected
|
|
127
|
+
? expectedSaleTokenRequired
|
|
128
|
+
: expectedNativeTokenRequired;
|
|
129
|
+
|
|
130
|
+
const zeroForOne = priceCloseEnough
|
|
131
|
+
? areTokensSorted
|
|
132
|
+
: isPriceGreaterThanExpected
|
|
133
|
+
? !areTokensSorted
|
|
134
|
+
: areTokensSorted;
|
|
135
|
+
|
|
136
|
+
const expectedTokenDTO = new GetAddLiquidityEstimationDto(
|
|
137
|
+
token0,
|
|
138
|
+
token1,
|
|
139
|
+
3000,
|
|
140
|
+
liquidityAmount,
|
|
141
|
+
-887220,
|
|
142
|
+
887220,
|
|
143
|
+
zeroForOne
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const addLiquidityEstimate = await getAddLiquidityEstimation(ctx, expectedTokenDTO);
|
|
147
|
+
|
|
148
|
+
const amount0 = new BigNumber(addLiquidityEstimate.amount0.toString());
|
|
149
|
+
const amount1 = new BigNumber(addLiquidityEstimate.amount1.toString());
|
|
150
|
+
|
|
151
|
+
const positionDto = new AddLiquidityDTO(
|
|
152
|
+
token0,
|
|
153
|
+
token1,
|
|
154
|
+
3000,
|
|
155
|
+
-887220,
|
|
156
|
+
887220,
|
|
157
|
+
amount0,
|
|
158
|
+
amount1,
|
|
159
|
+
amount0.times(0.9999999),
|
|
160
|
+
amount1.times(0.9999999),
|
|
161
|
+
undefined
|
|
162
|
+
);
|
|
163
|
+
positionDto.uniqueKey = sale.vaultAddress.toString();
|
|
164
|
+
|
|
165
|
+
await addLiquidity(ctx, positionDto, vaultAddressAlias);
|
|
166
|
+
|
|
167
|
+
// Burn any extra meme tokens
|
|
168
|
+
const sellingTokenToBurn = await fetchOrCreateBalance(ctx, vaultAddressAlias, memeToken);
|
|
169
|
+
const burnSellingTokenQuantity = new BurnTokenQuantity();
|
|
170
|
+
burnSellingTokenQuantity.tokenInstanceKey = memeToken;
|
|
171
|
+
burnSellingTokenQuantity.quantity = sellingTokenToBurn.getQuantityTotal();
|
|
172
|
+
|
|
173
|
+
await burnTokens(ctx, {
|
|
174
|
+
owner: vaultAddressAlias,
|
|
175
|
+
toBurn: [burnSellingTokenQuantity],
|
|
176
|
+
preValidated: true
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Burn any extra GALA
|
|
180
|
+
const nativeTokenToBurn = await fetchOrCreateBalance(ctx, vaultAddressAlias, nativeToken);
|
|
181
|
+
const burnNativeTokenQuantity = new BurnTokenQuantity();
|
|
182
|
+
burnNativeTokenQuantity.tokenInstanceKey = nativeToken;
|
|
183
|
+
burnNativeTokenQuantity.quantity = nativeTokenToBurn.getQuantityTotal();
|
|
184
|
+
|
|
185
|
+
if (burnNativeTokenQuantity.quantity) {
|
|
186
|
+
await burnTokens(ctx, {
|
|
187
|
+
owner: vaultAddressAlias,
|
|
188
|
+
toBurn: [burnNativeTokenQuantity],
|
|
189
|
+
preValidated: true
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// update sale status
|
|
194
|
+
sale.finalizeSale();
|
|
195
|
+
await putChainObject(ctx, sale);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function calculateFinalLaunchpadPrice(
|
|
199
|
+
sale: LaunchpadSale,
|
|
200
|
+
areTokensSorted: boolean
|
|
201
|
+
): { sqrtPrice: BigNumber; finalPrice: BigNumber } {
|
|
202
|
+
const totalTokensSold = new Decimal(sale.fetchTokensSold());
|
|
203
|
+
const basePrice = new Decimal(sale.fetchBasePrice());
|
|
204
|
+
const { exponentFactor, euler, decimals } = getBondingConstants();
|
|
205
|
+
|
|
206
|
+
const exponent = exponentFactor.mul(totalTokensSold).div(decimals);
|
|
207
|
+
const multiplicand = euler.pow(exponent);
|
|
208
|
+
const finalPriceDecimal = multiplicand.mul(basePrice).div(decimals);
|
|
209
|
+
|
|
210
|
+
const priceDecimal = areTokensSorted ? new Decimal(1).dividedBy(finalPriceDecimal) : finalPriceDecimal;
|
|
211
|
+
const sqrtPriceDecimal = priceDecimal.pow("0.5");
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
finalPrice: new BigNumber(new Decimal(1).dividedBy(finalPriceDecimal).toString()),
|
|
215
|
+
sqrtPrice: new BigNumber(sqrtPriceDecimal.toString())
|
|
216
|
+
};
|
|
217
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
import { UnauthorizedError } from "@gala-chain/api";
|
|
16
|
+
import { GalaChainContext } from "@gala-chain/chaincode";
|
|
17
|
+
import { getObjectByKey, putChainObject } from "@gala-chain/chaincode";
|
|
18
|
+
|
|
19
|
+
import { FinalizeTokenAllocationDto, LaunchpadFinalizeFeeAllocation } from "../../api/types";
|
|
20
|
+
import { PreConditionFailedError } from "../../api/utils/error";
|
|
21
|
+
import { fetchLaunchpadFeeAddress } from "../utils";
|
|
22
|
+
|
|
23
|
+
export async function finalizeTokenAllocation(
|
|
24
|
+
ctx: GalaChainContext,
|
|
25
|
+
dto: FinalizeTokenAllocationDto
|
|
26
|
+
): Promise<LaunchpadFinalizeFeeAllocation> {
|
|
27
|
+
const platformFeeAddress = await fetchLaunchpadFeeAddress(ctx);
|
|
28
|
+
if (!platformFeeAddress) {
|
|
29
|
+
throw new PreConditionFailedError(
|
|
30
|
+
"Platform fee configuration has yet to be defined. Platform fee configuration is not defined."
|
|
31
|
+
);
|
|
32
|
+
} else if (!platformFeeAddress.authorities.includes(ctx.callingUser)) {
|
|
33
|
+
throw new UnauthorizedError(`CallingUser ${ctx.callingUser} is not authorized to create or update`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const key = ctx.stub.createCompositeKey(LaunchpadFinalizeFeeAllocation.INDEX_KEY, []);
|
|
37
|
+
let feeAllocation = await getObjectByKey(ctx, LaunchpadFinalizeFeeAllocation, key).catch(() => undefined);
|
|
38
|
+
|
|
39
|
+
if (!feeAllocation) {
|
|
40
|
+
feeAllocation = new LaunchpadFinalizeFeeAllocation(dto.platformFeePercentage, dto.ownerFeePercentage);
|
|
41
|
+
} else {
|
|
42
|
+
feeAllocation.setAllocation(dto.platformFeePercentage, dto.ownerFeePercentage);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
await putChainObject(ctx, feeAllocation);
|
|
46
|
+
return feeAllocation;
|
|
47
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
export * from "./buyExactToken";
|
|
16
|
+
export * from "./buyWithNative";
|
|
17
|
+
export * from "./callMemeTokenIn";
|
|
18
|
+
export * from "./callMemeTokenOut";
|
|
19
|
+
export * from "./callNativeTokenIn";
|
|
20
|
+
export * from "./callNativeTokenOut";
|
|
21
|
+
export * from "./createSale";
|
|
22
|
+
export * from "./fetchSaleDetails";
|
|
23
|
+
export * from "./preMintCalculation";
|
|
24
|
+
export * from "./sellExactToken";
|
|
25
|
+
export * from "./finalizeTokenAllocation";
|
|
26
|
+
export * from "./sellWithNative";
|
|
27
|
+
export * from "./configureLaunchpadFeeConfig";
|
|
28
|
+
export * from "./fetchLaunchpadAdressConfig";
|