Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: DAO signature validation #448

Merged
merged 30 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ea5dcf9
refactor: dao signature validation
heueristik Aug 23, 2023
44972c2
chore: maintained changelog
heueristik Aug 23, 2023
b8bcc40
test: test default behaviour when no permission is granted
heueristik Aug 23, 2023
8d94efc
refactor: removed unused ERC1271Mock contract
heueristik Aug 24, 2023
63d31a8
chore: maintained changelog
heueristik Aug 24, 2023
9cd233d
chore: maintained changelog
heueristik Aug 25, 2023
4a1420f
refactor: deprecation of variables and functions
heueristik Aug 25, 2023
9a283ab
Merge remote-tracking branch 'origin/develop' into feature/OS-669-dao…
heueristik Aug 25, 2023
78d9b64
chore: bump protocol version to v1.4.0
heueristik Aug 25, 2023
1011871
chore: maintained changelog
heueristik Aug 25, 2023
aca7c5e
refactor: use removed instead of depreacted
heueristik Aug 25, 2023
98f939c
Merge remote-tracking branch 'origin/develop' into feature/OS-669-dao…
heueristik Aug 25, 2023
33d144f
chore: bump package versions
heueristik Aug 28, 2023
9224721
Merge remote-tracking branch 'origin/develop' into feature/OS-669-dao…
heueristik Aug 28, 2023
ca012cc
fix: wrong error name
heueristik Aug 28, 2023
602e22c
fix: wrong version number in changelog
heueristik Aug 28, 2023
8c3f223
Merge branch 'develop' into feature/OS-669-dao-refactoring
heueristik Aug 30, 2023
11a3b00
test: fixed broken test
heueristik Aug 30, 2023
e82dc3a
revert: do not export flags that are not needed in other files currently
heueristik Aug 31, 2023
80df2d3
Apply suggestions from code review
heueristik Sep 1, 2023
d2d5a54
chore: maintain changelog
heueristik Sep 1, 2023
25b7704
refactor: improved confusing and broken tests
heueristik Sep 1, 2023
65816bc
docs: minor comment improvement
heueristik Sep 1, 2023
01941b8
refactor: rename removed variable
heueristik Sep 1, 2023
c287c05
docs: improve comment
heueristik Sep 1, 2023
89817bd
test: check for correct value instead non-reverting call
heueristik Sep 1, 2023
cc7179e
test: move factory creation into beforeEach
heueristik Sep 1, 2023
182fe93
test: a specific and a generic condition are granted at the same time
heueristik Sep 1, 2023
2cd7249
Update packages/contracts/src/core/dao/DAO.sol
heueristik Sep 19, 2023
b89cb57
fix: wrong comment
heueristik Sep 20, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/contracts-ethers/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aragon/osx-ethers",
"version": "1.3.1-rc0",
"version": "1.4.0-rc0",
"description": "The Aragon OSx contract definitions for ethers.js",
"main": "dist/bundle-cjs.js",
"module": "dist/bundle-esm.js",
Expand Down
17 changes: 17 additions & 0 deletions packages/contracts/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## v1.4.0-rc0

### Added

- Added the `FunctionRemoved` error to `DAO`.

### Changed

- Renamed the `signatureValidator` variable in `DAO` to `__removed0`.
- Use the DAOs permission manager functionality to validate signatures.

### Removed

- Removed the `SignatureValidatorSet` event from `IDAO`.
- Removed unused `ERC1271Mock` contract.
- Removed the `setSignatureValidator` function and `signatureValidator` variable in `DAO`. In places, where the function must remain to not alter the `IDAO` interface ID, it will revert and explanatory notes are put in place..

## v1.3.1-rc0

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Currently, externally owned accounts (EOAs) can sign messages with their associa
An exemplary use case is a decentralized exchange with an off-chain order book, where buy/sell orders are signed messages.
To accept such a request, both, the external service provider and caller need to follow a standard with which the signed message of the caller can be validated.

