Skip to content

Commit 0ccb911

Browse files
committed
fix(tests): contract-keyed treasury for Token Management tokens
Signed-off-by: ValentinVPK <valentin.krumov@limechain.tech>
1 parent 4586961 commit 0ccb911

2 files changed

Lines changed: 70 additions & 48 deletions

File tree

test/token-service/token-managment/tokenManagmentContract.js

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ describe('TokenManagmentContract Test Suite', function () {
3636
let holderC;
3737
let holderT;
3838
let holderS;
39-
let holderAccountIdS;
4039
let tokenCreateCustomContractAddress;
4140
let tokenCreateContractAddress;
4241
let tokenTransferContractAddress;
@@ -130,18 +129,18 @@ describe('TokenManagmentContract Test Suite', function () {
130129
holderT = ethers.getAddress(
131130
(await hapi.createAccountWithContractIdKey(contractKeys)).address,
132131
);
133-
// Holds the main suite's supply: the treasury is signers[0] (one test
134-
// asserts that burning reduces the treasury balance) and the contracts
135-
// cannot debit it, so a seeded contract-keyed account is the source of every
136-
// transfer the tests make.
137-
const holderAccountS =
138-
await hapi.createAccountWithContractIdKey(contractKeys);
139-
holderAccountIdS = holderAccountS.accountId;
140-
holderS = ethers.getAddress(holderAccountS.address);
132+
// Treasury of the main suite's tokens. It has to be an account the
133+
// contracts may act for: updateTokenInfo carries the treasury field and so
134+
// needs its authorization, and it is the source of every transfer the tests
135+
// make. signers[0] can be neither now that it is not re-keyed, so it only
136+
// signs token creates (as the admin key) and pays for every transaction.
137+
holderS = ethers.getAddress(
138+
(await hapi.createAccountWithContractIdKey(contractKeys)).address,
139+
);
141140
erc20Contract = await utils.deployERC20Contract();
142141
tokenAddress = await utils.createFungibleTokenWithSECP256K1AdminKey(
143142
tokenCreateContract,
144-
signers[0].address,
143+
holderS,
145144
utils.getSignerCompressedPublicKey(),
146145
);
147146
await hapi.updateTokenKeys(tokenAddress, [
@@ -152,7 +151,7 @@ describe('TokenManagmentContract Test Suite', function () {
152151
]);
153152
nftTokenAddress = await utils.createNonFungibleTokenWithSECP256K1AdminKey(
154153
tokenCreateContract,
155-
signers[0].address,
154+
holderS,
156155
utils.getSignerCompressedPublicKey(),
157156
);
158157
await hapi.updateTokenKeys(nftTokenAddress, [
@@ -182,21 +181,15 @@ describe('TokenManagmentContract Test Suite', function () {
182181
// keys include it), then seeded from the treasury with a native transfer
183182
// signers[0] signs itself — the contracts cannot debit the treasury.
184183
await utils.associateAndGrantKyc(tokenCreateContract, tokenAddress, [
185-
holderS,
186184
holderA,
187185
holderB,
188186
holderC,
189187
]);
190188
await utils.associateAndGrantKyc(tokenCreateContract, nftTokenAddress, [
191-
holderS,
192189
holderA,
193190
holderB,
194191
holderC,
195192
]);
196-
await hapi.transferFromSigner(0, holderAccountIdS, {
197-
tokens: [{ token: tokenAddress, amount: 100000 }],
198-
nfts: [{ token: nftTokenAddress, serials: [mintedTokenSerialNumber] }],
199-
});
200193
});
201194

202195
after(function () {
@@ -207,7 +200,7 @@ describe('TokenManagmentContract Test Suite', function () {
207200
const newTokenAddress =
208201
await utils.createFungibleTokenWithSECP256K1AdminKey(
209202
tokenCreateContract,
210-
signers[0].address,
203+
holderS,
211204
utils.getSignerCompressedPublicKey(),
212205
);
213206
await hapi.updateTokenKeys(newTokenAddress, [
@@ -406,7 +399,7 @@ describe('TokenManagmentContract Test Suite', function () {
406399
name: TOKEN_UPDATE_NAME,
407400
symbol: TOKEN_UPDATE_SYMBOL,
408401
memo: TOKEN_UPDATE_MEMO,
409-
treasury: signers[0].address, // treasury has to be the signing account,
402+
treasury: holderS, // must be an account the contract may act for
410403
tokenSupplyType: tokenInfoBefore.tokenSupplyType,
411404
maxSupply: tokenInfoBefore.maxSupply,
412405
freezeDefault: tokenInfoBefore.freezeDefault,
@@ -567,16 +560,13 @@ describe('TokenManagmentContract Test Suite', function () {
567560
it('should be able to burn token', async function () {
568561
const amount = BigInt(111);
569562
const totalSupplyBefore = await erc20Contract.totalSupply(tokenAddress);
570-
const balanceBefore = await erc20Contract.balanceOf(
571-
tokenAddress,
572-
signers[0].address,
573-
);
563+
const balanceBefore = await erc20Contract.balanceOf(tokenAddress, holderS);
574564
await tokenManagmentContract.burnTokenPublic(tokenAddress, amount, []);
575565

576566
const balanceAfter = await pollForNewERC20Balance(
577567
erc20Contract,
578568
tokenAddress,
579-
signers[0].address,
569+
holderS,
580570
balanceBefore,
581571
);
582572
const totalSupplyAfter = await erc20Contract.totalSupply(tokenAddress);
@@ -708,7 +698,7 @@ describe('TokenManagmentContract Test Suite', function () {
708698
before(async function () {
709699
tokenAddress = await utils.createFungibleTokenWithSECP256K1AdminKey(
710700
tokenCreateContract,
711-
signers[0].address,
701+
holderS,
712702
utils.getSignerCompressedPublicKey(),
713703
);
714704
await hapi.updateTokenKeys(tokenAddress, [
@@ -725,6 +715,13 @@ describe('TokenManagmentContract Test Suite', function () {
725715
Constants.Contract.TokenCreateContract,
726716
);
727717
await utils.grantTokenKyc(tokenCreateContract, tokenAddress);
718+
// These blocks replace the shared token, so the holders have to be
719+
// associated to the new one as well — utils.associateToken only reaches
720+
// the contract itself now.
721+
await utils.associateAndGrantKyc(tokenCreateContract, tokenAddress, [
722+
holderA,
723+
holderB,
724+
]);
728725
});
729726

730727
it('should be able to change PAUSE key to contractId and pause the token with same contract', async function () {
@@ -740,7 +737,7 @@ describe('TokenManagmentContract Test Suite', function () {
740737
name: tokenInfoBefore.name,
741738
symbol: tokenInfoBefore.symbol,
742739
memo: tokenInfoBefore.memo,
743-
treasury: signers[0].address, // treasury has to be the signing account,
740+
treasury: holderS, // must be an account the contract may act for
744741
tokenSupplyType: tokenInfoBefore.tokenSupplyType,
745742
maxSupply: tokenInfoBefore.maxSupply,
746743
freezeDefault: tokenInfoBefore.freezeDefault,
@@ -802,7 +799,7 @@ describe('TokenManagmentContract Test Suite', function () {
802799
name: tokenInfoBefore.name,
803800
symbol: tokenInfoBefore.symbol,
804801
memo: tokenInfoBefore.memo,
805-
treasury: signers[0].address, // treasury has to be the signing account,
802+
treasury: holderS, // must be an account the contract may act for
806803
tokenSupplyType: tokenInfoBefore.tokenSupplyType,
807804
maxSupply: tokenInfoBefore.maxSupply,
808805
freezeDefault: tokenInfoBefore.freezeDefault,
@@ -814,7 +811,7 @@ describe('TokenManagmentContract Test Suite', function () {
814811
},
815812
};
816813

817-
tokenAfter.treasury = signers[0].address;
814+
tokenAfter.treasury = holderS;
818815
await updateTokenInfo(
819816
tokenManagmentContract,
820817
tokenAddress,
@@ -848,7 +845,7 @@ describe('TokenManagmentContract Test Suite', function () {
848845
name: tokenInfoBefore.name,
849846
symbol: tokenInfoBefore.symbol,
850847
memo: tokenInfoBefore.memo,
851-
treasury: signers[0].address, // treasury has to be the signing account,
848+
treasury: holderS, // must be an account the contract may act for
852849
tokenSupplyType: tokenInfoBefore.tokenSupplyType,
853850
maxSupply: tokenInfoBefore.maxSupply,
854851
freezeDefault: tokenInfoBefore.freezeDefault,
@@ -909,7 +906,7 @@ describe('TokenManagmentContract Test Suite', function () {
909906
name: tokenInfoBefore.name,
910907
symbol: tokenInfoBefore.symbol,
911908
memo: tokenInfoBefore.memo,
912-
treasury: signers[0].address, // treasury has to be the signing account,
909+
treasury: holderS, // must be an account the contract may act for
913910
tokenSupplyType: tokenInfoBefore.tokenSupplyType,
914911
maxSupply: tokenInfoBefore.maxSupply,
915912
freezeDefault: tokenInfoBefore.freezeDefault,
@@ -921,7 +918,7 @@ describe('TokenManagmentContract Test Suite', function () {
921918
},
922919
};
923920

924-
tokenAfter.treasury = signers[0].address;
921+
tokenAfter.treasury = holderS;
925922
await updateTokenInfo(
926923
tokenManagmentContract,
927924
tokenAddress,
@@ -960,7 +957,7 @@ describe('TokenManagmentContract Test Suite', function () {
960957
name: tokenInfoBefore.name,
961958
symbol: tokenInfoBefore.symbol,
962959
memo: tokenInfoBefore.memo,
963-
treasury: signers[0].address, // treasury has to be the signing account,
960+
treasury: holderS, // must be an account the contract may act for
964961
tokenSupplyType: tokenInfoBefore.tokenSupplyType,
965962
maxSupply: tokenInfoBefore.maxSupply,
966963
freezeDefault: tokenInfoBefore.freezeDefault,
@@ -972,7 +969,7 @@ describe('TokenManagmentContract Test Suite', function () {
972969
},
973970
};
974971

975-
token.treasury = signers[0].address;
972+
token.treasury = holderS;
976973

977974
await updateTokenInfo(tokenManagmentContract, tokenAddress, token);
978975
}
@@ -1037,7 +1034,7 @@ describe('TokenManagmentContract Test Suite', function () {
10371034
name: tokenInfoBefore.name,
10381035
symbol: tokenInfoBefore.symbol,
10391036
memo: tokenInfoBefore.memo,
1040-
treasury: signers[0].address, // treasury has to be the signing account,
1037+
treasury: holderS, // must be an account the contract may act for
10411038
tokenSupplyType: tokenInfoBefore.tokenSupplyType,
10421039
maxSupply: tokenInfoBefore.maxSupply,
10431040
freezeDefault: tokenInfoBefore.freezeDefault,
@@ -1049,7 +1046,7 @@ describe('TokenManagmentContract Test Suite', function () {
10491046
},
10501047
};
10511048

1052-
tokenAfter.treasury = signers[0].address;
1049+
tokenAfter.treasury = holderS;
10531050
await updateTokenInfo(
10541051
tokenManagmentContract,
10551052
tokenAddress,
@@ -1091,7 +1088,7 @@ describe('TokenManagmentContract Test Suite', function () {
10911088
name: tokenInfoBefore.name,
10921089
symbol: tokenInfoBefore.symbol,
10931090
memo: tokenInfoBefore.memo,
1094-
treasury: signers[0].address, // treasury has to be the signing account,
1091+
treasury: holderS, // must be an account the contract may act for
10951092
tokenSupplyType: tokenInfoBefore.tokenSupplyType,
10961093
maxSupply: tokenInfoBefore.maxSupply,
10971094
freezeDefault: tokenInfoBefore.freezeDefault,
@@ -1103,7 +1100,7 @@ describe('TokenManagmentContract Test Suite', function () {
11031100
},
11041101
};
11051102

1106-
token.treasury = signers[0].address;
1103+
token.treasury = holderS;
11071104

11081105
await updateTokenInfo(tokenManagmentContract, tokenAddress, token);
11091106
}
@@ -1171,7 +1168,7 @@ describe('TokenManagmentContract Test Suite', function () {
11711168
before(async function () {
11721169
tokenAddress = await utils.createFungibleTokenWithSECP256K1AdminKey(
11731170
tokenCreateContract,
1174-
signers[0].address,
1171+
holderS,
11751172
utils.getSignerCompressedPublicKey(),
11761173
);
11771174

@@ -1191,6 +1188,13 @@ describe('TokenManagmentContract Test Suite', function () {
11911188
);
11921189

11931190
await utils.grantTokenKyc(tokenCreateContract, tokenAddress);
1191+
// This block replaces the shared token, so the holders have to be
1192+
// associated to the new one as well — utils.associateToken only
1193+
// reaches the contract itself now.
1194+
await utils.associateAndGrantKyc(tokenCreateContract, tokenAddress, [
1195+
holderA,
1196+
holderB,
1197+
]);
11941198
});
11951199
describe('Positive', function () {
11961200
it('should be able to change PAUSE key to ECDSA_secp256k and pause the token with the same account', async function () {
@@ -1388,7 +1392,7 @@ describe('TokenManagmentContract Test Suite', function () {
13881392
before(async function () {
13891393
tokenAddress = await utils.createFungibleTokenWithSECP256K1AdminKey(
13901394
tokenCreateContract,
1391-
signers[0].address,
1395+
holderS,
13921396
utils.getSignerCompressedPublicKey(),
13931397
);
13941398
});
@@ -1417,6 +1421,13 @@ describe('TokenManagmentContract Test Suite', function () {
14171421
Constants.Contract.TokenCreateContract,
14181422
);
14191423
await utils.grantTokenKyc(tokenCreateContract, tokenAddress);
1424+
// This block replaces the shared token, so the holders have to be
1425+
// associated to the new one as well — utils.associateToken only
1426+
// reaches the contract itself now.
1427+
await utils.associateAndGrantKyc(tokenCreateContract, tokenAddress, [
1428+
holderA,
1429+
holderB,
1430+
]);
14201431

14211432
await tokenTransferContract.transferTokensPublic(
14221433
tokenAddress,

test/token-service/utils.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,20 @@ class Utils {
108108
}
109109

110110
static async getTokenAddress(tx) {
111-
const receipt = await tx.wait();
111+
let receipt;
112+
try {
113+
receipt = await tx.wait();
114+
} catch (err) {
115+
// [diag] strip once Token Management is green. The create helpers revert
116+
// with no reason, so name the HTS code behind it.
117+
console.log(
118+
'[diag] token create reverted, hts code =',
119+
await Utils.getHTSResponseCode(tx.hash).catch(
120+
(e) => `unavailable (${e.message})`,
121+
),
122+
);
123+
throw err;
124+
}
112125
const { tokenAddress } = receipt.logs.filter(
113126
(e) => e.fragment.name === Constants.Events.CreatedToken,
114127
)[0].args;
@@ -504,19 +517,17 @@ class Utils {
504517
);
505518
}
506519

507-
// KYC can only be granted to an account already associated with the token.
508-
// signers[1] is no longer associated through the contract (that needed the
509-
// account's key to include it), so granting to it reverts — and because these
510-
// calls carry no explicit gas limit, ethers estimates gas first and the revert
511-
// surfaces immediately rather than being swallowed. Callers that need KYC for
512-
// other accounts associate and grant those explicitly.
520+
// Grants KYC to the calling contract only. KYC can only be granted to an
521+
// account already associated with the token, and the signers are no longer
522+
// associated through the contract — that needed their keys to include it.
523+
// These calls carry no explicit gas limit, so ethers estimates gas first and
524+
// any revert surfaces immediately instead of being swallowed. Callers that
525+
// need KYC for other accounts associate and grant those explicitly.
513526
static async grantTokenKyc(contract, tokenAddress) {
514-
const signers = await ethers.getSigners();
515527
await contract.grantTokenKycPublic(
516528
tokenAddress,
517529
await contract.getAddress(),
518530
);
519-
await contract.grantTokenKycPublic(tokenAddress, signers[0].address);
520531
}
521532

522533
// [diag] Walk the error's cause chain and surface the relay's JSON-RPC body /

0 commit comments

Comments
 (0)