Omniscia Swisscoast Audit
HLQTYToken Code Style Findings
HLQTYToken Code Style Findings
HLQ-01C: Deprecated Revert Pattern
Type | Severity | Location |
---|---|---|
Code Style | HLQTYToken.sol:L232 |
Description:
The referenced revert
statement is issued with a string
argument which has been deprecated.
Example:
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
Type | Severity | Location |
---|---|---|
Gas Optimization | HLQTYToken.sol:L121, L198, L227, L238, L245-L249 |
Description:
The HLQTYToken::_checkResponse
function will either successfully execute and yield true
, or revert
.
Example:
209function _mint(210 address account,211 uint256 amount212)213internal214returns (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
Type | Severity | Location |
---|---|---|
Gas Optimization | HLQTYToken.sol:L230-L231 |
Description:
The referenced conditional is negated after being evaluated.
Example:
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
Type | Severity | Location |
---|---|---|
Code Style | HLQTYToken.sol:L52, L53 |
Description:
The HLQTY
token is represented as HLQT
which may be incorrect.
Example:
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
Type | Severity | Location |
---|---|---|
Gas Optimization | HLQTYToken.sol:L194, L206, L221, L241-L243 |
Description:
The HLQTYToken::_getTokenAddress
function is redundant as the tokenAddress
member is readily available throughout the contract.
Example:
209function _mint(210 address account,211 uint256 amount212)213internal214returns (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)
Type | Severity | Location |
---|---|---|
Gas Optimization | HLQTYToken.sol:L49 |
Description:
The linked variable is assigned to only once during the contract's constructor
.
Example:
84constructor85(86 address _communityIssuanceAddress,87 address _hlqtyStakingAddress,88 address _lockupFactoryAddress,89 address _multisigAddress90) 91 payable public92{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 rewards125 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.