Omniscia AllianceBlock Audit
AllianceBlockToken Code Style Findings
AllianceBlockToken Code Style Findings
ABT-01C: Enhancement of State Validation
Type | Severity | Location |
---|---|---|
Gas Optimization | AllianceBlockToken.sol:L65-L68 |
Description:
The snapshot
function is meant to create a snapshot of the token balances of each account. In the current implementation, a snapshot is always created when the protocol is paused, hence rendering snapshot
invocations during the token's paused state to be ineffectual.
Example:
57/**58 * @dev Creates a new snapshot and returns its snapshot id.59 *60 * Emits a {Snapshot} event that contains the same id.61 *62 * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a63 * set of accounts, for example using {AccessControl}, or it may be open to the public.64 */65function snapshot() public returns (uint256) {66 require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "NXRA: Snapshot invalid role");67 return _snapshot();68}69
70/**71 * @dev Returns the cap on the token's total supply.72 */73function cap() external view virtual returns (uint256) {74 return _cap;75}76
77/**78 * @dev Pauses all token transfers.79 *80 * See {ERC20Pausable} and {Pausable-_pause}.81 *82 * Requirements:83 *84 * - the caller must have the `PAUSER_ROLE`.85 */86function pause() public override {87 super.pause();88 _snapshot();89}
Recommendation:
We advise a require
check to be introduced that ensures the token is not paused
when snapshot
is invoked, preventing incorrect and gas-burdening snapshots from being created.
Alleviation (5bde836b591caa6c3dfd47b79f323317a26c8a0d):
The snapshot
mechanism now adequately evaluates that the protocol is not paused, ensuring snapshots are solely created once when the protocol is in a paused state.
ABT-02C: Loop Iterator Optimization
Type | Severity | Location |
---|---|---|
Gas Optimization | AllianceBlockToken.sol:L106 |
Description:
The linked for
loop increments / decrements the iterator "safely" due to Solidity's built-in safe arithmetics(post - 0.8.X
).
Example:
106for (uint256 i = 0; i < recipientsLength; i++) {
Recommendation:
We advise the increment / decrement operation to be performed in an unchecked
code block as the last statement within the for
loop to optimize its execution cost.
Alleviation (5bde836b591caa6c3dfd47b79f323317a26c8a0d):
The loop iterator has been optimized by being relocated to the end of the for
loop and wrapped in an unchecked
code block as advised.
ABT-03C: Potential Batch Mint Optimization
Type | Severity | Location |
---|---|---|
Gas Optimization | AllianceBlockToken.sol:L107, L122-L125 |
Description:
Given that the token implementation's batchMint
operation is expected to be invoked multiple times, we advise it to be made as optimal as possible. It currently invokes the _mint
function overridden in the AllianceBlockToken
that imposes a _cap
on the total supply, however, this is inefficient as the cap can be evaluated at the end of the function.
Example:
96/**97 * @dev Mints multiple values for multiple receivers98 */99function batchMint(address[] memory recipients, uint256[] memory values) public returns (bool) {100 require(hasRole(MINTER_ROLE, _msgSender()), "NXRA: Batch mint invalid role");101
102 uint256 recipientsLength = recipients.length;103 require(recipientsLength == values.length, "NXRA: Batch mint not same legth");104
105 uint256 totalValue = 0;106 for (uint256 i = 0; i < recipientsLength; i++) {107 _mint(recipients[i], values[i]);108 unchecked {109 // Overflow not possible: totalValue + amount is at most totalSupply + amount, which is checked above.110 totalValue += values[i];111 }112 }113
114 emit BatchMint(_msgSender(), recipientsLength, totalValue);115 return true;116}117
118/**119 * @dev See {ERC20-_mint}.120 * @dev Checks if cap is reached and calls normal _mint.121 */122function _mint(address account, uint256 amount) internal override {123 require(ERC20Upgradeable.totalSupply() + amount <= _cap, "NXRA: cap exceeded");124 super._mint(account, amount);125}
Recommendation:
We advise it to invoke super._mint
instead and the _cap
check to occur after the for
loop by evaluating that the ERC20Upgradeable.totalSupply()
is less-than-or-equal-to (<=
) the value of _cap
, significantly reducing the gas cost of the function.
Alleviation (5bde836b591caa6c3dfd47b79f323317a26c8a0d):
The batchMint
function has been significantly optimized by evaluating the total supply cap at the end of its execution as per our recommendation.
ABT-04C: Potentially Incorrect Error Messages
Type | Severity | Location |
---|---|---|
Code Style | AllianceBlockToken.sol:L30, L46, L66, L100, L103, L123 |
Description:
The referenced error messages make mention of the NXRA
acronym whilst the token itself is meant to represent AllianceBlock.
Example:
100require(hasRole(MINTER_ROLE, _msgSender()), "NXRA: Batch mint invalid role");
Recommendation:
We advise them to be evaluated and aptly renamed if deemed incorrect.
Alleviation (5bde836b591caa6c3dfd47b79f323317a26c8a0d):
The AllianceBlock team stated that NXRA
is the intended symbol
/ ticker of the token rendering this exhibit nullified as the error messages are correctly defined.