@gala-chain/launchpad 1.0.5 → 1.0.7
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/lib/package.json +1 -1
- package/lib/src/api/types/LaunchpadDtos.d.ts +5 -4
- package/lib/src/api/types/LaunchpadDtos.d.ts.map +1 -1
- package/lib/src/api/types/LaunchpadDtos.js +17 -15
- package/lib/src/api/types/LaunchpadDtos.js.map +1 -1
- package/lib/src/chaincode/LaunchpadContract.d.ts +4 -4
- package/lib/src/chaincode/LaunchpadContract.d.ts.map +1 -1
- package/lib/src/chaincode/LaunchpadContract.js +22 -16
- package/lib/src/chaincode/LaunchpadContract.js.map +1 -1
- package/lib/src/chaincode/launchpad/buyExactToken.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/buyExactToken.js +8 -1
- package/lib/src/chaincode/launchpad/buyExactToken.js.map +1 -1
- package/lib/src/chaincode/launchpad/buyWithNative.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/buyWithNative.js +9 -2
- package/lib/src/chaincode/launchpad/buyWithNative.js.map +1 -1
- package/lib/src/chaincode/launchpad/callMemeTokenOut.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/callMemeTokenOut.js +20 -7
- package/lib/src/chaincode/launchpad/callMemeTokenOut.js.map +1 -1
- package/lib/src/chaincode/launchpad/callNativeTokenIn.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/callNativeTokenIn.js.map +1 -1
- package/lib/src/chaincode/launchpad/callNativeTokenOut.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/callNativeTokenOut.js.map +1 -1
- package/lib/src/chaincode/launchpad/fetchLaunchpadAdressConfig.d.ts +2 -1
- package/lib/src/chaincode/launchpad/fetchLaunchpadAdressConfig.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/fetchLaunchpadAdressConfig.js +1 -1
- package/lib/src/chaincode/launchpad/fetchLaunchpadAdressConfig.js.map +1 -1
- package/lib/src/chaincode/launchpad/fetchLaunchpadFeeAmount.d.ts +12 -0
- package/lib/src/chaincode/launchpad/fetchLaunchpadFeeAmount.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/fetchLaunchpadFeeAmount.js +37 -0
- package/lib/src/chaincode/launchpad/fetchLaunchpadFeeAmount.js.map +1 -0
- package/lib/src/chaincode/launchpad/index.d.ts +0 -1
- package/lib/src/chaincode/launchpad/index.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/index.js +0 -1
- package/lib/src/chaincode/launchpad/index.js.map +1 -1
- package/lib/src/chaincode/launchpad/sellExactToken.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/sellExactToken.js +2 -1
- package/lib/src/chaincode/launchpad/sellExactToken.js.map +1 -1
- package/lib/src/chaincode/launchpad/sellWithNative.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/sellWithNative.js +2 -1
- package/lib/src/chaincode/launchpad/sellWithNative.js.map +1 -1
- package/lib/src/chaincode/test/launchpadgala.d.ts +154 -0
- package/lib/src/chaincode/test/launchpadgala.d.ts.map +1 -0
- package/lib/src/chaincode/test/launchpadgala.js +152 -0
- package/lib/src/chaincode/test/launchpadgala.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/api/types/LaunchpadDtos.ts +12 -14
- package/src/chaincode/LaunchpadContract.ts +25 -16
- package/src/chaincode/launchpad/buyExactToken.spec.ts +222 -0
- package/src/chaincode/launchpad/buyExactToken.ts +18 -2
- package/src/chaincode/launchpad/buyWithNative.spec.ts +221 -0
- package/src/chaincode/launchpad/buyWithNative.ts +20 -3
- package/src/chaincode/launchpad/callMemeTokenOut.spec.ts +150 -0
- package/src/chaincode/launchpad/callMemeTokenOut.ts +26 -15
- package/src/chaincode/launchpad/callNativeTokenIn.ts +1 -0
- package/src/chaincode/launchpad/callNativeTokenOut.ts +1 -0
- package/src/chaincode/launchpad/fetchLaunchpadAdressConfig.ts +5 -2
- package/src/chaincode/launchpad/fetchLaunchpadFeeAmount.spec.ts +67 -0
- package/src/chaincode/launchpad/fetchLaunchpadFeeAmount.ts +40 -0
- package/src/chaincode/launchpad/index.ts +0 -1
- package/src/chaincode/launchpad/sellExactToken.ts +2 -1
- package/src/chaincode/launchpad/sellWithNative.ts +2 -1
- package/src/chaincode/test/launchpadgala.ts +174 -0
- package/lib/src/chaincode/launchpad/preMintCalculation.d.ts +0 -17
- package/lib/src/chaincode/launchpad/preMintCalculation.d.ts.map +0 -1
- package/lib/src/chaincode/launchpad/preMintCalculation.js +0 -52
- package/lib/src/chaincode/launchpad/preMintCalculation.js.map +0 -1
- package/src/chaincode/launchpad/preMintCalculation.ts +0 -56
|
@@ -0,0 +1,150 @@
|
|
|
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 {
|
|
16
|
+
TokenBalance,
|
|
17
|
+
TokenClass,
|
|
18
|
+
TokenClassKey,
|
|
19
|
+
TokenInstance,
|
|
20
|
+
UserAlias,
|
|
21
|
+
asValidUserAlias,
|
|
22
|
+
randomUniqueKey
|
|
23
|
+
} from "@gala-chain/api";
|
|
24
|
+
import { currency, fixture, users } from "@gala-chain/test";
|
|
25
|
+
import BigNumber from "bignumber.js";
|
|
26
|
+
import { plainToInstance } from "class-transformer";
|
|
27
|
+
|
|
28
|
+
import { LaunchpadSale, NativeTokenQuantityDto } from "../../api/types";
|
|
29
|
+
import { LaunchpadContract } from "../LaunchpadContract";
|
|
30
|
+
import launchpadgala from "../test/launchpadgala";
|
|
31
|
+
|
|
32
|
+
describe("callMemeTokenOut", () => {
|
|
33
|
+
let currencyClass: TokenClass;
|
|
34
|
+
let currencyInstance: TokenInstance;
|
|
35
|
+
let launchpadGalaClass: TokenClass;
|
|
36
|
+
let launchpadGalaInstance: TokenInstance;
|
|
37
|
+
let launchpadGalaClassKey: TokenClassKey;
|
|
38
|
+
let vaultAddress: UserAlias;
|
|
39
|
+
let sale: LaunchpadSale;
|
|
40
|
+
let salelaunchpadGalaBalance: TokenBalance;
|
|
41
|
+
let saleCurrencyBalance: TokenBalance;
|
|
42
|
+
let userlaunchpadGalaBalance: TokenBalance;
|
|
43
|
+
let userCurrencyBalance: TokenBalance;
|
|
44
|
+
|
|
45
|
+
beforeEach(() => {
|
|
46
|
+
currencyClass = currency.tokenClass();
|
|
47
|
+
currencyInstance = currency.tokenInstance();
|
|
48
|
+
launchpadGalaClass = launchpadgala.tokenClass();
|
|
49
|
+
launchpadGalaInstance = launchpadgala.tokenInstance();
|
|
50
|
+
launchpadGalaClassKey = launchpadgala.tokenClassKey();
|
|
51
|
+
|
|
52
|
+
vaultAddress = asValidUserAlias(`service|${launchpadGalaClassKey.toStringKey()}$launchpad`);
|
|
53
|
+
|
|
54
|
+
// Initialize sale with manual values
|
|
55
|
+
sale = new LaunchpadSale(
|
|
56
|
+
vaultAddress,
|
|
57
|
+
launchpadGalaInstance.instanceKeyObj(),
|
|
58
|
+
undefined,
|
|
59
|
+
users.testUser1.identityKey
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// Create sale balances - sale needs tokens to pay out
|
|
63
|
+
salelaunchpadGalaBalance = plainToInstance(TokenBalance, {
|
|
64
|
+
...launchpadgala.tokenBalance(),
|
|
65
|
+
owner: vaultAddress,
|
|
66
|
+
quantity: new BigNumber("97.238975330345368866")
|
|
67
|
+
});
|
|
68
|
+
saleCurrencyBalance = plainToInstance(TokenBalance, {
|
|
69
|
+
...currency.tokenBalance(),
|
|
70
|
+
owner: vaultAddress,
|
|
71
|
+
quantity: new BigNumber("188809.790718")
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Create user balances - user needs tokens to swap
|
|
75
|
+
userlaunchpadGalaBalance = plainToInstance(TokenBalance, {
|
|
76
|
+
...launchpadgala.tokenBalance(),
|
|
77
|
+
owner: users.testUser1.identityKey,
|
|
78
|
+
quantity: new BigNumber("10000") // User has 10k launchpadGala tokens
|
|
79
|
+
});
|
|
80
|
+
userCurrencyBalance = plainToInstance(TokenBalance, {
|
|
81
|
+
...currency.tokenBalance(),
|
|
82
|
+
owner: users.testUser1.identityKey,
|
|
83
|
+
quantity: new BigNumber("10000") // User has 10k CURRENCY tokens
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("should calculate native token in amount", async () => {
|
|
88
|
+
// Given
|
|
89
|
+
sale.buyToken(new BigNumber("605.60177406237267161"), new BigNumber(0.01));
|
|
90
|
+
const { ctx, contract } = fixture(LaunchpadContract)
|
|
91
|
+
.registeredUsers(users.testUser1)
|
|
92
|
+
.savedState(
|
|
93
|
+
currencyClass,
|
|
94
|
+
currencyInstance,
|
|
95
|
+
launchpadGalaClass,
|
|
96
|
+
launchpadGalaInstance,
|
|
97
|
+
sale,
|
|
98
|
+
salelaunchpadGalaBalance,
|
|
99
|
+
saleCurrencyBalance,
|
|
100
|
+
userlaunchpadGalaBalance,
|
|
101
|
+
userCurrencyBalance
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const callMemeTokenOutDto = new NativeTokenQuantityDto(vaultAddress, new BigNumber(1));
|
|
105
|
+
callMemeTokenOutDto.uniqueKey = randomUniqueKey();
|
|
106
|
+
|
|
107
|
+
const signedDto = callMemeTokenOutDto.signed(users.testUser1.privateKey);
|
|
108
|
+
|
|
109
|
+
// When
|
|
110
|
+
const response = await contract.CallMemeTokenOut(ctx, signedDto);
|
|
111
|
+
|
|
112
|
+
// // Then
|
|
113
|
+
expect(response.Data).toMatchObject({
|
|
114
|
+
calculatedQuantity: "58497.530004606452819",
|
|
115
|
+
extraFees: { reverseBondingCurve: "0", transactionFees: "0.00000000" }
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("should calculate the pre mint amount successfully", async () => {
|
|
120
|
+
// Given
|
|
121
|
+
const { ctx, contract } = fixture(LaunchpadContract)
|
|
122
|
+
.registeredUsers(users.testUser1)
|
|
123
|
+
.savedState(
|
|
124
|
+
currencyClass,
|
|
125
|
+
currencyInstance,
|
|
126
|
+
launchpadGalaClass,
|
|
127
|
+
launchpadGalaInstance,
|
|
128
|
+
sale,
|
|
129
|
+
salelaunchpadGalaBalance,
|
|
130
|
+
saleCurrencyBalance,
|
|
131
|
+
userlaunchpadGalaBalance,
|
|
132
|
+
userCurrencyBalance
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const callMemeTokenOutDto = new NativeTokenQuantityDto(vaultAddress, new BigNumber(10));
|
|
136
|
+
callMemeTokenOutDto.IsPreMint = true;
|
|
137
|
+
callMemeTokenOutDto.uniqueKey = randomUniqueKey();
|
|
138
|
+
|
|
139
|
+
const signedDto = callMemeTokenOutDto.signed(users.testUser1.privateKey);
|
|
140
|
+
|
|
141
|
+
// When
|
|
142
|
+
const response = await contract.CallMemeTokenOut(ctx, signedDto);
|
|
143
|
+
|
|
144
|
+
// Then
|
|
145
|
+
expect(response.Data).toMatchObject({
|
|
146
|
+
calculatedQuantity: "458291.30295364487969",
|
|
147
|
+
extraFees: { reverseBondingCurve: "0", transactionFees: "0.00000000" }
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
});
|
|
@@ -37,38 +37,49 @@ import { calculateTransactionFee } from "./fees";
|
|
|
37
37
|
* @throws Error if the calculation results in an invalid state.
|
|
38
38
|
*/
|
|
39
39
|
export async function callMemeTokenOut(ctx: GalaChainContext, buyTokenDTO: NativeTokenQuantityDto) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
// Convert input amount to Decimal
|
|
41
|
+
let nativeTokens = new Decimal(buyTokenDTO.nativeTokenQuantity.toString());
|
|
42
|
+
|
|
43
|
+
// Initialize total tokens sold
|
|
44
|
+
let totalTokensSold = new Decimal(0);
|
|
45
45
|
|
|
46
|
-
if
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
// Fetch sale details and update parameters if this is not a sale premint calculation
|
|
47
|
+
if (!buyTokenDTO.IsPreMint) {
|
|
48
|
+
const sale = await fetchAndValidateSale(ctx, buyTokenDTO.vaultAddress);
|
|
49
|
+
totalTokensSold = new Decimal(sale.fetchTokensSold());
|
|
50
|
+
|
|
51
|
+
// Enforce market cap limit
|
|
52
|
+
if (
|
|
53
|
+
nativeTokens
|
|
54
|
+
.add(new Decimal(sale.nativeTokenQuantity))
|
|
55
|
+
.greaterThan(new Decimal(LaunchpadSale.MARKET_CAP))
|
|
56
|
+
) {
|
|
57
|
+
nativeTokens = new Decimal(LaunchpadSale.MARKET_CAP).minus(new Decimal(sale.nativeTokenQuantity));
|
|
58
|
+
}
|
|
50
59
|
}
|
|
51
60
|
|
|
52
|
-
|
|
61
|
+
// Load bonding curve constants
|
|
62
|
+
const basePrice = new Decimal(LaunchpadSale.BASE_PRICE);
|
|
63
|
+
const { exponentFactor, euler, decimals } = getBondingConstants();
|
|
53
64
|
|
|
65
|
+
// Apply bonding curve math
|
|
66
|
+
const constant = nativeTokens.mul(exponentFactor).div(basePrice);
|
|
54
67
|
const exponent1 = exponentFactor.mul(totalTokensSold).div(decimals);
|
|
55
|
-
|
|
56
68
|
const eResult1 = euler.pow(exponent1);
|
|
57
|
-
|
|
58
69
|
const ethScaled = constant.add(eResult1);
|
|
59
|
-
|
|
60
70
|
const lnEthScaled = ethScaled.ln().mul(decimals);
|
|
61
|
-
|
|
62
71
|
const lnEthScaledBase = lnEthScaled.div(exponentFactor);
|
|
63
|
-
|
|
64
72
|
const result = lnEthScaledBase.minus(totalTokensSold);
|
|
65
73
|
let roundedResult = result.toDecimalPlaces(18, Decimal.ROUND_DOWN);
|
|
66
74
|
|
|
75
|
+
// Cap total supply to 10 million
|
|
67
76
|
if (roundedResult.add(totalTokensSold).greaterThan(new Decimal("1e+7"))) {
|
|
68
77
|
roundedResult = new Decimal("1e+7").minus(new Decimal(totalTokensSold));
|
|
69
78
|
}
|
|
70
79
|
|
|
80
|
+
// Fetch fee configuration and return result
|
|
71
81
|
const launchpadFeeAddressConfiguration = await fetchLaunchpadFeeAddress(ctx);
|
|
82
|
+
|
|
72
83
|
return {
|
|
73
84
|
calculatedQuantity: roundedResult.toFixed(),
|
|
74
85
|
extraFees: {
|
|
@@ -60,6 +60,7 @@ export async function callNativeTokenIn(ctx: GalaChainContext, buyTokenDTO: Exac
|
|
|
60
60
|
const price = constantFactor.mul(differenceOfExponentials);
|
|
61
61
|
|
|
62
62
|
const launchpadFeeAddressConfiguration = await fetchLaunchpadFeeAddress(ctx);
|
|
63
|
+
|
|
63
64
|
const roundedPrice = price.toDecimalPlaces(8, Decimal.ROUND_UP).toFixed();
|
|
64
65
|
return {
|
|
65
66
|
calculatedQuantity: roundedPrice,
|
|
@@ -69,6 +69,7 @@ export async function callNativeTokenOut(ctx: GalaChainContext, sellTokenDTO: Ex
|
|
|
69
69
|
const sale = await fetchAndValidateSale(ctx, sellTokenDTO.vaultAddress);
|
|
70
70
|
const nativeTokensReceived = calculateNativeTokensReceived(sale, sellTokenDTO.tokenQuantity);
|
|
71
71
|
const launchpadFeeAddressConfiguration = await fetchLaunchpadFeeAddress(ctx);
|
|
72
|
+
|
|
72
73
|
return {
|
|
73
74
|
calculatedQuantity: nativeTokensReceived,
|
|
74
75
|
extraFees: {
|
|
@@ -12,13 +12,16 @@
|
|
|
12
12
|
* See the License for the specific language governing permissions and
|
|
13
13
|
* limitations under the License.
|
|
14
14
|
*/
|
|
15
|
-
import { NotFoundError, UnauthorizedError } from "@gala-chain/api";
|
|
15
|
+
import { ChainCallDTO, NotFoundError, UnauthorizedError } from "@gala-chain/api";
|
|
16
16
|
import { GalaChainContext } from "@gala-chain/chaincode";
|
|
17
17
|
|
|
18
18
|
import { LaunchpadFeeConfig } from "../../api/types";
|
|
19
19
|
import { fetchLaunchpadFeeAddress } from "../utils";
|
|
20
20
|
|
|
21
|
-
export async function fetchLaunchpadFeeConfig(
|
|
21
|
+
export async function fetchLaunchpadFeeConfig(
|
|
22
|
+
ctx: GalaChainContext,
|
|
23
|
+
dto: ChainCallDTO
|
|
24
|
+
): Promise<LaunchpadFeeConfig> {
|
|
22
25
|
const curatorOrgMsp = process.env.CURATOR_ORG_MSP ?? "CuratorOrg";
|
|
23
26
|
|
|
24
27
|
const platformFeeAddress = await fetchLaunchpadFeeAddress(ctx);
|
|
@@ -0,0 +1,67 @@
|
|
|
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 { ChainCallDTO, GalaChainErrorResponse, NotFoundError } from "@gala-chain/api";
|
|
16
|
+
import { fixture, users } from "@gala-chain/test";
|
|
17
|
+
import { plainToInstance } from "class-transformer";
|
|
18
|
+
|
|
19
|
+
import { LaunchpadFeeConfig, TransactionFeeResDto } from "../../api/types";
|
|
20
|
+
import { LaunchpadContract } from "../LaunchpadContract";
|
|
21
|
+
|
|
22
|
+
describe("fetchLaunchpadFeeAmount", () => {
|
|
23
|
+
it("Should return the feeAmount when LaunchpadFeeConfig exists", async () => {
|
|
24
|
+
//Given
|
|
25
|
+
const launchpadConfig = new LaunchpadFeeConfig(users.testUser2.identityKey, Number("0.32"), [
|
|
26
|
+
users.testUser2.identityKey
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
const { ctx, contract } = fixture(LaunchpadContract)
|
|
30
|
+
.registeredUsers(users.testUser3)
|
|
31
|
+
.savedState(launchpadConfig);
|
|
32
|
+
|
|
33
|
+
const dto = new ChainCallDTO();
|
|
34
|
+
|
|
35
|
+
dto.sign(users.testUser3.privateKey);
|
|
36
|
+
|
|
37
|
+
//When
|
|
38
|
+
const res = await contract.FetchLaunchpadFeeAmount(ctx, dto);
|
|
39
|
+
|
|
40
|
+
const expectedRes = plainToInstance(TransactionFeeResDto, {
|
|
41
|
+
feeAmount: 0.32
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
//Then
|
|
45
|
+
expect(res.Data).toEqual(expectedRes);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("Should revert when LaunchpadFeeConfig does not exists", async () => {
|
|
49
|
+
//Given
|
|
50
|
+
|
|
51
|
+
const { ctx, contract } = fixture(LaunchpadContract).registeredUsers(users.testUser3);
|
|
52
|
+
|
|
53
|
+
const dto = new ChainCallDTO();
|
|
54
|
+
|
|
55
|
+
dto.sign(users.testUser3.privateKey);
|
|
56
|
+
|
|
57
|
+
//When
|
|
58
|
+
const res = await contract.FetchLaunchpadFeeAmount(ctx, dto);
|
|
59
|
+
|
|
60
|
+
//Then
|
|
61
|
+
expect(res).toEqual(
|
|
62
|
+
new GalaChainErrorResponse(
|
|
63
|
+
new NotFoundError("Platform fee configuration has yet to be defined. Fee amount is not available.")
|
|
64
|
+
)
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
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 { ChainCallDTO, NotFoundError } from "@gala-chain/api";
|
|
16
|
+
import { GalaChainContext } from "@gala-chain/chaincode";
|
|
17
|
+
|
|
18
|
+
import { TransactionFeeResDto } from "../../api/types";
|
|
19
|
+
import { fetchLaunchpadFeeAddress } from "../utils";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @dev The fetchLaunchpadFeeAmount function retrieves the configured fee amount
|
|
23
|
+
* for Launchpad transactions. If no fee configuration is found, it throws a NotFoundError.
|
|
24
|
+
* @param ctx GalaChainContext – The execution context providing access to the GalaChain environment.
|
|
25
|
+
* @returns TransactionFeeResDto – An object containing:
|
|
26
|
+
* - feeAmount – The configured transaction fee amount for Launchpad transactions.
|
|
27
|
+
*/
|
|
28
|
+
export async function fetchLaunchpadFeeAmount(
|
|
29
|
+
ctx: GalaChainContext,
|
|
30
|
+
dto: ChainCallDTO
|
|
31
|
+
): Promise<TransactionFeeResDto> {
|
|
32
|
+
const feeConfig = await fetchLaunchpadFeeAddress(ctx);
|
|
33
|
+
|
|
34
|
+
if (!feeConfig) {
|
|
35
|
+
throw new NotFoundError("Platform fee configuration has yet to be defined. Fee amount is not available.");
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
feeAmount: feeConfig.feeAmount
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -20,7 +20,6 @@ export * from "./callNativeTokenIn";
|
|
|
20
20
|
export * from "./callNativeTokenOut";
|
|
21
21
|
export * from "./createSale";
|
|
22
22
|
export * from "./fetchSaleDetails";
|
|
23
|
-
export * from "./preMintCalculation";
|
|
24
23
|
export * from "./sellExactToken";
|
|
25
24
|
export * from "./finalizeTokenAllocation";
|
|
26
25
|
export * from "./sellWithNative";
|
|
@@ -132,6 +132,7 @@ export async function sellExactToken(
|
|
|
132
132
|
vaultAddress: sellTokenDTO.vaultAddress,
|
|
133
133
|
userAddress: ctx.callingUser,
|
|
134
134
|
isFinalized: false,
|
|
135
|
-
functionName: "SellExactToken"
|
|
135
|
+
functionName: "SellExactToken",
|
|
136
|
+
uniqueKey: sellTokenDTO.uniqueKey
|
|
136
137
|
};
|
|
137
138
|
}
|
|
@@ -131,6 +131,7 @@ export async function sellWithNative(
|
|
|
131
131
|
vaultAddress: sellTokenDTO.vaultAddress,
|
|
132
132
|
userAddress: ctx.callingUser,
|
|
133
133
|
isFinalized: false,
|
|
134
|
-
functionName: "SellWithNative"
|
|
134
|
+
functionName: "SellWithNative",
|
|
135
|
+
uniqueKey: sellTokenDTO.uniqueKey
|
|
135
136
|
};
|
|
136
137
|
}
|
|
@@ -0,0 +1,174 @@
|
|
|
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 {
|
|
16
|
+
GC_NETWORK_ID,
|
|
17
|
+
TokenAllowance,
|
|
18
|
+
TokenBalance,
|
|
19
|
+
TokenBurn,
|
|
20
|
+
TokenClass,
|
|
21
|
+
TokenClassKey,
|
|
22
|
+
TokenInstance,
|
|
23
|
+
TokenInstanceKey
|
|
24
|
+
} from "@gala-chain/api";
|
|
25
|
+
import { users } from "@gala-chain/test";
|
|
26
|
+
import { createInstanceFn, createPlainFn } from "@gala-chain/test/lib/src/data/utils";
|
|
27
|
+
import BigNumber from "bignumber.js";
|
|
28
|
+
|
|
29
|
+
process.env.LAUNCHPAD_GALA_CLASS_COLLECTION = process.env.LAUNCHPAD_GALA_CLASS_COLLECTION ?? "GALA";
|
|
30
|
+
process.env.LAUNCHPAD_GALA_CLASS_CATEGORY = process.env.LAUNCHPAD_GALA_CLASS_CATEGORY ?? "Unit";
|
|
31
|
+
process.env.LAUNCHPAD_GALA_CLASS_TYPE = process.env.LAUNCHPAD_GALA_CLASS_TYPE ?? "none";
|
|
32
|
+
process.env.LAUNCHPAD_GALA_CLASS_ADDITIONAL_KEY = process.env.LAUNCHPAD_GALA_CLASS_ADDITIONAL_KEY ?? "none";
|
|
33
|
+
|
|
34
|
+
const tokenClassKeyPlain = createPlainFn({
|
|
35
|
+
collection: process.env.LAUNCHPAD_GALA_CLASS_COLLECTION,
|
|
36
|
+
category: process.env.LAUNCHPAD_GALA_CLASS_CATEGORY,
|
|
37
|
+
type: process.env.LAUNCHPAD_GALA_CLASS_TYPE,
|
|
38
|
+
additionalKey: process.env.LAUNCHPAD_GALA_CLASS_ADDITIONAL_KEY
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const tokenClassPlain = createPlainFn({
|
|
42
|
+
...tokenClassKeyPlain(),
|
|
43
|
+
description: "Generated via automated test suite.",
|
|
44
|
+
decimals: 10,
|
|
45
|
+
image: "https://app.gala.games/test-image-placeholder-url.png",
|
|
46
|
+
isNonFungible: false,
|
|
47
|
+
maxCapacity: new BigNumber(100000000000000),
|
|
48
|
+
maxSupply: new BigNumber(100000000000000),
|
|
49
|
+
name: "AUTOMATEDTESTCOIN",
|
|
50
|
+
network: GC_NETWORK_ID,
|
|
51
|
+
symbol: "AUTC",
|
|
52
|
+
totalBurned: new BigNumber(0),
|
|
53
|
+
totalMintAllowance: new BigNumber(0),
|
|
54
|
+
totalSupply: new BigNumber(0),
|
|
55
|
+
authorities: [users.admin.identityKey]
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const tokenAllowancePlain = (txUnixTime: number) => ({
|
|
59
|
+
...tokenClassKeyPlain(),
|
|
60
|
+
allowanceType: 4,
|
|
61
|
+
quantity: new BigNumber(1000000000000),
|
|
62
|
+
quantitySpent: new BigNumber(0),
|
|
63
|
+
created: txUnixTime,
|
|
64
|
+
expires: 0,
|
|
65
|
+
instance: new BigNumber(0),
|
|
66
|
+
grantedBy: users.admin.identityKey,
|
|
67
|
+
grantedTo: users.admin.identityKey,
|
|
68
|
+
uses: new BigNumber(1),
|
|
69
|
+
usesSpent: new BigNumber(0)
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const tokenBurnAllowancePlain = (txUnixTime: number) => ({
|
|
73
|
+
...tokenClassKeyPlain(),
|
|
74
|
+
allowanceType: 6,
|
|
75
|
+
quantity: new BigNumber(1),
|
|
76
|
+
quantitySpent: new BigNumber(0),
|
|
77
|
+
created: txUnixTime,
|
|
78
|
+
expires: 0,
|
|
79
|
+
instance: new BigNumber(0),
|
|
80
|
+
grantedBy: users.testUser1.identityKey,
|
|
81
|
+
grantedTo: users.testUser2.identityKey,
|
|
82
|
+
uses: new BigNumber(1),
|
|
83
|
+
usesSpent: new BigNumber(0)
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const tokenBurnAllowanceUser3Plain = (txUnixTime: number) => ({
|
|
87
|
+
...tokenClassKeyPlain(),
|
|
88
|
+
allowanceType: 6,
|
|
89
|
+
quantity: new BigNumber(1),
|
|
90
|
+
quantitySpent: new BigNumber(0),
|
|
91
|
+
created: txUnixTime,
|
|
92
|
+
expires: 0,
|
|
93
|
+
instance: new BigNumber(0),
|
|
94
|
+
grantedBy: users.testUser3.identityKey,
|
|
95
|
+
grantedTo: users.testUser2.identityKey,
|
|
96
|
+
uses: new BigNumber(1),
|
|
97
|
+
usesSpent: new BigNumber(0)
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const tokenMintAllowancePlain = (txUnixTime: number) => ({
|
|
101
|
+
...tokenClassKeyPlain(),
|
|
102
|
+
allowanceType: 4,
|
|
103
|
+
quantity: new BigNumber(1),
|
|
104
|
+
quantitySpent: new BigNumber(0),
|
|
105
|
+
created: txUnixTime,
|
|
106
|
+
expires: 0,
|
|
107
|
+
instance: new BigNumber(0),
|
|
108
|
+
grantedBy: users.testUser1.identityKey,
|
|
109
|
+
grantedTo: users.testUser2.identityKey,
|
|
110
|
+
uses: new BigNumber(1),
|
|
111
|
+
usesSpent: new BigNumber(0)
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const tokenInstanceKeyPlain = createPlainFn({
|
|
115
|
+
...tokenClassKeyPlain(),
|
|
116
|
+
instance: new BigNumber(0)
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const tokenInstancePlain = createPlainFn({
|
|
120
|
+
...tokenInstanceKeyPlain(),
|
|
121
|
+
isNonFungible: false
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const tokenBalancePlain = createPlainFn({
|
|
125
|
+
...tokenClassKeyPlain(),
|
|
126
|
+
owner: users.testUser1.identityKey,
|
|
127
|
+
inUseHolds: [],
|
|
128
|
+
lockedHolds: [],
|
|
129
|
+
instanceIds: [],
|
|
130
|
+
quantity: new BigNumber("1000")
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const tokenBurnPlain = (txUnixTime: number) => ({
|
|
134
|
+
...tokenInstanceKeyPlain(),
|
|
135
|
+
burnedBy: users.testUser1.identityKey,
|
|
136
|
+
created: txUnixTime,
|
|
137
|
+
quantity: new BigNumber(1)
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const tokenBurnCounterPlain = (
|
|
141
|
+
txUnixTime: number,
|
|
142
|
+
timeKey: string,
|
|
143
|
+
epoch: string,
|
|
144
|
+
totalKnownBurnsCount: BigNumber
|
|
145
|
+
) => ({
|
|
146
|
+
...tokenBurnPlain(txUnixTime),
|
|
147
|
+
timeKey,
|
|
148
|
+
epoch,
|
|
149
|
+
totalKnownBurnsCount
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
export default {
|
|
153
|
+
tokenClassKeyPlain,
|
|
154
|
+
tokenClassKey: createInstanceFn(TokenClassKey, tokenClassKeyPlain()),
|
|
155
|
+
tokenClassPlain: tokenClassPlain,
|
|
156
|
+
tokenClass: createInstanceFn(TokenClass, tokenClassPlain()),
|
|
157
|
+
tokenAllowancePlain,
|
|
158
|
+
tokenAllowance: createInstanceFn(TokenAllowance, tokenAllowancePlain(1)),
|
|
159
|
+
tokenBurnAllowancePlain,
|
|
160
|
+
tokenBurnAllowance: createInstanceFn(TokenAllowance, tokenBurnAllowancePlain(1)),
|
|
161
|
+
tokenBurnAllowanceUser3Plain,
|
|
162
|
+
tokenBurnAllowanceUser3: createInstanceFn(TokenAllowance, tokenBurnAllowanceUser3Plain(1)),
|
|
163
|
+
tokenMintAllowancePlain,
|
|
164
|
+
tokenMintAllowance: createInstanceFn(TokenAllowance, tokenMintAllowancePlain(1)),
|
|
165
|
+
tokenInstanceKeyPlain,
|
|
166
|
+
tokenInstanceKey: createInstanceFn(TokenInstanceKey, tokenInstanceKeyPlain()),
|
|
167
|
+
tokenInstancePlain,
|
|
168
|
+
tokenInstance: createInstanceFn(TokenInstance, tokenInstancePlain()),
|
|
169
|
+
tokenBalancePlain,
|
|
170
|
+
tokenBalance: createInstanceFn(TokenBalance, tokenBalancePlain()),
|
|
171
|
+
tokenBurnPlain,
|
|
172
|
+
tokenBurn: createInstanceFn(TokenBurn, tokenBurnPlain(1)),
|
|
173
|
+
tokenBurnCounterPlain
|
|
174
|
+
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { PreMintCalculationDto } from "../../api/types";
|
|
2
|
-
/**
|
|
3
|
-
* Calculates the number of tokens that can be purchased using a specified amount
|
|
4
|
-
* of native tokens based on a bonding curve mechanism.
|
|
5
|
-
*
|
|
6
|
-
* This function applies the bonding curve formula for a brand new sale with zero tokens sold
|
|
7
|
-
* to determine the number of tokens the user can buy with the provided native token amount.
|
|
8
|
-
*
|
|
9
|
-
* @param buyTokenDTO - The Amount of native tokens to spend for the purchase.
|
|
10
|
-
*
|
|
11
|
-
* @returns A promise that resolves to a string representing the calculated amount of
|
|
12
|
-
* tokens to be received, rounded down to 18 decimal places.
|
|
13
|
-
*
|
|
14
|
-
* @throws Error if the calculation results in an invalid state.
|
|
15
|
-
*/
|
|
16
|
-
export declare function calculatePreMintTokens(buyTokenDTO: PreMintCalculationDto): Promise<string>;
|
|
17
|
-
//# sourceMappingURL=preMintCalculation.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"preMintCalculation.d.ts","sourceRoot":"","sources":["../../../../src/chaincode/launchpad/preMintCalculation.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAiB,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAGvE;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,WAAW,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBhG"}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculatePreMintTokens = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
/*
|
|
6
|
-
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
7
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
-
* you may not use this file except in compliance with the License.
|
|
9
|
-
* You may obtain a copy of the License at
|
|
10
|
-
*
|
|
11
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
*
|
|
13
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
* See the License for the specific language governing permissions and
|
|
17
|
-
* limitations under the License.
|
|
18
|
-
*/
|
|
19
|
-
const decimal_js_1 = tslib_1.__importDefault(require("decimal.js"));
|
|
20
|
-
const types_1 = require("../../api/types");
|
|
21
|
-
const utils_1 = require("../utils");
|
|
22
|
-
/**
|
|
23
|
-
* Calculates the number of tokens that can be purchased using a specified amount
|
|
24
|
-
* of native tokens based on a bonding curve mechanism.
|
|
25
|
-
*
|
|
26
|
-
* This function applies the bonding curve formula for a brand new sale with zero tokens sold
|
|
27
|
-
* to determine the number of tokens the user can buy with the provided native token amount.
|
|
28
|
-
*
|
|
29
|
-
* @param buyTokenDTO - The Amount of native tokens to spend for the purchase.
|
|
30
|
-
*
|
|
31
|
-
* @returns A promise that resolves to a string representing the calculated amount of
|
|
32
|
-
* tokens to be received, rounded down to 18 decimal places.
|
|
33
|
-
*
|
|
34
|
-
* @throws Error if the calculation results in an invalid state.
|
|
35
|
-
*/
|
|
36
|
-
async function calculatePreMintTokens(buyTokenDTO) {
|
|
37
|
-
const totalTokensSold = new decimal_js_1.default(0); // current tokens sold / x
|
|
38
|
-
const nativeTokens = new decimal_js_1.default(buyTokenDTO.nativeTokenQuantity.toString()); // native tokens used to buy / y
|
|
39
|
-
const basePrice = new decimal_js_1.default(types_1.LaunchpadSale.BASE_PRICE); // base price / a
|
|
40
|
-
const { exponentFactor, euler, decimals } = (0, utils_1.getBondingConstants)();
|
|
41
|
-
const constant = nativeTokens.mul(exponentFactor).div(basePrice);
|
|
42
|
-
const exponent1 = exponentFactor.mul(totalTokensSold).div(decimals);
|
|
43
|
-
const eResult1 = euler.pow(exponent1);
|
|
44
|
-
const ethScaled = constant.add(eResult1);
|
|
45
|
-
const lnEthScaled = ethScaled.ln().mul(decimals);
|
|
46
|
-
const lnEthScaledBase = lnEthScaled.div(exponentFactor);
|
|
47
|
-
const result = lnEthScaledBase.minus(totalTokensSold);
|
|
48
|
-
const roundedResult = result.toDecimalPlaces(18, decimal_js_1.default.ROUND_DOWN);
|
|
49
|
-
return roundedResult.toString();
|
|
50
|
-
}
|
|
51
|
-
exports.calculatePreMintTokens = calculatePreMintTokens;
|
|
52
|
-
//# sourceMappingURL=preMintCalculation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"preMintCalculation.js","sourceRoot":"","sources":["../../../../src/chaincode/launchpad/preMintCalculation.ts"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;;;;GAaG;AACH,oEAAiC;AAEjC,2CAAuE;AACvE,oCAA+C;AAE/C;;;;;;;;;;;;;GAaG;AACI,KAAK,UAAU,sBAAsB,CAAC,WAAkC;IAC7E,MAAM,eAAe,GAAG,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B;IAClE,MAAM,YAAY,GAAG,IAAI,oBAAO,CAAC,WAAW,CAAC,mBAAmB,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,gCAAgC;IAC9G,MAAM,SAAS,GAAG,IAAI,oBAAO,CAAC,qBAAa,CAAC,UAAU,CAAC,CAAC,CAAC,iBAAiB;IAC1E,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAA,2BAAmB,GAAE,CAAC;IAElE,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEjE,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEpE,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEtC,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEzC,MAAM,WAAW,GAAG,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEjD,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAExD,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACtD,MAAM,aAAa,GAAG,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,oBAAO,CAAC,UAAU,CAAC,CAAC;IAErE,OAAO,aAAa,CAAC,QAAQ,EAAE,CAAC;AAClC,CAAC;AAtBD,wDAsBC"}
|