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: use custom error for onlyOwner and address(0) check #236

Merged
merged 7 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 13 additions & 5 deletions .github/workflows/solc_version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,23 @@ jobs:
strategy:
matrix:
solc: [
"0.8.5",
"0.8.6",
"0.8.7",
"0.8.8",
"0.8.9",
# "0.8.10" skipped as default in hardhat.config.ts
"0.8.10",
"0.8.11",
"0.8.12",
"0.8.13",
"0.8.14",
"0.8.15",
"0.8.16",
"0.8.17",
# "0.8.17", # skipped as default in hardhat.config.ts
"0.8.18",
"0.8.19",
"0.8.20",
"0.8.21"
]
steps:
- uses: actions/checkout@v3
Expand All @@ -51,6 +58,7 @@ jobs:

- name: Compile Smart Contracts
run: |
solc contracts/**/*.sol \
@openzeppelin/=node_modules/@openzeppelin/ \
solidity-bytes-utils/=node_modules/solidity-bytes-utils/
solc contracts/**/*.sol --allow-paths $(pwd)/node_modules/ \
@openzeppelin/=$(pwd)/node_modules/@openzeppelin/ \
solidity-bytes-utils/=$(pwd)/node_modules/solidity-bytes-utils/ \
../=$(pwd)/contracts/
12 changes: 7 additions & 5 deletions implementations/contracts/ERC725.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.5;

// modules
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
Expand All @@ -10,6 +10,9 @@ import {ERC725YCore} from "./ERC725YCore.sol";
// constants
import {_INTERFACEID_ERC725X, _INTERFACEID_ERC725Y} from "./constants.sol";

// errors
import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol";

/**
* @title ERC725 bundle.
* @author Fabian Vogelsteller <[email protected]>
Expand All @@ -27,10 +30,9 @@ contract ERC725 is ERC725XCore, ERC725YCore {
* - `initialOwner` CANNOT be the zero address.
*/
constructor(address initialOwner) payable {
require(
initialOwner != address(0),
"Ownable: new owner is the zero address"
);
if (initialOwner == address(0)) {
revert OwnableCannotSetZeroAddressAsOwner();
}
OwnableUnset._setOwner(initialOwner);
}

Expand Down
2 changes: 1 addition & 1 deletion implementations/contracts/ERC725Init.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.5;

// modules
import {ERC725InitAbstract} from "./ERC725InitAbstract.sol";
Expand Down
12 changes: 7 additions & 5 deletions implementations/contracts/ERC725InitAbstract.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.5;

// modules
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
Expand All @@ -13,6 +13,9 @@ import {ERC725YCore} from "./ERC725YCore.sol";
// constants
import {_INTERFACEID_ERC725X, _INTERFACEID_ERC725Y} from "./constants.sol";

// errors
import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol";

/**
* @title Inheritable Proxy Implementation of ERC725 bundle
* @author Fabian Vogelsteller <[email protected]>
Expand All @@ -35,10 +38,9 @@ abstract contract ERC725InitAbstract is
function _initialize(
address initialOwner
) internal virtual onlyInitializing {
require(
initialOwner != address(0),
"Ownable: new owner is the zero address"
);
if (initialOwner == address(0)) {
revert OwnableCannotSetZeroAddressAsOwner();
}
OwnableUnset._setOwner(initialOwner);
}

Expand Down
12 changes: 7 additions & 5 deletions implementations/contracts/ERC725X.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.5;

// modules
import {OwnableUnset} from "./custom/OwnableUnset.sol";
import {ERC725XCore} from "./ERC725XCore.sol";

// errors
import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol";

/**
* @title Deployable implementation with `constructor` of ERC725X, a generic executor.
* @author Fabian Vogelsteller <[email protected]>
Expand All @@ -23,10 +26,9 @@ contract ERC725X is ERC725XCore {
* - `initialOwner` CANNOT be the zero address.
*/
constructor(address initialOwner) payable {
require(
initialOwner != address(0),
"Ownable: new owner is the zero address"
);
if (initialOwner == address(0)) {
revert OwnableCannotSetZeroAddressAsOwner();
}
OwnableUnset._setOwner(initialOwner);
}
}
2 changes: 1 addition & 1 deletion implementations/contracts/ERC725XCore.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.5;

