Skip to content

Commit d0bc2be

Browse files
authored
chore: Remove unused signature verifier solv6 contract (#315)
1 parent 3b28585 commit d0bc2be

File tree

16 files changed

+1173
-1951
lines changed

16 files changed

+1173
-1951
lines changed

.solcover.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ module.exports = {
1313
mocha: {
1414
timeout: 600000, // double timeout
1515
},
16-
skipFiles: ['facets/SignatureVerifier.sol', 'tools/'],
16+
skipFiles: ['tools/'],
1717
istanbulFolder: './coverage',
1818
};

abis/human-readable-abis/@iexec/solidity/contracts/ERC1271/IERC1271.sol/IERC1271.json

Lines changed: 0 additions & 3 deletions
This file was deleted.

abis/human-readable-abis/@iexec/solidity/contracts/ERC1654/IERC1654.sol/IERC1654.json

Lines changed: 0 additions & 3 deletions
This file was deleted.

abis/human-readable-abis/@iexec/solidity/contracts/ERC734/IERC734.sol/IERC734.json

Lines changed: 0 additions & 21 deletions
This file was deleted.

contracts/facets/IexecOrderManagementFacet.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
pragma solidity ^0.8.0;
55

66
import {IERC5313} from "@openzeppelin/contracts-v5/interfaces/IERC5313.sol";
7-
import {SignatureVerifier} from "./SignatureVerifier.v8.sol";
7+
import {SignatureVerifier} from "./SignatureVerifier.sol";
88
import {FacetBase} from "./FacetBase.v8.sol";
99
import {IexecOrderManagement} from "../interfaces/IexecOrderManagement.sol";
1010
import {PocoStorageLib} from "../libs/PocoStorageLib.v8.sol";

contracts/facets/IexecPoco1Facet.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {IexecPoco1} from "../interfaces/IexecPoco1.sol";
1414
import {IexecPoco1Errors} from "../interfaces/IexecPoco1Errors.sol";
1515
import {IexecEscrow} from "./IexecEscrow.v8.sol";
1616
import {IexecPocoCommon} from "./IexecPocoCommon.sol";
17-
import {SignatureVerifier} from "./SignatureVerifier.v8.sol";
17+
import {SignatureVerifier} from "./SignatureVerifier.sol";
1818

1919
struct Matching {
2020
bytes32 apporderHash;

contracts/facets/IexecPoco2Facet.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {IexecLibOrders_v5} from "../libs/IexecLibOrders_v5.sol";
1111
import {FacetBase} from "./FacetBase.v8.sol";
1212
import {IexecPoco2} from "../interfaces/IexecPoco2.sol";
1313
import {IexecEscrow} from "./IexecEscrow.v8.sol";
14-
import {SignatureVerifier} from "./SignatureVerifier.v8.sol";
14+
import {SignatureVerifier} from "./SignatureVerifier.sol";
1515

1616
contract IexecPoco2Facet is IexecPoco2, FacetBase, IexecEscrow, SignatureVerifier {
1717
modifier onlyScheduler(bytes32 _taskId) {

contracts/facets/IexecPocoAccessorsFacet.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {IApp} from "../registries/apps/IApp.v8.sol";
1212
import {IWorkerpool} from "../registries/workerpools/IWorkerpool.v8.sol";
1313
import {IexecPocoAccessors} from "../interfaces/IexecPocoAccessors.sol";
1414
import {IexecPocoCommon} from "./IexecPocoCommon.sol";
15-
import {SignatureVerifier} from "./SignatureVerifier.v8.sol";
15+
import {SignatureVerifier} from "./SignatureVerifier.sol";
1616

1717
/**
1818
* @title Getters contract for PoCo facets.

contracts/facets/IexecPocoBoostFacet.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {FacetBase} from "./FacetBase.v8.sol";
1717
import {IexecPocoBoost} from "../interfaces/IexecPocoBoost.sol";
1818
import {IexecEscrow} from "./IexecEscrow.v8.sol";
1919
import {IexecPocoCommon} from "./IexecPocoCommon.sol";
20-
import {SignatureVerifier} from "./SignatureVerifier.v8.sol";
20+
import {SignatureVerifier} from "./SignatureVerifier.sol";
2121
import {PocoStorageLib} from "../libs/PocoStorageLib.v8.sol";
2222

2323
//
Lines changed: 119 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,153 @@
11
// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH <[email protected]>
22
// SPDX-License-Identifier: Apache-2.0
33

4-
pragma solidity ^0.6.0;
5-
pragma experimental ABIEncoderV2;
4+
pragma solidity ^0.8.0;
65

7-
import "@iexec/solidity/contracts/ERC734/IERC734.sol";
8-
import "@iexec/solidity/contracts/ERC1271/IERC1271.sol";
9-
import "@iexec/solidity/contracts/ERC1654/IERC1654.sol";
10-
import {PocoStorageLib} from "../libs/PocoStorageLib.sol";
11-
import "./FacetBase.sol";
6+
import {IERC1271} from "@openzeppelin/contracts-v5/interfaces/IERC1271.sol";
7+
import {ECDSA} from "@openzeppelin/contracts-v5/utils/cryptography/ECDSA.sol";
8+
import {MessageHashUtils} from "@openzeppelin/contracts-v5/utils/cryptography/MessageHashUtils.sol";
9+
import {FacetBase} from "./FacetBase.v8.sol";
10+
import {IERC734} from "../external/interfaces/IERC734.sol";
11+
import {PocoStorageLib} from "../libs/PocoStorageLib.v8.sol";
1212

1313
contract SignatureVerifier is FacetBase {
14+
using ECDSA for bytes32;
15+
1416
/**
15-
* Prepare message/structure predicat used for signing
17+
* Hash a Typed Data using the configured domain.
18+
* @param structHash The original structure hash.
1619
*/
17-
function _toEthSignedMessage(bytes32 _msgHash) internal pure returns (bytes memory) {
18-
return abi.encodePacked("\x19Ethereum Signed Message:\n32", _msgHash);
20+
function _toTypedDataHash(bytes32 structHash) internal view returns (bytes32) {
21+
PocoStorageLib.PocoStorage storage $ = PocoStorageLib.getPocoStorage();
22+
return MessageHashUtils.toTypedDataHash($.m_eip712DomainSeparator, structHash);
1923
}
2024

21-
function _toEthTypedStruct(
22-
bytes32 _structHash,
23-
bytes32 _domainHash
24-
) internal pure returns (bytes memory) {
25-
return abi.encodePacked("\x19\x01", _domainHash, _structHash);
25+
/**
26+
* @notice Verify that an Ethereum Signed Message is signed by a particular account.
27+
* @param account The expected signer account.
28+
* @param message The original message that was signed.
29+
* @param signature The signature to be verified.
30+
*/
31+
function _verifySignatureOfEthSignedMessage(
32+
address account,
33+
bytes memory message,
34+
bytes calldata signature
35+
) internal view returns (bool) {
36+
return
37+
_verifySignature(
38+
account,
39+
MessageHashUtils.toEthSignedMessageHash(keccak256(message)),
40+
signature
41+
);
2642
}
2743

2844
/**
29-
* recover EOA signature (support both 65 bytes traditional and 64 bytes format EIP2098 format)
45+
* @notice Verify that a message is signed by an EOA or an ERC1271 smart contract.
46+
*
47+
* It supports short signatures.
48+
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
49+
* & https://github.com/OpenZeppelin/openzeppelin-contracts/pull/4915
50+
* https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.0.0/contracts/utils/cryptography/ECDSA.sol#L112
51+
*
52+
* @param account The expected signer account.
53+
* @param messageHash The message hash that was signed.
54+
* @param signature The signature to be verified.
3055
*/
31-
function _recover(bytes32 _hash, bytes memory _sign) internal pure returns (address) {
32-
bytes32 r;
33-
bytes32 s;
34-
uint8 v;
35-
36-
if (_sign.length == 65) // 65bytes: (r,s,v) form
37-
{
38-
assembly {
39-
r := mload(add(_sign, 0x20))
40-
s := mload(add(_sign, 0x40))
41-
v := byte(0, mload(add(_sign, 0x60)))
42-
}
43-
} else if (_sign.length == 64) // 64bytes: (r,vs) form → see EIP2098
44-
{
45-
assembly {
46-
r := mload(add(_sign, 0x20))
47-
s := and(
48-
mload(add(_sign, 0x40)),
49-
0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
50-
)
51-
v := shr(7, byte(0, mload(add(_sign, 0x40))))
52-
}
56+
function _verifySignature(
57+
address account,
58+
bytes32 messageHash,
59+
bytes calldata signature
60+
) internal view returns (bool) {
61+
// When the account is a smart contract, delegate signature verification.
62+
if (account.code.length > 0) {
63+
try IERC1271(account).isValidSignature(messageHash, signature) returns (bytes4 result) {
64+
return result == IERC1271.isValidSignature.selector;
65+
} catch {}
66+
return false;
67+
}
68+
// When the account is an EoA, check signature validity.
69+
address recoveredAddress = address(0); // Initialize local variable
70+
if (signature.length == 65) {
71+
//slither-disable-next-line unused-return
72+
(recoveredAddress, , ) = messageHash.tryRecover(signature);
73+
} else if (signature.length == 64) {
74+
//slither-disable-next-line unused-return
75+
(recoveredAddress, , ) = messageHash.tryRecover( // short signature
76+
bytes32(signature[:32]),
77+
bytes32(signature[32:])
78+
);
5379
} else {
5480
revert("invalid-signature-format");
5581
}
56-
57-
if (v < 27) v += 27;
58-
require(v == 27 || v == 28, "invalid-signature-v");
59-
return ecrecover(_hash, v, r, s);
82+
return recoveredAddress == account;
6083
}
6184

6285
/**
63-
* Check if contract exist, otherwize assumed to be EOA
86+
* @notice Verify that a message hash is presigned by a particular account.
87+
* @param account The expected presigner account.
88+
* @param messageHash The message hash that was presigned.
6489
*/
65-
function _isContract(address account) internal view returns (bool) {
66-
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
67-
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
68-
// for accounts without code, i.e. `keccak256('')`
69-
bytes32 codehash;
70-
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
71-
// solhint-disable-next-line no-inline-assembly
72-
assembly {
73-
codehash := extcodehash(account)
74-
}
75-
return (codehash != accountHash && codehash != 0x0);
90+
function _verifyPresignature(
91+
address account,
92+
bytes32 messageHash
93+
) internal view returns (bool) {
94+
PocoStorageLib.PocoStorage storage $ = PocoStorageLib.getPocoStorage();
95+
return account != address(0) && account == $.m_presigned[messageHash];
7696
}
7797

7898
/**
79-
* Address to bytes32 casting to ERC734
99+
* @notice Verify that a message hash is signed or presigned by a particular account.
100+
* @param account The expected signer or presigner account.
101+
* @param messageHash The message hash that was signed or presigned.
102+
* @param signature The signature to be verified. Not required for a presignature.
80103
*/
81-
function _addrToKey(address _addr) internal pure returns (bytes32) {
82-
return bytes32(uint256(_addr));
104+
function _verifySignatureOrPresignature(
105+
address account,
106+
bytes32 messageHash,
107+
bytes calldata signature
108+
) internal view returns (bool) {
109+
return
110+
_verifyPresignature(account, messageHash) ||
111+
_verifySignature(account, messageHash, signature);
83112
}
84113

85114
/**
86-
* Identity verification
115+
* @notice
116+
* This function makes an external call to an untrusted contract. It has to
117+
* be carefully called to avoid creating re-entrancy vulnerabilities. Calls to this function
118+
* has to be done before updating state variables.
119+
*
120+
* @notice Verify that an account is authorized based on a given restriction.
121+
* The given restriction can be:
122+
* (1) `0x`: No restriction, accept any address;
123+
* (2) `0x<same-address-than-restriction>`: Only accept the exact same address;
124+
* (3) `0x<ERC734-contract-address>`: Accept any address in a group (having
125+
* the given `GROUPMEMBER` purpose) inside an ERC734 Key Manager identity
126+
* contract.
127+
* @param restriction A simple address or an ERC734 identity contract
128+
* that might whitelist a given address in a group.
129+
* @param account An address to be checked.
87130
*/
88-
function _checkIdentity(
89-
address _identity,
90-
address _candidate,
91-
uint256 _purpose
92-
) internal view returns (bool valid) {
93-
return
94-
_identity == _candidate ||
95-
IERC734(_identity).keyHasPurpose(_addrToKey(_candidate), _purpose); // Simple address || ERC 734 identity contract
96-
}
97-
98-
function _checkPresignature(address _identity, bytes32 _hash) internal view returns (bool) {
99-
PocoStorageLib.PocoStorage storage $ = PocoStorageLib.getPocoStorage();
100-
return _identity != address(0) && _identity == $.m_presigned[_hash];
101-
}
102-
103-
function _checkSignature(
104-
address _identity,
105-
bytes32 _hash,
106-
bytes memory _signature
131+
function _isAccountAuthorizedByRestriction(
132+
address restriction,
133+
address account
107134
) internal view returns (bool) {
108-
if (_isContract(_identity)) {
109-
try IERC1654(_identity).isValidSignature(_hash, _signature) returns (bytes4 value) {
110-
return value == IERC1654(0).isValidSignature.selector;
111-
} catch (bytes memory /*lowLevelData*/) {}
112-
113-
return false;
114-
} else {
115-
return _recover(_hash, _signature) == _identity;
135+
if (
136+
restriction == address(0) || // No restriction
137+
restriction == account // Simple address restriction
138+
) {
139+
return true;
116140
}
117-
}
118-
119-
function _checkSignature(
120-
address _identity,
121-
bytes memory _predicat,
122-
bytes memory _signature
123-
) internal view returns (bool) {
124-
if (_isContract(_identity)) {
125-
try IERC1271(_identity).isValidSignature(_predicat, _signature) returns (bytes4 value) {
126-
return value == IERC1271(0).isValidSignature.selector;
127-
} catch (bytes memory /*lowLevelData*/) {}
128-
129-
try IERC1654(_identity).isValidSignature(keccak256(_predicat), _signature) returns (
130-
bytes4 value
131-
) {
132-
return value == IERC1654(0).isValidSignature.selector;
133-
} catch (bytes memory /*lowLevelData*/) {}
134-
135-
return false;
136-
} else {
137-
return _recover(keccak256(_predicat), _signature) == _identity;
141+
if (restriction.code.length > 0) {
142+
try
143+
IERC734(restriction).keyHasPurpose( // ERC734 identity contract restriction
144+
bytes32(uint256(uint160(account))),
145+
GROUPMEMBER_PURPOSE
146+
)
147+
returns (bool success) {
148+
return success;
149+
} catch {}
138150
}
139-
}
140-
141-
function _checkPresignatureOrSignature(
142-
address _identity,
143-
bytes32 _hash,
144-
bytes memory _signature
145-
) internal view returns (bool) {
146-
return
147-
_checkPresignature(_identity, _hash) || _checkSignature(_identity, _hash, _signature);
148-
}
149-
150-
function _checkPresignatureOrSignature(
151-
address _identity,
152-
bytes memory _predicat,
153-
bytes memory _signature
154-
) internal view returns (bool) {
155-
return
156-
_checkPresignature(_identity, keccak256(_predicat)) ||
157-
_checkSignature(_identity, _predicat, _signature);
151+
return false;
158152
}
159153
}

0 commit comments

Comments
 (0)