By supporting the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) standard, your DAO can validate signatures via its `isValidSignature` function that forwards the call to a signature validator contract. The signature validator can be set with `setSignatureValidator` function.
By supporting the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) standard, your DAO can validate signatures via its `isValidSignature` function that forwards the call to a signature validator contract.

<!-- Add a subsection explaining how signature validation works -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ The following functions in the DAO are permissioned:
| `_authorizeUpgrade` | `UPGRADE_DAO_PERMISSION_ID` | Required to upgrade the DAO (via the [UUPS](https://eips.ethereum.org/EIPS/eip-1822)). |
| `setMetadata` | `SET_METADATA_PERMISSION_ID` | Required to set the DAO’s metadata and [DAOstar.one DAO URI](https://eips.ethereum.org/EIPS/eip-4824). |
| `setTrustedForwarder` | `SET_TRUSTED_FORWARDER_PERMISSION_ID` | Required to set the DAO’s trusted forwarder for meta transactions. |
| `setSignatureValidator` | `SET_SIGNATURE_VALIDATOR_PERMISSION_ID` | Required to set the DAO’s signature validator contract (see ERC-1271). |
| `registerStandardCallback` | `REGISTER_STANDARD_CALLBACK_PERMISSION_ID` | Required to register a standard callback for an [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID. |

Plugins installed on the DAO might introduce other permissions and associated permission identifiers.
Expand Down
3 changes: 2 additions & 1 deletion packages/contracts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aragon/osx-artifacts",
"version": "1.3.1-rc0",
"version": "1.4.0-rc0",
"description": "The Aragon OSx Solidity contracts",
"main": "dist/bundle-cjs.js",
"module": "dist/bundle-esm.js",
Expand Down Expand Up @@ -42,6 +42,7 @@
"devDependencies": {
"@aragon/osx-ethers-v1.2.0": "npm:@aragon/[email protected]",
"@aragon/osx-v1.0.1": "npm:@aragon/[email protected]",
"@aragon/osx-v1.3.0-rc0.2": "npm:@aragon/[email protected]",
"@defi-wonderland/smock": "^2.3.4",
"@ensdomains/ens-contracts": "0.0.11",
"@nomicfoundation/hardhat-chai-matchers": "^1.0.5",
Expand Down
5 changes: 4 additions & 1 deletion packages/contracts/scripts/osx-versions-aliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@
*
* To add a new version alias, append it to this array.
*/
export const OSX_VERSION_ALIASES = ['@aragon/osx-v1.0.1/'];
export const OSX_VERSION_ALIASES = [
'@aragon/osx-v1.0.1/',
'@aragon/osx-v1.3.0-rc0.2/',
heueristik marked this conversation as resolved.
Show resolved Hide resolved
];
46 changes: 27 additions & 19 deletions packages/contracts/src/core/dao/DAO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ contract DAO is
bytes32 public constant SET_TRUSTED_FORWARDER_PERMISSION_ID =
keccak256("SET_TRUSTED_FORWARDER_PERMISSION");

/// @notice The ID of the permission required to call the `setSignatureValidator` function.
bytes32 public constant SET_SIGNATURE_VALIDATOR_PERMISSION_ID =
keccak256("SET_SIGNATURE_VALIDATOR_PERMISSION");

/// @notice The ID of the permission required to call the `registerStandardCallback` function.
bytes32 public constant REGISTER_STANDARD_CALLBACK_PERMISSION_ID =
keccak256("REGISTER_STANDARD_CALLBACK_PERMISSION");

/// @notice The ID of the permission required to validate [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signatures.
bytes32 public constant VALIDATE_SIGNATURE_PERMISSION_ID =
keccak256("VALIDATE_SIGNATURE_PERMISSION");

/// @notice The internal constant storing the maximal action array length.
uint256 internal constant MAX_ACTIONS = 256;

Expand All @@ -69,9 +69,10 @@ contract DAO is
/// @notice The second out of two values to which the `_reentrancyStatus` state variable (used by the `nonReentrant` modifier) can be set inidicating that a function was entered.
uint256 private constant _ENTERED = 2;

/// @notice The [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract.
/// @dev Added in v1.0.0.
IERC1271 public signatureValidator;
/// @notice Removed variable that is left here to maintain the storage layout.
/// @dev Introducedd in v1.0.0. Removed in v1.4.0.
heueristik marked this conversation as resolved.
Show resolved Hide resolved
/// @custom:oz-renamed-from signatureValidator
address private __removed1;
mathewmeconry marked this conversation as resolved.
Show resolved Hide resolved

/// @notice The address of the trusted forwarder verifying meta transactions.
/// @dev Added in v1.0.0.
Expand Down Expand Up @@ -109,6 +110,9 @@ contract DAO is
/// @notice Thrown if an upgrade is not supported from a specific protocol version .
error ProtocolVersionUpgradeNotSupported(uint8[3] protocolVersion);

/// @notice Thrown when a function is removed but left to not corrupt the interface ID.
error FunctionRemoved();

/// @notice Emitted when a new DAO URI is set.
/// @param daoURI The new URI.
event NewURI(string daoURI);
Expand Down Expand Up @@ -193,7 +197,6 @@ contract DAO is
_permissionId == UPGRADE_DAO_PERMISSION_ID ||
_permissionId == SET_METADATA_PERMISSION_ID ||
_permissionId == SET_TRUSTED_FORWARDER_PERMISSION_ID ||
_permissionId == SET_SIGNATURE_VALIDATOR_PERMISSION_ID ||
_permissionId == REGISTER_STANDARD_CALLBACK_PERMISSION_ID;
}

Expand Down Expand Up @@ -320,25 +323,30 @@ contract DAO is
}

/// @inheritdoc IDAO
function setSignatureValidator(
address _signatureValidator
) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) {
signatureValidator = IERC1271(_signatureValidator);

emit SignatureValidatorSet({signatureValidator: _signatureValidator});
function setSignatureValidator(address) external pure override {
revert FunctionRemoved();
}

/// @inheritdoc IDAO
/// @dev Relays the validation logic determining who is allowed to sign on behalf of the DAO to its permission manager.
/// Caller specific bypassing can be set direct granting (i.e., `grant({_where: dao, _who: specificErc1271Caller, _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID})`).
/// Caller specific signature validation logic can be set by granting with a `PermissionCondition` (i.e., `grantWithCondition({_where: dao, _who: specificErc1271Caller, _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID, _condition: yourConditionImplementation})`)
/// Generic signature validation logic can be set for all calling contracts by granting with a `PermissionCondition` to `PermissionManager.ANY_ADDR()` (i.e., `grantWithCondition({_where: dao, _who: PermissionManager.ANY_ADDR(), _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID, _condition: yourConditionImplementation})`).
function isValidSignature(
bytes32 _hash,
bytes memory _signature
) external view override(IDAO, IERC1271) returns (bytes4) {
if (address(signatureValidator) == address(0)) {
// Return the invalid magic number
return bytes4(0);
if (
isGranted({
_where: address(this),
_who: msg.sender,
_permissionId: VALIDATE_SIGNATURE_PERMISSION_ID,
_data: abi.encode(_hash, _signature)
})
) {
return 0x1626ba7e; // `type(IERC1271).interfaceId` = bytes4(keccak256("isValidSignature(bytes32,bytes)")`
}
// Forward the call to the set signature validator contract
return signatureValidator.isValidSignature(_hash, _signature);
return 0xffffffff; // `bytes4(uint32(type(uint32).max-1))`
mathewmeconry marked this conversation as resolved.
Show resolved Hide resolved
}

/// @notice Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method.
Expand Down
14 changes: 5 additions & 9 deletions packages/contracts/src/core/dao/IDAO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,7 @@ interface IDAO {
/// @param forwarder the new forwarder address.
event TrustedForwarderSet(address forwarder);

/// @notice Setter for the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract.
/// @param _signatureValidator The address of the signature validator.
function setSignatureValidator(address _signatureValidator) external;

/// @notice Emitted when the signature validator address is updated.
/// @param signatureValidator The address of the signature validator.
event SignatureValidatorSet(address signatureValidator);

/// @notice Checks whether a signature is valid for the provided hash by forwarding the call to the set [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract.
/// @notice Checks whether a signature is valid for a provided hash according to [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271).
/// @param _hash The hash of the data to be signed.
/// @param _signature The signature byte array associated with `_hash`.
/// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid.
Expand All @@ -135,4 +127,8 @@ interface IDAO {
bytes4 _callbackSelector,
bytes4 _magicNumber
) external;

/// @notice Removed function being left here to not corrupt the IDAO interface ID. Any call will revert.
/// @dev Introduced in v1.0.0. Removed in v1.4.0.
function setSignatureValidator(address) external;
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ abstract contract PermissionManager is Initializable {
error ConditionInterfacNotSupported(IPermissionCondition condition);

/// @notice Thrown for `ROOT_PERMISSION_ID` or `EXECUTE_PERMISSION_ID` permission grants where `who` or `where` is `ANY_ADDR`.

error PermissionsForAnyAddressDisallowed();

/// @notice Thrown for permission grants where `who` and `where` are both `ANY_ADDR`.
Expand Down
11 changes: 3 additions & 8 deletions packages/contracts/src/framework/dao/DAOFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ contract DAOFactory is ERC165, ProtocolVersion {
function _setDAOPermissions(DAO _dao) internal {
// set permissionIds on the dao itself.
PermissionLib.SingleTargetPermission[]
memory items = new PermissionLib.SingleTargetPermission[](6);
memory items = new PermissionLib.SingleTargetPermission[](5);

// Grant DAO all the permissions required
items[0] = PermissionLib.SingleTargetPermission(
Expand All @@ -183,21 +183,16 @@ contract DAOFactory is ERC165, ProtocolVersion {
_dao.UPGRADE_DAO_PERMISSION_ID()
);
items[2] = PermissionLib.SingleTargetPermission(
PermissionLib.Operation.Grant,
address(_dao),
_dao.SET_SIGNATURE_VALIDATOR_PERMISSION_ID()
);
items[3] = PermissionLib.SingleTargetPermission(
PermissionLib.Operation.Grant,
address(_dao),
_dao.SET_TRUSTED_FORWARDER_PERMISSION_ID()
);
items[4] = PermissionLib.SingleTargetPermission(
items[3] = PermissionLib.SingleTargetPermission(
PermissionLib.Operation.Grant,
address(_dao),
_dao.SET_METADATA_PERMISSION_ID()
);
items[5] = PermissionLib.SingleTargetPermission(
items[4] = PermissionLib.SingleTargetPermission(
PermissionLib.Operation.Grant,
address(_dao),
_dao.REGISTER_STANDARD_CALLBACK_PERMISSION_ID()
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/src/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aragon/osx",
"version": "1.3.1-rc0",
"version": "1.4.0-rc0",
"description": "The Aragon OSx Solidity contracts",
"publishConfig": {
"access": "public"
Expand Down
16 changes: 16 additions & 0 deletions packages/contracts/src/test/Migration.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,30 @@ pragma solidity 0.8.17;
*/

import {DAO as DAO_v1_0_0} from "@aragon/osx-v1.0.1/core/dao/DAO.sol";
import {DAO as DAO_v1_3_0} from "@aragon/osx-v1.3.0-rc0.2/core/dao/DAO.sol";
import {DAORegistry as DAORegistry_v1_0_0} from "@aragon/osx-v1.0.1/framework/dao/DAORegistry.sol";
import {DAORegistry as DAORegistry_v1_3_0} from "@aragon/osx-v1.3.0-rc0.2/framework/dao/DAORegistry.sol";

import {PluginRepo as PluginRepo_v1_0_0} from "@aragon/osx-v1.0.1/framework/plugin/repo/PluginRepo.sol";
import {PluginRepo as PluginRepo_v1_3_0} from "@aragon/osx-v1.3.0-rc0.2/framework/plugin/repo/PluginRepo.sol";

import {PluginRepoRegistry as PluginRepoRegistry_v1_0_0} from "@aragon/osx-v1.0.1/framework/plugin/repo/PluginRepoRegistry.sol";
import {PluginRepoRegistry as PluginRepoRegistry_v1_3_0} from "@aragon/osx-v1.3.0-rc0.2/framework/plugin/repo/PluginRepoRegistry.sol";

import {ENSSubdomainRegistrar as ENSSubdomainRegistrar_v1_0_0} from "@aragon/osx-v1.0.1/framework/utils/ens/ENSSubdomainRegistrar.sol";
import {ENSSubdomainRegistrar as ENSSubdomainRegistrar_v1_3_0} from "@aragon/osx-v1.3.0-rc0.2/framework/utils/ens/ENSSubdomainRegistrar.sol";

import {TokenVoting as TokenVoting_v1_0_0} from "@aragon/osx-v1.0.1/plugins/governance/majority-voting/token/TokenVoting.sol";
import {TokenVoting as TokenVoting_v1_3_0} from "@aragon/osx-v1.3.0-rc0.2/plugins/governance/majority-voting/token/TokenVoting.sol";

import {AddresslistVoting as AddresslistVoting_v1_0_0} from "@aragon/osx-v1.0.1/plugins/governance/majority-voting/addresslist/AddresslistVoting.sol";
import {AddresslistVoting as AddresslistVoting_v1_3_0} from "@aragon/osx-v1.3.0-rc0.2/plugins/governance/majority-voting/addresslist/AddresslistVoting.sol";

import {Multisig as Multisig_v1_0_0} from "@aragon/osx-v1.0.1/plugins/governance/multisig/Multisig.sol";
import {Multisig as Multisig_v1_3_0} from "@aragon/osx-v1.3.0-rc0.2/plugins/governance/multisig/Multisig.sol";

import {MerkleMinter as MerkleMinter_v1_0_0} from "@aragon/osx-v1.0.1/plugins/token/MerkleMinter.sol";
import {MerkleMinter as MerkleMinter_v1_3_0} from "@aragon/osx-v1.3.0-rc0.2/plugins/token/MerkleMinter.sol";

import {MerkleDistributor as MerkleDistributor_v1_0_0} from "@aragon/osx-v1.0.1/plugins/token/MerkleDistributor.sol";
import {MerkleDistributor as MerkleDistributor_v1_3_0} from "@aragon/osx-v1.3.0-rc0.2/plugins/token/MerkleDistributor.sol";
9 changes: 0 additions & 9 deletions packages/contracts/src/test/dao/ERC1271Mock.sol

This file was deleted.

25 changes: 15 additions & 10 deletions packages/contracts/src/test/permission/PermissionConditionMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@ pragma solidity 0.8.17;
import "../../core/permission/PermissionCondition.sol";

contract PermissionConditionMock is PermissionCondition {
bool internal _hasPermissionsResult = true;
bool public answer;

function isGranted(
address /* _where */,
address /* _who */,
bytes32 /* _permissionId */,
bytes memory /* _data */
) external view returns (bool) {
return _hasPermissionsResult;
constructor() {
answer = true;
}

function setAnswer(bool _answer) external {
answer = _answer;
}

function setWillPerform(bool _result) external {
_hasPermissionsResult = _result;
function isGranted(
address _where,
address _who,
bytes32 _permissionId,
bytes memory _data
) external view returns (bool) {
(_where, _who, _permissionId, _data);
return answer;
}
}
2 changes: 1 addition & 1 deletion packages/contracts/src/utils/protocol/ProtocolVersion.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ abstract contract ProtocolVersion is IProtocolVersion {

/// @inheritdoc IProtocolVersion
function protocolVersion() public pure returns (uint8[3] memory) {
return [1, 3, 0];
return [1, 4, 0];
}
}
Loading
Loading