Omniscia Colony Lab Audit
AuthorizedStaking Manual Review Findings
AuthorizedStaking Manual Review Findings
ASG-01M: Improper Increase of Registered Tokens
| Type | Severity | Location |
|---|---|---|
| Logical Fault | ![]() | AuthorizedStaking.sol:L286 |
Description:
The _restake function improperly increases the registered tokens in case both the from and to address are registered, such as during a self-transfer.
Example:
256/**257 * @notice Restakes tokens with the authorization limitations258 * @dev Covers stake and both restake partial and restake all259 */260function _restake(address from, address to, uint256 amount) internal virtual override {261 // stake conditions for accounts could be different262 require(263 stakeBalanceOf(to) + amount >= accountAuthorizedAmount(to),264 "not enough for authorization"265 );266
267 _decreaseTotalRegisteredTokens(from, amount);268
269 // restake all270 if (amount == stakeBalanceOf(from)) {271 _unregisterAccount(from);272 } else {273 // restake partial274 require(275 stakeBalanceOf(from) >= amount + accountAuthorizedAmount(from),276 "amount breaks authorization"277 );278 }279
280 // save conditions before actual stake,281 // expect: deposits[account] == 0282 _saveInitialConditions(to);283
284 super._restake(from, to, amount);285
286 _increaseTotalRegisteredTokens(to, amount);287}Recommendation:
We advise the accounting system to be corrected as it is currently broken.
Alleviation:
The contract's logic has been relocated to the StakingV2.sol file and has been properly alleviated by introducing an if clause that stops execution if the from and to addresses are equivalent.
ASG-02M: Inexistent Subtraction of Registered Tokens
| Type | Severity | Location |
|---|---|---|
| Logical Fault | ![]() | AuthorizedStaking.sol:L222-L235 |
Description:
Whenever an account is unregistered, their tokens remain accounted for in the totalRegisteredStake incorrectly.
Example:
213/**214 * @dev Decrease registered tokens only for registered accounts215 */216function _decreaseTotalRegisteredTokens(address account, uint256 amount) internal {217 if (isAccountRegistered(account)) {218 totalRegisteredStake -= amount;219 }220}221
222/**223 * @notice Makes account unregistered224 * @dev Also deletes account initialStakeConditions225 *226 * Emits a {Unregistered} event for authorized accounts227 */228function _unregisterAccount(address account) internal {229 delete initialStakeConditions[account];230
231 if (isAccountRegistered(account)) {232 registered[account] = false;233 emit Unregistered(account);234 }235}Recommendation:
We advise them to be properly decremented by a corresponding call during the _unregisterAccount function's execution.
Alleviation:
The contract's logic was relocated to the StakingV2.sol file and the logic has been updated to properly decrement the totalRegisteredStake variable thereby alleviating this exhibit.
ASG-03M: Inexplicable Capability of Re-Invocation
| Type | Severity | Location |
|---|---|---|
| Input Sanitization | ![]() | AuthorizedStaking.sol:L335-L344, L369-L374 |
Description:
The migrator and stakingV1Contract variables of the contract are powerful and should be assigned only once.
Example:
335/**336 * @notice Allows to set new migrator address337 * @param newMigrator Address of the new migrator338 *339 * Emits a {MigratorChanged} event340 */341function setMigrator(address newMigrator) external onlyOwner {342 migrator = newMigrator;343 emit MigratorChanged(newMigrator);344}Recommendation:
We advise the functions to prevent re-invocation by imposing a corresponding require check.
Alleviation:
The contract's logic has been relocated to the StakingV2.sol contract and the migrator as well as the stakingV1Contract can both be set once thereby alleviating this exhibit in full.


