@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,128 @@
|
|
|
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, LaunchpadSale, TradeResDto } from "../../api/types";
|
|
19
|
+
import { SlippageToleranceExceededError } from "../../api/utils/error";
|
|
20
|
+
import { fetchAndValidateSale } from "../utils";
|
|
21
|
+
import { callNativeTokenIn } from "./callNativeTokenIn";
|
|
22
|
+
import { finalizeSale } from "./finaliseSale";
|
|
23
|
+
|
|
24
|
+
BigNumber.config({
|
|
25
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Executes the purchase of an exact amount of tokens in a token sale.
|
|
30
|
+
*
|
|
31
|
+
* This function validates the sale, calculates the required native tokens,
|
|
32
|
+
* and performs the token transfer to complete the purchase. If the purchase
|
|
33
|
+
* consumes all tokens in the sale, the sale is marked as finalized.
|
|
34
|
+
*
|
|
35
|
+
* @param ctx - The context object providing access to the GalaChain environment.
|
|
36
|
+
* @param buyTokenDTO - The data transfer object containing the sale address,
|
|
37
|
+
* token amount to buy, and optional expected native token amount.
|
|
38
|
+
*
|
|
39
|
+
* @returns A promise that resolves to a `TradeResDto` containing the updated
|
|
40
|
+
* balances of the purchased token and the native token for the buyer.
|
|
41
|
+
*
|
|
42
|
+
* @throws DefaultError if the expected native tokens are insufficient to complete the purchase.
|
|
43
|
+
*/
|
|
44
|
+
export async function buyExactToken(
|
|
45
|
+
ctx: GalaChainContext,
|
|
46
|
+
buyTokenDTO: ExactTokenQuantityDto
|
|
47
|
+
): Promise<TradeResDto> {
|
|
48
|
+
let isSaleFinalized = false;
|
|
49
|
+
|
|
50
|
+
// Fetch and validate the sale based on the provided vault address
|
|
51
|
+
const sale = await fetchAndValidateSale(ctx, buyTokenDTO.vaultAddress);
|
|
52
|
+
const tokenLeftInVault = new BigNumber(sale.sellingTokenQuantity);
|
|
53
|
+
|
|
54
|
+
// Calculate the required amount of native tokens to buy the specified token amount
|
|
55
|
+
const callNativeTokenInResult1 = await callNativeTokenIn(ctx, buyTokenDTO);
|
|
56
|
+
let nativeTokensToBuy = new BigNumber(callNativeTokenInResult1.calculatedQuantity);
|
|
57
|
+
const nativeToken = sale.fetchNativeTokenInstanceKey();
|
|
58
|
+
const memeToken = sale.fetchSellingTokenInstanceKey();
|
|
59
|
+
|
|
60
|
+
// If the requested token amount exceeds what's available, adjust it and recalculate native tokens needed
|
|
61
|
+
if (tokenLeftInVault.lte(buyTokenDTO.tokenQuantity)) {
|
|
62
|
+
buyTokenDTO.tokenQuantity = tokenLeftInVault;
|
|
63
|
+
const callNativeTokenInResult2 = await callNativeTokenIn(ctx, buyTokenDTO);
|
|
64
|
+
nativeTokensToBuy = new BigNumber(callNativeTokenInResult2.calculatedQuantity);
|
|
65
|
+
isSaleFinalized = true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Check if the native tokens used exceed the market cap, finalizing the sale if true
|
|
69
|
+
if (
|
|
70
|
+
nativeTokensToBuy
|
|
71
|
+
.plus(new BigNumber(sale.nativeTokenQuantity))
|
|
72
|
+
.gte(new BigNumber(LaunchpadSale.MARKET_CAP))
|
|
73
|
+
) {
|
|
74
|
+
isSaleFinalized = true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Ensure the expected native token amount is not less than the actual amount required
|
|
78
|
+
if (buyTokenDTO.expectedNativeToken && buyTokenDTO.expectedNativeToken.comparedTo(nativeTokensToBuy) < 0) {
|
|
79
|
+
throw new SlippageToleranceExceededError(
|
|
80
|
+
"Gala tokens expected to perform this operation are less than the actual amount required."
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Transfer native tokens from the buyer to the vault
|
|
85
|
+
await transferToken(ctx, {
|
|
86
|
+
from: ctx.callingUser,
|
|
87
|
+
to: buyTokenDTO.vaultAddress,
|
|
88
|
+
tokenInstanceKey: nativeToken,
|
|
89
|
+
quantity: nativeTokensToBuy,
|
|
90
|
+
allowancesToUse: [],
|
|
91
|
+
authorizedOnBehalf: undefined
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Transfer meme tokens from the vault to the buyer
|
|
95
|
+
await transferToken(ctx, {
|
|
96
|
+
from: buyTokenDTO.vaultAddress,
|
|
97
|
+
to: ctx.callingUser,
|
|
98
|
+
tokenInstanceKey: memeToken,
|
|
99
|
+
quantity: buyTokenDTO.tokenQuantity,
|
|
100
|
+
allowancesToUse: [],
|
|
101
|
+
authorizedOnBehalf: {
|
|
102
|
+
callingOnBehalf: buyTokenDTO.vaultAddress,
|
|
103
|
+
callingUser: ctx.callingUser
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Update the sale record with the purchased token details
|
|
108
|
+
sale.buyToken(buyTokenDTO.tokenQuantity, nativeTokensToBuy);
|
|
109
|
+
await putChainObject(ctx, sale);
|
|
110
|
+
|
|
111
|
+
// If the sale is finalized, create a V3 pool and add liquidity
|
|
112
|
+
if (isSaleFinalized) {
|
|
113
|
+
await finalizeSale(ctx, sale);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Return the updated balance response
|
|
117
|
+
const token = await fetchTokenClass(ctx, sale.sellingToken);
|
|
118
|
+
return {
|
|
119
|
+
inputQuantity: nativeTokensToBuy.toFixed(),
|
|
120
|
+
outputQuantity: buyTokenDTO.tokenQuantity.toFixed(),
|
|
121
|
+
tokenName: token.name,
|
|
122
|
+
tradeType: "Buy",
|
|
123
|
+
vaultAddress: buyTokenDTO.vaultAddress,
|
|
124
|
+
userAddress: ctx.callingUser,
|
|
125
|
+
isFinalized: isSaleFinalized,
|
|
126
|
+
functionName: "BuyExactToken"
|
|
127
|
+
};
|
|
128
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
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, LaunchpadSale, NativeTokenQuantityDto, TradeResDto } from "../../api/types";
|
|
19
|
+
import { SlippageToleranceExceededError } from "../../api/utils/error";
|
|
20
|
+
import { fetchAndValidateSale } from "../utils";
|
|
21
|
+
import { callMemeTokenOut } from "./callMemeTokenOut";
|
|
22
|
+
import { callNativeTokenIn } from "./callNativeTokenIn";
|
|
23
|
+
import { finalizeSale } from "./finaliseSale";
|
|
24
|
+
|
|
25
|
+
BigNumber.config({
|
|
26
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Executes the purchase of tokens using a specified amount of native tokens.
|
|
31
|
+
*
|
|
32
|
+
* This function validates the sale, calculates the amount of tokens that can
|
|
33
|
+
* be purchased with the provided native tokens, and performs the token transfer
|
|
34
|
+
* to complete the purchase. If the purchase consumes all tokens in the sale,
|
|
35
|
+
* the sale is marked as finalized.
|
|
36
|
+
*
|
|
37
|
+
* @param ctx - The context object providing access to the GalaChain environment.
|
|
38
|
+
* @param buyTokenDTO - The data transfer object containing the sale address,
|
|
39
|
+
* native token amount to spend, and optional expected token amount.
|
|
40
|
+
*
|
|
41
|
+
* @returns A promise that resolves to a `TradeResDto` containing the updated
|
|
42
|
+
* balances of the purchased token and the native token for the buyer.
|
|
43
|
+
*
|
|
44
|
+
* @throws DefaultError if the expected tokens to be received are less than the
|
|
45
|
+
* actual amount provided by the operation.
|
|
46
|
+
*/
|
|
47
|
+
export async function buyWithNative(
|
|
48
|
+
ctx: GalaChainContext,
|
|
49
|
+
buyTokenDTO: NativeTokenQuantityDto
|
|
50
|
+
): Promise<TradeResDto> {
|
|
51
|
+
let isSaleFinalized = false;
|
|
52
|
+
const sale = await fetchAndValidateSale(ctx, buyTokenDTO.vaultAddress);
|
|
53
|
+
const tokensLeftInVault = new BigNumber(sale.sellingTokenQuantity);
|
|
54
|
+
const callMemeTokenOutResult = await callMemeTokenOut(ctx, buyTokenDTO);
|
|
55
|
+
let tokensToBuy = new BigNumber(callMemeTokenOutResult.calculatedQuantity);
|
|
56
|
+
|
|
57
|
+
const nativeToken = sale.fetchNativeTokenInstanceKey();
|
|
58
|
+
const memeToken = sale.fetchSellingTokenInstanceKey();
|
|
59
|
+
|
|
60
|
+
if (tokensLeftInVault.comparedTo(tokensToBuy) <= 0) {
|
|
61
|
+
tokensToBuy = tokensLeftInVault;
|
|
62
|
+
const nativeTokensrequiredToBuyDto = new ExactTokenQuantityDto(buyTokenDTO.vaultAddress, tokensToBuy);
|
|
63
|
+
const callNativeTokenInResult = await callNativeTokenIn(ctx, nativeTokensrequiredToBuyDto);
|
|
64
|
+
buyTokenDTO.nativeTokenQuantity = new BigNumber(callNativeTokenInResult.calculatedQuantity);
|
|
65
|
+
isSaleFinalized = true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (
|
|
69
|
+
buyTokenDTO.nativeTokenQuantity
|
|
70
|
+
.plus(new BigNumber(sale.nativeTokenQuantity))
|
|
71
|
+
.gte(new BigNumber(LaunchpadSale.MARKET_CAP))
|
|
72
|
+
)
|
|
73
|
+
isSaleFinalized = true;
|
|
74
|
+
|
|
75
|
+
if (buyTokenDTO.expectedToken && buyTokenDTO.expectedToken.comparedTo(tokensToBuy) > 0) {
|
|
76
|
+
throw new SlippageToleranceExceededError(
|
|
77
|
+
"Tokens expected from this operation are more than the the actual amount that will be provided."
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
await transferToken(ctx, {
|
|
82
|
+
from: ctx.callingUser,
|
|
83
|
+
to: buyTokenDTO.vaultAddress,
|
|
84
|
+
tokenInstanceKey: nativeToken,
|
|
85
|
+
quantity: buyTokenDTO.nativeTokenQuantity,
|
|
86
|
+
allowancesToUse: [],
|
|
87
|
+
authorizedOnBehalf: undefined
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
await transferToken(ctx, {
|
|
91
|
+
from: buyTokenDTO.vaultAddress,
|
|
92
|
+
to: ctx.callingUser,
|
|
93
|
+
tokenInstanceKey: memeToken,
|
|
94
|
+
quantity: tokensToBuy,
|
|
95
|
+
allowancesToUse: [],
|
|
96
|
+
authorizedOnBehalf: {
|
|
97
|
+
callingOnBehalf: buyTokenDTO.vaultAddress,
|
|
98
|
+
callingUser: ctx.callingUser
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
sale.buyToken(tokensToBuy, buyTokenDTO.nativeTokenQuantity);
|
|
103
|
+
await putChainObject(ctx, sale);
|
|
104
|
+
|
|
105
|
+
if (isSaleFinalized) {
|
|
106
|
+
await finalizeSale(ctx, sale);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const token = await fetchTokenClass(ctx, sale.sellingToken);
|
|
110
|
+
return {
|
|
111
|
+
inputQuantity: buyTokenDTO.nativeTokenQuantity.toFixed(),
|
|
112
|
+
outputQuantity: tokensToBuy.toFixed(),
|
|
113
|
+
tokenName: token.name,
|
|
114
|
+
tradeType: "Buy",
|
|
115
|
+
vaultAddress: buyTokenDTO.vaultAddress,
|
|
116
|
+
userAddress: ctx.callingUser,
|
|
117
|
+
isFinalized: isSaleFinalized,
|
|
118
|
+
functionName: "BuyWithNative"
|
|
119
|
+
};
|
|
120
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
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 { ValidationFailedError } from "@gala-chain/api";
|
|
16
|
+
import { GalaChainContext } from "@gala-chain/chaincode";
|
|
17
|
+
import { BigNumber } from "bignumber.js";
|
|
18
|
+
import Decimal from "decimal.js";
|
|
19
|
+
|
|
20
|
+
import { LaunchpadSale, NativeTokenQuantityDto } from "../../api/types";
|
|
21
|
+
import { fetchAndValidateSale, getBondingConstants } from "../utils";
|
|
22
|
+
import { calculateReverseBondingCurveFee } from "./fees";
|
|
23
|
+
|
|
24
|
+
BigNumber.config({
|
|
25
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function calculateMemeTokensRequired(sale: LaunchpadSale, requestedNativeTokenQuantity: BigNumber) {
|
|
29
|
+
const totalTokensSold = new Decimal(sale.fetchTokensSold()); // current tokens sold / x
|
|
30
|
+
let nativeTokens = new Decimal(requestedNativeTokenQuantity.toString()); // native tokens used to buy / y
|
|
31
|
+
const basePrice = new Decimal(sale.fetchBasePrice()); // base price / a
|
|
32
|
+
const { exponentFactor, euler, decimals } = getBondingConstants();
|
|
33
|
+
|
|
34
|
+
const nativeTokenInVault = new Decimal(sale.nativeTokenQuantity);
|
|
35
|
+
if (nativeTokens.greaterThan(nativeTokenInVault)) {
|
|
36
|
+
nativeTokens = nativeTokenInVault;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const exponent = exponentFactor.mul(totalTokensSold).div(decimals);
|
|
40
|
+
const exp1 = euler.pow(exponent);
|
|
41
|
+
const constantFactor = nativeTokens.mul(exponentFactor).div(basePrice);
|
|
42
|
+
|
|
43
|
+
if (exp1.lte(constantFactor)) {
|
|
44
|
+
throw new ValidationFailedError("Cannot sell more tokens than have been bought in this sale.");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const adjustedExp = exp1.minus(constantFactor);
|
|
48
|
+
const lnAdjustedExp = adjustedExp.ln();
|
|
49
|
+
const tokensSent = totalTokensSold.minus(lnAdjustedExp.mul(decimals).div(exponentFactor));
|
|
50
|
+
const roundedTokenSent = tokensSent.toDecimalPlaces(18, Decimal.ROUND_UP);
|
|
51
|
+
|
|
52
|
+
return roundedTokenSent.toFixed();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Calculates the number of tokens that can be sold in exchange for a specified amount
|
|
57
|
+
* of native tokens using a bonding curve mechanism.
|
|
58
|
+
*
|
|
59
|
+
* This function retrieves the sale details and applies the bonding curve formula
|
|
60
|
+
* to determine the number of tokens the user can sell based on the provided native token amount.
|
|
61
|
+
*
|
|
62
|
+
* @param ctx - The context object that provides access to the GalaChain environment.
|
|
63
|
+
* @param sellTokenDTO - An object containing the sale details:
|
|
64
|
+
* - `vaultAddress`: The address of the sale.
|
|
65
|
+
* - `nativeTokenAmount`: The amount of native tokens to be recieved from sale.
|
|
66
|
+
* - `expectedToken` (optional): The expected amount of tokens to be sold.
|
|
67
|
+
*
|
|
68
|
+
* @returns A promise that resolves to a string representing the calculated amount of
|
|
69
|
+
* tokens to be sent, rounded up to 18 decimal places.
|
|
70
|
+
*
|
|
71
|
+
* @throws Error if the calculation results in an invalid amount (e.g., `InvalidAmountError`).
|
|
72
|
+
*/
|
|
73
|
+
export async function callMemeTokenIn(ctx: GalaChainContext, sellTokenDTO: NativeTokenQuantityDto) {
|
|
74
|
+
const sale = await fetchAndValidateSale(ctx, sellTokenDTO.vaultAddress);
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
calculatedQuantity: calculateMemeTokensRequired(sale, sellTokenDTO.nativeTokenQuantity),
|
|
78
|
+
extraFees: {
|
|
79
|
+
reverseBondingCurve: calculateReverseBondingCurveFee(sale, sellTokenDTO.nativeTokenQuantity).toString()
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
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 } from "@gala-chain/chaincode";
|
|
16
|
+
import { BigNumber } from "bignumber.js";
|
|
17
|
+
import Decimal from "decimal.js";
|
|
18
|
+
|
|
19
|
+
import { LaunchpadSale, NativeTokenQuantityDto } from "../../api/types";
|
|
20
|
+
import { fetchAndValidateSale, getBondingConstants } from "../utils";
|
|
21
|
+
|
|
22
|
+
BigNumber.config({
|
|
23
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Calculates the number of tokens that can be purchased using a specified amount
|
|
28
|
+
* of native tokens based on a bonding curve mechanism.
|
|
29
|
+
*
|
|
30
|
+
* This function retrieves the sale details and applies the bonding curve formula
|
|
31
|
+
* to determine the number of tokens the user can buy with the provided native token amount.
|
|
32
|
+
*
|
|
33
|
+
* @param ctx - The context object providing access to the GalaChain environment.
|
|
34
|
+
* @param buyTokenDTO - The data transfer object containing the sale address
|
|
35
|
+
* and the amount of native tokens to spend for the purchase.
|
|
36
|
+
*
|
|
37
|
+
* @returns A promise that resolves to a string representing the calculated amount of
|
|
38
|
+
* tokens to be received, rounded down to 18 decimal places.
|
|
39
|
+
*
|
|
40
|
+
* @throws Error if the calculation results in an invalid state.
|
|
41
|
+
*/
|
|
42
|
+
export async function callMemeTokenOut(ctx: GalaChainContext, buyTokenDTO: NativeTokenQuantityDto) {
|
|
43
|
+
const sale = await fetchAndValidateSale(ctx, buyTokenDTO.vaultAddress);
|
|
44
|
+
const totalTokensSold = new Decimal(sale.fetchTokensSold()); // current tokens sold / x
|
|
45
|
+
let nativeTokens = new Decimal(buyTokenDTO.nativeTokenQuantity.toString()); // native tokens used to buy / y
|
|
46
|
+
const basePrice = new Decimal(sale.fetchBasePrice()); // base price / a
|
|
47
|
+
const { exponentFactor, euler, decimals } = getBondingConstants();
|
|
48
|
+
|
|
49
|
+
if (
|
|
50
|
+
nativeTokens.add(new Decimal(sale.nativeTokenQuantity)).greaterThan(new Decimal(LaunchpadSale.MARKET_CAP))
|
|
51
|
+
) {
|
|
52
|
+
nativeTokens = new Decimal(LaunchpadSale.MARKET_CAP).minus(new Decimal(sale.nativeTokenQuantity));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const constant = nativeTokens.mul(exponentFactor).div(basePrice);
|
|
56
|
+
|
|
57
|
+
const exponent1 = exponentFactor.mul(totalTokensSold).div(decimals);
|
|
58
|
+
|
|
59
|
+
const eResult1 = euler.pow(exponent1);
|
|
60
|
+
|
|
61
|
+
const ethScaled = constant.add(eResult1);
|
|
62
|
+
|
|
63
|
+
const lnEthScaled = ethScaled.ln().mul(decimals);
|
|
64
|
+
|
|
65
|
+
const lnEthScaledBase = lnEthScaled.div(exponentFactor);
|
|
66
|
+
|
|
67
|
+
const result = lnEthScaledBase.minus(totalTokensSold);
|
|
68
|
+
let roundedResult = result.toDecimalPlaces(18, Decimal.ROUND_DOWN);
|
|
69
|
+
|
|
70
|
+
if (roundedResult.add(totalTokensSold).greaterThan(new Decimal("1e+7"))) {
|
|
71
|
+
roundedResult = new Decimal("1e+7").minus(new Decimal(totalTokensSold));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
calculatedQuantity: roundedResult.toFixed(),
|
|
76
|
+
extraFees: {
|
|
77
|
+
reverseBondingCurve: "0"
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
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 } from "@gala-chain/chaincode";
|
|
16
|
+
import { BigNumber } from "bignumber.js";
|
|
17
|
+
import Decimal from "decimal.js";
|
|
18
|
+
|
|
19
|
+
import { ExactTokenQuantityDto } from "../../api/types";
|
|
20
|
+
import { fetchAndValidateSale, getBondingConstants } from "../utils";
|
|
21
|
+
|
|
22
|
+
BigNumber.config({
|
|
23
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Calculates the amount of native tokens required to purchase a specified amount
|
|
28
|
+
* of tokens using a bonding curve mechanism.
|
|
29
|
+
*
|
|
30
|
+
* This function retrieves the sale details and applies the bonding curve formula
|
|
31
|
+
* to determine the cost in native tokens for the given token amount.
|
|
32
|
+
*
|
|
33
|
+
* @param ctx - The context object providing access to the GalaChain environment.
|
|
34
|
+
* @param buyTokenDTO - The data transfer object containing the sale address
|
|
35
|
+
* and the exact amount of tokens to be purchased.
|
|
36
|
+
*
|
|
37
|
+
* @returns A promise that resolves to a string representing the calculated amount of
|
|
38
|
+
* native tokens required for the purchase, rounded up to 8 decimal places.
|
|
39
|
+
*
|
|
40
|
+
* @throws Error if the calculation encounters an invalid state or data.
|
|
41
|
+
*/
|
|
42
|
+
export async function callNativeTokenIn(ctx: GalaChainContext, buyTokenDTO: ExactTokenQuantityDto) {
|
|
43
|
+
const sale = await fetchAndValidateSale(ctx, buyTokenDTO.vaultAddress);
|
|
44
|
+
const totalTokensSold = new Decimal(sale.fetchTokensSold());
|
|
45
|
+
|
|
46
|
+
let tokensToBuy = new Decimal(buyTokenDTO.tokenQuantity.toString());
|
|
47
|
+
const basePrice = new Decimal(sale.fetchBasePrice());
|
|
48
|
+
const { exponentFactor, euler, decimals } = getBondingConstants();
|
|
49
|
+
|
|
50
|
+
if (tokensToBuy.add(totalTokensSold).greaterThan(new Decimal("1e+7"))) {
|
|
51
|
+
tokensToBuy = new Decimal(sale.sellingTokenQuantity);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const exponent1 = exponentFactor.mul(totalTokensSold.add(tokensToBuy)).div(decimals);
|
|
55
|
+
const exponent2 = exponentFactor.mul(totalTokensSold).div(decimals);
|
|
56
|
+
|
|
57
|
+
const eResult1 = euler.pow(exponent1);
|
|
58
|
+
const eResult2 = euler.pow(exponent2);
|
|
59
|
+
|
|
60
|
+
const constantFactor = basePrice.div(exponentFactor);
|
|
61
|
+
const differenceOfExponentials = eResult1.minus(eResult2);
|
|
62
|
+
|
|
63
|
+
const price = constantFactor.mul(differenceOfExponentials);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
calculatedQuantity: price.toDecimalPlaces(8, Decimal.ROUND_UP).toFixed(),
|
|
67
|
+
extraFees: {
|
|
68
|
+
reverseBondingCurve: "0"
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
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 } from "@gala-chain/chaincode";
|
|
16
|
+
import { BigNumber } from "bignumber.js";
|
|
17
|
+
import Decimal from "decimal.js";
|
|
18
|
+
|
|
19
|
+
import { ExactTokenQuantityDto, LaunchpadSale } from "../../api/types";
|
|
20
|
+
import { fetchAndValidateSale, getBondingConstants } from "../utils";
|
|
21
|
+
import { calculateReverseBondingCurveFee } from "./fees";
|
|
22
|
+
|
|
23
|
+
BigNumber.config({
|
|
24
|
+
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
function calculateNativeTokensReceived(sale: LaunchpadSale, tokensToSellBn: BigNumber) {
|
|
28
|
+
const totalTokensSold = new Decimal(sale.fetchTokensSold());
|
|
29
|
+
|
|
30
|
+
let tokensToSell = new Decimal(tokensToSellBn.toString());
|
|
31
|
+
const basePrice = new Decimal(sale.fetchBasePrice());
|
|
32
|
+
const { exponentFactor, euler, decimals } = getBondingConstants();
|
|
33
|
+
|
|
34
|
+
let newTotalTokensSold = totalTokensSold.minus(tokensToSell);
|
|
35
|
+
|
|
36
|
+
if (newTotalTokensSold.comparedTo(0) < 0) {
|
|
37
|
+
tokensToSell = totalTokensSold;
|
|
38
|
+
newTotalTokensSold = new Decimal(0);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const exponent1 = exponentFactor.mul(newTotalTokensSold.add(tokensToSell)).div(decimals);
|
|
42
|
+
const exponent2 = exponentFactor.mul(newTotalTokensSold).div(decimals);
|
|
43
|
+
|
|
44
|
+
const eResult1 = euler.pow(exponent1);
|
|
45
|
+
const eResult2 = euler.pow(exponent2);
|
|
46
|
+
|
|
47
|
+
const constantFactor = basePrice.div(exponentFactor);
|
|
48
|
+
const differenceOfExponentials = eResult1.minus(eResult2);
|
|
49
|
+
const price = constantFactor.mul(differenceOfExponentials);
|
|
50
|
+
const roundedPrice = price.toDecimalPlaces(8, Decimal.ROUND_DOWN);
|
|
51
|
+
|
|
52
|
+
return roundedPrice.toFixed();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Calculates the amount of native tokens a user would receive when selling
|
|
57
|
+
* a specified amount of tokens based on a bonding curve mechanism.
|
|
58
|
+
*
|
|
59
|
+
* This function retrieves the sale details and applies the bonding curve formula
|
|
60
|
+
* to determine the value in native tokens for the given token amount.
|
|
61
|
+
*
|
|
62
|
+
* @param ctx - The context object providing access to the GalaChain environment.
|
|
63
|
+
* @param sellTokenDTO - The data transfer object containing the sale address
|
|
64
|
+
* and the exact amount of tokens to be sold.
|
|
65
|
+
*
|
|
66
|
+
* @returns A promise that resolves to a string representing the calculated amount of
|
|
67
|
+
* native tokens to be received, rounded down to 8 decimal places.
|
|
68
|
+
*
|
|
69
|
+
* @throws DefaultError if the calculated new total tokens sold is less than zero
|
|
70
|
+
* or if the input amount is invalid.
|
|
71
|
+
*/
|
|
72
|
+
export async function callNativeTokenOut(ctx: GalaChainContext, sellTokenDTO: ExactTokenQuantityDto) {
|
|
73
|
+
const sale = await fetchAndValidateSale(ctx, sellTokenDTO.vaultAddress);
|
|
74
|
+
const nativeTokensReceived = calculateNativeTokensReceived(sale, sellTokenDTO.tokenQuantity);
|
|
75
|
+
return {
|
|
76
|
+
calculatedQuantity: nativeTokensReceived,
|
|
77
|
+
extraFees: {
|
|
78
|
+
reverseBondingCurve: calculateReverseBondingCurveFee(sale, BigNumber(nativeTokensReceived)).toString()
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
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, ErrorCode, UnauthorizedError, ValidationFailedError } from "@gala-chain/api";
|
|
16
|
+
import { GalaChainContext } from "@gala-chain/chaincode";
|
|
17
|
+
import { getObjectByKey, putChainObject } from "@gala-chain/chaincode";
|
|
18
|
+
|
|
19
|
+
import { ConfigureLaunchpadFeeAddressDto, LaunchpadFeeConfig } from "../../api/types";
|
|
20
|
+
|
|
21
|
+
export async function configureLaunchpadFeeAddress(
|
|
22
|
+
ctx: GalaChainContext,
|
|
23
|
+
dto: ConfigureLaunchpadFeeAddressDto
|
|
24
|
+
): Promise<LaunchpadFeeConfig> {
|
|
25
|
+
if (!dto.newPlatformFeeAddress && !dto.newAuthorities?.length) {
|
|
26
|
+
throw new ValidationFailedError("None of the input fields are present.");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const curatorOrgMsp = process.env.CURATOR_ORG_MSP ?? "CuratorOrg";
|
|
30
|
+
|
|
31
|
+
const key = ctx.stub.createCompositeKey(LaunchpadFeeConfig.INDEX_KEY, []);
|
|
32
|
+
let platformFeeAddress = await getObjectByKey(ctx, LaunchpadFeeConfig, key).catch((e) => {
|
|
33
|
+
const chainError = ChainError.from(e);
|
|
34
|
+
if (chainError.matches(ErrorCode.NOT_FOUND)) {
|
|
35
|
+
return undefined;
|
|
36
|
+
} else {
|
|
37
|
+
throw chainError;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (ctx.clientIdentity.getMSPID() !== curatorOrgMsp) {
|
|
42
|
+
if (!platformFeeAddress || !platformFeeAddress.authorities.includes(ctx.callingUser)) {
|
|
43
|
+
throw new UnauthorizedError(`CallingUser ${ctx.callingUser} is not authorized to create or update`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!platformFeeAddress) {
|
|
48
|
+
if (!dto.newPlatformFeeAddress) {
|
|
49
|
+
throw new ValidationFailedError(
|
|
50
|
+
"Must provide a platform fee address in the initial setup of the configuration."
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
platformFeeAddress = new LaunchpadFeeConfig(
|
|
54
|
+
dto.newPlatformFeeAddress,
|
|
55
|
+
dto.newAuthorities ?? [ctx.callingUser]
|
|
56
|
+
);
|
|
57
|
+
} else if (platformFeeAddress && platformFeeAddress.authorities.includes(ctx.callingUser)) {
|
|
58
|
+
platformFeeAddress.setNewFeeAddress(
|
|
59
|
+
dto.newPlatformFeeAddress ?? platformFeeAddress.feeAddress,
|
|
60
|
+
dto.newAuthorities ?? platformFeeAddress.authorities
|
|
61
|
+
);
|
|
62
|
+
} else {
|
|
63
|
+
throw new UnauthorizedError(`CallingUser ${ctx.callingUser} is not authorized to create or update`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
await putChainObject(ctx, platformFeeAddress);
|
|
67
|
+
|
|
68
|
+
return platformFeeAddress;
|
|
69
|
+
}
|