BRICSChainToken smart contracts security audit report performed by chhajershrenik.
Commit: c203cc42f2c683269ad88249a658e996943cc266
In total, 4 issues were reported, including:
- 1 medium severity issues.
- 3 low severity issues.
In total, 19 notes were reported, including:
- 12 minor observations.
- 7 owner privileges.
The function deprecate()
does not check if the _upgradedAddress
is not address(0)
, if the _upgradedAddress
is set to address(0)
by default or by mistake this could lead to unexpected reverts to the contracts functionalities. Additionally, consider adding a public flag isUpgradedToken
to the contract at the _upgradedAddress
address.
Functions transfer()
and transferFrom()
allow the destination address (_to
) to address zero, which would lead to a loss of wallet token if tokens are sent to address(0)
by default or by mistake.
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L422-L426
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L122-L135
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L167-L188
Consider adding a zero address check to the deprecate()
, transfer()
and transferFrom()
functions.
The function approve()
can used to modify token approvals for a spender even when the contract state is paused.
Consider adding the modifier whenNotPaused
to the function approve()
.
The short address attack check via the onlyPayloadSize
modifier is not considered a correct mitigation for the attack and is even potentially harmful when extending contracts.
If the functions transfer()
and transferFrom()
are used by a subcontract's function with fewer arguments the modifier onlyPayloadSize
with the short address check will fail. This was fixed in Solidity 0.5.0: ethereum/solidity#4224.
Consider removing the modifier onlyPayloadSize
and upgrading the contract version.
Functions transfer()
and transferFrom()
do not return the boolean flag true
for successful operations, if any contract interacted with the BRICSChainToken
token using the standard ERC20 interface, the function would return false
by default even for successful operations.
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L122-L135
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L167-L188
Consider returning a boolean flag for true
or false
the functions transfer()
and transferFrom()
for successful or reverted transactions respectively.
- Functions
pause()
andunpause()
allow the owner to change the active state of the contract, pausing the state of the contract disables the transfer of tokens for all users. - Functions
addBlackList()
andremoveBlackList()
allows the owner to add or remove a wallet to/from the blacklist the blacklisted user cannot transfer tokens. - Function
destroyBlackFunds()
allows the owner to destroy all funds of a blacklisted wallet. - Function
deprecate()
allows the owner of the contract to upgrade and implement the contract's existing logic. - Functions
issue()
andredeem()
allows the owner to Issue or Redeem the token from the owner's wallet. - Function
mint()
andmintTo()
allows the owner to mint an arbitrary amount of tokens for a wallet. - Function
setParams()
allows the owner to apply transaction fees of up to 2% for token transfers to a wallet. The transaction fee limit can be overwritten if the contract implementation is upgraded using the functiondeprecate()
.
- Unlocked Pragma.
Contracts should be deployed using the same compiler version/flags with which they have been tested. Locking the floating pragma, i.e. by not using ^ in pragma solidity ^0.4.17, ensures that contracts do not accidentally get deployed using a compiler version with unfixed bugs.
- Missing docstrings.
The contracts in the code base lack documentation. This hinders reviewers’ understanding of the code’s intention, which is fundamental to correctly assessing not only security but also correctness. Additionally, docstrings improve readability and ease maintenance. They should explicitly explain the purpose or intention of the functions, the scenarios under which they can fail, the roles allowed to call them, the values returned, and the events emitted.
Consider thoroughly documenting all functions (and their parameters) that are part of the contracts’ public API. Functions implementing sensitive functionality, even if not public, should be documented as well. When writing docstrings, consider following the Ethereum Natural Specification Format (NatSpec).
- Missing test suite.
The contract is missing a test suite to validate and verify the behavior of the contract functionalities. Add tests are recommended to ensure that the contract functions and behaves as expected.
- Functions not used internally could be marked as external.
It's a good coding practice to mark a function external when it's not called within the contract but only from outside the contract.
- Contract
BasicToken
inherits theOwnable
contract but does not use any of its functionalities and, therefore can safely be removed.
- Ownable contract does not use Ownable2Step to transfer ownership of the contract, any mistake in the
newOwner
address would result in making the functions with the modifieronlyOwner()
inaccessible. Consider implementing openzeppelin's Ownable2Step contract to transfer ownerships.
- Functions do not emit Events.
Functions transferOwnership()
, BRICSChainToken()
, issue()
, redeem()
, and destroyBlackFunds()
does not emit event corresponding to the transfer of ownership and token transfers concerning ERC-20 Standard respectively. The ERC-20 standard suggests emitting a Transfer event from/to address(0) when minting or burning tokens for the functions issue()
, redeem()
, and destroyBlackFunds()
. The same applies to the constructor BRICSChainToken()
.
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L64-L68
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L365-L372
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L441-L448
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L455-L461
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L326-L332
-
The
BRICSChainToken
token'sdecimals
variable does not comply with the ERC-20 Standard, consider using the uint8 data type for the variable. -
If the contract is upgraded using the function
deprecate()
the functionsissue()
, andredeem()
can not be upgraded additionally the functions would be rendered useless. Consider adding upgrade mechanisms to these functions as well.
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L441-L448
- https://github.com/bricschain/bricschaintoken/blob/c203cc42f2c683269ad88249a658e996943cc266/BRICSChainToken.sol#L455-L461
-
Consider marking the address parameter in all three blacklist events (
DestroyedBlackFunds
,AddedBlackList
, andRemovedBlackList
) as indexed, to allow a client to listen for changes to their status. -
Function
getOwner()
in the contractBlackList
is redundant as the function is already inherited from the contractOwnable
.
- Consider adding require statements as token preconditions to avoid zero transfers for the functions
transfer()
,transferFrom()
,issue()
,redeem()
,mint()
,mintTo()
, andburn()
.
Token approvals can be changed when the contract state is paused.
It's not an issue, since transferFrom is paused.