Omniscia Swisscoast Audit

HLQTYToken Code Style Findings

HLQTYToken Code Style Findings

HLQ-01C: Deprecated Revert Pattern

TypeSeverityLocation
Code StyleHLQTYToken.sol:L232

Description:

The referenced revert statement is issued with a string argument which has been deprecated.

Example:

packages/contracts/contracts/HLQTY/HLQTYToken.sol
229if (
230 !((_balanceOf(address(this)) - balance) ==
231 amount)
232) revert('The smart contract is not the treasury account');

Recommendation:

We advise a require check with an accompanying message to be introduced, increasing the legibility of the check.

Alleviation (04618e407bddce5b22e9cadd787fd3334bd3afe6):

The referenced if-revert statement has been replaced by a require statement per our recommendation, optimizing its legibility.

HLQ-02C: Inefficient Function Implementation

Description:

The HLQTYToken::_checkResponse function will either successfully execute and yield true, or revert.

Example:

packages/contracts/contracts/HLQTY/HLQTYToken.sol
209function _mint(
210 address account,
211 uint256 amount
212)
213internal
214returns (bool)
215{
216 require(account != address(0), "ERC20: mint to the zero address");
217 require(amount <= uint256(type(int64).max), "Amount exceeds int64 limits");
218
219 int64 safeAmount = int64(amount);
220
221 address currentTokenAddress = _getTokenAddress();
222
223 uint256 balance = _balanceOf(address(this));
224
225 (int responseCode, ,) = HederaTokenService.mintToken(currentTokenAddress, safeAmount, new bytes[](0));
226
227 bool success = _checkResponse(responseCode);
228
229 if (
230 !((_balanceOf(address(this)) - balance) ==
231 amount)
232 ) revert('The smart contract is not the treasury account');
233
234 _transfer(address(this), account, amount);
235
236 emit TokensMinted(msg.sender, currentTokenAddress, safeAmount, account);
237
238 return success;
239}
240
241function _getTokenAddress() internal view returns (address) {
242 return tokenAddress;
243}
244
245function _checkResponse(int responseCode) internal pure returns (bool) {
246 // Using require to check the condition, and provide a custom error message if it fails.
247 require(responseCode == HederaResponseCodes.SUCCESS, "ResponseCodeInvalid: provided code is not success");
248 return true;
249}

Recommendation:

We advise its return variable to be removed, ensuring that it is invoked as a validation function without requiring use of its return argument.

Alleviation (04618e407bddce5b22e9cadd787fd3334bd3afe6):

The HLQTToken::_checkResponse function has been updated to no longer return a variable, addressing this exhibit.

HLQ-03C: Inefficient Negation of Conditional

Description:

The referenced conditional is negated after being evaluated.

Example:

packages/contracts/contracts/HLQTY/HLQTYToken.sol
229if (
230 !((_balanceOf(address(this)) - balance) ==
231 amount)
232) revert('The smart contract is not the treasury account');

Recommendation:

We advise the negation to be incorporated to the comparison itself, adjusting the equality check to an inequality check.

Alleviation (04618e407bddce5b22e9cadd787fd3334bd3afe6):

The negation of the conditional is no longer preformed in its require form, optimizing its gas cost.

HLQ-04C: Potentially Incorrect Token Name / Symbol

TypeSeverityLocation
Code StyleHLQTYToken.sol:L52, L53

Description:

The HLQTY token is represented as HLQT which may be incorrect.

Example:

packages/contracts/contracts/HLQTY/HLQTYToken.sol
52string constant internal _NAME = "HLQT";
53string constant internal _SYMBOL = "HLQT";

Recommendation:

We advise the Swisscoast team to evaluate this exhibit and adjust the names accordingly.

Alleviation (04618e407bddce5b22e9cadd787fd3334bd3afe6):

The contract and corresponding file has been renamed instead, indicating that the HLQT name is the correct one and thus addressing this exhibit.

HLQ-05C: Redundant Function Implementation

Description:

The HLQTYToken::_getTokenAddress function is redundant as the tokenAddress member is readily available throughout the contract.

Example:

packages/contracts/contracts/HLQTY/HLQTYToken.sol
209function _mint(
210 address account,
211 uint256 amount
212)
213internal
214returns (bool)
215{
216 require(account != address(0), "ERC20: mint to the zero address");
217 require(amount <= uint256(type(int64).max), "Amount exceeds int64 limits");
218
219 int64 safeAmount = int64(amount);
220
221 address currentTokenAddress = _getTokenAddress();
222
223 uint256 balance = _balanceOf(address(this));
224
225 (int responseCode, ,) = HederaTokenService.mintToken(currentTokenAddress, safeAmount, new bytes[](0));
226
227 bool success = _checkResponse(responseCode);
228
229 if (
230 !((_balanceOf(address(this)) - balance) ==
231 amount)
232 ) revert('The smart contract is not the treasury account');
233
234 _transfer(address(this), account, amount);
235
236 emit TokensMinted(msg.sender, currentTokenAddress, safeAmount, account);
237
238 return success;
239}
240
241function _getTokenAddress() internal view returns (address) {
242 return tokenAddress;
243}

Recommendation:

We advise the tokenAddress to be utilized directly, optimizing the gas cost of the contract.

Alleviation (04618e407bddce5b22e9cadd787fd3334bd3afe6):

The HLQTToken::_getTokenAddress function has been safely removed, optimizing the bytecode size and gas cost of the contract.

HLQ-06C: Variable Mutability Specifier (Immutable)

Description:

The linked variable is assigned to only once during the contract's constructor.

Example:

packages/contracts/contracts/HLQTY/HLQTYToken.sol
84constructor
85(
86 address _communityIssuanceAddress,
87 address _hlqtyStakingAddress,
88 address _lockupFactoryAddress,
89 address _multisigAddress
90)
91 payable public
92{
93 checkContract(_communityIssuanceAddress);
94 checkContract(_hlqtyStakingAddress);
95 checkContract(_lockupFactoryAddress);
96
97 multisigAddress = _multisigAddress;
98 deploymentStartTime = block.timestamp;
99
100 communityIssuanceAddress = _communityIssuanceAddress;
101 hlqtyStakingAddress = _hlqtyStakingAddress;
102 lockupContractFactory = ILockupContractFactory(_lockupFactoryAddress);
103
104 // --- Deploy Hedera HTS ---
105
106 IHederaTokenService.HederaToken memory token;
107 token.name = _NAME;
108 token.symbol = _SYMBOL;
109 token.treasury = address(this);
110
111 token.expiry = createAutoRenewExpiry(address(this), 8000000);
112
113 IHederaTokenService.TokenKey[] memory keys = new IHederaTokenService.TokenKey[](1);
114 keys[0] = getSingleKey(KeyType.SUPPLY, KeyValueType.INHERIT_ACCOUNT_KEY, bytes(""));
115
116 token.tokenKeys = keys;
117
118 (int responseCode, address createdTokenAddress) =
119 HederaTokenService.createFungibleToken(token, 0, _DECIMALS);
120
121 _checkResponse(responseCode);
122 tokenAddress = createdTokenAddress;
123
124 uint _lpRewardsEntitlement = _1_MILLION.mul(4).div(3); // Allocate 1.33 million for LP rewards
125 lpRewardsEntitlement = _lpRewardsEntitlement;
126}

Recommendation:

We advise it to be set as immutable greatly optimizing its read-access gas cost.

Alleviation (04618e407bddce5b22e9cadd787fd3334bd3afe6):

The tokenAddress contract-level variable of the contract has been set as immutable, optimizing its read-access gas cost significantly.