Skip to content

Commit

Permalink
update acceptance tests to use new signatures. Create new acceptance… (
Browse files Browse the repository at this point in the history
…#510)

* update acceptance tests to use new signatures.  Create new acceptance test to exercise old create token function signatures

Signed-off-by: lukelee-sl <luke.lee@swirldslabs.com>

* increase fees for account

Signed-off-by: lukelee-sl <luke.lee@swirldslabs.com>

* update description of HTS Precompile V1 test

Signed-off-by: lukelee-sl <luke.lee@swirldslabs.com>

* adjust fees

Signed-off-by: lukelee-sl <luke.lee@swirldslabs.com>

* increase fee for v1 acceptance tests

Signed-off-by: lukelee-sl <luke.lee@swirldslabs.com>

* increase fee for v1 acceptance tests once more

Signed-off-by: lukelee-sl <luke.lee@swirldslabs.com>

* address review comments

Signed-off-by: lukelee-sl <luke.lee@swirldslabs.com>

* refactor tests

Signed-off-by: lukelee-sl <luke.lee@swirldslabs.com>

Signed-off-by: lukelee-sl <luke.lee@swirldslabs.com>
  • Loading branch information
lukelee-sl authored Sep 14, 2022
1 parent c85f187 commit 44c4164
Show file tree
Hide file tree
Showing 19 changed files with 5,629 additions and 48 deletions.
148 changes: 148 additions & 0 deletions packages/server/tests/acceptance/htsPrecompile_v1.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*-
*
* Hedera JSON RPC Relay
*
* Copyright (C) 2022 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

// external resources
import { solidity } from 'ethereum-waffle';
import chai, { expect } from 'chai';

chai.use(solidity);

import { AliasAccount } from '../clients/servicesClient';
import { ethers } from 'ethers';
import ERC20MockJson from '../contracts/contracts_v1/ERC20Mock.json';
import BaseHTSJson from '../contracts/contracts_v1/BaseHTS.json';


describe('HTS Precompile V1 Acceptance Tests', async function () {
this.timeout(240 * 1000); // 240 seconds
const { servicesNode, relay } = global;

const TX_SUCCESS_CODE = 22;

const accounts: AliasAccount[] = [];
let BaseHTSContractAddress;
let HTSTokenContractAddress;
let NftHTSTokenContractAddress;
let baseHTSContract;
let baseHTSContractOwner;
let baseHTSContractReceiverWalletFirst;
let baseHTSContractReceiverWalletSecond;
let HTSTokenWithCustomFeesContractAddress;

this.beforeAll(async () => {
accounts[0] = await servicesNode.createAliasAccount(60, relay.provider);
accounts[1] = await servicesNode.createAliasAccount(15, relay.provider);
accounts[2] = await servicesNode.createAliasAccount(15, relay.provider);

// alow mirror node a 2 full record stream write windows (2 sec) and a buffer to persist setup details
await new Promise(r => setTimeout(r, 5000));

BaseHTSContractAddress = await deployBaseHTSContract();
baseHTSContract = new ethers.Contract(BaseHTSContractAddress, BaseHTSJson.abi, accounts[0].wallet);

baseHTSContractOwner = baseHTSContract;
baseHTSContractReceiverWalletFirst = baseHTSContract.connect(accounts[1].wallet);
baseHTSContractReceiverWalletSecond = baseHTSContract.connect(accounts[2].wallet);
});

async function deployBaseHTSContract() {
const baseHTSFactory = new ethers.ContractFactory(BaseHTSJson.abi, BaseHTSJson.bytecode, accounts[0].wallet);
const baseHTS = await baseHTSFactory.deploy({gasLimit: 10_000_000});
const { contractAddress } = await baseHTS.deployTransaction.wait();

return contractAddress;
}

async function createHTSToken() {
const baseHTSContract = new ethers.Contract(BaseHTSContractAddress, BaseHTSJson.abi, accounts[0].wallet);
const tx = await baseHTSContract.createFungibleTokenPublic(accounts[0].wallet.address, {
value: ethers.BigNumber.from('10000000000000000000'),
gasLimit: 1_000_000
});
const { tokenAddress } = (await tx.wait()).events.filter(e => e.event = 'CreatedToken')[0].args;

return tokenAddress;
}

async function createNftHTSToken() {
const baseHTSContract = new ethers.Contract(BaseHTSContractAddress, BaseHTSJson.abi, accounts[0].wallet);
const tx = await baseHTSContract.createNonFungibleTokenPublic(accounts[0].wallet.address, {
value: ethers.BigNumber.from('10000000000000000000'),
gasLimit: 1_000_000
});
const { tokenAddress } = (await tx.wait()).events.filter(e => e.event = 'CreatedToken')[0].args;

return tokenAddress;
}

async function createHTSTokenWithCustomFees() {
const baseHTSContract = new ethers.Contract(BaseHTSContractAddress, BaseHTSJson.abi, accounts[0].wallet);
const tx = await baseHTSContract.createFungibleTokenWithCustomFeesPublic(accounts[0].wallet.address, HTSTokenContractAddress, {
value: ethers.BigNumber.from('20000000000000000000'),
gasLimit: 1_000_000
});
const txReceipt = await tx.wait();
const { tokenAddress } = txReceipt.events.filter(e => e.event === 'CreatedToken')[0].args;

return tokenAddress;
}

it('should create associate to a fungible token', async function() {
HTSTokenContractAddress = await createHTSToken();

const txCO = await baseHTSContractOwner.associateTokenPublic(BaseHTSContractAddress, HTSTokenContractAddress, { gasLimit: 1_000_000 });
expect((await txCO.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE);

const txRWF = await baseHTSContractReceiverWalletFirst.associateTokenPublic(accounts[1].wallet.address, HTSTokenContractAddress, { gasLimit: 1_000_000 });
expect((await txRWF.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE);

const txRWS = await baseHTSContractReceiverWalletSecond.associateTokenPublic(accounts[2].wallet.address, HTSTokenContractAddress, { gasLimit: 1_000_000 });
expect((await txRWS.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE);
});

it('should create and associate to an nft', async function() {
NftHTSTokenContractAddress = await createNftHTSToken();

const txCO = await baseHTSContractOwner.associateTokenPublic(BaseHTSContractAddress, NftHTSTokenContractAddress, { gasLimit: 1_000_000 });
expect((await txCO.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE);

const txRWF = await baseHTSContractReceiverWalletFirst.associateTokenPublic(accounts[1].wallet.address, NftHTSTokenContractAddress, { gasLimit: 1_000_000 });
expect((await txRWF.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE);

const txRWS = await baseHTSContractReceiverWalletSecond.associateTokenPublic(accounts[2].wallet.address, NftHTSTokenContractAddress, { gasLimit: 1_000_000 });
expect((await txRWS.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE);
});

it('should create and associate to a fungible token with custom fees', async function() {
HTSTokenWithCustomFeesContractAddress = await createHTSTokenWithCustomFees();

const baseHTSContractOwner = new ethers.Contract(BaseHTSContractAddress, BaseHTSJson.abi, accounts[0].wallet);
const txCO = await baseHTSContractOwner.associateTokenPublic(BaseHTSContractAddress, HTSTokenWithCustomFeesContractAddress, { gasLimit: 1_000_000 });
expect((await txCO.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE);

const baseHTSContractReceiverWalletFirst = new ethers.Contract(BaseHTSContractAddress, BaseHTSJson.abi, accounts[1].wallet);
const txRWF = await baseHTSContractReceiverWalletFirst.associateTokenPublic(accounts[1].wallet.address, HTSTokenWithCustomFeesContractAddress, { gasLimit: 1_000_000 });
expect((await txRWF.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE);

const baseHTSContractReceiverWalletSecond = new ethers.Contract(BaseHTSContractAddress, BaseHTSJson.abi, accounts[2].wallet);
const txRWS = await baseHTSContractReceiverWalletSecond.associateTokenPublic(accounts[2].wallet.address, HTSTokenWithCustomFeesContractAddress, { gasLimit: 1_000_000 });
expect((await txRWS.wait()).events.filter(e => e.event === 'ResponseCode')[0].args.responseCode).to.equal(TX_SUCCESS_CODE);
});
});
28 changes: 14 additions & 14 deletions packages/server/tests/contracts/BaseHTS.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions packages/server/tests/contracts/BaseHTS.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ contract BaseHTS is FeeHelper {
string name = "tokenName";
string symbol = "tokenSymbol";
string memo = "memo";
uint initialTotalSupply = 1000;
uint32 maxSupply = 1000;
uint decimals = 8;
uint64 initialTotalSupply = 1000;
int64 maxSupply = 1000;
uint32 decimals = 8;
bool freezeDefaultStatus = false;

event CreatedToken(address tokenAddress);
Expand Down
8 changes: 4 additions & 4 deletions packages/server/tests/contracts/HederaTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ abstract contract HederaTokenService is HederaResponseCodes {
/// @return tokenAddress the created token's address
function createFungibleToken(
IHederaTokenService.HederaToken memory token,
uint initialTotalSupply,
uint decimals) nonEmptyExpiry(token)
uint64 initialTotalSupply,
uint32 decimals) nonEmptyExpiry(token)
internal returns (int responseCode, address tokenAddress) {
(bool success, bytes memory result) = precompileAddress.call{value: msg.value}(
abi.encodeWithSelector(IHederaTokenService.createFungibleToken.selector,
Expand All @@ -176,8 +176,8 @@ abstract contract HederaTokenService is HederaResponseCodes {
/// @return tokenAddress the created token's address
function createFungibleTokenWithCustomFees(
IHederaTokenService.HederaToken memory token,
uint initialTotalSupply,
uint decimals,
uint64 initialTotalSupply,
uint32 decimals,
IHederaTokenService.FixedFee[] memory fixedFees,
IHederaTokenService.FractionalFee[] memory fractionalFees) nonEmptyExpiry(token)
internal returns (int responseCode, address tokenAddress) {
Expand Down
44 changes: 22 additions & 22 deletions packages/server/tests/contracts/IHederaTokenService.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,9 @@
"type": "bool"
},
{
"internalType": "uint32",
"internalType": "int64",
"name": "maxSupply",
"type": "uint32"
"type": "int64"
},
{
"internalType": "bool",
Expand Down Expand Up @@ -288,14 +288,14 @@
"type": "tuple"
},
{
"internalType": "uint256",
"internalType": "uint64",
"name": "initialTotalSupply",
"type": "uint256"
"type": "uint64"
},
{
"internalType": "uint256",
"internalType": "uint32",
"name": "decimals",
"type": "uint256"
"type": "uint32"
}
],
"name": "createFungibleToken",
Expand Down Expand Up @@ -344,9 +344,9 @@
"type": "bool"
},
{
"internalType": "uint32",
"internalType": "int64",
"name": "maxSupply",
"type": "uint32"
"type": "int64"
},
{
"internalType": "bool",
Expand Down Expand Up @@ -425,14 +425,14 @@
"type": "tuple"
},
{
"internalType": "uint256",
"internalType": "uint64",
"name": "initialTotalSupply",
"type": "uint256"
"type": "uint64"
},
{
"internalType": "uint256",
"internalType": "uint32",
"name": "decimals",
"type": "uint256"
"type": "uint32"
},
{
"components": [
Expand Down Expand Up @@ -550,9 +550,9 @@
"type": "bool"
},
{
"internalType": "uint32",
"internalType": "int64",
"name": "maxSupply",
"type": "uint32"
"type": "int64"
},
{
"internalType": "bool",
Expand Down Expand Up @@ -677,9 +677,9 @@
"type": "bool"
},
{
"internalType": "uint32",
"internalType": "int64",
"name": "maxSupply",
"type": "uint32"
"type": "int64"
},
{
"internalType": "bool",
Expand Down Expand Up @@ -1075,9 +1075,9 @@
"type": "bool"
},
{
"internalType": "uint32",
"internalType": "int64",
"name": "maxSupply",
"type": "uint32"
"type": "int64"
},
{
"internalType": "bool",
Expand Down Expand Up @@ -1357,9 +1357,9 @@
"type": "bool"
},
{
"internalType": "uint32",
"internalType": "int64",
"name": "maxSupply",
"type": "uint32"
"type": "int64"
},
{
"internalType": "bool",
Expand Down Expand Up @@ -1866,9 +1866,9 @@
"type": "bool"
},
{
"internalType": "uint32",
"internalType": "int64",
"name": "maxSupply",
"type": "uint32"
"type": "int64"
},
{
"internalType": "bool",
Expand Down
10 changes: 5 additions & 5 deletions packages/server/tests/contracts/IHederaTokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ interface IHederaTokenService {
// IWA Compatibility. Depends on TokenSupplyType. For tokens of type FUNGIBLE_COMMON - the
// maximum number of tokens that can be in circulation. For tokens of type NON_FUNGIBLE_UNIQUE -
// the maximum number of NFTs (serial numbers) that can be minted. This field can never be changed!
uint32 maxSupply;
int64 maxSupply;

// The default Freeze status (frozen or unfrozen) of Hedera accounts relative to this token. If
// true, an account must be unfrozen before it can receive the token
Expand Down Expand Up @@ -359,8 +359,8 @@ interface IHederaTokenService {
/// @return tokenAddress the created token's address
function createFungibleToken(
HederaToken memory token,
uint initialTotalSupply,
uint decimals)
uint64 initialTotalSupply,
uint32 decimals)
external payable returns (int responseCode, address tokenAddress);

/// Creates a Fungible Token with the specified properties
Expand All @@ -374,8 +374,8 @@ interface IHederaTokenService {
/// @return tokenAddress the created token's address
function createFungibleTokenWithCustomFees(
HederaToken memory token,
uint initialTotalSupply,
uint decimals,
uint64 initialTotalSupply,
uint32 decimals,
FixedFee[] memory fixedFees,
FractionalFee[] memory fractionalFees)
external payable returns (int responseCode, address tokenAddress);
Expand Down
Loading

0 comments on commit 44c4164

Please sign in to comment.