diff --git a/README.md b/README.md index d0dfae51..b7e80a22 100644 --- a/README.md +++ b/README.md @@ -205,7 +205,7 @@ import {Hsc} from "hedera-forking/Hsc.sol"; contract CreateTokenScript is Script { uint256 PRIVATE_KEY = vm.envUint("PRIVATE_KEY"); - function run() public { + function run() external returns (int64 responseCode, address tokenAddress) { Hsc.htsSetup(); address signer = vm.addr(PRIVATE_KEY); @@ -232,7 +232,7 @@ contract CreateTokenScript is Script { token.tokenKeys = keys; token.expiry = expiry; - (int64 responseCode, address tokenAddress) = IHederaTokenService(HTS_ADDRESS).createFungibleToken{value: 10 ether}(token, 10000, 4); + (responseCode, tokenAddress) = IHederaTokenService(HTS_ADDRESS).createFungibleToken{value: 10 ether}(token, 10000, 4); console.log("Response code %d", int(responseCode)); console.log("Token address %s", tokenAddress); diff --git a/contracts/Store.sol b/contracts/Store.sol index abf7d144..8487d806 100644 --- a/contracts/Store.sol +++ b/contracts/Store.sol @@ -3,6 +3,19 @@ pragma solidity ^0.8.0; import {Vm} from "forge-std/Vm.sol"; +/** + * @dev This library provides utility functions to store values of different types + * to an address' storage slot. + * + * Values are stored using `vm.store`. + * This allows `view` functions to modify the state. + * Most notably this is used when fetching remote data and + * stored in the address' storage slot before it can be returned. + * + * For types smaller than 32 bytes, + * it support storing them in a non-zero `offset`. + * A non-zero `offset` is used by Solidity to pack many fields into a single storage slot. + */ library Store { Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); @@ -46,7 +59,7 @@ library Store { } function storeInt64(address target, uint256 slot, int64 value) internal { - bytes32 data = bytes32(abi.encodePacked(value)); + bytes32 data = bytes32(uint256(uint64(value))); storeBytes32(target, slot, data); } diff --git a/contracts/Str.sol b/contracts/Str.sol index aa062d2f..51c3bb63 100644 --- a/contracts/Str.sol +++ b/contracts/Str.sol @@ -1,6 +1,17 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.6.0; +/** + * @dev This library provides utility functions that operate on `string`s. + * + * Notice we cannot use the `string.concat` function provided by Solidity because they have changed its signature. + * From https://soliditylang.org/blog/2022/02/16/solidity-0.8.12-release-announcement/ + * + * > General: `string.concat` now properly takes strings as arguments and returns string memory. + * > It was accidentally introduced as a copy of `bytes.concat` before. + * + * Therefore this library provides a `concat` function with support for different arities. + */ library Str { function concat(string memory s1, string memory s2) internal pure returns (string memory) { return string(abi.encodePacked(s1, s2)); diff --git a/contracts/Surl.sol b/contracts/Surl.sol index 8aa5ca65..813ff693 100644 --- a/contracts/Surl.sol +++ b/contracts/Surl.sol @@ -7,12 +7,13 @@ import {Str} from "./Str.sol"; /** * @dev This library provides utility functions originally from the Surl library. * - * The original Surl library can be found at: https://github.com/memester-xyz/surl + * The original Surl library can be found at https://github.com/memester-xyz/surl. * * We have inlined the necessary functionality from Surl instead of using it as a submodule - * to keep dependencies lean and avoid unnecessary submodule cloning. Using Surl as a submodule - * previously required pulling multiple additional dependencies, including an outdated version of - * Foundry (v1.3.0) and other libraries such as forge-std, solidity-stringutils, and ds-test. + * to keep dependencies lean and avoid unnecessary submodule cloning. + * Using Surl as a submodule previously required pulling multiple additional dependencies, + * including an outdated version of Foundry (v1.3.0) and other libraries such as + * `forge-std`, `solidity-stringutils`, and `ds-test`. * * By inlining the required code, we reduce dependency bloat and improve maintainability. */ diff --git a/examples/foundry-hts/script/CreateToken.s.sol b/examples/foundry-hts/script/CreateToken.s.sol index 59f3cfaf..aca02e21 100644 --- a/examples/foundry-hts/script/CreateToken.s.sol +++ b/examples/foundry-hts/script/CreateToken.s.sol @@ -16,7 +16,7 @@ import {Hsc} from "hedera-forking/Hsc.sol"; contract CreateTokenScript is Script { uint256 PRIVATE_KEY = vm.envUint("PRIVATE_KEY"); - function run() public { + function run() external returns (int64 responseCode, address tokenAddress) { Hsc.htsSetup(); address signer = vm.addr(PRIVATE_KEY); @@ -43,7 +43,7 @@ contract CreateTokenScript is Script { token.tokenKeys = keys; token.expiry = expiry; - (int64 responseCode, address tokenAddress) = IHederaTokenService(HTS_ADDRESS).createFungibleToken{value: 10 ether}(token, 10000, 4); + (responseCode, tokenAddress) = IHederaTokenService(HTS_ADDRESS).createFungibleToken{value: 10 ether}(token, 10000, 4); console.log("Response code %d", int(responseCode)); console.log("Token address %s", tokenAddress); diff --git a/test/HTS.t.sol b/test/HTS.t.sol index 92fa2fa0..8c6f1ef2 100644 --- a/test/HTS.t.sol +++ b/test/HTS.t.sol @@ -107,6 +107,13 @@ contract HTSTest is Test, TestSetup { assertEq(tokenInfo.ledgerId, testMode == TestMode.FFI ? "0x01" : "0x00"); } + function test_HTS_getTokenInfo_should_return_token_autoRenewPeriod_for_valid_token() external view { + address token = MFCT; + (int64 responseCode, IHederaTokenService.TokenInfo memory tokenInfo) = IHederaTokenService(HTS_ADDRESS).getTokenInfo(token); + assertEq(responseCode, HederaResponseCodes.SUCCESS); + assertEq(tokenInfo.token.expiry.autoRenewPeriod, 7776000); + } + function test_HTS_getTokenInfo_should_return_custom_fees_for_valid_token() external view { (int64 responseCode, IHederaTokenService.TokenInfo memory tokenInfo) = IHederaTokenService(HTS_ADDRESS).getTokenInfo(CTCF); assertEq(responseCode, HederaResponseCodes.SUCCESS);