diff --git a/.gitmodules b/.gitmodules index 888d42dcd9..e1e7d6c2c5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "lib/forge-std"] path = lib/forge-std url = https://github.com/foundry-rs/forge-std +[submodule "lib/openzeppelin-contracts"] + path = lib/openzeppelin-contracts + url = https://github.com/OpenZeppelin/openzeppelin-contracts.git + branch = release-v5.4 diff --git a/README.md b/README.md index d7a2a27f42..58d9cad140 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
-
+
diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts
new file mode 160000
index 0000000000..c64a1edb67
--- /dev/null
+++ b/lib/openzeppelin-contracts
@@ -0,0 +1 @@
+Subproject commit c64a1edb67b6e3f4a15cca8909c9482ad33a02b0
diff --git a/package.json b/package.json
index dc0dc21352..d773f2e872 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
},
"scripts": {
"prepare": "husky && npm run git-submodule:init",
+ "postinstall": "ln -fs ../lib/openzeppelin-contracts node_modules/@openzeppelin-v5",
"lint": "run-s -l lint:*",
"lint:syncpack": "syncpack lint",
"lint:shellcheck": "tasks/shellcheck-all-tasks.sh",
diff --git a/packages/automation-contracts/autowrap/contracts/Manager.sol b/packages/automation-contracts/autowrap/contracts/Manager.sol
index 50e6a3d603..435678ea04 100644
--- a/packages/automation-contracts/autowrap/contracts/Manager.sol
+++ b/packages/automation-contracts/autowrap/contracts/Manager.sol
@@ -31,7 +31,7 @@ contract Manager is IManager, Ownable {
address _cfa,
uint64 _minLower,
uint64 _minUpper
- ) {
+ ) Ownable(_msgSender()) {
if (_cfa == address(0)) revert ZeroAddress();
if (_minLower >= _minUpper) revert WrongLimits(_minLower, _minUpper);
diff --git a/packages/automation-contracts/autowrap/contracts/strategies/StrategyBase.sol b/packages/automation-contracts/autowrap/contracts/strategies/StrategyBase.sol
index ffd3902005..ae1787fef9 100644
--- a/packages/automation-contracts/autowrap/contracts/strategies/StrategyBase.sol
+++ b/packages/automation-contracts/autowrap/contracts/strategies/StrategyBase.sol
@@ -14,6 +14,8 @@ abstract contract StrategyBase is IStrategy, Ownable {
/// @dev IStrategy.manager implementation.
address public override manager;
+ constructor() Ownable(_msgSender()) { }
+
/// @dev IStrategy.changeManager implementation.
function changeManager(address newManager)
external
diff --git a/packages/automation-contracts/autowrap/foundry.toml b/packages/automation-contracts/autowrap/foundry.toml
index 1f6a37e505..a724979827 100644
--- a/packages/automation-contracts/autowrap/foundry.toml
+++ b/packages/automation-contracts/autowrap/foundry.toml
@@ -9,7 +9,8 @@ optimizer_runs = 200
remappings = [
'@superfluid-finance/solidity-semantic-money/src/=packages/solidity-semantic-money/src/',
'@superfluid-finance/ethereum-contracts/=packages/ethereum-contracts/',
- '@openzeppelin/=node_modules/@openzeppelin/',
+ '@openzeppelin-v5/=lib/openzeppelin-contracts/',
+ '@openzeppelin/=lib/openzeppelin-contracts/',
'ds-test/=lib/forge-std/lib/ds-test/src/',
'forge-std/=lib/forge-std/src/']
out = 'packages/automation-contracts/autowrap/out/default'
diff --git a/packages/automation-contracts/autowrap/hardhat.config.js b/packages/automation-contracts/autowrap/hardhat.config.js
index 923ae77b0e..5a81333b34 100644
--- a/packages/automation-contracts/autowrap/hardhat.config.js
+++ b/packages/automation-contracts/autowrap/hardhat.config.js
@@ -4,10 +4,22 @@ require("@nomiclabs/hardhat-etherscan");
require("hardhat-deploy");
require("hardhat/config");
require("./script/addStrategy");
+const {TASK_COMPILE_GET_REMAPPINGS} = require("hardhat/builtin-tasks/task-names");
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more
+// Remapping for OpenZeppelin contracts
+subtask(TASK_COMPILE_GET_REMAPPINGS).setAction(
+ async (_, __, runSuper) => {
+ const remappings = await runSuper();
+ return {
+ ...remappings,
+ "@openzeppelin/contracts/": "@openzeppelin-v5/contracts/",
+ };
+ }
+);
+
/**
* @type import('hardhat/config').HardhatUserConfig
*/
diff --git a/packages/automation-contracts/autowrap/package.json b/packages/automation-contracts/autowrap/package.json
index 210a9aa315..aa2f8489d7 100644
--- a/packages/automation-contracts/autowrap/package.json
+++ b/packages/automation-contracts/autowrap/package.json
@@ -3,7 +3,6 @@
"description": "Open contracts that allow upgrading underlying token to supertokens based on running stream",
"version": "0.3.0",
"devDependencies": {
- "@openzeppelin/contracts": "^4.9.6",
"@superfluid-finance/ethereum-contracts": "^1.13.0",
"@superfluid-finance/metadata": "^1.6.0"
},
diff --git a/packages/automation-contracts/autowrap/test/Manager.t.sol b/packages/automation-contracts/autowrap/test/Manager.t.sol
index 1441948c5c..c9d244914a 100644
--- a/packages/automation-contracts/autowrap/test/Manager.t.sol
+++ b/packages/automation-contracts/autowrap/test/Manager.t.sol
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
+import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/superfluid/SuperToken.sol";
import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol";
@@ -108,7 +109,7 @@ contract ManagerTests is FoundrySuperfluidTester {
vm.prank(admin);
manager.setLimits(newMinLower, newMinUpper);
// non owner can't set new limits
- vm.expectRevert(bytes("Ownable: caller is not the owner"));
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, address(this)));
manager.setLimits(newMinLower, newMinUpper);
}
@@ -124,7 +125,7 @@ contract ManagerTests is FoundrySuperfluidTester {
manager.addApprovedStrategy(address(wrapStrategy));
vm.stopPrank();
// non owner can't add new strategy
- vm.expectRevert(bytes("Ownable: caller is not the owner"));
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, address(this)));
manager.addApprovedStrategy(address(wrapStrategy));
bool isStrategyApproved = manager.approvedStrategies(address(wrapStrategy));
assertTrue(isStrategyApproved, "strategy should be register");
@@ -135,7 +136,7 @@ contract ManagerTests is FoundrySuperfluidTester {
//add strategy to be removed
manager.addApprovedStrategy(address(wrapStrategy));
// non owner can't add new strategy
- vm.expectRevert(bytes("Ownable: caller is not the owner"));
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, address(this)));
manager.removeApprovedStrategy(address(wrapStrategy));
vm.startPrank(admin);
vm.expectEmit(true, true, true, true);
diff --git a/packages/automation-contracts/autowrap/test/WrapStrategy.t.sol b/packages/automation-contracts/autowrap/test/WrapStrategy.t.sol
index 9d56150faf..57631cc57b 100644
--- a/packages/automation-contracts/autowrap/test/WrapStrategy.t.sol
+++ b/packages/automation-contracts/autowrap/test/WrapStrategy.t.sol
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
+import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/superfluid/SuperToken.sol";
import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol";
@@ -75,7 +76,7 @@ contract WrapStrategyTests is FoundrySuperfluidTester {
function testCannotChangeManagerContractIfNotOwner() public {
Manager newManager = new Manager(address(sf.cfa), MIN_LOWER, MIN_UPPER);
vm.prank(admin);
- vm.expectRevert(bytes("Ownable: caller is not the owner"));
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, admin));
wrapStrategy.changeManager(address(newManager));
}
diff --git a/packages/automation-contracts/scheduler/contracts/VestingSchedulerV2.sol b/packages/automation-contracts/scheduler/contracts/VestingSchedulerV2.sol
index 54bba3b547..c09fe2e837 100644
--- a/packages/automation-contracts/scheduler/contracts/VestingSchedulerV2.sol
+++ b/packages/automation-contracts/scheduler/contracts/VestingSchedulerV2.sol
@@ -7,7 +7,6 @@ import {
import { SuperAppBase } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperAppBase.sol";
import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
import { IVestingSchedulerV2 } from "./interface/IVestingSchedulerV2.sol";
-import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
contract VestingSchedulerV2 is IVestingSchedulerV2, SuperAppBase {
@@ -221,10 +220,7 @@ contract VestingSchedulerV2 is IVestingSchedulerV2, SuperAppBase {
remainderAmount: remainderAmount
});
} else {
- uint256 cliffAmount = SafeMath.mul(
- cliffPeriod,
- SafeCast.toUint256(flowRate)
- );
+ uint256 cliffAmount = cliffPeriod * SafeCast.toUint256(flowRate);
params = ScheduleCreationParams({
superToken: superToken,
sender: sender,
diff --git a/packages/automation-contracts/scheduler/contracts/VestingSchedulerV3.sol b/packages/automation-contracts/scheduler/contracts/VestingSchedulerV3.sol
index d726ea4197..4025220fb1 100644
--- a/packages/automation-contracts/scheduler/contracts/VestingSchedulerV3.sol
+++ b/packages/automation-contracts/scheduler/contracts/VestingSchedulerV3.sol
@@ -3,7 +3,6 @@
pragma solidity ^0.8.0;
/// @dev OpenZeppelin Imports
-import {SafeMath} from "@openzeppelin/contracts/utils/math/SafeMath.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
/// @dev Superfluid Protocol Imports
@@ -532,7 +531,7 @@ contract VestingSchedulerV3 is IVestingSchedulerV3, IRelayRecipient {
});
} else {
// Linear Default Cliff (calculated based on the overall vesting flow rate)
- cliffAmount = SafeMath.mul(cliffPeriod, SafeCast.toUint256(flowRate));
+ cliffAmount = cliffPeriod * SafeCast.toUint256(flowRate);
params = ScheduleCreationParams({
superToken: superToken,
sender: sender,
diff --git a/packages/automation-contracts/scheduler/foundry.toml b/packages/automation-contracts/scheduler/foundry.toml
index 102964fdb5..d430bfbe9f 100644
--- a/packages/automation-contracts/scheduler/foundry.toml
+++ b/packages/automation-contracts/scheduler/foundry.toml
@@ -9,7 +9,8 @@ optimizer_runs = 200
remappings = [
'@superfluid-finance/solidity-semantic-money/src/=packages/solidity-semantic-money/src/',
'@superfluid-finance/ethereum-contracts/=packages/ethereum-contracts/',
- '@openzeppelin/=node_modules/@openzeppelin/',
+ '@openzeppelin-v5/=lib/openzeppelin-contracts/',
+ '@openzeppelin/=lib/openzeppelin-contracts/',
'ds-test/=lib/forge-std/lib/ds-test/src/',
'forge-std/=lib/forge-std/src/']
out = 'packages/automation-contracts/scheduler/out/default'
diff --git a/packages/automation-contracts/scheduler/hardhat.config.js b/packages/automation-contracts/scheduler/hardhat.config.js
index 8db0889983..a9e469ef6e 100644
--- a/packages/automation-contracts/scheduler/hardhat.config.js
+++ b/packages/automation-contracts/scheduler/hardhat.config.js
@@ -3,10 +3,22 @@ require("@nomiclabs/hardhat-ethers");
require("@nomiclabs/hardhat-etherscan");
require("hardhat-deploy");
require("hardhat/config");
+const {TASK_COMPILE_GET_REMAPPINGS} = require("hardhat/builtin-tasks/task-names");
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more
+// Remapping for OpenZeppelin contracts
+subtask(TASK_COMPILE_GET_REMAPPINGS).setAction(
+ async (_, __, runSuper) => {
+ const remappings = await runSuper();
+ return {
+ ...remappings,
+ "@openzeppelin/contracts/": "@openzeppelin-v5/contracts/",
+ };
+ }
+);
+
/**
* @type import('hardhat/config').HardhatUserConfig
*/
diff --git a/packages/automation-contracts/scheduler/package.json b/packages/automation-contracts/scheduler/package.json
index 1d31a2e123..2d61476077 100644
--- a/packages/automation-contracts/scheduler/package.json
+++ b/packages/automation-contracts/scheduler/package.json
@@ -3,7 +3,6 @@
"description": "Open contracts that allow scheduling streams and vestings onchain",
"version": "1.3.0",
"devDependencies": {
- "@openzeppelin/contracts": "^4.9.6",
"@superfluid-finance/ethereum-contracts": "^1.13.0",
"@superfluid-finance/metadata": "^1.6.0"
},
diff --git a/packages/automation-contracts/scheduler/test/VestingSchedulerV2.t.sol b/packages/automation-contracts/scheduler/test/VestingSchedulerV2.t.sol
index 73c42cb5d6..16b5cb2a6a 100644
--- a/packages/automation-contracts/scheduler/test/VestingSchedulerV2.t.sol
+++ b/packages/automation-contracts/scheduler/test/VestingSchedulerV2.t.sol
@@ -7,7 +7,6 @@ import { IVestingSchedulerV2 } from "./../contracts/interface/IVestingSchedulerV
import { VestingSchedulerV2 } from "./../contracts/VestingSchedulerV2.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol";
import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
-import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import "forge-std/console.sol";
@@ -899,7 +898,7 @@ contract VestingSchedulerV2Tests is FoundrySuperfluidTester {
);
console.log("Revert with overflow.");
- vm.expectRevert("SafeCast: value doesn't fit in 96 bits");
+ vm.expectRevert(); // SafeCastOverflowedIntDowncast
vestingScheduler.createVestingScheduleFromAmountAndDuration(
superToken,
bob,
@@ -1961,7 +1960,7 @@ contract VestingSchedulerV2Tests is FoundrySuperfluidTester {
);
console.log("Revert with overflow.");
- vm.expectRevert("SafeCast: value doesn't fit in 96 bits");
+ vm.expectRevert(); // SafeCastOverflowedIntDowncast
vestingScheduler.createVestingScheduleFromAmountAndDuration(
superToken,
bob,
diff --git a/packages/automation-contracts/scheduler/test/VestingSchedulerV3.t.sol b/packages/automation-contracts/scheduler/test/VestingSchedulerV3.t.sol
index ce5282242e..89b3984180 100644
--- a/packages/automation-contracts/scheduler/test/VestingSchedulerV3.t.sol
+++ b/packages/automation-contracts/scheduler/test/VestingSchedulerV3.t.sol
@@ -1105,7 +1105,7 @@ contract VestingSchedulerV3Tests is FoundrySuperfluidTester {
);
console.log("Revert with overflow.");
- vm.expectRevert("SafeCast: value doesn't fit in 96 bits");
+ vm.expectRevert(); // SafeCastOverflowedIntDowncast
vestingScheduler.createVestingScheduleFromAmountAndDuration(
superToken,
bob,
@@ -2189,7 +2189,7 @@ contract VestingSchedulerV3Tests is FoundrySuperfluidTester {
);
console.log("Revert with overflow.");
- vm.expectRevert("SafeCast: value doesn't fit in 96 bits");
+ vm.expectRevert(); // SafeCastOverflowedIntDowncast
vestingScheduler.createVestingScheduleFromAmountAndDuration(
superToken,
bob,
diff --git a/packages/ethereum-contracts/CHANGELOG.md b/packages/ethereum-contracts/CHANGELOG.md
index 30ab0e7116..dbaa27f513 100644
--- a/packages/ethereum-contracts/CHANGELOG.md
+++ b/packages/ethereum-contracts/CHANGELOG.md
@@ -20,6 +20,24 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- `ISuperfluidPool`: `getClaimable` and `getClaimableNow` could previously return non-zero values for connected pools, which was inconsistent with what `claimAll` would actually do in this situation (claim nothing).
### Breaking
+- Updated OpenZeppelin library from v.4.9.6 to v5.4.0.
+The import path now includes the major version, making it easier for contracts integrating with this protocol to use a different major version of OpenZeppelin.
+Projects using Superfluid contracts as a dependency need to configure a mapping:
+ - Foundry: add this to remappings: `'@openzeppelin-v5/=lib/openzeppelin-contracts/',`
+ - Hardhat (>=v2.17.2): add `@openzeppelin/contracts` as a project dependency and a subtask in your hardhat config:
+```
+import { TASK_COMPILE_GET_REMAPPINGS } from "hardhat/builtin-tasks/task-names";
+
+subtask(TASK_COMPILE_GET_REMAPPINGS).setAction(
+ async (_, __, runSuper) => {
+ const remappings = await runSuper();
+ return {
+ ...remappings,
+ "@openzeppelin-v5/contracts/": "@openzeppelin/contracts/",
+ };
+ }
+);
+```
- PoolMemberNFT pruning: `IPoolMemberNFT` and `PoolMemberNFT` removed, `POOL_MEMBER_NFT()` removed from `ISuperToken`.
## [v1.13.0]
diff --git a/packages/ethereum-contracts/contracts/agreements/AgreementLibrary.sol b/packages/ethereum-contracts/contracts/agreements/AgreementLibrary.sol
index 6d7324c214..22d4e66ddb 100644
--- a/packages/ethereum-contracts/contracts/agreements/AgreementLibrary.sol
+++ b/packages/ethereum-contracts/contracts/agreements/AgreementLibrary.sol
@@ -9,7 +9,7 @@ import {
} from "../interfaces/superfluid/ISuperfluid.sol";
import { ISuperfluidToken } from "../interfaces/superfluid/ISuperfluidToken.sol";
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
/**
diff --git a/packages/ethereum-contracts/contracts/agreements/ConstantFlowAgreementV1.sol b/packages/ethereum-contracts/contracts/agreements/ConstantFlowAgreementV1.sol
index bf225b729b..ec7a840200 100644
--- a/packages/ethereum-contracts/contracts/agreements/ConstantFlowAgreementV1.sol
+++ b/packages/ethereum-contracts/contracts/agreements/ConstantFlowAgreementV1.sol
@@ -13,7 +13,7 @@ import {
SuperfluidGovernanceConfigs
} from "../interfaces/superfluid/ISuperfluid.sol";
import { AgreementBase } from "./AgreementBase.sol";
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
import { AgreementLibrary } from "./AgreementLibrary.sol";
import { SolvencyHelperLibrary } from "../libs/SolvencyHelperLibrary.sol";
diff --git a/packages/ethereum-contracts/contracts/agreements/InstantDistributionAgreementV1.sol b/packages/ethereum-contracts/contracts/agreements/InstantDistributionAgreementV1.sol
index 701852a2c4..1481e1d8f1 100644
--- a/packages/ethereum-contracts/contracts/agreements/InstantDistributionAgreementV1.sol
+++ b/packages/ethereum-contracts/contracts/agreements/InstantDistributionAgreementV1.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
import {
IInstantDistributionAgreementV1, ISuperfluidToken
diff --git a/packages/ethereum-contracts/contracts/agreements/gdav1/GDAv1StorageLayout.sol b/packages/ethereum-contracts/contracts/agreements/gdav1/GDAv1StorageLayout.sol
index ea768eb77c..7e4ba559d7 100644
--- a/packages/ethereum-contracts/contracts/agreements/gdav1/GDAv1StorageLayout.sol
+++ b/packages/ethereum-contracts/contracts/agreements/gdav1/GDAv1StorageLayout.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
// open-zeppelin
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
// semantic-money
import {
BasicParticle,
diff --git a/packages/ethereum-contracts/contracts/agreements/gdav1/GeneralDistributionAgreementV1.sol b/packages/ethereum-contracts/contracts/agreements/gdav1/GeneralDistributionAgreementV1.sol
index 08b23cde33..ff864bbf30 100644
--- a/packages/ethereum-contracts/contracts/agreements/gdav1/GeneralDistributionAgreementV1.sol
+++ b/packages/ethereum-contracts/contracts/agreements/gdav1/GeneralDistributionAgreementV1.sol
@@ -2,7 +2,7 @@
// solhint-disable not-rely-on-time
pragma solidity ^0.8.23;
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
import { ISuperfluid, ISuperfluidGovernance, IAccessControl } from "../../interfaces/superfluid/ISuperfluid.sol";
import {
@@ -319,7 +319,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
{
newCtx = ctx;
- if (pool.superToken().isPool(this, memberAddr)) {
+ if (memberAddr == address(0) || pool.superToken().isPool(this, memberAddr)) {
revert GDA_CANNOT_CONNECT_POOL();
}
diff --git a/packages/ethereum-contracts/contracts/agreements/gdav1/PoolAdminNFT.sol b/packages/ethereum-contracts/contracts/agreements/gdav1/PoolAdminNFT.sol
index f75fdad8cf..a93c3b61ea 100644
--- a/packages/ethereum-contracts/contracts/agreements/gdav1/PoolAdminNFT.sol
+++ b/packages/ethereum-contracts/contracts/agreements/gdav1/PoolAdminNFT.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
+import { IERC721Metadata } from "@openzeppelin-v5/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import { IPoolAdminNFT } from "../../interfaces/agreements/gdav1/IPoolAdminNFT.sol";
import { PoolNFTBase } from "./PoolNFTBase.sol";
import { IGeneralDistributionAgreementV1, ISuperfluid } from "../../interfaces/superfluid/ISuperfluid.sol";
diff --git a/packages/ethereum-contracts/contracts/agreements/gdav1/PoolNFTBase.sol b/packages/ethereum-contracts/contracts/agreements/gdav1/PoolNFTBase.sol
index 0af81e2919..ee431389a4 100644
--- a/packages/ethereum-contracts/contracts/agreements/gdav1/PoolNFTBase.sol
+++ b/packages/ethereum-contracts/contracts/agreements/gdav1/PoolNFTBase.sol
@@ -6,7 +6,8 @@ pragma solidity ^0.8.23;
// Notes: We use these interfaces in natspec documentation below, grep @inheritdoc
// solhint-disable-next-line no-unused-import
-import { IERC165, IERC721, IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
+import { IERC165 } from "@openzeppelin-v5/contracts/interfaces/IERC165.sol";
+import { IERC721 } from "@openzeppelin-v5/contracts/token/ERC721/IERC721.sol";
import { UUPSProxiable } from "../../upgradability/UUPSProxiable.sol";
import { IGeneralDistributionAgreementV1, ISuperfluid } from "../../interfaces/superfluid/ISuperfluid.sol";
import { ISuperTokenFactory } from "../../interfaces/superfluid/ISuperTokenFactory.sol";
diff --git a/packages/ethereum-contracts/contracts/agreements/gdav1/SuperfluidPool.sol b/packages/ethereum-contracts/contracts/agreements/gdav1/SuperfluidPool.sol
index 83234be488..1a12c5edb6 100644
--- a/packages/ethereum-contracts/contracts/agreements/gdav1/SuperfluidPool.sol
+++ b/packages/ethereum-contracts/contracts/agreements/gdav1/SuperfluidPool.sol
@@ -4,8 +4,8 @@ pragma solidity ^0.8.23;
// Notes: We use these interfaces in natspec documentation below, grep @inheritdoc
// solhint-disable-next-line no-unused-import
-import { IERC20, IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
+import { IERC20, IERC20Metadata } from "@openzeppelin-v5/contracts/token/ERC20/extensions/IERC20Metadata.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
import {
BasicParticle,
SemanticMoney,
diff --git a/packages/ethereum-contracts/contracts/agreements/gdav1/SuperfluidPoolDeployerLibrary.sol b/packages/ethereum-contracts/contracts/agreements/gdav1/SuperfluidPoolDeployerLibrary.sol
index a8025e8269..486c031c90 100644
--- a/packages/ethereum-contracts/contracts/agreements/gdav1/SuperfluidPoolDeployerLibrary.sol
+++ b/packages/ethereum-contracts/contracts/agreements/gdav1/SuperfluidPoolDeployerLibrary.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { BeaconProxy } from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
+import { BeaconProxy } from "@openzeppelin-v5/contracts/proxy/beacon/BeaconProxy.sol";
import { ISuperfluidToken } from "../../interfaces/superfluid/ISuperfluidToken.sol";
import { SuperfluidPool } from "./SuperfluidPool.sol";
import { PoolConfig, PoolERC20Metadata } from "../../interfaces/agreements/gdav1/IGeneralDistributionAgreementV1.sol";
diff --git a/packages/ethereum-contracts/contracts/gov/SuperfluidGovernanceII.sol b/packages/ethereum-contracts/contracts/gov/SuperfluidGovernanceII.sol
index 541c24254d..f34badd014 100644
--- a/packages/ethereum-contracts/contracts/gov/SuperfluidGovernanceII.sol
+++ b/packages/ethereum-contracts/contracts/gov/SuperfluidGovernanceII.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.23;
import { UUPSProxy } from "../upgradability/UUPSProxy.sol";
-import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+import { Ownable } from "@openzeppelin-v5/contracts/access/Ownable.sol";
import { UUPSProxiable } from "../upgradability/UUPSProxiable.sol";
import { SuperfluidGovernanceBase } from "./SuperfluidGovernanceBase.sol";
import { ISuperfluid } from "../interfaces/superfluid/ISuperfluid.sol";
@@ -13,7 +13,9 @@ import { ISuperfluid } from "../interfaces/superfluid/ISuperfluid.sol";
* IMPORTANT! Make sure the inheritance order remains in sync with the logic contract (Ownable first)!
*/
// solhint-disable-next-line no-empty-blocks
-contract SuperfluidGovernanceIIProxy is Ownable, UUPSProxy { }
+contract SuperfluidGovernanceIIProxy is Ownable, UUPSProxy {
+ constructor() Ownable(_msgSender()) {}
+}
contract SuperfluidGovernanceII is
Ownable,
@@ -21,6 +23,9 @@ contract SuperfluidGovernanceII is
SuperfluidGovernanceBase
{
error SF_GOV_II_ONLY_OWNER();
+
+ constructor() Ownable(_msgSender()) {}
+
function _requireAuthorised() private view {
if (owner() != _msgSender()) revert SF_GOV_II_ONLY_OWNER();
}
diff --git a/packages/ethereum-contracts/contracts/interfaces/agreements/gdav1/IPoolNFTBase.sol b/packages/ethereum-contracts/contracts/interfaces/agreements/gdav1/IPoolNFTBase.sol
index 54230b61e8..5d17b00429 100644
--- a/packages/ethereum-contracts/contracts/interfaces/agreements/gdav1/IPoolNFTBase.sol
+++ b/packages/ethereum-contracts/contracts/interfaces/agreements/gdav1/IPoolNFTBase.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity >=0.8.4;
-import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
+import { IERC721Metadata } from "@openzeppelin-v5/contracts/token/ERC721/extensions/IERC721Metadata.sol";
interface IPoolNFTBase is IERC721Metadata {
error POOL_NFT_APPROVE_TO_CALLER(); // 0x9212b333
diff --git a/packages/ethereum-contracts/contracts/interfaces/agreements/gdav1/ISuperfluidPool.sol b/packages/ethereum-contracts/contracts/interfaces/agreements/gdav1/ISuperfluidPool.sol
index b36e1f633f..9c58986c26 100644
--- a/packages/ethereum-contracts/contracts/interfaces/agreements/gdav1/ISuperfluidPool.sol
+++ b/packages/ethereum-contracts/contracts/interfaces/agreements/gdav1/ISuperfluidPool.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity >=0.8.4;
-import { IERC20, IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
+import { IERC20, IERC20Metadata } from "@openzeppelin-v5/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import { ISuperfluidToken } from "../../superfluid/ISuperfluidToken.sol";
/**
diff --git a/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol b/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol
index 56b2d9f428..267aec9a8e 100644
--- a/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol
+++ b/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol
@@ -2,10 +2,10 @@
pragma solidity >= 0.8.11;
import { ISuperfluidToken } from "./ISuperfluidToken.sol";
-import { IERC20, IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
-import { IERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
-import { IERC5267 } from "@openzeppelin/contracts/interfaces/IERC5267.sol";
-import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol";
+import { IERC20, IERC20Metadata } from "@openzeppelin-v5/contracts/token/ERC20/extensions/IERC20Metadata.sol";
+import { IERC20Permit } from "@openzeppelin-v5/contracts/token/ERC20/extensions/IERC20Permit.sol";
+import { IERC5267 } from "@openzeppelin-v5/contracts/interfaces/IERC5267.sol";
+import { IERC777 } from "@openzeppelin-v5/contracts/interfaces/IERC777.sol";
import { IPoolAdminNFT } from "../agreements/gdav1/IPoolAdminNFT.sol";
/**
diff --git a/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperTokenFactory.sol b/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperTokenFactory.sol
index 9796eb6240..04034b584c 100644
--- a/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperTokenFactory.sol
+++ b/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperTokenFactory.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >= 0.8.11;
-import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
+import { IERC20Metadata } from "@openzeppelin-v5/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import { ISuperToken } from "./ISuperToken.sol";
/**
* @title Super token factory interface
diff --git a/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol b/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol
index b5f9c1a28d..a68f25be7c 100644
--- a/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol
+++ b/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol
@@ -16,9 +16,9 @@ import {
} from "./Definitions.sol";
/// Super token related interfaces:
/// Note: CustomSuperTokenBase is not included for people building CustomSuperToken.
-import { IERC20, IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
-import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol";
-import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol";
+import { IERC20, IERC20Metadata } from "@openzeppelin-v5/contracts/token/ERC20/extensions/IERC20Metadata.sol";
+import { IERC777 } from "@openzeppelin-v5/contracts/interfaces/IERC777.sol";
+import { IAccessControl } from "@openzeppelin-v5/contracts/access/IAccessControl.sol";
import { ISuperfluidToken } from "./ISuperfluidToken.sol";
import { ISuperToken } from "./ISuperToken.sol";
import { ISuperTokenFactory } from "./ISuperTokenFactory.sol";
diff --git a/packages/ethereum-contracts/contracts/libs/ERC777Helper.sol b/packages/ethereum-contracts/contracts/libs/ERC777Helper.sol
index 1842629981..50175fc3fc 100644
--- a/packages/ethereum-contracts/contracts/libs/ERC777Helper.sol
+++ b/packages/ethereum-contracts/contracts/libs/ERC777Helper.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { IERC1820Registry } from "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol";
+import { IERC1820Registry } from "@openzeppelin-v5/contracts/interfaces/IERC1820Registry.sol";
/**
* @title ERC777 helper library
diff --git a/packages/ethereum-contracts/contracts/mocks/AgreementMock.t.sol b/packages/ethereum-contracts/contracts/mocks/AgreementMock.t.sol
index bcfac48017..241dc0a77e 100644
--- a/packages/ethereum-contracts/contracts/mocks/AgreementMock.t.sol
+++ b/packages/ethereum-contracts/contracts/mocks/AgreementMock.t.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
import {
ISuperfluid,
diff --git a/packages/ethereum-contracts/contracts/mocks/ERC777SenderRecipientMock.t.sol b/packages/ethereum-contracts/contracts/mocks/ERC777SenderRecipientMock.t.sol
index f6ca024fce..29602e77ce 100644
--- a/packages/ethereum-contracts/contracts/mocks/ERC777SenderRecipientMock.t.sol
+++ b/packages/ethereum-contracts/contracts/mocks/ERC777SenderRecipientMock.t.sol
@@ -1,19 +1,55 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { Context } from "@openzeppelin/contracts/utils/Context.sol";
-import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol";
-import { IERC777Sender } from "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol";
-import { IERC777Recipient } from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol";
-import { IERC1820Registry } from "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol";
-import {
- ERC1820Implementer, IERC1820Implementer
-} from "@openzeppelin/contracts/utils/introspection/ERC1820Implementer.sol";
+import { Context } from "@openzeppelin-v5/contracts/utils/Context.sol";
+import { IERC20 } from "@openzeppelin-v5/contracts/token/ERC20/IERC20.sol";
+import { IERC777 } from "@openzeppelin-v5/contracts/interfaces/IERC777.sol";
+import { IERC777Sender } from "@openzeppelin-v5/contracts/interfaces/IERC777Sender.sol";
+import { IERC777Recipient } from "@openzeppelin-v5/contracts/interfaces/IERC777Recipient.sol";
+import { IERC1820Registry } from "@openzeppelin-v5/contracts/interfaces/IERC1820Registry.sol";
+import { IERC1820Implementer } from "@openzeppelin-v5/contracts/interfaces/IERC1820Implementer.sol";
import { ISuperToken } from "../superfluid/SuperToken.sol";
+// Copy of OpenZeppelin v4.9.6: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.9.6/
+/**
+ * @dev Implementation of the {IERC1820Implementer} interface.
+ *
+ * Contracts may inherit from this and call {_registerInterfaceForAddress} to
+ * declare their willingness to be implementers.
+ * {IERC1820Registry-setInterfaceImplementer} should then be called for the
+ * registration to be complete.
+ *
+ * CAUTION: This file is deprecated as of v4.9 and will be removed in the next major release.
+ */
+contract ERC1820Implementer is IERC1820Implementer {
+ bytes32 private constant _ERC1820_ACCEPT_MAGIC = keccak256("ERC1820_ACCEPT_MAGIC");
+
+ mapping(bytes32 => mapping(address => bool)) private _supportedInterfaces;
+
+ /**
+ * @dev See {IERC1820Implementer-canImplementInterfaceForAddress}.
+ */
+ function canImplementInterfaceForAddress(
+ bytes32 interfaceHash,
+ address account
+ ) public view virtual override returns (bytes32) {
+ return _supportedInterfaces[interfaceHash][account] ? _ERC1820_ACCEPT_MAGIC : bytes32(0x00);
+ }
+
+ /**
+ * @dev Declares the contract as willing to be an implementer of
+ * `interfaceHash` for `account`.
+ *
+ * See {IERC1820Registry-setInterfaceImplementer} and
+ * {IERC1820Registry-interfaceHash}.
+ */
+ function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal virtual {
+ _supportedInterfaces[interfaceHash][account] = true;
+ }
+}
+
contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient, ERC1820Implementer {
event TokensToSendCalled(
address operator,
diff --git a/packages/ethereum-contracts/contracts/mocks/SuperTokenMock.t.sol b/packages/ethereum-contracts/contracts/mocks/SuperTokenMock.t.sol
index d511f2dc8a..166929543f 100644
--- a/packages/ethereum-contracts/contracts/mocks/SuperTokenMock.t.sol
+++ b/packages/ethereum-contracts/contracts/mocks/SuperTokenMock.t.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
+import { SafeERC20 } from "@openzeppelin-v5/contracts/token/ERC20/utils/SafeERC20.sol";
import {
ISuperfluid, IERC20, IPoolAdminNFT
diff --git a/packages/ethereum-contracts/contracts/superfluid/FullUpgradableSuperTokenProxy.sol b/packages/ethereum-contracts/contracts/superfluid/FullUpgradableSuperTokenProxy.sol
index 5870bd8174..27db1af84a 100644
--- a/packages/ethereum-contracts/contracts/superfluid/FullUpgradableSuperTokenProxy.sol
+++ b/packages/ethereum-contracts/contracts/superfluid/FullUpgradableSuperTokenProxy.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.23;
import { ISuperTokenFactory } from "../interfaces/superfluid/ISuperTokenFactory.sol";
-import { Proxy } from "@openzeppelin/contracts/proxy/Proxy.sol";
+import { Proxy } from "@openzeppelin-v5/contracts/proxy/Proxy.sol";
/**
@@ -29,6 +29,14 @@ contract FullUpgradableSuperTokenProxy is Proxy {
}
}
+ /**
+ * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
+ * is empty.
+ */
+ receive() external payable virtual {
+ _fallback();
+ }
+
function _implementation() internal override view returns (address impl) {
ISuperTokenFactory factory;
assembly { // solium-disable-line
@@ -37,5 +45,4 @@ contract FullUpgradableSuperTokenProxy is Proxy {
assert(address(factory) != address(0));
return address(factory.getSuperTokenLogic());
}
-
}
diff --git a/packages/ethereum-contracts/contracts/superfluid/SuperToken.sol b/packages/ethereum-contracts/contracts/superfluid/SuperToken.sol
index 9d6e3bf6b4..fa9d4af9ad 100644
--- a/packages/ethereum-contracts/contracts/superfluid/SuperToken.sol
+++ b/packages/ethereum-contracts/contracts/superfluid/SuperToken.sol
@@ -13,13 +13,11 @@ import {
} from "../interfaces/superfluid/ISuperfluid.sol";
import { SuperfluidToken } from "./SuperfluidToken.sol";
import { ERC777Helper } from "../libs/ERC777Helper.sol";
-import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
-import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol";
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
-import { IERC777Recipient } from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol";
-import { IERC777Sender } from "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol";
-import { Address } from "@openzeppelin/contracts/utils/Address.sol";
-import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+import { SafeERC20 } from "@openzeppelin-v5/contracts/token/ERC20/utils/SafeERC20.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
+import { IERC777Recipient } from "@openzeppelin-v5/contracts/interfaces/IERC777Recipient.sol";
+import { IERC777Sender } from "@openzeppelin-v5/contracts/interfaces/IERC777Sender.sol";
+import { ECDSA } from "@openzeppelin-v5/contracts/utils/cryptography/ECDSA.sol";
// placeholder type needed as an intermediate step before complete removal
@@ -36,9 +34,7 @@ contract SuperToken is
SuperfluidToken,
ISuperToken
{
- using SafeMath for uint256;
using SafeCast for uint256;
- using Address for address;
using ERC777Helper for ERC777Helper.Operators;
using SafeERC20 for IERC20;
@@ -362,10 +358,9 @@ contract SuperToken is
_move(operator, holder, recipient, amount, "", "");
if (spender != holder) {
- _approve(
- holder,
- spender,
- _allowances[holder][spender].sub(amount, "SuperToken: transfer amount exceeds allowance"));
+ require(amount <= _allowances[holder][spender], "SuperToken: transfer amount exceeds allowance");
+ // TODO: this triggers an `Approval` event, which shouldn't happen for transfers.
+ _approve(holder, spender, _allowances[holder][spender] - amount);
}
return true;
@@ -576,7 +571,7 @@ contract SuperToken is
if (implementer != address(0)) {
IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
} else if (requireReceptionAck) {
- if (to.isContract()) revert SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT();
+ if (to.code.length > 0) revert SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT();
}
}
@@ -638,8 +633,8 @@ contract SuperToken is
function decreaseAllowance(address spender, uint256 subtractedValue)
public virtual override returns (bool) {
- _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue,
- "SuperToken: decreased allowance below zero"));
+ require(subtractedValue <= _allowances[msg.sender][spender], "SuperToken: decreased allowance below zero");
+ _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);
return true;
}
@@ -918,8 +913,8 @@ contract SuperToken is
external virtual override
onlyHost
{
- _approve(account, spender, _allowances[account][spender].sub(subtractedValue,
- "SuperToken: decreased allowance below zero"));
+ require(subtractedValue <= _allowances[account][spender], "SuperToken: decreased allowance below zero");
+ _approve(account, spender, _allowances[account][spender] - subtractedValue);
}
function operationTransferFrom(
diff --git a/packages/ethereum-contracts/contracts/superfluid/SuperTokenFactory.sol b/packages/ethereum-contracts/contracts/superfluid/SuperTokenFactory.sol
index 943ca4c56b..94d2ba8833 100644
--- a/packages/ethereum-contracts/contracts/superfluid/SuperTokenFactory.sol
+++ b/packages/ethereum-contracts/contracts/superfluid/SuperTokenFactory.sol
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
-import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+import { IERC20Metadata } from "@openzeppelin-v5/contracts/token/ERC20/extensions/IERC20Metadata.sol";
+import { Ownable } from "@openzeppelin-v5/contracts/access/Ownable.sol";
import {
ISuperTokenFactory,
ISuperToken
diff --git a/packages/ethereum-contracts/contracts/superfluid/Superfluid.sol b/packages/ethereum-contracts/contracts/superfluid/Superfluid.sol
index 7df746f332..cbd88198b6 100644
--- a/packages/ethereum-contracts/contracts/superfluid/Superfluid.sol
+++ b/packages/ethereum-contracts/contracts/superfluid/Superfluid.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
import { UUPSProxiable } from "../upgradability/UUPSProxiable.sol";
import { UUPSProxy } from "../upgradability/UUPSProxy.sol";
diff --git a/packages/ethereum-contracts/contracts/superfluid/SuperfluidToken.sol b/packages/ethereum-contracts/contracts/superfluid/SuperfluidToken.sol
index cb5218676e..c75fc48f69 100644
--- a/packages/ethereum-contracts/contracts/superfluid/SuperfluidToken.sol
+++ b/packages/ethereum-contracts/contracts/superfluid/SuperfluidToken.sol
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
+import { IERC20 } from "@openzeppelin-v5/contracts/token/ERC20/IERC20.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
import {
ISuperfluid,
ISuperAgreement,
diff --git a/packages/ethereum-contracts/contracts/tokens/PureSuperToken.sol b/packages/ethereum-contracts/contracts/tokens/PureSuperToken.sol
index 0deeb3dcff..d0466d4006 100644
--- a/packages/ethereum-contracts/contracts/tokens/PureSuperToken.sol
+++ b/packages/ethereum-contracts/contracts/tokens/PureSuperToken.sol
@@ -8,7 +8,7 @@ import {
from "../interfaces/superfluid/CustomSuperTokenBase.sol";
import { IPureSuperTokenCustom } from "../interfaces/tokens/IPureSuperToken.sol";
import { UUPSProxy } from "../upgradability/UUPSProxy.sol";
-import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+import { IERC20 } from "@openzeppelin-v5/contracts/token/ERC20/IERC20.sol";
/**
diff --git a/packages/ethereum-contracts/contracts/upgradability/BeaconProxiable.sol b/packages/ethereum-contracts/contracts/upgradability/BeaconProxiable.sol
index 43db85e730..b11cf3389f 100644
--- a/packages/ethereum-contracts/contracts/upgradability/BeaconProxiable.sol
+++ b/packages/ethereum-contracts/contracts/upgradability/BeaconProxiable.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
+import { Initializable } from "./Initializable.sol";
abstract contract BeaconProxiable is Initializable {
diff --git a/packages/ethereum-contracts/contracts/upgradability/Initializable.sol b/packages/ethereum-contracts/contracts/upgradability/Initializable.sol
new file mode 100644
index 0000000000..6a3607234b
--- /dev/null
+++ b/packages/ethereum-contracts/contracts/upgradability/Initializable.sol
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: MIT
+// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
+
+pragma solidity ^0.8.2;
+
+/**
+ * Note: Copy from Openzeppelin v4.9.6. We need to stick with this version due to storage layout changes in v5.
+ *
+ * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
+ * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
+ * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
+ * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
+ *
+ * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
+ * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
+ * case an upgrade adds a module that needs to be initialized.
+ *
+ * For example:
+ *
+ * [.hljs-theme-light.nopadding]
+ * ```solidity
+ * contract MyToken is ERC20Upgradeable {
+ * function initialize() initializer public {
+ * __ERC20_init("MyToken", "MTK");
+ * }
+ * }
+ *
+ * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
+ * function initializeV2() reinitializer(2) public {
+ * __ERC20Permit_init("MyToken");
+ * }
+ * }
+ * ```
+ *
+ * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
+ * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
+ *
+ * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
+ * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
+ *
+ * [CAUTION]
+ * ====
+ * Avoid leaving a contract uninitialized.
+ *
+ * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
+ * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
+ * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
+ *
+ * [.hljs-theme-light.nopadding]
+ * ```
+ * /// @custom:oz-upgrades-unsafe-allow constructor
+ * constructor() {
+ * _disableInitializers();
+ * }
+ * ```
+ * ====
+ */
+abstract contract Initializable {
+ /**
+ * @dev Indicates that the contract has been initialized.
+ * @custom:oz-retyped-from bool
+ */
+ uint8 private _initialized;
+
+ /**
+ * @dev Indicates that the contract is in the process of being initialized.
+ */
+ bool private _initializing;
+
+ /**
+ * @dev Triggered when the contract has been initialized or reinitialized.
+ */
+ event Initialized(uint8 version);
+
+ /**
+ * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
+ * `onlyInitializing` functions can be used to initialize parent contracts.
+ *
+ * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
+ * constructor.
+ *
+ * Emits an {Initialized} event.
+ */
+ modifier initializer() {
+ bool isTopLevelCall = !_initializing;
+ require(
+ // NOTE (Superfluid):
+ // The original version used `!(Address.isContract(address(this)))` here.
+ // That method is nomore available in OZ v5, thus the logic behind it (code.length check) was inlined.
+ (isTopLevelCall && _initialized < 1) || (address(this).code.length == 0 && _initialized == 1),
+ "Initializable: contract is already initialized"
+ );
+ _initialized = 1;
+ if (isTopLevelCall) {
+ _initializing = true;
+ }
+ _;
+ if (isTopLevelCall) {
+ _initializing = false;
+ emit Initialized(1);
+ }
+ }
+
+ /**
+ * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
+ * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
+ * used to initialize parent contracts.
+ *
+ * A reinitializer may be used after the original initialization step. This is essential to configure modules that
+ * are added through upgrades and that require initialization.
+ *
+ * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
+ * cannot be nested. If one is invoked in the context of another, execution will revert.
+ *
+ * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
+ * a contract, executing them in the right order is up to the developer or operator.
+ *
+ * WARNING: setting the version to 255 will prevent any future reinitialization.
+ *
+ * Emits an {Initialized} event.
+ */
+ modifier reinitializer(uint8 version) {
+ require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
+ _initialized = version;
+ _initializing = true;
+ _;
+ _initializing = false;
+ emit Initialized(version);
+ }
+
+ /**
+ * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
+ * {initializer} and {reinitializer} modifiers, directly or indirectly.
+ */
+ modifier onlyInitializing() {
+ require(_initializing, "Initializable: contract is not initializing");
+ _;
+ }
+
+ /**
+ * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
+ * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
+ * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
+ * through proxies.
+ *
+ * Emits an {Initialized} event the first time it is successfully executed.
+ */
+ function _disableInitializers() internal virtual {
+ require(!_initializing, "Initializable: contract is initializing");
+ if (_initialized != type(uint8).max) {
+ _initialized = type(uint8).max;
+ emit Initialized(type(uint8).max);
+ }
+ }
+
+ /**
+ * @dev Returns the highest version that has been initialized. See {reinitializer}.
+ */
+ function _getInitializedVersion() internal view returns (uint8) {
+ return _initialized;
+ }
+
+ /**
+ * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
+ */
+ function _isInitializing() internal view returns (bool) {
+ return _initializing;
+ }
+}
\ No newline at end of file
diff --git a/packages/ethereum-contracts/contracts/upgradability/SuperfluidUpgradeableBeacon.sol b/packages/ethereum-contracts/contracts/upgradability/SuperfluidUpgradeableBeacon.sol
index 3dc1bbc9f6..9860d3a106 100644
--- a/packages/ethereum-contracts/contracts/upgradability/SuperfluidUpgradeableBeacon.sol
+++ b/packages/ethereum-contracts/contracts/upgradability/SuperfluidUpgradeableBeacon.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.23;
import {
UpgradeableBeacon
-} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
+} from "@openzeppelin-v5/contracts/proxy/beacon/UpgradeableBeacon.sol";
import { BeaconProxiable } from "./BeaconProxiable.sol";
contract SuperfluidUpgradeableBeacon is UpgradeableBeacon {
@@ -11,7 +11,7 @@ contract SuperfluidUpgradeableBeacon is UpgradeableBeacon {
error INCOMPATIBLE_LOGIC(); // 0x5af2144c
error NO_PROXY_LOOP(); // 0z66750bca
- constructor(address implementation_) UpgradeableBeacon(implementation_) {}
+ constructor(address implementation_) UpgradeableBeacon(implementation_, _msgSender()) {}
function upgradeTo(address newImplementation) public override onlyOwner {
if (newImplementation == address(0)) {
diff --git a/packages/ethereum-contracts/contracts/upgradability/UUPSProxiable.sol b/packages/ethereum-contracts/contracts/upgradability/UUPSProxiable.sol
index 13f5fc9036..5371dec35b 100644
--- a/packages/ethereum-contracts/contracts/upgradability/UUPSProxiable.sol
+++ b/packages/ethereum-contracts/contracts/upgradability/UUPSProxiable.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.23;
import { UUPSUtils } from "./UUPSUtils.sol";
-import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
+import { Initializable } from "./Initializable.sol";
/**
* @title UUPS (Universal Upgradeable Proxy Standard) Proxiable contract.
diff --git a/packages/ethereum-contracts/contracts/upgradability/UUPSProxy.sol b/packages/ethereum-contracts/contracts/upgradability/UUPSProxy.sol
index c871838a61..d28793be17 100644
--- a/packages/ethereum-contracts/contracts/upgradability/UUPSProxy.sol
+++ b/packages/ethereum-contracts/contracts/upgradability/UUPSProxy.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.23;
import { UUPSUtils } from "./UUPSUtils.sol";
-import { Proxy } from "@openzeppelin/contracts/proxy/Proxy.sol";
+import { Proxy } from "@openzeppelin-v5/contracts/proxy/Proxy.sol";
/**
@@ -10,7 +10,7 @@ import { Proxy } from "@openzeppelin/contracts/proxy/Proxy.sol";
*
* NOTE:
* - Compliant with [Universal Upgradeable Proxy Standard](https://eips.ethereum.org/EIPS/eip-1822)
- * - Compiiant with [Standard Proxy Storage Slots](https://eips.ethereum.org/EIPS/eip-1967)
+ * - Compliant with [Standard Proxy Storage Slots](https://eips.ethereum.org/EIPS/eip-1967)
* - Implements delegation of calls to other contracts, with proper forwarding of
* return values and bubbling of failures.
* - It defines a fallback function that delegates all calls to the implementation.
@@ -28,10 +28,17 @@ contract UUPSProxy is Proxy {
UUPSUtils.setImplementation(initialAddress);
}
+ /**
+ * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
+ * is empty.
+ */
+ receive() external payable virtual {
+ _fallback();
+ }
+
/// @dev Proxy._implementation implementation
function _implementation() internal virtual override view returns (address)
{
return UUPSUtils.implementation();
}
-
}
diff --git a/packages/ethereum-contracts/contracts/utils/BatchLiquidator.sol b/packages/ethereum-contracts/contracts/utils/BatchLiquidator.sol
index d8d2ccd01e..04ff928a85 100644
--- a/packages/ethereum-contracts/contracts/utils/BatchLiquidator.sol
+++ b/packages/ethereum-contracts/contracts/utils/BatchLiquidator.sol
@@ -5,7 +5,7 @@ import {
ISuperfluid, ISuperAgreement, ISuperToken, ISuperfluidPool,
IConstantFlowAgreementV1, IGeneralDistributionAgreementV1
} from "../interfaces/superfluid/ISuperfluid.sol";
-import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+import { ERC20 } from "@openzeppelin-v5/contracts/token/ERC20/ERC20.sol";
/**
* @title Batch liquidator contract
diff --git a/packages/ethereum-contracts/contracts/utils/ERC2771Forwarder.sol b/packages/ethereum-contracts/contracts/utils/ERC2771Forwarder.sol
index cc2da07420..f0b8fe9bdd 100644
--- a/packages/ethereum-contracts/contracts/utils/ERC2771Forwarder.sol
+++ b/packages/ethereum-contracts/contracts/utils/ERC2771Forwarder.sol
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+import { Ownable } from "@openzeppelin-v5/contracts/access/Ownable.sol";
/**
* @title Forwards calls preserving the original msg.sender according to ERC-2771
*/
contract ERC2771Forwarder is Ownable {
+ constructor() Ownable(_msgSender()) {}
+
/**
* @dev Forwards a call passing along the original msg.sender encoded as specified in ERC-2771.
* @param target The target contract to call
diff --git a/packages/ethereum-contracts/contracts/utils/Resolver.sol b/packages/ethereum-contracts/contracts/utils/Resolver.sol
index 36ee7aa156..63416e7dbe 100644
--- a/packages/ethereum-contracts/contracts/utils/Resolver.sol
+++ b/packages/ethereum-contracts/contracts/utils/Resolver.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.11;
-import { AccessControlEnumerable } from "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
+import { AccessControlEnumerable } from "@openzeppelin-v5/contracts/access/extensions/AccessControlEnumerable.sol";
import { IResolver } from "../interfaces/utils/IResolver.sol";
@@ -20,7 +20,7 @@ contract Resolver is IResolver, AccessControlEnumerable {
mapping(string => address) private _registry;
constructor() {
- _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
+ _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function set(string calldata name, address target) external override {
diff --git a/packages/ethereum-contracts/contracts/utils/SimpleACL.sol b/packages/ethereum-contracts/contracts/utils/SimpleACL.sol
index 05fb553429..3ea1568989 100644
--- a/packages/ethereum-contracts/contracts/utils/SimpleACL.sol
+++ b/packages/ethereum-contracts/contracts/utils/SimpleACL.sol
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;
-import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
+import { AccessControl } from "@openzeppelin-v5/contracts/access/AccessControl.sol";
contract SimpleACL is AccessControl {
constructor() {
- _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
+ _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
/// Allows the default admin to set the admin role for a given role.
diff --git a/packages/ethereum-contracts/contracts/utils/SimpleForwarder.sol b/packages/ethereum-contracts/contracts/utils/SimpleForwarder.sol
index 612c9734cd..6b6cde8e50 100644
--- a/packages/ethereum-contracts/contracts/utils/SimpleForwarder.sol
+++ b/packages/ethereum-contracts/contracts/utils/SimpleForwarder.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;
-import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+import { Ownable } from "@openzeppelin-v5/contracts/access/Ownable.sol";
/**
* @title Forwards arbitrary calls
@@ -10,6 +10,8 @@ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
* This is necessary for security reasons if the calling account has privileged access anywhere.
*/
contract SimpleForwarder is Ownable {
+ constructor() Ownable(_msgSender()) {}
+
/**
* @dev Forwards a call for which msg.sender doesn't matter
* @param target The target contract to call
diff --git a/packages/ethereum-contracts/contracts/utils/SuperUpgrader.sol b/packages/ethereum-contracts/contracts/utils/SuperUpgrader.sol
index ba410beb21..3398369daa 100644
--- a/packages/ethereum-contracts/contracts/utils/SuperUpgrader.sol
+++ b/packages/ethereum-contracts/contracts/utils/SuperUpgrader.sol
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { AccessControlEnumerable } from "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
-import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
+import { AccessControlEnumerable } from "@openzeppelin-v5/contracts/access/extensions/AccessControlEnumerable.sol";
+import { SafeERC20 } from "@openzeppelin-v5/contracts/token/ERC20/utils/SafeERC20.sol";
import {
ISuperToken,
IERC20
@@ -29,10 +29,10 @@ contract SuperUpgrader is AccessControlEnumerable {
constructor(address adminRole, address[] memory backendAddr) {
require(adminRole != address(0), "adminRole is empty");
- _setupRole(DEFAULT_ADMIN_ROLE, adminRole);
+ _grantRole(DEFAULT_ADMIN_ROLE, adminRole);
for (uint256 i = 0; i < backendAddr.length; ++i) {
require(backendAddr[i] != address(0), "backend can't be zero");
- _setupRole(BACKEND_ROLE, backendAddr[i]);
+ _grantRole(BACKEND_ROLE, backendAddr[i]);
}
}
@@ -60,8 +60,7 @@ contract SuperUpgrader is AccessControlEnumerable {
IERC20 token = IERC20(superToken.getUnderlyingToken());
uint256 beforeBalance = token.balanceOf(address(this));
token.safeTransferFrom(account, address(this), amount);
- token.safeApprove(address(superToken), 0);
- token.safeApprove(address(superToken), amount);
+ token.forceApprove(address(superToken), amount);
// upgrade tokens and send back to user
superToken.upgradeTo(
account,
diff --git a/packages/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeployer.t.sol b/packages/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeployer.t.sol
index ce98d91d71..4fe858cd10 100644
--- a/packages/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeployer.t.sol
+++ b/packages/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeployer.t.sol
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.11;
-import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
-import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+import { IERC20Metadata } from "@openzeppelin-v5/contracts/token/ERC20/extensions/IERC20Metadata.sol";
+import { IERC20 } from "@openzeppelin-v5/contracts/token/ERC20/IERC20.sol";
import { SuperfluidFrameworkDeploymentSteps, TokenDeployerLibrary } from "./SuperfluidFrameworkDeploymentSteps.t.sol";
import { ISuperTokenFactory } from "../superfluid/SuperTokenFactory.sol";
import { SuperToken } from "../superfluid/SuperToken.sol";
diff --git a/packages/ethereum-contracts/contracts/utils/TOGA.sol b/packages/ethereum-contracts/contracts/utils/TOGA.sol
index 30dcf941c5..c83755e549 100644
--- a/packages/ethereum-contracts/contracts/utils/TOGA.sol
+++ b/packages/ethereum-contracts/contracts/utils/TOGA.sol
@@ -1,14 +1,14 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
import {
ISuperfluid, ISuperToken, IConstantFlowAgreementV1
} from "../interfaces/superfluid/ISuperfluid.sol";
-import { IERC1820Registry } from "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol";
-import { IERC777Recipient } from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol";
+import { IERC1820Registry } from "@openzeppelin-v5/contracts/interfaces/IERC1820Registry.sol";
+import { IERC777Recipient } from "@openzeppelin-v5/contracts/interfaces/IERC777Recipient.sol";
/**
* @title TOGA: Transparent Ongoing Auction
diff --git a/packages/ethereum-contracts/contracts/utils/TestGovernance.sol b/packages/ethereum-contracts/contracts/utils/TestGovernance.sol
index 33ee9c7182..20fdf38d63 100644
--- a/packages/ethereum-contracts/contracts/utils/TestGovernance.sol
+++ b/packages/ethereum-contracts/contracts/utils/TestGovernance.sol
@@ -7,7 +7,7 @@ import {
} from "../interfaces/superfluid/ISuperfluid.sol";
import { SuperfluidGovernanceBase } from "../gov/SuperfluidGovernanceBase.sol";
-import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+import { Ownable } from "@openzeppelin-v5/contracts/access/Ownable.sol";
/**
@@ -21,6 +21,8 @@ contract TestGovernance is
{
ISuperfluid private _host;
+ constructor() Ownable(_msgSender()) {}
+
function initialize(
ISuperfluid host,
address rewardAddress,
diff --git a/packages/ethereum-contracts/contracts/utils/TestResolver.sol b/packages/ethereum-contracts/contracts/utils/TestResolver.sol
index e7b0c46f7d..0e47479715 100644
--- a/packages/ethereum-contracts/contracts/utils/TestResolver.sol
+++ b/packages/ethereum-contracts/contracts/utils/TestResolver.sol
@@ -9,10 +9,10 @@ import { Resolver } from "./Resolver.sol";
/// @dev Used by the SuperfluidFrameworkDeployer to grant admin privileges to its deployer
contract TestResolver is Resolver {
constructor(address _additionalAdmin) {
- _setupRole(DEFAULT_ADMIN_ROLE, _additionalAdmin);
+ _grantRole(DEFAULT_ADMIN_ROLE, _additionalAdmin);
}
function addAdmin(address _additionalAdmin) external {
- _setupRole(DEFAULT_ADMIN_ROLE, _additionalAdmin);
+ _grantRole(DEFAULT_ADMIN_ROLE, _additionalAdmin);
}
}
diff --git a/packages/ethereum-contracts/contracts/utils/TestToken.sol b/packages/ethereum-contracts/contracts/utils/TestToken.sol
index cea59f442f..55fe727b8c 100644
--- a/packages/ethereum-contracts/contracts/utils/TestToken.sol
+++ b/packages/ethereum-contracts/contracts/utils/TestToken.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.11;
-import { ERC20, ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
+import { ERC20, ERC20Permit } from "@openzeppelin-v5/contracts/token/ERC20/extensions/ERC20Permit.sol";
/**
* @title Test token contract
diff --git a/packages/ethereum-contracts/foundry.toml b/packages/ethereum-contracts/foundry.toml
index cc999464ae..d0e6a3f967 100644
--- a/packages/ethereum-contracts/foundry.toml
+++ b/packages/ethereum-contracts/foundry.toml
@@ -14,7 +14,7 @@ optimizer_runs = 200
remappings = [
'@superfluid-finance/ethereum-contracts/contracts/=packages/ethereum-contracts/contracts/',
'@superfluid-finance/solidity-semantic-money/src/=packages/solidity-semantic-money/src/',
- '@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/',
+ '@openzeppelin-v5/=lib/openzeppelin-contracts/',
'ds-test/=lib/forge-std/lib/ds-test/src/',
'forge-std/=lib/forge-std/src/']
out = 'packages/ethereum-contracts/build/foundry/default'
diff --git a/packages/ethereum-contracts/hardhat.config.ts b/packages/ethereum-contracts/hardhat.config.ts
index 80b4c605b1..fb8b2d98a3 100644
--- a/packages/ethereum-contracts/hardhat.config.ts
+++ b/packages/ethereum-contracts/hardhat.config.ts
@@ -173,7 +173,9 @@ const config: HardhatUserConfig = {
)
: undefined,
},
- typechain: {target: "ethers-v5"},
+ typechain: {
+ target: "ethers-v5"
+ },
};
export default config;
diff --git a/packages/ethereum-contracts/ops-scripts/deploy-framework.js b/packages/ethereum-contracts/ops-scripts/deploy-framework.js
index 194ae71af4..ea3b9d60e3 100644
--- a/packages/ethereum-contracts/ops-scripts/deploy-framework.js
+++ b/packages/ethereum-contracts/ops-scripts/deploy-framework.js
@@ -826,25 +826,6 @@ module.exports = eval(`(${S.toString()})({skipArgv: true})`)(async function (
return newAddress !== ZERO_ADDRESS ? newAddress : prevAddr;
}
- async function getOrDeployHelper(
- Contract,
- getPrevAddrFn,
- outputKey
- ) {
- let prevAddr = await getPrevAddrFn().catch(_err => {
- console.error(`### Error getting ${Contract.contractName} address, likely not yet deployed`);
- return ZERO_ADDRESS;
- });
-
- if (prevAddr !== ZERO_ADDRESS) {
- return prevAddr;
- }
-
- const instance = await web3tx(Contract.new, `${Contract.contractName}.new`)();
- output += `${outputKey}=${instance.address}\n`;
- return instance.address;
- }
-
const simpleForwarderAddress = await getOrDeployForwarder(
superfluid,
SimpleForwarder,
@@ -859,11 +840,9 @@ module.exports = eval(`(${S.toString()})({skipArgv: true})`)(async function (
"ERC2771_FORWARDER"
);
- const simpleAclAddress = await getOrDeployHelper(
- SimpleACL,
- () => superfluid.getSimpleACL(),
- "SIMPLE_ACL"
- );
+ // SimpleACL has now been deployed on all networks.
+ // It shall never be deployed in the upgrade path in order to eliminate the risk of accidental state loss.
+ const simpleAclAddress = await superfluid.getSimpleACL();
console.log("SimpleACL address", simpleAclAddress);
// get previous callback gas limit, make sure we don't decrease it
diff --git a/packages/ethereum-contracts/package.json b/packages/ethereum-contracts/package.json
index 72219b4a52..8ea4b955fe 100644
--- a/packages/ethereum-contracts/package.json
+++ b/packages/ethereum-contracts/package.json
@@ -5,7 +5,6 @@
"dependencies": {
"@decentral.ee/web3-helpers": "0.5.3",
"@nomiclabs/hardhat-ethers": "2.2.3",
- "@openzeppelin/contracts": "4.9.6",
"@truffle/contract": "4.6.31",
"ethereumjs-tx": "2.1.2",
"ethereumjs-util": "7.1.5",
@@ -50,7 +49,8 @@
"license": "AGPL-3.0-or-later OR MIT",
"main": "./dev-scripts/index.js",
"peerDependencies": {
- "ethers": "^5.7.2"
+ "ethers": "^5.7.2",
+ "@openzeppelin/contracts": "^5.0.0"
},
"repository": {
"type": "git",
diff --git a/packages/ethereum-contracts/test/contracts/superfluid/SuperToken.NonStandard.test.ts b/packages/ethereum-contracts/test/contracts/superfluid/SuperToken.NonStandard.test.ts
index e5b019a3c4..7930323bb6 100644
--- a/packages/ethereum-contracts/test/contracts/superfluid/SuperToken.NonStandard.test.ts
+++ b/packages/ethereum-contracts/test/contracts/superfluid/SuperToken.NonStandard.test.ts
@@ -141,11 +141,13 @@ describe("SuperToken's Non Standard Functions", function () {
it("#2.2 - should not upgrade without enough underlying balance", async () => {
const initialBalance = await testToken.balanceOf(alice);
console.log("SuperToken.upgrade - bad balance");
- await expectRevertedWith(
+ await expectCustomError(
superToken
.connect(aliceSigner)
.upgrade(initialBalance.add(toBN(1))),
- "ERC20: transfer amount exceeds balance"
+ testToken,
+ "ERC20InsufficientBalance",
+ [alice, initialBalance, initialBalance.add(toBN(1))]
);
await t.validateSystemInvariance();
});
diff --git a/packages/ethereum-contracts/test/contracts/utils/SuperUpgrader.test.ts b/packages/ethereum-contracts/test/contracts/utils/SuperUpgrader.test.ts
index aaba699bc9..e2eeb72fd7 100644
--- a/packages/ethereum-contracts/test/contracts/utils/SuperUpgrader.test.ts
+++ b/packages/ethereum-contracts/test/contracts/utils/SuperUpgrader.test.ts
@@ -1,6 +1,6 @@
import {assert} from "chai";
import {ethers, web3} from "hardhat";
-import {expectRevertedWith} from "../../utils/expectRevert";
+import {expectCustomError, expectRevertedWith} from "../../utils/expectRevert";
import TestEnvironment from "../../TestEnvironment";
import {toWad} from "./helpers";
@@ -195,11 +195,13 @@ describe("Superfluid Super Upgrader Contract", function () {
const backendSigner = await ethers.getSigner(backend[0]);
console.log("upgrader.upgrade");
- await expectRevertedWith(
+ await expectCustomError(
upgrader
.connect(backendSigner)
.upgrade(superToken.address, alice, 1),
- "ERC20: insufficient allowance"
+ testToken,
+ "ERC20InsufficientAllowance",
+ [upgrader.address, 0, 1]
);
});
@@ -212,11 +214,13 @@ describe("Superfluid Super Upgrader Contract", function () {
.connect(aliceSigner)
.approve(upgrader.address, toWad("1"));
- await expectRevertedWith(
+ await expectCustomError(
upgrader
.connect(backendSigner)
.upgrade(superToken.address, alice, "1000000000000000001"),
- "ERC20: insufficient allowance"
+ testToken,
+ "ERC20InsufficientAllowance",
+ [upgrader.address, toWad("1"), "1000000000000000001"]
);
});
@@ -308,14 +312,18 @@ describe("Superfluid Super Upgrader Contract", function () {
"operation not allowed"
);
- await expectRevertedWith(
+ await expectCustomError(
upgrader.connect(eveSigner).grantBackendAgent(eve),
- `AccessControl: account ${eve.toLowerCase()} is missing role ${DEFAULT_ADMIN_ROLE}`
+ upgrader,
+ "AccessControlUnauthorizedAccount",
+ [eve, DEFAULT_ADMIN_ROLE]
);
- await expectRevertedWith(
+ await expectCustomError(
upgrader.connect(eveSigner).revokeBackendAgent(backend[1]),
- `AccessControl: account ${eve.toLowerCase()} is missing role ${DEFAULT_ADMIN_ROLE}`
+ upgrader,
+ "AccessControlUnauthorizedAccount",
+ [eve, DEFAULT_ADMIN_ROLE]
);
});
diff --git a/packages/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol b/packages/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol
index e680cd1748..06f0a346f2 100644
--- a/packages/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol
+++ b/packages/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol
@@ -3,8 +3,8 @@ pragma solidity >=0.8.11;
import "forge-std/Test.sol";
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
-import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
+import { EnumerableSet } from "@openzeppelin-v5/contracts/utils/structs/EnumerableSet.sol";
import { ERC1820RegistryCompiled } from "../../contracts/libs/ERC1820RegistryCompiled.sol";
import { SuperfluidFrameworkDeployer } from "../../contracts/utils/SuperfluidFrameworkDeployer.t.sol";
import { Superfluid } from "../../contracts/superfluid/Superfluid.sol";
diff --git a/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreement.t.sol b/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreement.t.sol
index 0c3050b781..36a55bc3a4 100644
--- a/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreement.t.sol
+++ b/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreement.t.sol
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
-import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
-import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol";
+import { EnumerableSet } from "@openzeppelin-v5/contracts/utils/structs/EnumerableSet.sol";
+import { SafeCast } from "@openzeppelin-v5/contracts/utils/math/SafeCast.sol";
+import { IAccessControl } from "@openzeppelin-v5/contracts/access/IAccessControl.sol";
import "@superfluid-finance/solidity-semantic-money/src/SemanticMoney.sol";
import "../../FoundrySuperfluidTester.t.sol";
import {
@@ -1093,6 +1093,16 @@ contract GeneralDistributionAgreementV1IntegrationTest is FoundrySuperfluidTeste
new bytes(0)
);
vm.stopPrank();
+
+ // cannot connect the zero address
+ vm.startPrank(alice);
+ vm.expectRevert(IGeneralDistributionAgreementV1.GDA_CANNOT_CONNECT_POOL.selector);
+ sf.host.callAgreement(
+ sf.gda,
+ abi.encodeCall(sf.gda.tryConnectPoolFor, (freePool, address(0), new bytes(0))),
+ new bytes(0)
+ );
+ vm.stopPrank();
}
/*//////////////////////////////////////////////////////////////////////////
diff --git a/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreementV1.prop.t.sol b/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreementV1.prop.t.sol
index cfef124724..b29f40b8d2 100644
--- a/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreementV1.prop.t.sol
+++ b/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreementV1.prop.t.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.23;
import "forge-std/Test.sol";
-import { IBeacon } from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
+import { IBeacon } from "@openzeppelin-v5/contracts/proxy/beacon/UpgradeableBeacon.sol";
import "@superfluid-finance/solidity-semantic-money/src/SemanticMoney.sol";
import { ERC1820RegistryCompiled } from "../../../../contracts/libs/ERC1820RegistryCompiled.sol";
diff --git a/packages/ethereum-contracts/test/foundry/superfluid/ERC721.t.sol b/packages/ethereum-contracts/test/foundry/superfluid/ERC721.t.sol
index d59e9756cb..7fd88ddcd2 100644
--- a/packages/ethereum-contracts/test/foundry/superfluid/ERC721.t.sol
+++ b/packages/ethereum-contracts/test/foundry/superfluid/ERC721.t.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { IERC721Metadata } from "@openzeppelin/contracts/interfaces/IERC721Metadata.sol";
+import { IERC721Metadata } from "@openzeppelin-v5/contracts/interfaces/IERC721Metadata.sol";
import { FoundrySuperfluidTester } from "../FoundrySuperfluidTester.t.sol";
import { PoolAdminNFTMock } from "./PoolNFTMock.t.sol";
import { TestToken } from "../../../contracts/utils/TestToken.sol";
diff --git a/packages/ethereum-contracts/test/foundry/superfluid/PoolAdminNFT.t.sol b/packages/ethereum-contracts/test/foundry/superfluid/PoolAdminNFT.t.sol
index 1d33ffbea6..fa408d06ec 100644
--- a/packages/ethereum-contracts/test/foundry/superfluid/PoolAdminNFT.t.sol
+++ b/packages/ethereum-contracts/test/foundry/superfluid/PoolAdminNFT.t.sol
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { IERC165, IERC721, IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
-import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
+import { IERC165 } from "@openzeppelin-v5/contracts/interfaces/IERC165.sol";
+import { IERC721, IERC721Metadata } from "@openzeppelin-v5/contracts/token/ERC721/extensions/IERC721Metadata.sol";
+import { Strings } from "@openzeppelin-v5/contracts/utils/Strings.sol";
import { PoolNFTBaseIntegrationTest, FakePool } from "./PoolNFTBase.t.sol";
import { IPoolNFTBase } from "../../../contracts/interfaces/agreements/gdav1/IPoolNFTBase.sol";
import { IPoolAdminNFT } from "../../../contracts/interfaces/agreements/gdav1/IPoolAdminNFT.sol";
diff --git a/packages/ethereum-contracts/test/foundry/superfluid/PoolNFTBase.t.sol b/packages/ethereum-contracts/test/foundry/superfluid/PoolNFTBase.t.sol
index fc0a513105..db2f8bb02e 100644
--- a/packages/ethereum-contracts/test/foundry/superfluid/PoolNFTBase.t.sol
+++ b/packages/ethereum-contracts/test/foundry/superfluid/PoolNFTBase.t.sol
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.23;
-import { IERC165, IERC721, IERC721Metadata } from "@openzeppelin/contracts/interfaces/IERC721Metadata.sol";
-import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
+import { IERC165 } from "@openzeppelin-v5/contracts/interfaces/IERC165.sol";
+import { IERC721 } from "@openzeppelin-v5/contracts/interfaces/IERC721.sol";
+import { IERC721Metadata } from "@openzeppelin-v5/contracts/interfaces/IERC721Metadata.sol";
+import { Strings } from "@openzeppelin-v5/contracts/utils/Strings.sol";
import { SuperTokenV1Library } from "../../../contracts/apps/SuperTokenV1Library.sol";
import {
PoolNFTBaseStorageLayoutMock,
diff --git a/packages/ethereum-contracts/test/foundry/superfluid/PoolNFTMock.t.sol b/packages/ethereum-contracts/test/foundry/superfluid/PoolNFTMock.t.sol
index b58f105d03..6d1ac8b3b2 100644
--- a/packages/ethereum-contracts/test/foundry/superfluid/PoolNFTMock.t.sol
+++ b/packages/ethereum-contracts/test/foundry/superfluid/PoolNFTMock.t.sol
@@ -2,7 +2,7 @@
// solhint-disable reason-string
pragma solidity ^0.8.23;
-import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
+import { Strings } from "@openzeppelin-v5/contracts/utils/Strings.sol";
import {
IGeneralDistributionAgreementV1, ISuperfluid
diff --git a/packages/ethereum-contracts/test/foundry/superfluid/Superfluid.BatchCall.t.sol b/packages/ethereum-contracts/test/foundry/superfluid/Superfluid.BatchCall.t.sol
index 90e3426610..e270d2c572 100644
--- a/packages/ethereum-contracts/test/foundry/superfluid/Superfluid.BatchCall.t.sol
+++ b/packages/ethereum-contracts/test/foundry/superfluid/Superfluid.BatchCall.t.sol
@@ -12,7 +12,7 @@ import { SuperTokenV1Library } from "../../../contracts/apps/SuperTokenV1Library
import { SuperAppMock } from "../../../contracts/mocks/SuperAppMocks.t.sol";
import { SimpleForwarder } from "../../../contracts/utils/SimpleForwarder.sol";
import { ERC2771Forwarder } from "../../../contracts/utils/ERC2771Forwarder.sol";
-import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol';
+import { Ownable } from '@openzeppelin-v5/contracts/access/Ownable.sol';
import { BaseRelayRecipient } from "../../../contracts/libs/BaseRelayRecipient.sol";
// A mock for an arbitrary external contract
@@ -43,6 +43,8 @@ contract TestContract {
contract TestContract2771 is TestContract, Ownable, BaseRelayRecipient {
error NotOwner();
+ constructor() Ownable(_msgSender()) {}
+
// Expects the msgSender to be encoded in calldata as specified by ERC-2771.
// Will revert if relayed for anybody but the contract owner.
function privilegedFn() public returns (bool) {
@@ -454,7 +456,7 @@ contract SuperfluidBatchCallTest is FoundrySuperfluidTester {
// only the owner of the forwarder shall be allowed to relay
vm.startPrank(eve);
- vm.expectRevert("Ownable: caller is not the owner");
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, eve));
forwarder.forward2771Call(
address(testContract),
alice,
@@ -619,7 +621,7 @@ contract SuperfluidBatchCallTest is FoundrySuperfluidTester {
// eve isn't allowed to withdraw
vm.startPrank(eve);
- vm.expectRevert("Ownable: caller is not the owner");
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, eve));
forwarder.withdrawLostNativeTokens(payable(bob));
vm.stopPrank();
@@ -643,7 +645,7 @@ contract SuperfluidBatchCallTest is FoundrySuperfluidTester {
// eve isn't allowed to withdraw
vm.startPrank(eve);
- vm.expectRevert("Ownable: caller is not the owner");
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, eve));
forwarder.withdrawLostNativeTokens(payable(bob));
vm.stopPrank();
diff --git a/packages/ethereum-contracts/test/foundry/upgradability/SuperfluidUpgradeableBeacon.t.sol b/packages/ethereum-contracts/test/foundry/upgradability/SuperfluidUpgradeableBeacon.t.sol
index 5117ad87a5..00029d76cf 100644
--- a/packages/ethereum-contracts/test/foundry/upgradability/SuperfluidUpgradeableBeacon.t.sol
+++ b/packages/ethereum-contracts/test/foundry/upgradability/SuperfluidUpgradeableBeacon.t.sol
@@ -2,6 +2,7 @@
pragma solidity ^0.8.23;
import { Test } from "forge-std/Test.sol";
+import { Ownable } from "@openzeppelin-v5/contracts/access/Ownable.sol";
import { SuperfluidUpgradeableBeacon } from "../../../contracts/upgradability/SuperfluidUpgradeableBeacon.sol";
@@ -32,7 +33,7 @@ contract SuperfluidUpgradeableBeaconTest is Test {
function testRevertNonOwnerUpgrade() public {
ProxiableBeacon proxiableBeacon = new ProxiableBeacon();
- vm.expectRevert("Ownable: caller is not the owner");
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, address(this)));
beacon.upgradeTo(address(proxiableBeacon));
}
diff --git a/packages/ethereum-contracts/test/foundry/utils/TOGA.t.sol b/packages/ethereum-contracts/test/foundry/utils/TOGA.t.sol
index 51c7bda1e5..cf0fe99b8e 100644
--- a/packages/ethereum-contracts/test/foundry/utils/TOGA.t.sol
+++ b/packages/ethereum-contracts/test/foundry/utils/TOGA.t.sol
@@ -5,8 +5,8 @@ import "forge-std/Test.sol";
import { FoundrySuperfluidTester, SuperTokenV1Library } from "../FoundrySuperfluidTester.t.sol";
import { ISuperToken } from "../../../contracts/superfluid/SuperToken.sol";
import { TOGA } from "../../../contracts/utils/TOGA.sol";
-import { IERC1820Registry } from "@openzeppelin/contracts/interfaces/IERC1820Registry.sol";
-import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+import { IERC1820Registry } from "@openzeppelin-v5/contracts/interfaces/IERC1820Registry.sol";
+import { IERC20 } from "@openzeppelin-v5/contracts/token/ERC20/IERC20.sol";
import { TestToken } from "../../../contracts/utils/TestToken.sol";
/**
diff --git a/packages/ethereum-contracts/test/test-solc-compatibility.sh b/packages/ethereum-contracts/test/test-solc-compatibility.sh
index 116f3317ec..c4a397d019 100755
--- a/packages/ethereum-contracts/test/test-solc-compatibility.sh
+++ b/packages/ethereum-contracts/test/test-solc-compatibility.sh
@@ -31,12 +31,12 @@ fi
# from here - don't forget to add 0x to our generated sha256
# workaround to make solc to find OZ library
-ln -sf ../../node_modules/@openzeppelin .
+ln -s ../../lib/openzeppelin-contracts @openzeppelin-v5
# verify they are compatible with the minimum version of the SOLC we support
find contracts/{interfaces/,apps/} -name '*.sol' | while read i;do
- $SOLC --allow-paths '@openzeppelin' $i
+ $SOLC --allow-paths '@openzeppelin-v5' $i
done
echo SUCCESS
-rm -f @openzeppelin
+rm -f @openzeppelin-v5
diff --git a/packages/ethereum-contracts/test/utils/expectRevert.ts b/packages/ethereum-contracts/test/utils/expectRevert.ts
index 0427617c3e..e432e161d4 100644
--- a/packages/ethereum-contracts/test/utils/expectRevert.ts
+++ b/packages/ethereum-contracts/test/utils/expectRevert.ts
@@ -16,12 +16,6 @@ export const expectCustomError = async (
customErrorString: string,
args?: any
) => {
- args
- ? await expect(func)
- .to.be.revertedWithCustomError(contract, customErrorString)
- .withArgs(args)
- : await expect(func).to.be.revertedWithCustomError(
- contract,
- customErrorString
- );
+ const expectation = expect(func).to.be.revertedWithCustomError(contract, customErrorString);
+ args ? await expectation.withArgs(...(Array.isArray(args) ? args : [args])) : await expectation;
};
diff --git a/packages/hot-fuzz/foundry.toml b/packages/hot-fuzz/foundry.toml
index eb05ebf501..2d630772b8 100644
--- a/packages/hot-fuzz/foundry.toml
+++ b/packages/hot-fuzz/foundry.toml
@@ -8,7 +8,8 @@ optimizer_runs = 200
remappings = [
'@superfluid-finance/ethereum-contracts/contracts/=packages/ethereum-contracts/contracts/',
'@superfluid-finance/solidity-semantic-money/src/=packages/solidity-semantic-money/src/',
- '@openzeppelin/=node_modules/@openzeppelin/',
+ '@openzeppelin-v5/=lib/openzeppelin-contracts/',
+ '@openzeppelin/=lib/openzeppelin-contracts/',
'ds-test/=lib/forge-std/lib/ds-test/src/',
'forge-std/=lib/forge-std/src/']
out = 'packages/hot-fuzz/build/foundry/out'
diff --git a/packages/hot-fuzz/package.json b/packages/hot-fuzz/package.json
index f375ec2321..7037b37cbd 100644
--- a/packages/hot-fuzz/package.json
+++ b/packages/hot-fuzz/package.json
@@ -6,9 +6,6 @@
"hot-fuzz": "./hot-fuzz"
},
"bugs": "https://github.com/superfluid-finance/protocol-monorepo/issues",
- "dependencies": {
- "@openzeppelin/contracts": "4.9.6"
- },
"devDependencies": {
"@superfluid-finance/ethereum-contracts": "^1.13.0"
},
diff --git a/packages/sdk-core/package.json b/packages/sdk-core/package.json
index 9e84c7575b..226e326cfa 100644
--- a/packages/sdk-core/package.json
+++ b/packages/sdk-core/package.json
@@ -55,7 +55,7 @@
"pretest": "yarn testenv:start",
"test": "hardhat test --tsconfig \"tsconfig.test.json\"",
"dev": "nodemon -e ts -x yarn test",
- "clean": "rm -rf node_modules; rm -rf dist; rm -rf src/typechain-types; rm -rf src/typechain; rm -rf src/abi; find . -type f -name '*.generated.ts' -exec rm {} +",
+ "clean": "rm -rf node_modules; rm -rf dist; rm -rf typechain-types; rm -rf src/typechain; rm -rf src/abi; find . -type f -name '*.generated.ts' -exec rm {} +",
"test-coverage": "nyc --reporter=html --reporter=lcov --reporter=json yarn test",
"posttest": "yarn testenv:stop",
"check-updates": "ncu --target minor --dep prod,dev",
diff --git a/packages/sdk-core/tasks/build-types.sh b/packages/sdk-core/tasks/build-types.sh
index f22129c155..b7eb72fe55 100755
--- a/packages/sdk-core/tasks/build-types.sh
+++ b/packages/sdk-core/tasks/build-types.sh
@@ -15,5 +15,11 @@ fi
# copy the typechain files over from ethereum-contracts
cp -r ../ethereum-contracts/typechain-types ./src/typechain-types
+# Remove the Address export from typechain-types to avoid conflict with mappedSubgraphTypes
+# OpenZeppelin v5 added a custom error to Address library, giving it a non-empty ABI
+# This causes typechain to generate types for it, but it's not needed for the SDK
+sed -i '/export type { Address } from ".\/@openzeppelin-v5\/contracts\/utils\/Address";/d' ./src/typechain-types/index.ts
+sed -i '/export { Address__factory } from ".\/factories\/@openzeppelin-v5\/contracts\/utils\/Address__factory";/d' ./src/typechain-types/index.ts
+
# compile the typechain files in sdk-core
tsc -p tsconfig.typechain.json
diff --git a/packages/solidity-semantic-money/foundry.toml b/packages/solidity-semantic-money/foundry.toml
index 9313afd96e..a9efc578bc 100644
--- a/packages/solidity-semantic-money/foundry.toml
+++ b/packages/solidity-semantic-money/foundry.toml
@@ -11,7 +11,7 @@ optimizer_runs = 200
via_ir = false
remappings = [
'@superfluid-finance/solidity-semantic-money/src/=packages/solidity-semantic-money/src/',
- '@openzeppelin/=node_modules/@openzeppelin/',
+ '@openzeppelin/=lib/openzeppelin-contracts/',
'ds-test/=lib/forge-std/lib/ds-test/src/',
'forge-std/=lib/forge-std/src/']
diff --git a/packages/solidity-semantic-money/package.json b/packages/solidity-semantic-money/package.json
index a83fa185dd..e7298a9834 100644
--- a/packages/solidity-semantic-money/package.json
+++ b/packages/solidity-semantic-money/package.json
@@ -3,9 +3,6 @@
"description": "Semantic money implementation in solidity.",
"version": "0.1.0",
"bugs": "https://github.com/superfluid-finance/protocol-monorepo/issues",
- "dependencies": {
- "@openzeppelin/contracts": "4.9.6"
- },
"directories": {
"src": "src",
"test": "test"
diff --git a/yarn.lock b/yarn.lock
index 033a0de49d..0178a85b0d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3032,11 +3032,6 @@
find-up "^4.1.0"
fs-extra "^8.1.0"
-"@openzeppelin/contracts@4.9.6", "@openzeppelin/contracts@^4.9.6":
- version "4.9.6"
- resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.6.tgz#2a880a24eb19b4f8b25adc2a5095f2aa27f39677"
- integrity sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA==
-
"@openzeppelin/test-helpers@^0.5.16":
version "0.5.16"
resolved "https://registry.yarnpkg.com/@openzeppelin/test-helpers/-/test-helpers-0.5.16.tgz#2c9054f85069dfbfb5e8cef3ed781e8caf241fb3"