@gala-chain/launchpad 1.0.1 → 1.0.3
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 +2 -2
- package/lib/src/api/types/LaunchpadBatchSubmitAuthorities.d.ts +12 -0
- package/lib/src/api/types/LaunchpadBatchSubmitAuthorities.d.ts.map +1 -0
- package/lib/src/api/types/LaunchpadBatchSubmitAuthorities.js +56 -0
- package/lib/src/api/types/LaunchpadBatchSubmitAuthorities.js.map +1 -0
- package/lib/src/api/types/LaunchpadDtos.d.ts +14 -0
- package/lib/src/api/types/LaunchpadDtos.d.ts.map +1 -1
- package/lib/src/api/types/LaunchpadDtos.js +45 -1
- package/lib/src/api/types/LaunchpadDtos.js.map +1 -1
- package/lib/src/api/types/LaunchpadFeeConfig.d.ts +3 -2
- package/lib/src/api/types/LaunchpadFeeConfig.d.ts.map +1 -1
- package/lib/src/api/types/LaunchpadFeeConfig.js +15 -6
- package/lib/src/api/types/LaunchpadFeeConfig.js.map +1 -1
- package/lib/src/api/types/LaunchpadFinalizeAllocation.js +1 -2
- package/lib/src/api/types/LaunchpadFinalizeAllocation.js.map +1 -1
- package/lib/src/api/types/LaunchpadSale.js +1 -2
- package/lib/src/api/types/LaunchpadSale.js.map +1 -1
- package/lib/src/api/types/index.d.ts +1 -0
- package/lib/src/api/types/index.d.ts.map +1 -1
- package/lib/src/api/types/index.js +1 -0
- package/lib/src/api/types/index.js.map +1 -1
- package/lib/src/api/validators/decorators.js.map +1 -1
- package/lib/src/chaincode/LaunchpadContract.d.ts +6 -1
- package/lib/src/chaincode/LaunchpadContract.d.ts.map +1 -1
- package/lib/src/chaincode/LaunchpadContract.js +97 -0
- 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 +22 -9
- 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 +31 -9
- package/lib/src/chaincode/launchpad/buyWithNative.js.map +1 -1
- package/lib/src/chaincode/launchpad/callMemeTokenIn.d.ts +1 -0
- package/lib/src/chaincode/launchpad/callMemeTokenIn.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/callMemeTokenIn.js +3 -5
- package/lib/src/chaincode/launchpad/callMemeTokenIn.js.map +1 -1
- package/lib/src/chaincode/launchpad/callMemeTokenOut.d.ts +1 -0
- package/lib/src/chaincode/launchpad/callMemeTokenOut.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/callMemeTokenOut.js +5 -5
- package/lib/src/chaincode/launchpad/callMemeTokenOut.js.map +1 -1
- package/lib/src/chaincode/launchpad/callNativeTokenIn.d.ts +1 -0
- package/lib/src/chaincode/launchpad/callNativeTokenIn.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/callNativeTokenIn.js +7 -6
- package/lib/src/chaincode/launchpad/callNativeTokenIn.js.map +1 -1
- package/lib/src/chaincode/launchpad/callNativeTokenOut.d.ts +1 -0
- package/lib/src/chaincode/launchpad/callNativeTokenOut.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/callNativeTokenOut.js +4 -5
- package/lib/src/chaincode/launchpad/callNativeTokenOut.js.map +1 -1
- package/lib/src/chaincode/launchpad/configureLaunchpadFeeConfig.d.ts +12 -0
- package/lib/src/chaincode/launchpad/configureLaunchpadFeeConfig.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/configureLaunchpadFeeConfig.js +26 -6
- package/lib/src/chaincode/launchpad/configureLaunchpadFeeConfig.js.map +1 -1
- package/lib/src/chaincode/launchpad/createSale.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/createSale.js +10 -12
- package/lib/src/chaincode/launchpad/createSale.js.map +1 -1
- package/lib/src/chaincode/launchpad/fees.d.ts +1 -0
- package/lib/src/chaincode/launchpad/fees.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/fees.js +6 -2
- package/lib/src/chaincode/launchpad/fees.js.map +1 -1
- package/lib/src/chaincode/launchpad/fetchLaunchpadAdressConfig.js.map +1 -1
- package/lib/src/chaincode/launchpad/fetchSaleDetails.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/fetchSaleDetails.js +0 -4
- package/lib/src/chaincode/launchpad/fetchSaleDetails.js.map +1 -1
- package/lib/src/chaincode/launchpad/finaliseSale.js +3 -3
- package/lib/src/chaincode/launchpad/finaliseSale.js.map +1 -1
- package/lib/src/chaincode/launchpad/finalizeTokenAllocation.js.map +1 -1
- package/lib/src/chaincode/launchpad/index.d.ts +1 -0
- package/lib/src/chaincode/launchpad/index.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/index.js +1 -0
- package/lib/src/chaincode/launchpad/index.js.map +1 -1
- package/lib/src/chaincode/launchpad/launchpadBatchSubmitAuthorizations.d.ts +24 -0
- package/lib/src/chaincode/launchpad/launchpadBatchSubmitAuthorizations.d.ts.map +1 -0
- package/lib/src/chaincode/launchpad/launchpadBatchSubmitAuthorizations.js +84 -0
- package/lib/src/chaincode/launchpad/launchpadBatchSubmitAuthorizations.js.map +1 -0
- package/lib/src/chaincode/launchpad/preMintCalculation.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/preMintCalculation.js +0 -4
- package/lib/src/chaincode/launchpad/preMintCalculation.js.map +1 -1
- package/lib/src/chaincode/launchpad/sellExactToken.d.ts.map +1 -1
- package/lib/src/chaincode/launchpad/sellExactToken.js +27 -11
- 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 +30 -8
- package/lib/src/chaincode/launchpad/sellWithNative.js.map +1 -1
- package/lib/src/chaincode/utils/launchpadSaleUtils.js +2 -2
- package/lib/src/chaincode/utils/launchpadSaleUtils.js.map +1 -1
- package/lib/src/cli.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/api/types/LaunchpadBatchSubmitAuthorities.ts +53 -0
- package/src/api/types/LaunchpadDtos.ts +38 -0
- package/src/api/types/LaunchpadFeeConfig.ts +13 -4
- package/src/api/types/index.ts +1 -0
- package/src/chaincode/LaunchpadContract.ts +104 -1
- package/src/chaincode/launchpad/buyExactToken.ts +18 -6
- package/src/chaincode/launchpad/buyWithNative.ts +29 -6
- package/src/chaincode/launchpad/callMemeTokenIn.ts +9 -8
- package/src/chaincode/launchpad/callMemeTokenOut.ts +9 -7
- package/src/chaincode/launchpad/callNativeTokenIn.ts +11 -8
- package/src/chaincode/launchpad/callNativeTokenOut.ts +9 -8
- package/src/chaincode/launchpad/configureLaunchpadFeeConfig.ts +27 -4
- package/src/chaincode/launchpad/createSale.ts +1 -5
- package/src/chaincode/launchpad/fees.ts +5 -1
- package/src/chaincode/launchpad/fetchSaleDetails.ts +0 -5
- package/src/chaincode/launchpad/finaliseSale.ts +3 -3
- package/src/chaincode/launchpad/index.ts +1 -0
- package/src/chaincode/launchpad/launchpadBatchSubmitAuthorizations.spec.ts +185 -0
- package/src/chaincode/launchpad/launchpadBatchSubmitAuthorizations.ts +105 -0
- package/src/chaincode/launchpad/preMintCalculation.ts +0 -5
- package/src/chaincode/launchpad/sellExactToken.ts +30 -15
- package/src/chaincode/launchpad/sellWithNative.ts +31 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gala-chain/launchpad",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "GalaChain Launchpad Chaincode",
|
|
5
5
|
"main": "lib/src/index.js",
|
|
6
6
|
"types": "lib/src/index.d.ts",
|
|
@@ -49,6 +49,6 @@
|
|
|
49
49
|
"prettier": "^3.1.1",
|
|
50
50
|
"ts-jest": "^29.1.2",
|
|
51
51
|
"ts-node": "^10.9.1",
|
|
52
|
-
"typescript": "^5.
|
|
52
|
+
"typescript": "^5.1.6"
|
|
53
53
|
}
|
|
54
|
-
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Gala Games Inc. All rights reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
import { ChainObject } from "@gala-chain/api";
|
|
16
|
+
import { Exclude } from "class-transformer";
|
|
17
|
+
import { ArrayNotEmpty, IsString } from "class-validator";
|
|
18
|
+
|
|
19
|
+
export class LaunchpadBatchSubmitAuthorities extends ChainObject {
|
|
20
|
+
@Exclude()
|
|
21
|
+
public static INDEX_KEY = "GCLBSA"; // GalaChain Launchpad Batch Submit Authorities
|
|
22
|
+
|
|
23
|
+
@ArrayNotEmpty()
|
|
24
|
+
@IsString({ each: true })
|
|
25
|
+
authorities: string[];
|
|
26
|
+
|
|
27
|
+
constructor(authorities: string[]) {
|
|
28
|
+
super();
|
|
29
|
+
this.authorities = authorities;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public addOrUpdateAuthorities(newAuthorities: string[]) {
|
|
33
|
+
this.authorities = newAuthorities;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public addAuthority(authority: string) {
|
|
37
|
+
if (!this.authorities.includes(authority)) {
|
|
38
|
+
this.authorities.push(authority);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public removeAuthority(authority: string) {
|
|
43
|
+
this.authorities = this.authorities.filter((auth) => auth !== authority);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public isAuthorized(authority: string): boolean {
|
|
47
|
+
return this.authorities.includes(authority);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public getAuthorities(): string[] {
|
|
51
|
+
return [...this.authorities];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -24,6 +24,8 @@ import {
|
|
|
24
24
|
import BigNumber from "bignumber.js";
|
|
25
25
|
import { Type } from "class-transformer";
|
|
26
26
|
import {
|
|
27
|
+
ArrayNotEmpty,
|
|
28
|
+
IsArray,
|
|
27
29
|
IsBoolean,
|
|
28
30
|
IsNotEmpty,
|
|
29
31
|
IsNumber,
|
|
@@ -275,6 +277,9 @@ export class TradeResDto {
|
|
|
275
277
|
@IsNotEmpty()
|
|
276
278
|
public inputQuantity: string;
|
|
277
279
|
|
|
280
|
+
@IsNotEmpty()
|
|
281
|
+
public totalFees: string;
|
|
282
|
+
|
|
278
283
|
@IsNotEmpty()
|
|
279
284
|
public outputQuantity: string;
|
|
280
285
|
|
|
@@ -328,6 +333,12 @@ export class ConfigureLaunchpadFeeAddressDto extends SubmitCallDTO {
|
|
|
328
333
|
@IsUserAlias()
|
|
329
334
|
public newPlatformFeeAddress?: UserAlias;
|
|
330
335
|
|
|
336
|
+
@IsOptional()
|
|
337
|
+
@IsNumber()
|
|
338
|
+
@Min(0)
|
|
339
|
+
@Max(1)
|
|
340
|
+
public newFeeAmount?: number;
|
|
341
|
+
|
|
331
342
|
@IsOptional()
|
|
332
343
|
@IsUserAlias({ each: true })
|
|
333
344
|
public newAuthorities?: UserAlias[];
|
|
@@ -355,6 +366,10 @@ export class TradeCalculationResFeesDto {
|
|
|
355
366
|
@IsNotEmpty()
|
|
356
367
|
@IsString()
|
|
357
368
|
reverseBondingCurve: string;
|
|
369
|
+
|
|
370
|
+
@IsNotEmpty()
|
|
371
|
+
@IsString()
|
|
372
|
+
transactionFees: string;
|
|
358
373
|
}
|
|
359
374
|
|
|
360
375
|
export class TradeCalculationResDto {
|
|
@@ -366,3 +381,26 @@ export class TradeCalculationResDto {
|
|
|
366
381
|
@Type(() => TradeCalculationResFeesDto)
|
|
367
382
|
public extraFees: TradeCalculationResFeesDto;
|
|
368
383
|
}
|
|
384
|
+
|
|
385
|
+
export class AuthorizeBatchSubmitterDto extends SubmitCallDTO {
|
|
386
|
+
@IsArray()
|
|
387
|
+
@ArrayNotEmpty()
|
|
388
|
+
@IsString({ each: true })
|
|
389
|
+
authorities: string[];
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export class DeauthorizeBatchSubmitterDto extends SubmitCallDTO {
|
|
393
|
+
@IsString()
|
|
394
|
+
authority: string;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export class FetchBatchSubmitAuthoritiesDto extends ChainCallDTO {
|
|
398
|
+
// No additional fields needed for fetching all authorities
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
export class BatchSubmitAuthoritiesResDto extends ChainCallDTO {
|
|
402
|
+
@IsArray()
|
|
403
|
+
@ArrayNotEmpty()
|
|
404
|
+
@IsString({ each: true })
|
|
405
|
+
authorities: string[];
|
|
406
|
+
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { ChainObject, IsUserAlias, UserAlias } from "@gala-chain/api";
|
|
16
16
|
import { Exclude } from "class-transformer";
|
|
17
|
-
import { ArrayNotEmpty, IsNotEmpty } from "class-validator";
|
|
17
|
+
import { ArrayNotEmpty, IsNotEmpty, IsNumber, Max, Min } from "class-validator";
|
|
18
18
|
import { JSONSchema } from "class-validator-jsonschema";
|
|
19
19
|
|
|
20
20
|
@JSONSchema({
|
|
@@ -22,24 +22,33 @@ import { JSONSchema } from "class-validator-jsonschema";
|
|
|
22
22
|
})
|
|
23
23
|
export class LaunchpadFeeConfig extends ChainObject {
|
|
24
24
|
@Exclude()
|
|
25
|
-
public static INDEX_KEY = "
|
|
25
|
+
public static INDEX_KEY = "GCLPFC"; // GalaChain Launchpad Fee Configuration
|
|
26
26
|
|
|
27
27
|
@IsNotEmpty()
|
|
28
28
|
@IsUserAlias()
|
|
29
29
|
feeAddress: UserAlias;
|
|
30
30
|
|
|
31
|
+
@IsNotEmpty()
|
|
32
|
+
@IsNumber()
|
|
33
|
+
@Min(0)
|
|
34
|
+
@Max(1)
|
|
35
|
+
public feeAmount: number;
|
|
36
|
+
|
|
31
37
|
@ArrayNotEmpty()
|
|
32
38
|
@IsUserAlias({ each: true })
|
|
33
39
|
authorities: UserAlias[];
|
|
34
40
|
|
|
35
|
-
constructor(feeAddress: UserAlias, authorities: UserAlias[]) {
|
|
41
|
+
constructor(feeAddress: UserAlias, feeAmount: number, authorities: UserAlias[]) {
|
|
36
42
|
super();
|
|
37
43
|
this.feeAddress = feeAddress;
|
|
44
|
+
this.feeAmount = feeAmount;
|
|
38
45
|
this.authorities = authorities;
|
|
39
46
|
}
|
|
40
47
|
|
|
41
|
-
public
|
|
48
|
+
public updateFeeConfig(newfeeAddress: UserAlias, newFeeAmount: number, newAuthorities: UserAlias[]) {
|
|
42
49
|
this.feeAddress = newfeeAddress;
|
|
50
|
+
this.feeAmount = newFeeAmount;
|
|
43
51
|
this.authorities = newAuthorities;
|
|
52
|
+
this.validate();
|
|
44
53
|
}
|
|
45
54
|
}
|
package/src/api/types/index.ts
CHANGED
|
@@ -12,21 +12,29 @@
|
|
|
12
12
|
* See the License for the specific language governing permissions and
|
|
13
13
|
* limitations under the License.
|
|
14
14
|
*/
|
|
15
|
+
import { BatchDto, GalaChainResponse, UnauthorizedError } from "@gala-chain/api";
|
|
15
16
|
import {
|
|
17
|
+
BatchWriteLimitExceededError,
|
|
16
18
|
EVALUATE,
|
|
17
19
|
Evaluate,
|
|
18
20
|
GalaChainContext,
|
|
19
21
|
GalaContract,
|
|
20
22
|
GalaTransaction,
|
|
21
|
-
|
|
23
|
+
SUBMIT,
|
|
24
|
+
Submit,
|
|
25
|
+
getApiMethod
|
|
22
26
|
} from "@gala-chain/chaincode";
|
|
23
27
|
|
|
24
28
|
import { version } from "../../package.json";
|
|
25
29
|
import {
|
|
30
|
+
AuthorizeBatchSubmitterDto,
|
|
31
|
+
BatchSubmitAuthoritiesResDto,
|
|
26
32
|
ConfigureLaunchpadFeeAddressDto,
|
|
27
33
|
CreateSaleResDto,
|
|
28
34
|
CreateTokenSaleDTO,
|
|
35
|
+
DeauthorizeBatchSubmitterDto,
|
|
29
36
|
ExactTokenQuantityDto,
|
|
37
|
+
FetchBatchSubmitAuthoritiesDto,
|
|
30
38
|
FetchSaleDto,
|
|
31
39
|
FinalizeTokenAllocationDto,
|
|
32
40
|
LaunchpadFeeConfig,
|
|
@@ -45,6 +53,7 @@ import {
|
|
|
45
53
|
sellWithNativeFeeGate
|
|
46
54
|
} from "./dexLaunchpadFeeGate";
|
|
47
55
|
import {
|
|
56
|
+
authorizeLaunchpadBatchSubmitter,
|
|
48
57
|
buyExactToken,
|
|
49
58
|
buyWithNative,
|
|
50
59
|
calculatePreMintTokens,
|
|
@@ -54,9 +63,12 @@ import {
|
|
|
54
63
|
callNativeTokenOut,
|
|
55
64
|
configureLaunchpadFeeAddress,
|
|
56
65
|
createSale,
|
|
66
|
+
deauthorizeLaunchpadBatchSubmitter,
|
|
67
|
+
fetchLaunchpadBatchSubmitAuthorities,
|
|
57
68
|
fetchLaunchpadFeeConfig,
|
|
58
69
|
fetchSaleDetails,
|
|
59
70
|
finalizeTokenAllocation,
|
|
71
|
+
getLaunchpadBatchSubmitAuthorities,
|
|
60
72
|
sellExactToken,
|
|
61
73
|
sellWithNative
|
|
62
74
|
} from "./launchpad";
|
|
@@ -208,4 +220,95 @@ export class LaunchpadContract extends GalaContract {
|
|
|
208
220
|
public async FetchLaunchpadFeeConfig(ctx: GalaChainContext): Promise<LaunchpadFeeConfig> {
|
|
209
221
|
return fetchLaunchpadFeeConfig(ctx);
|
|
210
222
|
}
|
|
223
|
+
|
|
224
|
+
@GalaTransaction({
|
|
225
|
+
type: SUBMIT,
|
|
226
|
+
in: BatchDto,
|
|
227
|
+
out: "object",
|
|
228
|
+
description: "Submit a batch of transactions",
|
|
229
|
+
verifySignature: true
|
|
230
|
+
})
|
|
231
|
+
public async BatchSubmit(ctx: GalaChainContext, batchDto: BatchDto): Promise<GalaChainResponse<unknown>[]> {
|
|
232
|
+
// Check if the calling user is authorized to submit batches
|
|
233
|
+
const batchAuthorities = await fetchLaunchpadBatchSubmitAuthorities(ctx);
|
|
234
|
+
if (!batchAuthorities.isAuthorized(ctx.callingUser)) {
|
|
235
|
+
throw new UnauthorizedError(
|
|
236
|
+
`CallingUser ${ctx.callingUser} is not authorized to submit batches. ` +
|
|
237
|
+
`Authorized users: ${batchAuthorities.getAuthorities().join(", ")}`
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const responses: GalaChainResponse<unknown>[] = [];
|
|
242
|
+
|
|
243
|
+
const softWritesLimit = batchDto.writesLimit ?? BatchDto.WRITES_DEFAULT_LIMIT;
|
|
244
|
+
const writesLimit = Math.min(softWritesLimit, BatchDto.WRITES_HARD_LIMIT);
|
|
245
|
+
let writesCount = ctx.stub.getWritesCount();
|
|
246
|
+
|
|
247
|
+
for (const [index, op] of batchDto.operations.entries()) {
|
|
248
|
+
// Use sandboxed context to avoid flushes of writes and deletes, and populate
|
|
249
|
+
// the stub with current writes and deletes.
|
|
250
|
+
const sandboxCtx = ctx.createReadOnlyContext(index);
|
|
251
|
+
sandboxCtx.stub.setWrites(ctx.stub.getWrites());
|
|
252
|
+
sandboxCtx.stub.setDeletes(ctx.stub.getDeletes());
|
|
253
|
+
|
|
254
|
+
// Execute the operation. Collect both successful and failed responses.
|
|
255
|
+
let response: GalaChainResponse<unknown>;
|
|
256
|
+
try {
|
|
257
|
+
if (writesCount >= writesLimit) {
|
|
258
|
+
throw new BatchWriteLimitExceededError(writesLimit);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const method = getApiMethod(this, op.method, (m) => m.isWrite && m.methodName !== "BatchSubmit");
|
|
262
|
+
response = await this[method.methodName](sandboxCtx, op.dto);
|
|
263
|
+
} catch (error) {
|
|
264
|
+
response = GalaChainResponse.Error(error);
|
|
265
|
+
}
|
|
266
|
+
responses.push(response);
|
|
267
|
+
|
|
268
|
+
// Update the current context with the writes and deletes if the operation
|
|
269
|
+
// is successful.
|
|
270
|
+
if (GalaChainResponse.isSuccess(response)) {
|
|
271
|
+
ctx.stub.setWrites(sandboxCtx.stub.getWrites());
|
|
272
|
+
ctx.stub.setDeletes(sandboxCtx.stub.getDeletes());
|
|
273
|
+
writesCount = ctx.stub.getWritesCount();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return responses;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
@Submit({
|
|
280
|
+
in: AuthorizeBatchSubmitterDto,
|
|
281
|
+
out: BatchSubmitAuthoritiesResDto,
|
|
282
|
+
allowedOrgs: [process.env.CURATOR_ORG_MSP ?? "CuratorOrg"]
|
|
283
|
+
})
|
|
284
|
+
public async AuthorizeBatchSubmitter(
|
|
285
|
+
ctx: GalaChainContext,
|
|
286
|
+
dto: AuthorizeBatchSubmitterDto
|
|
287
|
+
): Promise<BatchSubmitAuthoritiesResDto> {
|
|
288
|
+
return await authorizeLaunchpadBatchSubmitter(ctx, dto);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@Submit({
|
|
292
|
+
in: DeauthorizeBatchSubmitterDto,
|
|
293
|
+
out: BatchSubmitAuthoritiesResDto,
|
|
294
|
+
allowedOrgs: [process.env.CURATOR_ORG_MSP ?? "CuratorOrg"]
|
|
295
|
+
})
|
|
296
|
+
public async DeauthorizeBatchSubmitter(
|
|
297
|
+
ctx: GalaChainContext,
|
|
298
|
+
dto: DeauthorizeBatchSubmitterDto
|
|
299
|
+
): Promise<BatchSubmitAuthoritiesResDto> {
|
|
300
|
+
return await deauthorizeLaunchpadBatchSubmitter(ctx, dto);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
@GalaTransaction({
|
|
304
|
+
type: EVALUATE,
|
|
305
|
+
in: FetchBatchSubmitAuthoritiesDto,
|
|
306
|
+
out: BatchSubmitAuthoritiesResDto
|
|
307
|
+
})
|
|
308
|
+
public async GetBatchSubmitAuthorities(
|
|
309
|
+
ctx: GalaChainContext,
|
|
310
|
+
dto: FetchBatchSubmitAuthoritiesDto
|
|
311
|
+
): Promise<BatchSubmitAuthoritiesResDto> {
|
|
312
|
+
return await getLaunchpadBatchSubmitAuthorities(ctx, dto);
|
|
313
|
+
}
|
|
211
314
|
}
|
|
@@ -13,18 +13,14 @@
|
|
|
13
13
|
* limitations under the License.
|
|
14
14
|
*/
|
|
15
15
|
import { GalaChainContext, fetchTokenClass, putChainObject, transferToken } from "@gala-chain/chaincode";
|
|
16
|
-
import
|
|
16
|
+
import BigNumber from "bignumber.js";
|
|
17
17
|
|
|
18
18
|
import { ExactTokenQuantityDto, LaunchpadSale, TradeResDto } from "../../api/types";
|
|
19
19
|
import { SlippageToleranceExceededError } from "../../api/utils/error";
|
|
20
|
-
import { fetchAndValidateSale } from "../utils";
|
|
20
|
+
import { fetchAndValidateSale, fetchLaunchpadFeeAddress } from "../utils";
|
|
21
21
|
import { callNativeTokenIn } from "./callNativeTokenIn";
|
|
22
22
|
import { finalizeSale } from "./finaliseSale";
|
|
23
23
|
|
|
24
|
-
BigNumber.config({
|
|
25
|
-
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
26
|
-
});
|
|
27
|
-
|
|
28
24
|
/**
|
|
29
25
|
* Executes the purchase of an exact amount of tokens in a token sale.
|
|
30
26
|
*
|
|
@@ -53,6 +49,7 @@ export async function buyExactToken(
|
|
|
53
49
|
|
|
54
50
|
// Calculate the required amount of native tokens to buy the specified token amount
|
|
55
51
|
const callNativeTokenInResult1 = await callNativeTokenIn(ctx, buyTokenDTO);
|
|
52
|
+
let transactionFees = callNativeTokenInResult1.extraFees.transactionFees;
|
|
56
53
|
let nativeTokensToBuy = new BigNumber(callNativeTokenInResult1.calculatedQuantity);
|
|
57
54
|
const nativeToken = sale.fetchNativeTokenInstanceKey();
|
|
58
55
|
const memeToken = sale.fetchSellingTokenInstanceKey();
|
|
@@ -62,6 +59,7 @@ export async function buyExactToken(
|
|
|
62
59
|
buyTokenDTO.tokenQuantity = tokenLeftInVault;
|
|
63
60
|
const callNativeTokenInResult2 = await callNativeTokenIn(ctx, buyTokenDTO);
|
|
64
61
|
nativeTokensToBuy = new BigNumber(callNativeTokenInResult2.calculatedQuantity);
|
|
62
|
+
transactionFees = callNativeTokenInResult2.extraFees.transactionFees;
|
|
65
63
|
isSaleFinalized = true;
|
|
66
64
|
}
|
|
67
65
|
|
|
@@ -81,6 +79,19 @@ export async function buyExactToken(
|
|
|
81
79
|
);
|
|
82
80
|
}
|
|
83
81
|
|
|
82
|
+
// Transfer transaction fees
|
|
83
|
+
const launchpadFeeAddressConfiguration = await fetchLaunchpadFeeAddress(ctx);
|
|
84
|
+
if (launchpadFeeAddressConfiguration && transactionFees) {
|
|
85
|
+
await transferToken(ctx, {
|
|
86
|
+
from: ctx.callingUser,
|
|
87
|
+
to: launchpadFeeAddressConfiguration.feeAddress,
|
|
88
|
+
tokenInstanceKey: nativeToken,
|
|
89
|
+
quantity: new BigNumber(transactionFees),
|
|
90
|
+
allowancesToUse: [],
|
|
91
|
+
authorizedOnBehalf: undefined
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
84
95
|
// Transfer native tokens from the buyer to the vault
|
|
85
96
|
await transferToken(ctx, {
|
|
86
97
|
from: ctx.callingUser,
|
|
@@ -117,6 +128,7 @@ export async function buyExactToken(
|
|
|
117
128
|
const token = await fetchTokenClass(ctx, sale.sellingToken);
|
|
118
129
|
return {
|
|
119
130
|
inputQuantity: nativeTokensToBuy.toFixed(),
|
|
131
|
+
totalFees: transactionFees,
|
|
120
132
|
outputQuantity: buyTokenDTO.tokenQuantity.toFixed(),
|
|
121
133
|
tokenName: token.name,
|
|
122
134
|
tradeType: "Buy",
|
|
@@ -13,19 +13,15 @@
|
|
|
13
13
|
* limitations under the License.
|
|
14
14
|
*/
|
|
15
15
|
import { GalaChainContext, fetchTokenClass, putChainObject, transferToken } from "@gala-chain/chaincode";
|
|
16
|
-
import
|
|
16
|
+
import BigNumber from "bignumber.js";
|
|
17
17
|
|
|
18
18
|
import { ExactTokenQuantityDto, LaunchpadSale, NativeTokenQuantityDto, TradeResDto } from "../../api/types";
|
|
19
19
|
import { SlippageToleranceExceededError } from "../../api/utils/error";
|
|
20
|
-
import { fetchAndValidateSale } from "../utils";
|
|
20
|
+
import { fetchAndValidateSale, fetchLaunchpadFeeAddress } from "../utils";
|
|
21
21
|
import { callMemeTokenOut } from "./callMemeTokenOut";
|
|
22
22
|
import { callNativeTokenIn } from "./callNativeTokenIn";
|
|
23
23
|
import { finalizeSale } from "./finaliseSale";
|
|
24
24
|
|
|
25
|
-
BigNumber.config({
|
|
26
|
-
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
27
|
-
});
|
|
28
|
-
|
|
29
25
|
/**
|
|
30
26
|
* Executes the purchase of tokens using a specified amount of native tokens.
|
|
31
27
|
*
|
|
@@ -49,22 +45,30 @@ export async function buyWithNative(
|
|
|
49
45
|
buyTokenDTO: NativeTokenQuantityDto
|
|
50
46
|
): Promise<TradeResDto> {
|
|
51
47
|
let isSaleFinalized = false;
|
|
48
|
+
|
|
49
|
+
// Fetch and validate sale state
|
|
52
50
|
const sale = await fetchAndValidateSale(ctx, buyTokenDTO.vaultAddress);
|
|
53
51
|
const tokensLeftInVault = new BigNumber(sale.sellingTokenQuantity);
|
|
52
|
+
|
|
53
|
+
// Calculate how many tokens the user can buy and fee info
|
|
54
54
|
const callMemeTokenOutResult = await callMemeTokenOut(ctx, buyTokenDTO);
|
|
55
|
+
let transactionFees = callMemeTokenOutResult.extraFees.transactionFees;
|
|
55
56
|
let tokensToBuy = new BigNumber(callMemeTokenOutResult.calculatedQuantity);
|
|
56
57
|
|
|
57
58
|
const nativeToken = sale.fetchNativeTokenInstanceKey();
|
|
58
59
|
const memeToken = sale.fetchSellingTokenInstanceKey();
|
|
59
60
|
|
|
61
|
+
// If vault has fewer tokens than what user wants to buy, cap the purchase
|
|
60
62
|
if (tokensLeftInVault.comparedTo(tokensToBuy) <= 0) {
|
|
61
63
|
tokensToBuy = tokensLeftInVault;
|
|
62
64
|
const nativeTokensrequiredToBuyDto = new ExactTokenQuantityDto(buyTokenDTO.vaultAddress, tokensToBuy);
|
|
63
65
|
const callNativeTokenInResult = await callNativeTokenIn(ctx, nativeTokensrequiredToBuyDto);
|
|
66
|
+
transactionFees = callMemeTokenOutResult.extraFees.transactionFees;
|
|
64
67
|
buyTokenDTO.nativeTokenQuantity = new BigNumber(callNativeTokenInResult.calculatedQuantity);
|
|
65
68
|
isSaleFinalized = true;
|
|
66
69
|
}
|
|
67
70
|
|
|
71
|
+
// Finalize sale if market cap is reached
|
|
68
72
|
if (
|
|
69
73
|
buyTokenDTO.nativeTokenQuantity
|
|
70
74
|
.plus(new BigNumber(sale.nativeTokenQuantity))
|
|
@@ -72,12 +76,27 @@ export async function buyWithNative(
|
|
|
72
76
|
)
|
|
73
77
|
isSaleFinalized = true;
|
|
74
78
|
|
|
79
|
+
// Check for slippage condition
|
|
75
80
|
if (buyTokenDTO.expectedToken && buyTokenDTO.expectedToken.comparedTo(tokensToBuy) > 0) {
|
|
76
81
|
throw new SlippageToleranceExceededError(
|
|
77
82
|
"Tokens expected from this operation are more than the the actual amount that will be provided."
|
|
78
83
|
);
|
|
79
84
|
}
|
|
80
85
|
|
|
86
|
+
// Transfer transaction fees to launchpad fee address
|
|
87
|
+
const launchpadFeeAddressConfiguration = await fetchLaunchpadFeeAddress(ctx);
|
|
88
|
+
if (launchpadFeeAddressConfiguration && transactionFees) {
|
|
89
|
+
await transferToken(ctx, {
|
|
90
|
+
from: ctx.callingUser,
|
|
91
|
+
to: launchpadFeeAddressConfiguration.feeAddress,
|
|
92
|
+
tokenInstanceKey: nativeToken,
|
|
93
|
+
quantity: new BigNumber(transactionFees),
|
|
94
|
+
allowancesToUse: [],
|
|
95
|
+
authorizedOnBehalf: undefined
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Transfer native tokens from buyer to vault
|
|
81
100
|
await transferToken(ctx, {
|
|
82
101
|
from: ctx.callingUser,
|
|
83
102
|
to: buyTokenDTO.vaultAddress,
|
|
@@ -87,6 +106,7 @@ export async function buyWithNative(
|
|
|
87
106
|
authorizedOnBehalf: undefined
|
|
88
107
|
});
|
|
89
108
|
|
|
109
|
+
// Transfer meme tokens from vault to buyer
|
|
90
110
|
await transferToken(ctx, {
|
|
91
111
|
from: buyTokenDTO.vaultAddress,
|
|
92
112
|
to: ctx.callingUser,
|
|
@@ -99,9 +119,11 @@ export async function buyWithNative(
|
|
|
99
119
|
}
|
|
100
120
|
});
|
|
101
121
|
|
|
122
|
+
// Update sale object with purchase data
|
|
102
123
|
sale.buyToken(tokensToBuy, buyTokenDTO.nativeTokenQuantity);
|
|
103
124
|
await putChainObject(ctx, sale);
|
|
104
125
|
|
|
126
|
+
// Finalize sale if it's complete
|
|
105
127
|
if (isSaleFinalized) {
|
|
106
128
|
await finalizeSale(ctx, sale);
|
|
107
129
|
}
|
|
@@ -109,6 +131,7 @@ export async function buyWithNative(
|
|
|
109
131
|
const token = await fetchTokenClass(ctx, sale.sellingToken);
|
|
110
132
|
return {
|
|
111
133
|
inputQuantity: buyTokenDTO.nativeTokenQuantity.toFixed(),
|
|
134
|
+
totalFees: transactionFees,
|
|
112
135
|
outputQuantity: tokensToBuy.toFixed(),
|
|
113
136
|
tokenName: token.name,
|
|
114
137
|
tradeType: "Buy",
|
|
@@ -14,16 +14,12 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { ValidationFailedError } from "@gala-chain/api";
|
|
16
16
|
import { GalaChainContext } from "@gala-chain/chaincode";
|
|
17
|
-
import
|
|
17
|
+
import BigNumber from "bignumber.js";
|
|
18
18
|
import Decimal from "decimal.js";
|
|
19
19
|
|
|
20
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
|
-
});
|
|
21
|
+
import { fetchAndValidateSale, fetchLaunchpadFeeAddress, getBondingConstants } from "../utils";
|
|
22
|
+
import { calculateReverseBondingCurveFee, calculateTransactionFee } from "./fees";
|
|
27
23
|
|
|
28
24
|
function calculateMemeTokensRequired(sale: LaunchpadSale, requestedNativeTokenQuantity: BigNumber) {
|
|
29
25
|
const totalTokensSold = new Decimal(sale.fetchTokensSold()); // current tokens sold / x
|
|
@@ -72,11 +68,16 @@ function calculateMemeTokensRequired(sale: LaunchpadSale, requestedNativeTokenQu
|
|
|
72
68
|
*/
|
|
73
69
|
export async function callMemeTokenIn(ctx: GalaChainContext, sellTokenDTO: NativeTokenQuantityDto) {
|
|
74
70
|
const sale = await fetchAndValidateSale(ctx, sellTokenDTO.vaultAddress);
|
|
71
|
+
const launchpadFeeAddressConfiguration = await fetchLaunchpadFeeAddress(ctx);
|
|
75
72
|
|
|
76
73
|
return {
|
|
77
74
|
calculatedQuantity: calculateMemeTokensRequired(sale, sellTokenDTO.nativeTokenQuantity),
|
|
78
75
|
extraFees: {
|
|
79
|
-
reverseBondingCurve: calculateReverseBondingCurveFee(sale, sellTokenDTO.nativeTokenQuantity).toString()
|
|
76
|
+
reverseBondingCurve: calculateReverseBondingCurveFee(sale, sellTokenDTO.nativeTokenQuantity).toString(),
|
|
77
|
+
transactionFees: calculateTransactionFee(
|
|
78
|
+
sellTokenDTO.nativeTokenQuantity,
|
|
79
|
+
launchpadFeeAddressConfiguration?.feeAmount
|
|
80
|
+
)
|
|
80
81
|
}
|
|
81
82
|
};
|
|
82
83
|
}
|
|
@@ -13,15 +13,12 @@
|
|
|
13
13
|
* limitations under the License.
|
|
14
14
|
*/
|
|
15
15
|
import { GalaChainContext } from "@gala-chain/chaincode";
|
|
16
|
-
import
|
|
16
|
+
import BigNumber from "bignumber.js";
|
|
17
17
|
import Decimal from "decimal.js";
|
|
18
18
|
|
|
19
19
|
import { LaunchpadSale, NativeTokenQuantityDto } from "../../api/types";
|
|
20
|
-
import { fetchAndValidateSale, getBondingConstants } from "../utils";
|
|
21
|
-
|
|
22
|
-
BigNumber.config({
|
|
23
|
-
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
24
|
-
});
|
|
20
|
+
import { fetchAndValidateSale, fetchLaunchpadFeeAddress, getBondingConstants } from "../utils";
|
|
21
|
+
import { calculateTransactionFee } from "./fees";
|
|
25
22
|
|
|
26
23
|
/**
|
|
27
24
|
* Calculates the number of tokens that can be purchased using a specified amount
|
|
@@ -71,10 +68,15 @@ export async function callMemeTokenOut(ctx: GalaChainContext, buyTokenDTO: Nativ
|
|
|
71
68
|
roundedResult = new Decimal("1e+7").minus(new Decimal(totalTokensSold));
|
|
72
69
|
}
|
|
73
70
|
|
|
71
|
+
const launchpadFeeAddressConfiguration = await fetchLaunchpadFeeAddress(ctx);
|
|
74
72
|
return {
|
|
75
73
|
calculatedQuantity: roundedResult.toFixed(),
|
|
76
74
|
extraFees: {
|
|
77
|
-
reverseBondingCurve: "0"
|
|
75
|
+
reverseBondingCurve: "0",
|
|
76
|
+
transactionFees: calculateTransactionFee(
|
|
77
|
+
BigNumber(nativeTokens.toFixed()),
|
|
78
|
+
launchpadFeeAddressConfiguration?.feeAmount
|
|
79
|
+
)
|
|
78
80
|
}
|
|
79
81
|
};
|
|
80
82
|
}
|
|
@@ -13,15 +13,12 @@
|
|
|
13
13
|
* limitations under the License.
|
|
14
14
|
*/
|
|
15
15
|
import { GalaChainContext } from "@gala-chain/chaincode";
|
|
16
|
-
import
|
|
16
|
+
import BigNumber from "bignumber.js";
|
|
17
17
|
import Decimal from "decimal.js";
|
|
18
18
|
|
|
19
19
|
import { ExactTokenQuantityDto } from "../../api/types";
|
|
20
|
-
import { fetchAndValidateSale, getBondingConstants } from "../utils";
|
|
21
|
-
|
|
22
|
-
BigNumber.config({
|
|
23
|
-
ROUNDING_MODE: BigNumber.ROUND_UP
|
|
24
|
-
});
|
|
20
|
+
import { fetchAndValidateSale, fetchLaunchpadFeeAddress, getBondingConstants } from "../utils";
|
|
21
|
+
import { calculateTransactionFee } from "./fees";
|
|
25
22
|
|
|
26
23
|
/**
|
|
27
24
|
* Calculates the amount of native tokens required to purchase a specified amount
|
|
@@ -62,10 +59,16 @@ export async function callNativeTokenIn(ctx: GalaChainContext, buyTokenDTO: Exac
|
|
|
62
59
|
|
|
63
60
|
const price = constantFactor.mul(differenceOfExponentials);
|
|
64
61
|
|
|
62
|
+
const launchpadFeeAddressConfiguration = await fetchLaunchpadFeeAddress(ctx);
|
|
63
|
+
const roundedPrice = price.toDecimalPlaces(8, Decimal.ROUND_UP).toFixed();
|
|
65
64
|
return {
|
|
66
|
-
calculatedQuantity:
|
|
65
|
+
calculatedQuantity: roundedPrice,
|
|
67
66
|
extraFees: {
|
|
68
|
-
reverseBondingCurve: "0"
|
|
67
|
+
reverseBondingCurve: "0",
|
|
68
|
+
transactionFees: calculateTransactionFee(
|
|
69
|
+
BigNumber(roundedPrice),
|
|
70
|
+
launchpadFeeAddressConfiguration?.feeAmount
|
|
71
|
+
)
|
|
69
72
|
}
|
|
70
73
|
};
|
|
71
74
|
}
|
|
@@ -13,16 +13,12 @@
|
|
|
13
13
|
* limitations under the License.
|
|
14
14
|
*/
|
|
15
15
|
import { GalaChainContext } from "@gala-chain/chaincode";
|
|
16
|
-
import
|
|
16
|
+
import BigNumber from "bignumber.js";
|
|
17
17
|
import Decimal from "decimal.js";
|
|
18
18
|
|
|
19
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
|
-
});
|
|
20
|
+
import { fetchAndValidateSale, fetchLaunchpadFeeAddress, getBondingConstants } from "../utils";
|
|
21
|
+
import { calculateReverseBondingCurveFee, calculateTransactionFee } from "./fees";
|
|
26
22
|
|
|
27
23
|
function calculateNativeTokensReceived(sale: LaunchpadSale, tokensToSellBn: BigNumber) {
|
|
28
24
|
const totalTokensSold = new Decimal(sale.fetchTokensSold());
|
|
@@ -72,10 +68,15 @@ function calculateNativeTokensReceived(sale: LaunchpadSale, tokensToSellBn: BigN
|
|
|
72
68
|
export async function callNativeTokenOut(ctx: GalaChainContext, sellTokenDTO: ExactTokenQuantityDto) {
|
|
73
69
|
const sale = await fetchAndValidateSale(ctx, sellTokenDTO.vaultAddress);
|
|
74
70
|
const nativeTokensReceived = calculateNativeTokensReceived(sale, sellTokenDTO.tokenQuantity);
|
|
71
|
+
const launchpadFeeAddressConfiguration = await fetchLaunchpadFeeAddress(ctx);
|
|
75
72
|
return {
|
|
76
73
|
calculatedQuantity: nativeTokensReceived,
|
|
77
74
|
extraFees: {
|
|
78
|
-
reverseBondingCurve: calculateReverseBondingCurveFee(sale, BigNumber(nativeTokensReceived)).toString()
|
|
75
|
+
reverseBondingCurve: calculateReverseBondingCurveFee(sale, BigNumber(nativeTokensReceived)).toString(),
|
|
76
|
+
transactionFees: calculateTransactionFee(
|
|
77
|
+
BigNumber(nativeTokensReceived),
|
|
78
|
+
launchpadFeeAddressConfiguration?.feeAmount
|
|
79
|
+
)
|
|
79
80
|
}
|
|
80
81
|
};
|
|
81
82
|
}
|