// interfaces
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
Expand Down
2 changes: 1 addition & 1 deletion implementations/contracts/ERC725XInit.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.5;

// modules
import {ERC725XInitAbstract} from "./ERC725XInitAbstract.sol";
Expand Down
12 changes: 7 additions & 5 deletions implementations/contracts/ERC725XInitAbstract.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.5;

// modules
import {
Expand All @@ -8,6 +8,9 @@ import {
import {OwnableUnset} from "./custom/OwnableUnset.sol";
import {ERC725XCore} from "./ERC725XCore.sol";

// errors
import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol";

/**
* @title Inheritable Proxy Implementation of ERC725X, a generic executor.
* @author Fabian Vogelsteller <[email protected]>
Expand All @@ -27,10 +30,9 @@ abstract contract ERC725XInitAbstract is Initializable, ERC725XCore {
function _initialize(
address initialOwner
) internal virtual onlyInitializing {
require(
initialOwner != address(0),
"Ownable: new owner is the zero address"
);
if (initialOwner == address(0)) {
revert OwnableCannotSetZeroAddressAsOwner();
}
OwnableUnset._setOwner(initialOwner);
}
}
12 changes: 7 additions & 5 deletions implementations/contracts/ERC725Y.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.4;

// modules
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {OwnableUnset} from "./custom/OwnableUnset.sol";
import {ERC725YCore} from "./ERC725YCore.sol";

// errors
import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol";

/**
* @title Deployable implementation with `constructor` of ERC725Y, a generic data key/value store.
* @author Fabian Vogelsteller <[email protected]>
Expand All @@ -22,10 +25,9 @@ contract ERC725Y is ERC725YCore {
* - `initialOwner` CANNOT be the zero address.
*/
constructor(address initialOwner) payable {
require(
initialOwner != address(0),
"Ownable: new owner is the zero address"
);
if (initialOwner == address(0)) {
revert OwnableCannotSetZeroAddressAsOwner();
}
OwnableUnset._setOwner(initialOwner);
}
}
2 changes: 1 addition & 1 deletion implementations/contracts/ERC725YCore.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.4;

// interfaces
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
Expand Down
2 changes: 1 addition & 1 deletion implementations/contracts/ERC725YInit.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.4;

// modules
import {ERC725YInitAbstract} from "./ERC725YInitAbstract.sol";
Expand Down
12 changes: 7 additions & 5 deletions implementations/contracts/ERC725YInitAbstract.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.4;

// modules
import {
Expand All @@ -8,6 +8,9 @@ import {
import {OwnableUnset} from "./custom/OwnableUnset.sol";
import {ERC725YCore} from "./ERC725YCore.sol";

// errors
import {OwnableCannotSetZeroAddressAsOwner} from "./errors.sol";

/**
* @title Inheritable Proxy Implementation of ERC725Y, a generic data key/value store
* @author Fabian Vogelsteller <[email protected]>
Expand All @@ -25,10 +28,9 @@ abstract contract ERC725YInitAbstract is Initializable, ERC725YCore {
function _initialize(
address initialOwner
) internal virtual onlyInitializing {
require(
initialOwner != address(0),
"Ownable: new owner is the zero address"
);
if (initialOwner == address(0)) {
revert OwnableCannotSetZeroAddressAsOwner();
}
OwnableUnset._setOwner(initialOwner);
}
}
19 changes: 13 additions & 6 deletions implementations/contracts/custom/OwnableUnset.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
pragma solidity ^0.8.4;

// errors
import {
OwnableCannotSetZeroAddressAsOwner,
OwnableCallerNotTheOwner
} from "../errors.sol";

/**
* @title OwnableUnset
Expand Down Expand Up @@ -47,18 +53,19 @@ abstract contract OwnableUnset {
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
if (newOwner == address(0)) {
revert OwnableCannotSetZeroAddressAsOwner();
}
_setOwner(newOwner);
}

/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == msg.sender, "Ownable: caller is not the owner");
if (owner() != msg.sender) {
revert OwnableCallerNotTheOwner(msg.sender);
}
}

/**
Expand Down
14 changes: 13 additions & 1 deletion implementations/contracts/errors.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
pragma solidity ^0.8.4;

/**
* @dev Reverts when trying to set `address(0)` as the contract owner when deploying the contract,
* initializing it or transferring ownership of the contract.
*/
error OwnableCannotSetZeroAddressAsOwner();

/**
* @dev Reverts when only the owner is allowed to call the function.
* @param callerAddress The address that tried to make the call.
*/
error OwnableCallerNotTheOwner(address callerAddress);

/**
* @dev Reverts when trying to send more native tokens `value` than available in current `balance`.
Expand Down
11 changes: 7 additions & 4 deletions implementations/test/ERC725.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ describe('ERC725', () => {
newOwner: ethers.constants.AddressZero,
};

await expect(
new ERC725__factory(accounts[0]).deploy(deployParams.newOwner),
).to.be.revertedWith('Ownable: new owner is the zero address');
const contractToDeploy = new ERC725__factory(accounts[0]);

await expect(contractToDeploy.deploy(deployParams.newOwner)).to.be.revertedWithCustomError(
contractToDeploy,
'OwnableCannotSetZeroAddressAsOwner',
);
});

it("should deploy the contract with the owner's address", async () => {
Expand Down Expand Up @@ -108,7 +111,7 @@ describe('ERC725', () => {
it('should revert when initializing with address(0) as owner', async () => {
await expect(
context.erc725['initialize(address)'](ethers.constants.AddressZero),
).to.be.revertedWith('Ownable: new owner is the zero address');
).to.be.revertedWithCustomError(context.erc725, 'OwnableCannotSetZeroAddressAsOwner');
});

it("should initialize the contract with the owner's address", async () => {
Expand Down
16 changes: 12 additions & 4 deletions implementations/test/ERC725X.behaviour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ export const shouldBehaveLikeERC725X = (buildContext: () => Promise<ERC725XTestC

expect(accountOwner).to.equal(context.accounts.anyone.address);
});

it('should revert when transferring ownership to `address(0)`', async () => {
await expect(
context.erc725X
.connect(context.accounts.owner)
.transferOwnership(ethers.constants.AddressZero),
).to.be.revertedWithCustomError(context.erc725X, 'OwnableCannotSetZeroAddressAsOwner');
});
});

describe('When non-owner is transferring ownership', () => {
Expand All @@ -126,7 +134,7 @@ export const shouldBehaveLikeERC725X = (buildContext: () => Promise<ERC725XTestC
context.erc725X
.connect(context.accounts.anyone)
.transferOwnership(context.accounts.anyone.address),
).to.be.revertedWith('Ownable: caller is not the owner');
).to.be.revertedWithCustomError(context.erc725X, 'OwnableCallerNotTheOwner');
});
});

Expand All @@ -146,7 +154,7 @@ export const shouldBehaveLikeERC725X = (buildContext: () => Promise<ERC725XTestC
it('should revert', async () => {
await expect(
context.erc725X.connect(context.accounts.anyone).renounceOwnership(),
).to.be.revertedWith('Ownable: caller is not the owner');
).to.be.revertedWithCustomError(context.erc725X, 'OwnableCallerNotTheOwner');
});
});
});
Expand Down Expand Up @@ -196,7 +204,7 @@ export const shouldBehaveLikeERC725X = (buildContext: () => Promise<ERC725XTestC
context.erc725X
.connect(context.accounts.anyone)
.execute(txParams.Operation, txParams.to, txParams.value, txParams.data),
).to.be.revertedWith('Ownable: caller is not the owner');
).to.be.revertedWithCustomError(context.erc725X, 'OwnableCallerNotTheOwner');
});
});
});
Expand Down Expand Up @@ -1624,7 +1632,7 @@ export const shouldBehaveLikeERC725X = (buildContext: () => Promise<ERC725XTestC
context.erc725X
.connect(context.accounts.anyone)
.executeBatch(txParams.Operations, txParams.to, txParams.values, txParams.data),
).to.be.revertedWith('Ownable: caller is not the owner');
).to.be.revertedWithCustomError(context.erc725X, 'OwnableCallerNotTheOwner');
});
});
});
Expand Down
Loading
Loading