Compiling contracts normally via truffle compile --all
or oz compile
works fine. However, when measuring test coverage with solidity-coverage, I cannot go past beyond the compile step.
Environment
- @openzeppelin/contracts-ethereum-package 2.2.3
- @openzeppelin/contracts-ethereum-package 2.5.2
- ethereumjs-testrpc-sc 6.5.1-sc.0
- solidity 0.5.10
- solidity-coverage 0.6.5
- truffle 5.035
Details
I suspect the problem is that solidity-coverage modifies the contract methods to add its own events and this messes up with the way GSNRecipient expects to be inherited.
I get these compilation errors:
Error: CompileError: /Users/paulrberg/Projects/Sablier/Sablier/packages/payroll/coverageEnv/contracts/Payroll.sol:190:5: TypeError: Overriding function changes state mutability from "view" to "nonpayable".
function acceptRelayedCall(
^ (Relevant source part starts here and spans across multiple lines).
@openzeppelin/contracts-ethereum-package/contracts/GSN/bouncers/GSNBouncerSignature.sol:22:5: Overridden function is here:
function acceptRelayedCall(
^ (Relevant source part starts here and spans across multiple lines).
,/Users/paulrberg/Projects/Sablier/Sablier/packages/payroll/coverageEnv/contracts/Payroll.sol:190:5: TypeError: Overriding function changes state mutability from "view" to "nonpayable".
function acceptRelayedCall(
^ (Relevant source part starts here and spans across multiple lines).
@openzeppelin/contracts-ethereum-package/contracts/GSN/IRelayRecipient.sol:12:5: Overridden function is here:
function acceptRelayedCall(
^ (Relevant source part starts here and spans across multiple lines).
Code to reproduce
How I implemented acceptRelayedCall
:
function acceptRelayedCall(
address relay,
address from,
bytes calldata encodedFunction,
uint256 transactionFee,
uint256 gasPrice,
uint256 gasLimit,
uint256 _nonce,
bytes calldata approvalData,
uint256
) external view returns (uint256, bytes memory) {
bytes memory blob = abi.encodePacked(
relay,
from,
encodedFunction,
transactionFee,
gasPrice,
gasLimit,
_nonce, // Prevents replays on RelayHub
getHubAddr(), // Prevents replays in multiple RelayHubs
address(this) // Prevents replays in multiple recipients
);
if (keccak256(blob).toEthSignedMessageHash().recover(approvalData) == owner()) {
return _approveRelayedCall();
} else {
return _rejectRelayedCall(uint256(GSNBouncerSignatureErrorCodes.INVALID_SIGNER));
}
}
See the whole contract for more details.