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 @@

Welcome to superfluid protocol-monorepo 👋

- + npm 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"