Presale - contributionToken double cast and invalid comparison
The Presale can be configured to accept `ETH` or a valid `ERC20` `token`. This `token` is stored as an `ERC20` contract type in the state variable `contributionToken`. It is then directly compared to constant `ETH` which is `address(0x0)` in various locations. Additionally, the `_transfer` function double casts the `token` to `ERC20` if the `contributionToken` is passed as an argument.\\n`contribute` - invalid comparison of contract type against `address(0x00)`. Even though this is accepted in solidity `<0.5.0` it is going to raise a compiler error with newer versions (>=0.5.0).\\n```\\nfunction contribute(address \\_contributor, uint256 \\_value) external payable nonReentrant auth(CONTRIBUTE\\_ROLE) {\\n    require(state() == State.Funding, ERROR\\_INVALID\\_STATE);\\n\\n    if (contributionToken == ETH) {\\n        require(msg.value == \\_value, ERROR\\_INVALID\\_CONTRIBUTE\\_VALUE);\\n    } else {\\n        require(msg.value == 0,      ERROR\\_INVALID\\_CONTRIBUTE\\_VALUE);\\n    }\\n```\\n\\n`_transfer` - double cast `token` to `ERC20` if it is the contribution `token`.\\n```\\nrequire(ERC20(\\_token).safeTransfer(\\_to, \\_amount), ERROR\\_TOKEN\\_TRANSFER\\_REVERTED);\\n```\\n
`contributionToken` can either be `ETH` or a valid `ERC20` contract address. It is therefore recommended to store the token as an address type instead of the more precise contract type to resolve the double cast and the invalid contract type to address comparison or cast the `ERC20` type to `address()` before comparison.
```\\nfunction contribute(address \\_contributor, uint256 \\_value) external payable nonReentrant auth(CONTRIBUTE\\_ROLE) {\\n    require(state() == State.Funding, ERROR\\_INVALID\\_STATE);\\n\\n    if (contributionToken == ETH) {\\n        require(msg.value == \\_value, ERROR\\_INVALID\\_CONTRIBUTE\\_VALUE);\\n    } else {\\n        require(msg.value == 0,      ERROR\\_INVALID\\_CONTRIBUTE\\_VALUE);\\n    }\\n```\\n