@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,61 @@
|
|
|
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 { BigNumber } from "bignumber.js";
|
|
16
|
+
import Decimal from "decimal.js";
|
|
17
|
+
|
|
18
|
+
import { LaunchpadSale, PreMintCalculationDto } from "../../api/types";
|
|
19
|
+
import { getBondingConstants } from "../utils";
|
|
20
|
+
|
|
21
|
+
BigNumber.config({
|
|
22
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Calculates the number of tokens that can be purchased using a specified amount
|
|
27
|
+
* of native tokens based on a bonding curve mechanism.
|
|
28
|
+
*
|
|
29
|
+
* This function applies the bonding curve formula for a brand new sale with zero tokens sold
|
|
30
|
+
* to determine the number of tokens the user can buy with the provided native token amount.
|
|
31
|
+
*
|
|
32
|
+
* @param buyTokenDTO - The Amount of native tokens to spend for the purchase.
|
|
33
|
+
*
|
|
34
|
+
* @returns A promise that resolves to a string representing the calculated amount of
|
|
35
|
+
* tokens to be received, rounded down to 18 decimal places.
|
|
36
|
+
*
|
|
37
|
+
* @throws Error if the calculation results in an invalid state.
|
|
38
|
+
*/
|
|
39
|
+
export async function calculatePreMintTokens(buyTokenDTO: PreMintCalculationDto): Promise<string> {
|
|
40
|
+
const totalTokensSold = new Decimal(0); // current tokens sold / x
|
|
41
|
+
const nativeTokens = new Decimal(buyTokenDTO.nativeTokenQuantity.toString()); // native tokens used to buy / y
|
|
42
|
+
const basePrice = new Decimal(LaunchpadSale.BASE_PRICE); // base price / a
|
|
43
|
+
const { exponentFactor, euler, decimals } = getBondingConstants();
|
|
44
|
+
|
|
45
|
+
const constant = nativeTokens.mul(exponentFactor).div(basePrice);
|
|
46
|
+
|
|
47
|
+
const exponent1 = exponentFactor.mul(totalTokensSold).div(decimals);
|
|
48
|
+
|
|
49
|
+
const eResult1 = euler.pow(exponent1);
|
|
50
|
+
|
|
51
|
+
const ethScaled = constant.add(eResult1);
|
|
52
|
+
|
|
53
|
+
const lnEthScaled = ethScaled.ln().mul(decimals);
|
|
54
|
+
|
|
55
|
+
const lnEthScaledBase = lnEthScaled.div(exponentFactor);
|
|
56
|
+
|
|
57
|
+
const result = lnEthScaledBase.minus(totalTokensSold);
|
|
58
|
+
const roundedResult = result.toDecimalPlaces(18, Decimal.ROUND_DOWN);
|
|
59
|
+
|
|
60
|
+
return roundedResult.toString();
|
|
61
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
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 { GalaChainContext, fetchTokenClass, putChainObject, transferToken } from "@gala-chain/chaincode";
|
|
16
|
+
import { BigNumber } from "bignumber.js";
|
|
17
|
+
|
|
18
|
+
import { ExactTokenQuantityDto, NativeTokenQuantityDto, TradeResDto } from "../../api/types";
|
|
19
|
+
import { SlippageToleranceExceededError } from "../../api/utils/error";
|
|
20
|
+
import { fetchAndValidateSale } from "../utils";
|
|
21
|
+
import { callMemeTokenIn } from "./callMemeTokenIn";
|
|
22
|
+
import { callNativeTokenOut } from "./callNativeTokenOut";
|
|
23
|
+
import { payReverseBondingCurveFee } from "./fees";
|
|
24
|
+
|
|
25
|
+
BigNumber.config({
|
|
26
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Executes the sale of an exact amount of tokens for native tokens (e.g., GALA).
|
|
31
|
+
*
|
|
32
|
+
* This function facilitates selling a specific token amount by transferring the tokens to
|
|
33
|
+
* the sale vault and providing the calculated native tokens in return. It ensures validation
|
|
34
|
+
* of the sale, handles insufficient vault balances, and checks expected vs. actual native tokens.
|
|
35
|
+
*
|
|
36
|
+
* @param ctx - The context object providing access to the GalaChain environment.
|
|
37
|
+
* @param sellTokenDTO - An object containing the sale details:
|
|
38
|
+
* - `vaultAddress`: The address of the sale.
|
|
39
|
+
* - `tokenAmount`: The exact amount of tokens to sell.
|
|
40
|
+
* - `expectedNativeToken` (optional): The expected amount of native tokens in return.
|
|
41
|
+
*
|
|
42
|
+
* @returns A promise that resolves to a `TradeResDto` object containing the updated
|
|
43
|
+
* balances of the seller's tokens and native tokens.
|
|
44
|
+
*
|
|
45
|
+
* @throws DefaultError if the expected native tokens exceed the actual amount to be provided.
|
|
46
|
+
*/
|
|
47
|
+
export async function sellExactToken(
|
|
48
|
+
ctx: GalaChainContext,
|
|
49
|
+
sellTokenDTO: ExactTokenQuantityDto
|
|
50
|
+
): Promise<TradeResDto> {
|
|
51
|
+
const sale = await fetchAndValidateSale(ctx, sellTokenDTO.vaultAddress);
|
|
52
|
+
|
|
53
|
+
const callNativeTokenOutResult = await callNativeTokenOut(ctx, sellTokenDTO);
|
|
54
|
+
let nativeTokensToProvide = new BigNumber(callNativeTokenOutResult.calculatedQuantity);
|
|
55
|
+
const nativeTokensLeftInVault = new BigNumber(sale.nativeTokenQuantity);
|
|
56
|
+
const nativeToken = sale.fetchNativeTokenInstanceKey();
|
|
57
|
+
const memeToken = sale.fetchSellingTokenInstanceKey();
|
|
58
|
+
|
|
59
|
+
if (nativeTokensLeftInVault.comparedTo(nativeTokensToProvide) < 0) {
|
|
60
|
+
nativeTokensToProvide = nativeTokensLeftInVault;
|
|
61
|
+
const nativeTokensBeingSoldDto = new NativeTokenQuantityDto(
|
|
62
|
+
sellTokenDTO.vaultAddress,
|
|
63
|
+
nativeTokensToProvide
|
|
64
|
+
);
|
|
65
|
+
const callMemeTokenInResult = await callMemeTokenIn(ctx, nativeTokensBeingSoldDto);
|
|
66
|
+
sellTokenDTO.tokenQuantity = new BigNumber(callMemeTokenInResult.calculatedQuantity);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (
|
|
70
|
+
sellTokenDTO.expectedNativeToken &&
|
|
71
|
+
sellTokenDTO.expectedNativeToken.comparedTo(nativeTokensToProvide) > 0
|
|
72
|
+
) {
|
|
73
|
+
throw new SlippageToleranceExceededError(
|
|
74
|
+
"Expected Gala tokens from this operation exceeds the actual amount that will be provided."
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// The fee must be paid BEFORE the sale can happen.
|
|
79
|
+
// That means you cannot pay the fee using proceeds from the sale.
|
|
80
|
+
await payReverseBondingCurveFee(
|
|
81
|
+
ctx,
|
|
82
|
+
sale,
|
|
83
|
+
nativeTokensToProvide,
|
|
84
|
+
sellTokenDTO.extraFees?.maxAcceptableReverseBondingCurveFee
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
await transferToken(ctx, {
|
|
88
|
+
from: ctx.callingUser,
|
|
89
|
+
to: sellTokenDTO.vaultAddress,
|
|
90
|
+
tokenInstanceKey: memeToken,
|
|
91
|
+
quantity: sellTokenDTO.tokenQuantity,
|
|
92
|
+
allowancesToUse: [],
|
|
93
|
+
authorizedOnBehalf: undefined
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
await transferToken(ctx, {
|
|
97
|
+
from: sellTokenDTO.vaultAddress,
|
|
98
|
+
to: ctx.callingUser,
|
|
99
|
+
tokenInstanceKey: nativeToken,
|
|
100
|
+
quantity: nativeTokensToProvide,
|
|
101
|
+
allowancesToUse: [],
|
|
102
|
+
authorizedOnBehalf: {
|
|
103
|
+
callingOnBehalf: sellTokenDTO.vaultAddress,
|
|
104
|
+
callingUser: ctx.callingUser
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
sale.sellToken(sellTokenDTO.tokenQuantity, nativeTokensToProvide);
|
|
109
|
+
await putChainObject(ctx, sale);
|
|
110
|
+
|
|
111
|
+
const token = await fetchTokenClass(ctx, sale.sellingToken);
|
|
112
|
+
return {
|
|
113
|
+
inputQuantity: sellTokenDTO.tokenQuantity.toFixed(),
|
|
114
|
+
outputQuantity: nativeTokensToProvide.toFixed(),
|
|
115
|
+
tokenName: token.name,
|
|
116
|
+
tradeType: "Sell",
|
|
117
|
+
vaultAddress: sellTokenDTO.vaultAddress,
|
|
118
|
+
userAddress: ctx.callingUser,
|
|
119
|
+
isFinalized: false,
|
|
120
|
+
functionName: "SellExactToken"
|
|
121
|
+
};
|
|
122
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
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 { GalaChainContext, fetchTokenClass, putChainObject, transferToken } from "@gala-chain/chaincode";
|
|
16
|
+
import { BigNumber } from "bignumber.js";
|
|
17
|
+
|
|
18
|
+
import { NativeTokenQuantityDto, TradeResDto } from "../../api/types";
|
|
19
|
+
import { SlippageToleranceExceededError } from "../../api/utils/error";
|
|
20
|
+
import { fetchAndValidateSale } from "../utils";
|
|
21
|
+
import { callMemeTokenIn } from "./callMemeTokenIn";
|
|
22
|
+
import { payReverseBondingCurveFee } from "./fees";
|
|
23
|
+
|
|
24
|
+
BigNumber.config({
|
|
25
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Executes a sale of tokens using native tokens (e.g., GALA) in exchange for the specified token amount.
|
|
30
|
+
*
|
|
31
|
+
* This function handles the process of selling tokens for native tokens in the sale vault, ensuring
|
|
32
|
+
* that the token amount and native token quantity are properly adjusted based on the sale vault's
|
|
33
|
+
* available balance. It also checks if the expected token amount matches the actual amount required.
|
|
34
|
+
*
|
|
35
|
+
* @param ctx - The context object that provides access to the GalaChain environment.
|
|
36
|
+
* @param sellTokenDTO - An object containing the sale details:
|
|
37
|
+
* - `vaultAddress`: The address of the sale.
|
|
38
|
+
* - `nativeTokenAmount`: The amount of native tokens to be used in the sale.
|
|
39
|
+
* - `expectedToken` (optional): The expected amount of tokens to be received in return.
|
|
40
|
+
*
|
|
41
|
+
* @returns A promise that resolves to a `TradeResDto` object containing the updated
|
|
42
|
+
* balances of the seller's tokens and native tokens.
|
|
43
|
+
*
|
|
44
|
+
* @throws DefaultError if the expected token amount is less than the actual amount required
|
|
45
|
+
* for the operation.
|
|
46
|
+
*/
|
|
47
|
+
export async function sellWithNative(
|
|
48
|
+
ctx: GalaChainContext,
|
|
49
|
+
sellTokenDTO: NativeTokenQuantityDto
|
|
50
|
+
): Promise<TradeResDto> {
|
|
51
|
+
const sale = await fetchAndValidateSale(ctx, sellTokenDTO.vaultAddress);
|
|
52
|
+
|
|
53
|
+
const nativeTokensLeftInVault = new BigNumber(sale.nativeTokenQuantity);
|
|
54
|
+
if (nativeTokensLeftInVault.comparedTo(sellTokenDTO.nativeTokenQuantity) < 0) {
|
|
55
|
+
sellTokenDTO.nativeTokenQuantity = nativeTokensLeftInVault;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const callMemeTokenInResult = await callMemeTokenIn(ctx, sellTokenDTO);
|
|
59
|
+
const tokensToSell = new BigNumber(callMemeTokenInResult.calculatedQuantity);
|
|
60
|
+
const nativeToken = sale.fetchNativeTokenInstanceKey();
|
|
61
|
+
const memeToken = sale.fetchSellingTokenInstanceKey();
|
|
62
|
+
|
|
63
|
+
if (sellTokenDTO.expectedToken && sellTokenDTO.expectedToken.comparedTo(tokensToSell) < 0) {
|
|
64
|
+
throw new SlippageToleranceExceededError(
|
|
65
|
+
"Token amount expected to cost for this operation is less than the the actual amount required."
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// The fee must be paid BEFORE the sale can happen.
|
|
70
|
+
// That means you cannot pay the fee using proceeds from the sale.
|
|
71
|
+
await payReverseBondingCurveFee(
|
|
72
|
+
ctx,
|
|
73
|
+
sale,
|
|
74
|
+
sellTokenDTO.nativeTokenQuantity,
|
|
75
|
+
sellTokenDTO.extraFees?.maxAcceptableReverseBondingCurveFee
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
await transferToken(ctx, {
|
|
79
|
+
from: ctx.callingUser,
|
|
80
|
+
to: sellTokenDTO.vaultAddress,
|
|
81
|
+
tokenInstanceKey: memeToken,
|
|
82
|
+
quantity: tokensToSell,
|
|
83
|
+
allowancesToUse: [],
|
|
84
|
+
authorizedOnBehalf: undefined
|
|
85
|
+
});
|
|
86
|
+
await transferToken(ctx, {
|
|
87
|
+
from: sellTokenDTO.vaultAddress,
|
|
88
|
+
to: ctx.callingUser,
|
|
89
|
+
tokenInstanceKey: nativeToken,
|
|
90
|
+
quantity: sellTokenDTO.nativeTokenQuantity,
|
|
91
|
+
allowancesToUse: [],
|
|
92
|
+
authorizedOnBehalf: {
|
|
93
|
+
callingOnBehalf: sellTokenDTO.vaultAddress,
|
|
94
|
+
callingUser: ctx.callingUser
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
sale.sellToken(tokensToSell, sellTokenDTO.nativeTokenQuantity);
|
|
99
|
+
await putChainObject(ctx, sale);
|
|
100
|
+
|
|
101
|
+
const token = await fetchTokenClass(ctx, sale.sellingToken);
|
|
102
|
+
return {
|
|
103
|
+
inputQuantity: tokensToSell.toFixed(),
|
|
104
|
+
outputQuantity: sellTokenDTO.nativeTokenQuantity.toFixed(),
|
|
105
|
+
tokenName: token.name,
|
|
106
|
+
tradeType: "Sell",
|
|
107
|
+
vaultAddress: sellTokenDTO.vaultAddress,
|
|
108
|
+
userAddress: ctx.callingUser,
|
|
109
|
+
isFinalized: false,
|
|
110
|
+
functionName: "SellWithNative"
|
|
111
|
+
};
|
|
112
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
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 "./launchpadSaleUtils";
|
|
@@ -0,0 +1,68 @@
|
|
|
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 { ChainError, DefaultError, ErrorCode, NotFoundError } from "@gala-chain/api";
|
|
16
|
+
import { GalaChainContext, getObjectByKey } from "@gala-chain/chaincode";
|
|
17
|
+
import Decimal from "decimal.js";
|
|
18
|
+
|
|
19
|
+
import { LaunchpadFeeConfig, LaunchpadSale, SaleStatus } from "../../api/types";
|
|
20
|
+
|
|
21
|
+
export async function fetchAndValidateSale(
|
|
22
|
+
ctx: GalaChainContext,
|
|
23
|
+
vaultAddress: string
|
|
24
|
+
): Promise<LaunchpadSale> {
|
|
25
|
+
const key = ctx.stub.createCompositeKey(LaunchpadSale.INDEX_KEY, [vaultAddress]);
|
|
26
|
+
const sale = await getObjectByKey(ctx, LaunchpadSale, key).catch((e) => {
|
|
27
|
+
const chainError = ChainError.from(e);
|
|
28
|
+
if (chainError.matches(ErrorCode.NOT_FOUND)) {
|
|
29
|
+
return undefined;
|
|
30
|
+
} else {
|
|
31
|
+
throw chainError;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (sale === undefined) {
|
|
36
|
+
throw new NotFoundError("Sale record not found.");
|
|
37
|
+
}
|
|
38
|
+
if (sale.saleStatus === SaleStatus.END) {
|
|
39
|
+
throw new DefaultError("This sale has already ended.");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return sale;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function getBondingConstants() {
|
|
46
|
+
return {
|
|
47
|
+
exponentFactor: new Decimal("1166069000000"), // exponent factor / b
|
|
48
|
+
euler: new Decimal("2.7182818284590452353602874713527"), // e
|
|
49
|
+
decimals: new Decimal("1e+18") // scaling factor for decimals
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function fetchLaunchpadFeeAddress(
|
|
54
|
+
ctx: GalaChainContext
|
|
55
|
+
): Promise<LaunchpadFeeConfig | undefined> {
|
|
56
|
+
const key = ctx.stub.createCompositeKey(LaunchpadFeeConfig.INDEX_KEY, []);
|
|
57
|
+
|
|
58
|
+
const platformFeeAddress = await getObjectByKey(ctx, LaunchpadFeeConfig, key).catch((e) => {
|
|
59
|
+
const chainError = ChainError.from(e);
|
|
60
|
+
if (chainError.matches(ErrorCode.NOT_FOUND)) {
|
|
61
|
+
return undefined;
|
|
62
|
+
} else {
|
|
63
|
+
throw chainError;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return platformFeeAddress;
|
|
68
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
// Import and run standard fabric-chaincode-node cli
|
|
18
|
+
import type { ContractAPI } from "@gala-chain/api";
|
|
19
|
+
import type { GalaContract } from "@gala-chain/chaincode";
|
|
20
|
+
import "fabric-shim/cli";
|
|
21
|
+
import fs from "fs";
|
|
22
|
+
|
|
23
|
+
const [, , customCommand] = process.argv;
|
|
24
|
+
if (customCommand === "get-contract-names") {
|
|
25
|
+
printContractNames();
|
|
26
|
+
process.exit(0);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (customCommand === "get-contract-api") {
|
|
30
|
+
saveContractAPI("/tmp/contract-api.json");
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getContractInstances(): GalaContract[] {
|
|
35
|
+
// importing contracts would produce a lot of noise, so we set the log level to error
|
|
36
|
+
process.env.CORE_CHAINCODE_LOGGING_LEVEL = "error";
|
|
37
|
+
process.env.LOG_LEVEL = "error";
|
|
38
|
+
|
|
39
|
+
const { contracts } = require("./index");
|
|
40
|
+
return (contracts ?? [])
|
|
41
|
+
.filter((c: any) => typeof c === "function")
|
|
42
|
+
.map((Cls) => new Cls())
|
|
43
|
+
.filter((c: GalaContract) => typeof c.getName === "function");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function printContractNames() {
|
|
47
|
+
const response = getContractInstances()
|
|
48
|
+
.map((c) => c.getName())
|
|
49
|
+
.filter((name: string) => name !== undefined)
|
|
50
|
+
.sort()
|
|
51
|
+
.map((contractName: string) => ({ contractName }));
|
|
52
|
+
|
|
53
|
+
console.log(JSON.stringify(response));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function saveContractAPI(path: string) {
|
|
57
|
+
const response = getContractInstances()
|
|
58
|
+
.map((c) => c.getContractAPI())
|
|
59
|
+
.filter((api: ContractAPI) => api !== undefined)
|
|
60
|
+
.sort((a, b) => a.contractName.localeCompare(b.contractName));
|
|
61
|
+
|
|
62
|
+
fs.writeFileSync(path, JSON.stringify(response));
|
|
63
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// sort-imports-ignore
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import "dotenv/config";
|
|
17
|
+
|
|
18
|
+
import { GalaContract, GalaJSONSerializer } from "@gala-chain/chaincode";
|
|
19
|
+
|
|
20
|
+
import { LaunchpadContract } from "./chaincode";
|
|
21
|
+
|
|
22
|
+
export const contracts: { new (): GalaContract }[] = [LaunchpadContract];
|
|
23
|
+
|
|
24
|
+
export * from "./chaincode";
|
|
25
|
+
export * from "./api";
|
|
26
|
+
|
|
27
|
+
export const serializers = {
|
|
28
|
+
transaction: "galaJsonSerializer",
|
|
29
|
+
serializers: {
|
|
30
|
+
galaJsonSerializer: GalaJSONSerializer
|
|
31
|
+
}
|
|
32
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compileOnSave": false,
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"moduleDetection": "force",
|
|
5
|
+
"baseUrl": ".",
|
|
6
|
+
"rootDir": ".",
|
|
7
|
+
"module": "commonjs",
|
|
8
|
+
"moduleResolution": "node",
|
|
9
|
+
"resolveJsonModule": true,
|
|
10
|
+
"target": "ES2019",
|
|
11
|
+
"lib": ["ES2019"],
|
|
12
|
+
"emitDecoratorMetadata": true,
|
|
13
|
+
"experimentalDecorators": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"sourceMap": true,
|
|
17
|
+
"importHelpers": true,
|
|
18
|
+
"esModuleInterop": true,
|
|
19
|
+
"strictNullChecks": true,
|
|
20
|
+
"composite": true,
|
|
21
|
+
"skipLibCheck": true,
|
|
22
|
+
"noPropertyAccessFromIndexSignature": false,
|
|
23
|
+
"strictPropertyInitialization": false
|
|
24
|
+
},
|
|
25
|
+
"exclude": ["node_modules"],
|
|
26
|
+
"include": [
|
|
27
|
+
"package.json"
|
|
28
|
+
]
|
|
29
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": ".",
|
|
5
|
+
"outDir": "lib",
|
|
6
|
+
"declarationDir": "lib",
|
|
7
|
+
"composite": true,
|
|
8
|
+
"declarationMap": true,
|
|
9
|
+
"sourceMap": true
|
|
10
|
+
},
|
|
11
|
+
"files": [],
|
|
12
|
+
"include": ["**/*", "package.json"],
|
|
13
|
+
"exclude": ["lib", "**/*spec.ts", "src/__mocks__", "src/__test__"],
|
|
14
|
+
"references": [
|
|
15
|
+
{
|
|
16
|
+
"path": "./tsconfig.spec.json"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "../dist/out-tsc",
|
|
5
|
+
"module": "commonjs",
|
|
6
|
+
"types": ["jest", "node"],
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"sourceMap": true
|
|
9
|
+
},
|
|
10
|
+
"include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"]
|
|
11
|
+
}
|