GPA Smart Contract Audit
By: New Alchemy
Tags: Ethereum, Smart Contracts, Security, Solidity, Token Sale

Critical Issues

No critical issues were found.

Moderate Issues

1. Fixed: Outdated Dependencies

Utilizing third-party, standardized, battle-tested components provides significant benefits in contract security. These components have a known track record and are generally carefully inspected by many people, well tested and quickly patched when vulnerabilities arise. However, many of these benefits are lost when dependencies become outdated or disconnected from their original source.

The package.json file present in the GitHub repository specifically includes the following dependency references:

"openzeppelin-solidity": "1.10.0",

Openzeppelin-solidity should be upgraded to 1.12.0 as follows:

"openzeppelin-solidity": "1.12.0",

Re-test v2.0: The GPAToken.io team has updated the openzeppelin-solidity version in the package.json file to the most recent version. Thus, this issue has been fully remediated and the associated risk mitigated.

Minor Issues

2. Informational: Lack of Short-Address Attack Protection

Some Ethereum clients may create malformed messages if a user is persuaded to call a method on a contract with an address that is not a full 20 bytes long. In such a “short-address attack”, an attacker generates an address whose last byte is 0x00, then sends the first 19 bytes of that address to a victim. When the victim makes a contract method call, it appends the 19-byte address to msg.data followed by a value. Since the high-order byte of the value is almost certainly 0x00, reading 20 bytes from the expected location of the address in msg.data will result in the correct address. However, the value is then left-shifted by one byte, effectively multiplying it by 256 and potentially causing the victim to transfer a much larger number of tokens than intended. msg.data will be one byte shorter than expected, but due to how the EVM works, reads past its end will just return 0x00.

This attack affects methods where method parameters include an address followed immediately by a value. There are several of these in the InsurePal smart contracts, with a summary of each contract, line number and function listed below.

GPA.sol

85: function transfer(address _to, uint256 _value) public allowedTrade returns (bool)

95: function transferFrom(address _from, address _to, uint256 _value) public allowedTrade returns (bool) GPAAirDrop.sol

19: function execAirDrop(address _tokenAddr, address[] addrList, uint256[] valList) public onlyOwner returns (uint256)

While the root cause of this flaw is buggy serializers and how the EVM works, it can be easily mitigated in contracts. When called externally, an affected method should verify that msg.data.length is at least the minimum length of the method's expected arguments (for instance, msg.data.length for an external call to PermissionedToken.sol::transfer() should be at least 68: 4 for the hash, 32 for the address (including 12 bytes of padding), and 32 for the value; some clients may add additional padding to the end). This can be implemented in a modifier. External calls can be detected in the following ways:

Compare the first four bytes of msg.data against the method hash. If they don't match, then the call is internal and no short-address check is necessary.

against the method hash. If they don't match, then the call is internal and no short-address check is necessary. Avoid creating public methods that may be subject to short-address attacks; instead create only external methods that check for short addresses as described above. public methods can be simulated by having the external methods call private or internal methods that perform the actual operations and that do not check for short-address attacks.

Whether or not it is appropriate for contracts to mitigate the short-address attack is a contentious issue among smart-contract developers. Many, including those behind the OpenZeppelin project, have explicitly chosen not to do so. While it is New Alchemy’s position that there is value in protecting users by incorporating low-cost mitigations into likely target functions, GPA would not stand out from the community if they also choose not to do so.

Re-test v2.0: New Alchemy has discussed this issue with the GPA Token team at length. As noted above, this is a contentious issue among smart contract developers, there are clear community trends towards accepting rather than mitigating this vulnerability, and there are external dependencies such as UI and tools that must be considered. GPAToken.io has chosen to accept this risk at this time and consider future mitigation as their application evolves. New Alchemy considers this an entirely reasonable approach.

3. Fixed: GPAAirDrop extra gas usage

As the only use of targetToken is immediately after being set within the same function, this could be a memory variable within the execAirDrop function rather than stored on the blockchain.

Re-test v2.0: The GPAToken.io team has removed the targetToken variable from the source code. By removing the variable the team has effectively mitigated the finding, and as such New Alchemy considers this finding fixed.

4. Fixed: Unhandled return value

GPAAirDrop.sol

28: targetToken.transferFrom(msg.sender, addrList[i], valList[i].mul(10 ** uint256(decimals)));

https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md states that Callers MUST handle false from returns (bool success). Callers MUST NOT assume that false is never returned! but the return value is ignored.

Re-test v2.0: New Alchemy has inspected the updated project repository to confirm the the return values are handled in all use cases. This security issue has been addressed and remediated.

Smart Contract ABI Reference

This section provides the fully-elaborated application binary interface (ABI) for 3 of the primary contracts as seen at runtime. The ABI defines how the contracts may be interacted with while running inside the EVM. The tables make for very easy inspection of top-level specifics including:

The definitive reference of all exposed functions

Correct input and output function signatures

Presence of constructors and fallbacks as expected

Correct state mutability (pure, view, nonpayable, payable)

Extraneous functions which should be private

contracts/GPA ABI Reference

contracts/GPAAirDrop.sol:GPAAirDrop ABI Reference