Omniscia Alliance Block Audit

Router Static Analysis Findings

Router Static Analysis Findings

ROU-01S: Data Location Optimization

TypeSeverityLocation
Gas OptimizationInformationalRouter.sol:L73

Description:

The signatures array of updateMember is set as memory whilst its function is set as external.

Example:

contracts/Router.sol
73function updateMember(address account, bool status, bytes[] memory signatures)
74 onlyValidSignatures(signatures.length)
75 external override
76{
77 bytes32 ethHash = LibDiamond.computeMemberUpdateMessage(account, status);
78 LibDiamond.validateSignatures(ethHash, signatures);
79
80 if (status) {
81 LibFeeCalculator.addNewMember(account);
82 } else {
83 LibRouter.Storage storage rs = LibRouter.routerStorage();
84 uint256 claimableFees = LibFeeCalculator.claimReward(account);
85 IERC20(rs.albtToken).transfer(account, claimableFees);
86 }
87
88 LibDiamond.updateMember(account, status);
89 emit MemberUpdated(account, status);
90}

Recommendation:

We advise the data location of the signatures array to be set as calldata greatly optimizing the gas cost of the function. The calldata specifier can still be applied in internal functions as well, such as the validateSignatures function used from the LibDiamond implementation.

Alleviation:

The membership-controlled contract implementation was replaced by a singular LibGovernance implementation thus no longer rendering this exhibit applicable.

ROU-02S: Unused Return Value

TypeSeverityLocation
Standard ConformityInformationalRouter.sol:L85

Description:

The ERC20 transfer performed by updateMember does not evaluate the return bool value.

Example:

contracts/Router.sol
73function updateMember(address account, bool status, bytes[] memory signatures)
74 onlyValidSignatures(signatures.length)
75 external override
76{
77 bytes32 ethHash = LibDiamond.computeMemberUpdateMessage(account, status);
78 LibDiamond.validateSignatures(ethHash, signatures);
79
80 if (status) {
81 LibFeeCalculator.addNewMember(account);
82 } else {
83 LibRouter.Storage storage rs = LibRouter.routerStorage();
84 uint256 claimableFees = LibFeeCalculator.claimReward(account);
85 IERC20(rs.albtToken).transfer(account, claimableFees);
86 }
87
88 LibDiamond.updateMember(account, status);
89 emit MemberUpdated(account, status);
90}

Recommendation:

Although the ALBT implementation would never return a false boolean under any circumstance, it is still best practice to use a safe wrapper implementation of ERC20, such as SafeERC20, to ensure return values are properly evaluated.

Alleviation:

The membership-controlled contract implementation was replaced by a singular LibGovernance implementation thus no longer rendering this exhibit applicable.