EnduracoinToken smart contract security audit report performed by GreyWolf
Commit 512d6d7d3392386ef52ee8e71ae830a24ffa6f52
- EnduracoinToken.sol
- EnduracoinValue.sol
- ManageApprovers.sol
- StringHelpers.sol
- ChangeRequests.sol
In total, 2 issues were reported, including:
-
0 high severity issues.
-
1 medium severity issue.
-
1 low severity issue.
In total, 2 notes were reported, including:
-
1 minor observation.
-
1 owner privileges.
All major functions (transfer
, approve
, transferFrom
, etc) of EnduracoinToken have modifier requiresMultiSig()
.
This modifier apply checking of vote results if pendingChange.addrValueToChange == owner()
. It means that any approver who create newChangeRequest
with parameter addressToUse
equal to owner address will block all tokens functionality until voting will be finished.
- https://github.com/CallistoSecurity/EnduracoinToken/blob/512d6d7d3392386ef52ee8e71ae830a24ffa6f52/v4/EnduracoinToken.sol#L112
- https://github.com/CallistoSecurity/EnduracoinToken/blob/512d6d7d3392386ef52ee8e71ae830a24ffa6f52/v4/ChangeRequests.sol#L69
- https://github.com/CallistoSecurity/EnduracoinToken/blob/512d6d7d3392386ef52ee8e71ae830a24ffa6f52/v4/EnduracoinToken.sol#L72
50 Billion Enduracoin will be pre-minted to the owner's wallet. If tokens are burnt, the owner has the right to mint new tokens up to 50 Billion in total supply.
In the function execChangeRequest
when ChangeType
is transferOwnership
and if new owner address already added to approver list, the old address will not be removed from approvers. Only if new owner isn't approver it will be added to the list and old address will be removed.
- https://github.com/CallistoSecurity/EnduracoinToken/blob/512d6d7d3392386ef52ee8e71ae830a24ffa6f52/v4/EnduracoinToken.sol#L45-L47
- https://github.com/CallistoSecurity/EnduracoinToken/blob/512d6d7d3392386ef52ee8e71ae830a24ffa6f52/v4/EnduracoinToken.sol#L49-L50
Rewrite this part: https://github.com/CallistoSecurity/EnduracoinToken/blob/512d6d7d3392386ef52ee8e71ae830a24ffa6f52/v4/EnduracoinToken.sol#L44-L53
like this:
else if(pendingChangeType == uint8(ChangeType.transferOwnership)) {
if(validateApproverExists(owner()))
_removeApprover(owner());
if(!validateApproverExists(pendingChange.addrValueToChange))
_setApprover(pendingChange.addrValueToChange);
transferOwnership(pendingChange.addrValueToChange);
}
- The modifier
requiresMultiSig
restrictowner
to call function until voting is finished, but allow anybody else to call function without restriction. Therefore, in the context of the contractEnduracoinValue
it does not make any sense and can be removed or replaced by the modifieronlyApprovers
.
- https://github.com/CallistoSecurity/EnduracoinToken/blob/512d6d7d3392386ef52ee8e71ae830a24ffa6f52/v4/EnduracoinValue.sol#L166
- https://github.com/CallistoSecurity/EnduracoinToken/blob/512d6d7d3392386ef52ee8e71ae830a24ffa6f52/v4/EnduracoinValue.sol#L180
- https://github.com/CallistoSecurity/EnduracoinToken/blob/512d6d7d3392386ef52ee8e71ae830a24ffa6f52/v4/EnduracoinValue.sol#L189
- The
getPendingChangeRequest()
is a view function, so does not requireonlyApprovers
modifier.
-
Owner can't create change request and must be the last approver in voting. If owner vote earlier the change request can't be approved and all others approver should vote against it to be able create new request. It's not a security issue, but may cause inconvenient.
-
In the
EnduracoinValue
contract the comment say: "LASTDAY_OF_YEAR21
represents the last day of year 21 from the start date.", but value 8030 = 22 * 365. So it's last day of year 22. Also, this number does not take into account years with 366 days.
- In the
EnduracoinValue
contract thecurrentDayInPeriod
should be in range from 0 to 364. Therefore conditionif(daysSinceStart > 365)
should be changed toif(daysSinceStart >= 365)
. or can be removed at all.